【原创】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 已经恢复,则将缓存队列中的内容顺序执行)

      上述问题并未针对“异常情况下对 数据库进行操作时可能遇到的问题” 进行深入的说明,具体问题一定会更加复杂。一点体会:若想真正的把数据库同步功能做好,最起码需要深入理解数据一致性的相关理论,若有一个成熟的框架可以使用就更加完美了。 

时间: 2024-12-08 01:25:07

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

【原创】modb 功能设计之“支持对sql语句的相关日志记录”

[需求分析] 终于到了处理 sql 日志的阶段了,万里长征重点的关键一步. 需要考虑解决的问题点如下:  在哪个模块上做 sql 日志记录 都要记录哪些信息才能做到跨机房数据同步时,具有可查询.可分析.可监控的目的 sql 日志记录的模式或者说频率 针对 MoDB 要做跨机房数据的同步这个功能,那么可以对 sql 语句进行记录的"地方"有:  modb 应用中 Atlas 应用中 其中 Atlas 目前已支持 sql 日志的记录,格式如下:  ? 1 [11/25/2013 14:58

link环境下如何使用"md5"技术制作下载器和《网盘软件》之间的同步?

问题描述 link环境下如何使用"md5"技术制作下载器和<网盘软件>之间的同步? link环境下如何使用"md5"技术制作下载器和<网盘软件>之间的同步? 解决方案 计算文件的md5值,和服务器上的比较,如果不一致,就说明文件修改过啦

服务器-多个git server之间如何同步?

问题描述 多个git server之间如何同步? 公司之前只有一个git server服务器,现在要增加到三个,并且有两个server之间的带宽很少.所以现在碰到了一个难点,就是多个git server 服务器之间如何同步? 这个情况在跨国公司应该是很常见的,请教各位是否知道大公司是怎么解决的?非常感谢.

cas-单点登录系统怎样与其它应用之间数据同步?

问题描述 单点登录系统怎样与其它应用之间数据同步? 单点登录系统里有用户的基本信息可以修改.第次登录都修改数据库,不是太合理.是否有什么更好的解决方法? 解决方案 设计模式里面有一种 模式, 观察者模式,可能实现你要的结果.

java多线程中两个容器之间的同步

问题描述 java多线程中两个容器之间的同步 写了一个多线程的爬虫(对多线程不熟悉),但是每次队列中都有重复的元素,我把代码逻辑贴上来,大家帮我看一下,谢谢了: 在进程中: queue = LinkedBlockingQueue set = ConcurrentSkipListSet 在每个进程中使用了bfs bfs: while(!queue.empty()){ s = queue.poll() //...逻辑代码 set.add(s) //对s所有子状态扩展 for(son : s.sons

tomcat集群memcached解决session共享 之 多个memcached节点之间如何同步session

问题描述 tomcat集群memcached解决session共享 之 多个memcached节点之间如何同步session tomcat集群memcached解决session共享 之 多个memcached节点之间如何同步session 问题简单描述: 多个tomcat集群,并且有多个memcached节点做session共享, 那么如何保证每一个tomcat从不同的memcached节点取session的一致性? 是不是每一个tomcat的session都会自动写入所有的memcached

介绍一种有效的方法实现在RTC中多个stream之间代码同步

Rational Team Concert(RTC)虽然作为目前流行的代码管理工具之一,但对于多 stream 上的源代码同步,大多数http://www.aliyun.com/zixun/aggregation/7155.html">开发人员是通过在每个 stream 上重复提交代码并且人工保证同步,这无疑增加了我们平时开发的成本.本文将主要介绍一种有效的方法,以实现在 RTC 中多个 stream 之间代码同步,从而降低重复提交代码的成本,避免由于重复提交代码所带来的缺陷. Strea

多个客户端控制同一台硬件设备,如何保证客户端之间的同步?

问题描述 目前应用环境:PC上安装监控软件,通过Socket与硬件通讯,获取硬件状态信息,并下发控制指令.预实现应用环境:多台PC上安装监控客户端软件,通过Socket控制同一台硬件,如果某个客户端对硬件下发了控制指令.改变了硬件状态信息,其它客户端能及时获知,并进行硬件状态信息的调整和控制功能的使能.现在想使用C/S架构实现,服务器端直接与硬件通讯,客户端通过服务器端间接和硬件通讯,那么如何保持各个客户端之间的同步呢?例如,对硬件的某个控制功能类似开关,"开"了以后就只能"

【原创】modb 功能设计之“支持部分MySQL客户端协议”-3

 在研究完 MySQL 官方文档上对 Connector/C 的说明后,终于可以 开工实践了,先搞个小 demo 出来运行看看.  开发环境:Windows XP SP3 v11 + VS2010 + MySQL Connector/C 6.1.2 测试代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <stdio.h> #