大多数时候,dble结点是无状态的,所以可以用常用的高可用/负载均衡软件来接入各个结点。
这里不讨论各个负载均衡软件的使用。
主要讨论一下某些情况下需要同步状态的操作和细节。
注:本部分内容需要额外部署zookeeper用于管理集群的状态和同步。
以ZK为例
# 开启集群模式
clusterEnable=true
# 集群模式元数据中心为zk
clusterMode=zk
# zk地址
clusterIP=10.186.19.aa:2281,10.186.60.bb:2281
#zk为dble提供的根目录
rootPath=/dble
#本组dble的组名
clusterId=cluster-1
# 是否需要同步Ha状态
#needSyncHa=false
# 拉取一致性binlog线的超时时间
#showBinlogStatusTimeout=60000
#自增序列类型
sequenceHandlerType=2
#自增序列默认开始时间
#sequenceStartTime=2010-11-04 09:42:54
#自增序列类型为3时,instanceId是否由ZK生成
#sequenceInstanceByZk=true
instanceName 实例名称,用于发起集群任务或者汇报自己完成集群任务的标记 instanceId (自增序列使用,根据类型范围为0到1023 或者0到511)
通过执行脚本init_zk_data.sh方式将某个结点的配置文件等数据写入ZK,所有结点启动时都从ZK拉取配置数据。
在第一个结点第一次启动时自动将自己的配置文件写入ZK,其他结点启动时从ZK拉取。
第一个结点的判定:用分布式锁抢占的方式,未抢占到结点会阻塞等待直到获取到分布式锁,如果此时初始化标记已经被设置,则从ZK拉取配置,否则将自己本地配置写入。
做DDL时候会在执行的某个节点成功后,将消息推给ZK,ZK负责通知其他结点做变更。流程如下图:
注:
-
新结点启动时,加载元数据前会检测是否有其他结点在做DDL变更,如果有,则等待。
否则加分布式锁防止加载元数据期间其他结点做DDL变更, 直到元数据加载完释放分布式锁 。 -
回收指的是:每个节点ddl完成后会告知分布式协调器自己已经完成,并检查如果所有结点均完成,则删除schema.table 结点。此操作为原子操作。
-
发起结点故障:如果执行DDL的结点故障下线,其他结点会侦听到此消息,保证解开对应结点的tablemeta锁,并记录故障告警(如果配置了告警通道),需要运维人工介入修改ZK对应ddl结点的状态,检查各个结点meta数据状态,可能需要reload metadata。
-
逻辑上不应该有某个监听节点上加载meta失败的情况,如果发生了,告警处理
(人工介入对应结点的meta是不正确的,需要reload meta)
-
注:view目前是异步模式,可能存在某个间隙view修改成功,查询仍旧拿到旧版的view结构。
执行流程如下图:
注:如果在部分结点失败,则会返回错误及错误原因以及结点名。 设计影响面:db.xml,sharding.xml, userxml ,sequence_conf.properties 和sequence_db_conf.properties
获得后端数据库实例的一致性binlog位置。由于两阶段提交的第二阶段执行在各结点无法保证时序性和同步性,所以直接下发show master status获取binlog可能会造成不一致。
如下图,当前端收到show @@binlog.status 语句时,遍历当前所有活动session查看状态 。
若session处于绿色区域,则在进入红色区域前等待知道show @@binlog.status结果返回
若存在session处于红色区域,则需要等待所有红色区域的session返回结果走出红色区域后下发show master status。
此处有可能有死锁发生。
场景:session1 正在更新tableA,处于绿色区域,session2下发有关于tableA 的DDL,等待 metaLock解锁,处于红色区域.session3 下发show @@binlog.status.
此时session1 等待session3, session2等待session1,session3等待session2.
因此引入超时机制。如果session3 等待超过showBinlogStatusTimeout(默认60s,可配置),自动放弃等待,环状锁解除。
1.收到请求后同步通知ZK,先等待本身结点准备工作结束,之后zk通知其他结点处理。
2.所有结点遍历各自的活动的session,进入红色区域的等待处理完成,绿色区域的暂停进入红色区域。
3.结点将准备好/超时将状态上报给ZK
4.主节点等待所有结点状态上报完成之后,判断是否可以执行任务,若是,则执行show @@binlog.status并返回结果,否则报告本次执行失败。
5.主节点通过ZK通知各结点继续之前的任务
若有结点超时未准备好,主节点会报超时错误,并通过ZK通知各结点继续之前的任务。
主节点执行过程中故障下线,其他结点会感知,保证自己结点一定时间后自动解锁继续原有任务。
ZK状态需要人工干预。人工等待所有结点超时之后,手动删除/修改zk上的状态信息以便下次执行时不出问题。
在使用集群模式是,使用zk进行view视图信息的管理,使得整个dble集群能够进行视图信息的同步 由于视图只用于数据查询且不会造成数据异常的属性,在视图同步时采用异步同步的方法
注 在zk上的view数据信息如下形式 key schema.table value {"serverId":"create_Server_id", "createSql":"view_create_sql"}
dble启动时候会在online的目录下注册自己的信息,如果此时正在做DDL,会阻塞一段时间,防止表结构元数据不一致。
功能:
1.作为集群协调时候检查哪些dble完成了对应任务的标准
2.dble故障后同集群的其他实例会发现状态并处理完收尾的状态,主要是DDL状态残留,拉取一致性binlog线或者暂停流量的残余。
当启用needSyncHa时候,此选项才生效
1.申请分布式锁
2.本地执行disable
3.将信息写入集群
4.等待所有结点完成disable
5.完成并清理
6.释放分布式锁
1.申请分布式锁
2.本地执行enable
3.将信息写入集群
4.释放分布式锁
5.其他订阅结点异步完成enable
1.申请分布式锁
2.本地执行switch
3.将信息写入集群
4.释放分布式锁
5.其他订阅结点异步完成switch
- 申请分布式锁 pause_node.lock
- 通知其他结点
- 本结点停流量
- 等待其他结点完成停流量 或者超时
- 返回暂停成功或者失败
- 释放分布式锁
- 申请分布式锁 pause_node.lock
- 本结点恢复流量
- 通知其他结点
- 等待其他结点完成恢复流量 或者超时
- 返回暂停成功或者失败
- 释放分布式锁
在使用集群模式时,未完成的XA日志会存放在zookeeper上,更加安全,防止某台机器硬盘物理损坏导致日志丢失(此处可能会有并发高吞吐引发的性能及其他问题,待测试)。
rootPath(配置在cluster.cnf中的)
clusterId(配置在cluster.cnf中的)
conf
inited
status
operator
instanceName(临时的,key为bootstrap.cnf配置内容。功能:reload响应id)
sharding(sharding.xml的json信息)
db(db.xml的json信息)
user(user.xml的json信息)
migration(用于暂停流量)
pause
instanceName(临时的,key为bootstrap.cnf配置内容。功能:响应结点)
resume
instanceName(临时的,key为bootstrap.cnf配置内容。功能:响应结点)
sequences
instanceid //zk 分布式方式
incr_sequence//批量步长方式
table_name
common(sequence_conf.properties 或者sequence_db_conf.properties)
binlog_pause
status (发生时建立,结束后回收)
instanceName(临时的,key为bootstrap.cnf配置内容。功能:响应结点)
lock
syncMeta.lock(临时的,启动时防止元数据变更)
confInit.lock
confChange.lock
binlogStatus.lock
ddl_lock/schema.table
view_lock/`schema`.`table`
dbGroup_locks/groupName
pause_node.lock
online
instanceName(临时的,key为bootstrap.cnf配置内容。)
ddl
schema.table(ddl运行时)
instanceName(临时的,key为bootstrap.cnf配置内容。功能:响应结点)
schema.table2
xalog
node1
node2
view
schema:view
operator (订阅目录)
schema.view:(update/delete,注意:create当作update处理)
instanceName(临时的,key为bootstrap.cnf配置内容。功能:响应结点)
dbGroups
dbGroup_status
groupName
dbGroup_response
instanceName(临时的,key为bootstrap.cnf配置内容。功能:响应结点)
类twitter snowflake 方式,ZK完成的工作是生成每个节点的instanceID。
类offset-step 方式,ZK完成的工作是存储当前的Step值。