前言

什么是数据一致性分发?

比方说对于电商中的订单服务,在生成订单数据后,需要将订单数据同步到其他系统/服务。
image.png
来自【1】

据分发的通常做法-双写

双写一般有两种做法:
1、将写数据库和发送消息放到一个事务下,如下图;
这种方式存在一些问题:如果发消息异常(网络抖动什么的)了,数据就会回滚,那么就可能出现在服务内数据不存在,在MQ中却存在数据的情况;
image.png
来自【1】

2、第二种做法,在保存完数据库后,再发送消息
采用这种方式的话,为了保证下游收到消息,防止消息丢失,需要采用有对应的补偿重试逻辑(目前,我所在的项目就是这么做)。

  1. //保存到数据库
  2. saveToDb(Entity o);
  3. try{
  4. //2、投递消息
  5. sendMessageToMQ(msg);
  6. }catch (Exception e){
  7. }

方案1-事件性发件箱模式

Transactional Outbox
简单来说:
1、新增一个消息表,订单服务将落订单数据和落消息表数据放在同一个事务内
2、新增一个线程或服务,从消息表拉取消息投递到MQ中
image.png
来自【1】


方案2-变更数据捕获(Change Data Capture, CDC)

简单来说,就是整一个服务,订阅订单服务中订单表的数据变更记录,并解析成消息,投递到MQ
image.png
来自【1】
开源框架工具:

  1. 第一个是阿里开源的Canal,目前在github上有超过1.4万颗星,这个项目在国内用得比较多,之前在拍拍贷的实时数据场景,Canal也有不少成功的应用。Canal主要支持MySQL binlog的增量订阅和消费。它是基于MySQL的Master/Slave机制,它的Miner角色是通过伪装成Slave来实现的。这个项目的使用文档相对比较完善,建议大家一步参考学习。
  2. 第二个是Redhat开源的Debezium,目前在github上有超过3.2k星,这个项目在国外用得较多。Debezium主要是在Kafka Connect的基础上开发的,它不仅支持mysql数据库,还支持postgres/sqlserver/mongodb等数据库。
  3. 第三个是Zendesk开源的Maxwell,目前在github上有超过2.1k星。Maxwell是一个轻量级的CDC Deamon,主要支持MySQL binlog的变更数据捕获和处理。
  4. 第四个是Airbnb开源的SpinalTap,目前在github上有两百多颗星。SpinalTap主要支持MySQL binlog的变更捕获和处理。这个项目的星虽然不多,但是它是在Airbnb SOA服务化过程中,通过实践落地出来的一个项目,值得参考。

比较
image.png


参考

1、https://gitee.com/geektime-geekbang/geektime-distributed
2、https://app.yinxiang.com/fx/f7fdf855-a354-42a3-a43a-c3af57fb64cc