【原创】modb 功能设计之“多级 modb 之间的同步”

简介:
      modb 在最初设计中采用的是两级模型,但很快就遇到了多级同步的需求。解决多级同步问题首先需要引入多级路由 key ,即将原来两级模型中的单个 key 值扩展为 key 的 array ,具体变化如下:  

两级使用的数据格式  
?
1
2
3
4
5
6
7
8
{
     "src" : "172.16.80.111" ,
     "keys" : "key_1" ,
     "app" : "A" ,
     "state" : "transfer"
     "sql" : "insert into users values(?,?,?)" ;
     "sql-args" : [1, 2, "abc" ]
}
多级使用的数据格式  
?
1
2
3
4
5
6
7
{
     "src" : "172.16.80.111" ,
     "keys" : [ "key_1" , "key_2" ]
     "app" : "A" ,
     "sql" : "insert into users values(?,?,?)" ;
     "sql-args" : [1, 2, "abc" ]
}
而在 modb 的业务逻辑处理中也需要增加相应的处理,具体如下:  

      假设处理的是三级数据同步情况,分别为 modb-A 、modb-B 和 modb-C 三级平台域(分别位于三级服务域中),且 A 是 B 的上级,B 是 C 的上级。A 级平台域中某业务对数据进行了变更,然后需要将此变更信息同步到 B 和 C 级平台域。  
 

通过数据操作入口进行数据变更后,将发送如下消息给 modb-A:  
?
1
2
3
4
5
6
7
{
     "src" : "172.16.80.111" ,
     "keys" : [ "key_B" , "key_C" ]
     "app" : "A" ,
     "sql" : "insert into users values(?,?,?)" ;
     "sql-args" : [1, 2, "abc" ]
}
modb-A 接收到此消息后(此时 A 级平台域的数据库已经发生了变更),并根据配置将  
  • 向同在 A 级的其他平台域进行消息转发;
  • 根据 key 值进行对下级的路由转发;
在进行消息转发前,modb-A 还会对消息内容做如下修改:  
?
1
2
3
4
5
6
7
{
     "src" : "172.16.80.111" ,
     "keys" : [ "key_C" ]
     "app" : "A" ,
     "sql" : "insert into users values(?,?,?)" ;
     "sql-args" : [1, 2, "abc" ]
}
即从 keys 数组中移除 key_B 。  

      modb-B 在接收到上述消息后,将从中提取出 sql 内容进行执行,并对 keys 数组内容进行检查,看是否还有其他 key 的存在,若有,则表明需要继续进行向下级的路由转发。            
      modb-B 重新获取到该消息后(此时 B 级平台域的数据库已经得到了更新),首先检测 keys 数组中是否还有其他 key 存在,若有,则在进行转发前会对消息内容做如下修改:  
      (这里 modb-B 先后两次作为 consumer 收到 rabbitmq 消息是因为分别订阅了远端和本地的 queue 所致,好处是处理起来模型统一        
?
1
2
3
4
5
6
7
{
     "src" : "172.16.80.111" ,
     "keys" : []
     "app" : "A" ,
     "sql" : "insert into users values(?,?,?)" ;
     "sql-args" : [1, 2, "abc" ]
}
即从 keys 数组中移除 key_C 。  

      modb-C 接收到上述消息后,将从中提取 sql 内容进行执行,并对 keys 数组内容进行检查,看是否还有其他 key 的存在,若没有,则表明已不再需要继续进行路由。  
      modb-C 重新获取到该消息后(此时 C 级平台域的数据库已经得到了更新),首先检测 keys 数组中是否还有其他 key 存在,若没有,则只需要对相同服务域中的平台域进行广播,而无需进行下一级转发。  

      上述模型的优点是简单,仅通过配置就可以完成多级关系的数据同步功能;缺点是存在单点,不具有动态变更上下级关系的能力,需要通过其他方式进行后续配置。  

可能遇到的异常情况:  
  • rabbitmq 服务器异常 -- 业务更新本地数据库成功后,将发送通知消息到 rabbitmq 服务器,需要业务端能够判断出“服务器不可用”状态,并触发重传等操作;
  • modb 进程异常 -- 业务更新本地数据库成功后,发送通知消息到 rabbitmq 服务器,若要求在 modb 进程异常的情况下消息不丢失,则需要 rabbitmq 启用对消息的持久化功能,并且最好取消掉 exclusive 和 auto_delete 等相关属性的设置,可能还需要处理当 queue 不存在时消息被 blackholed 的情况;
  • Atlas 异常 -- 若在业务尚未成功更新本地数据库前发生 Atlas 异常,则要求业务能够告之当前情况下“无法建立数据库连接”;若在业务成功更新本地数据库后发生 Atlas 异常,此时向外部 modb 同步当前更新没有问题,但无法同步外部 modb 对本地数据库的更新。(可能的一种解决办法:令 modb 支持缓存功能,当发现 Atlas 异常时则将更新消息放入缓存队列,并在每次接收到新的更新消息时触发一次针对 Atlas 是否恢复的检测。若 Atlas 已经恢复,则将缓存队列中的内容顺序执行

      上述问题并未针对“异常情况下对   数据库进行操作时可能遇到的问题”   进行深入的说明,具体问题一定会更加复杂。一点体会:若想真正的把数据库同步功能做好,最起码需要深入理解数据一致性的相关理论,若有一个成熟的框架可以使用就更加完美了。  
相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
4月前
|
SQL 数据安全/隐私保护
怎样解决上下级关系文件查看的权限控制问题
怎样解决上下级关系文件查看的权限控制问题
25 0
|
11月前
|
数据库
多主复制的适用场景(2)-需离线操作的客户端和协作编辑
3.1.2 需离线操作的客户端 应用在断网后仍需继续工作。 如手机、PC和其他设备上的日历应用。无论设备当前是否连网,都需随时查看
57 0
|
算法 Linux
linux多线程同步设计
linux多线程同步设计
130 0
linux多线程同步设计
|
存储 监控 安全
lsyncd 配合 rsync 实时差异同步节点文件
lsyncd 配合 rsync 实时差异同步节点文件
393 0
|
SQL 存储 关系型数据库
PostgreSQL 流复制搭建主从环境,同步和异步的解释,压力测试,主从角色切换|学习笔记
快速学习PostgreSQL 流复制搭建主从环境,同步和异步的解释,压力测试,主从角色切换
731 0
PostgreSQL 流复制搭建主从环境,同步和异步的解释,压力测试,主从角色切换|学习笔记
|
机器学习/深度学习 算法 关系型数据库
MySQL组复制构建在Paxos分布式算法基础上实现的
MySQL组复制构建在Paxos分布式算法基础上实现的
318 0
|
前端开发 JavaScript .NET
【自然框架】 之 主从表的添加、修改
摘要 1、 这里不是说如何做一个人员管理,这里要说的是自然框架如何处理主从表的添加、修改。人员管理只是一个例子。2、 人员管理的表的“结构”。3、 Tab标签页,通过js脚本+iframe实现的Tab效果。
1468 0

热门文章

最新文章