异构数据库业务数据同步机制设计
基本场景和要求:
- 变更管理基本考虑是业务级别,可能需要进行业务处理,不适于使用系统级通用的数据变更管理机制
- 变更管理的信息包括学生信息、教师信息、家长信息和组织架构信息。
- 变更的单位为信息条目,简单起见,不考虑条目之间的依赖和关联关系
- 变更通知的范围包括市州-区县-学校、组织
- 同一类型和范围的条目支持批量操作,最多 50 条/批(不超过 100K)
- 整体的变更过程应该为异步方式,各个处理阶段进行解耦。可以提供在各个阶段的最大的性能模式。而且不影响和依赖其他的处理过程。
- 支持主动模式(通知模式) 和被动模式(基于时间标志的访问)
基本构想和流程如下,当需要记录的变更信息进行变更的时候,使用触发器将变更要素(类型和 ID) 将变更记录到变更信息表中。(这一步处理的效率至关重要,可以考虑使用触发存储过程,工作表和历史表分离,快速只增加记录等方式处理)。
变更信息记录到变更信息表后,使用一个变更通知服务,跟踪变更信息表,并及时的将变更信息检索,处理,转换为变更通知信息,发送到变更消息总线对应的主题中去。
在需要接收数据变更的系统中,部署变更数据订阅和处理服务。此服务订阅其角色权限相关的主题,如果主题中有新的发布消息,则会及时收到此消息。
系统要素
数据变更表
数据变更表包括工作表和归档表两个表,表的结构相同,工作表只保存当天的工作记录,每天定时将已经通知完成的数据记录转移到归档表中。这样设计的目的是通过限制工作表的大小,保证数据变更记录的性能。
数据变更表的基本结构为:
- ID - ID 由时间戳+序号确定,为唯一 ID
- TYPE 变更类型, 第一位为数据操作类型 1-增加 2-移除 3-非关键修改 4-关键修改;第二位为业务类型 1-学生 2-家长 3-教师 4-学校 5-机构
- content 变更内容,jsonb,安业务需求的变更内容,如变更前值,后值等,也可以简单为空
- CID - contentid,变更信息记录原始标识,为 bigint(转化后)
变更触发器和存储过程
在需要监控的数据表上部署相应的数据变更触发器,当数据变更时,向想要的变更内容(通常只包括变更项目和类型)追加到变更信息表中,这一阶段的工作就已经完成。和具体的变更处理进行了解耦。
变更处理的存储过程,可以区分不同的变更类型和内容,并生成新的变更事件 ID,写入到变更信息表中。
变更通知服务
数据变更通知服务程序,持续扫描是否有新的变更信息,并根据变更程序,处理并生成变更消息,发送到对应的消息主题当中。
变更通知服务,同时还兼有维护工作表和归档表数据转移的职责,每天定时将已经通知完成的记录,转移到归档表中。
变更消息总线
变更消息总线基于 MQTT 的服务器如 emqx 实现。也就是说,变更消息总线技术,基本上基于公开标准的 MQTT3.1 协议。基本 QOS 级别为 1(保证收到一次)。
变更消息的发送基于业务+范围层次化的主题结构,级别结构如下:
一级主题主要是业务类型:
- 1 student 学生 1
- 2 stuinfo 学生详情 2
- 3 guardian 家长 3
- 4 teacher 教师 4
- 5 school 学校 5
- 6 organization 机构 6
其次是范围层次,为简化起见,使用三级范围层次,分别为:
市州编码/区县编码/学校编码
主题的编码示例如下:
如 student/5101/07/101
表示的是这是一个学生变更通知。 市州订阅 student/5101/#
;区县订阅 student/5101/07
;学校订阅 student/5101/07/101
(为转义的学校编码)。当该学校的学生信息发生变化时,向此主题发送一个学生变更的信息,三级接收者都会以不同的角色接收到这个消息。
这种方式需要解决的主要问题是:
- 消息主题路径的规划和管理比较复杂,特别是授权管理和动态的路径管理。
主题和消息规划还有另外一种思路,相对比较简单。 主题只有两个层次 业务类型/业务范围(市州)。 消息发送时,逻辑上而言,所有订阅此业务和市州之下的订阅者都会收到消息,但在消息结构上,标注了消息的主要信息,但消息内容加密,只有授权的接收者才能通过协商的密钥进行解密。这一方式需要解决的问题包括:
- 一个密钥分发和协商体系
- 如果不能使用主题路径,一个消息可能需要多次加密和分发,带来了处理的复杂性
消息发布方为变更通知服务;消息订阅方为变更订阅服务。
变更订阅服务
变更订阅服务,同样是一个 MQTT 客户端程序,同时连接需要变更目标的数据库。
通过订阅特定的数据变更主题
时间标志和处理
为了方便进行版本和技术状态的管理,每条记录都有一个时间版本标志字段 rversion。 rversion 的定义和使用方式如下:
- rversion = 0|Date.now()/1000,即 rversion 基本可以表示为当前时间戳秒,但新生成时间戳
- rversion 只能增加,不能减少
- rversion % 2 = 0,即时间标志为偶数时,表示此记录已更新,但未通知;如果为奇数,则表示已通知
- 在数据库内部,更新数据应生成新时间版本标记,方法为 rversion = rversion + 2 - rversion % 2,表示在原有版本上有未通知的新版本。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 开发用的 SSL 体系
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论