微服务--数据同步

Posted 喵叔哟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务--数据同步相关的知识,希望对你有一定的参考价值。

一、案例

在某商城系统中有如下三个表:

  1. 商品表
序号字段
1商品编号
2名称
3分类
4型号
5生产日期
6商品条码
  1. 订单表
序号字段
1订单编号
2下单时间
3下单用户
4总金额
  1. 子订单表
序号字段
1子订单编号
2商品编号
3单价
4数量
  1. 采购表
序号字段
1采购编号
2下单日期
3供应商
4总金额
  1. 采购子表
序号字段
1子采购编号
2商品编号
3单价
4数量

该商城按照微服务划分原则把商品相关的接口放在了商品服务中,把订单相关的接口放在订单服务中,把采购相关的接口放在采购服务中。并且后台管理系统具有如下查询功能:

  1. 根据商品型号、分类和生产日期、编码查询订单;
  2. 根据商品型号、分类和生产日期、编号查找采购单。

上面的这两种查询功能按照如下顺序执行:

  1. 先按照商品字段查询匹配的商品信息;
  2. 在订单服务中或者采购服务中查找对应商品的订单。

该方案存在一定的问题:

  1. 商品数量越多,查询出来符合要求的商品就越多,那么订单和采购服务查询的效率就会越来越低;
  2. 这里很明显,商品是一个核心服务,依赖这个核心服务的服务会越来越多,商品数量越来越多,那么商品服务就会出现请求超时的情况,进而造成依赖于它的服务也出现请求失败的问题。

二、数据冗余方案

要解决上一小节中的问题,我们首先会先到的方案是数据冗余。所谓的数据冗余就是在订单表和采购单表中增加商品信息的字段。这样每次查询订单和采购单的时候,就不需要依赖商品服务了,那么这里又出现了一个问题,如果商品更新了,怎么同步冗余数据。一般来说有两种方法:

  1. 每次更新商品后,再调用订单和采购服务更新冗余数据。这个方法会出现 数据一致性问题依赖问题。如果订单和采购服务的冗余数据更新失败,那么整个操作流程都要回滚,如果不进行回滚商品服务的数据和订单以及采购服务的冗余数据又不一致了,如果对整个流程进行回滚的话,就出现了非核心服务导致核心服务数据不正常的情况。从职责方面来说,我们更新商品信息关注的是商品服务,但现在又需要去调用其他的服务,显然不合理,并且后续如果被依赖的服务太多,那么每次更新商品服务就要去调用其他服务来更新冗余数据,增加更新失败的风险。
  2. 每次更新商品后,向MQ发布一条消息,订单和采购服务收到消息后更新各自的冗余数据。该方法商品服务不需要调用其他服务,只需要发送一条MQ即可,并且如果订单和采购服务的冗余数据更新失败了只需要使用MQ的重试机制即可,也不会影响到商品数据。但是这个方法依然存在几个问题,首先我们并不是只保存商品信息就行了,还需要保存商品分类和生产批号等冗余信息,那么就要订阅分类和生产批号等变更的消息;其次每个依赖商品服务的服务都需要实现冗余数据更新的逻辑,这样就造成了代码重复问题;最后这么多的消息订阅,就会出现MQ消息类型过多,调试的时候会搞不清楚消息被哪个节点消费了。

三、解耦业务逻辑的数据同步方案

为了解决上面的问题,又引入了解耦业务逻辑的数据同步方案,大致思路如下:

  1. 把商品和相关的表实时同步到需要一台和使用这些数据的数据库中;
  2. 查询采购和订单服务中的数据时,直接关联同步过来的商品表相关数据即可;
  3. 禁止采购和订单服务修改商品和相关的表。

这个方案避免了两个问题:

  1. 商品无需依赖其他服务,如果其他服务的冗余数据同步失败,也不需要回滚自身流程;
  2. 采购和订单服务不需要关注冗余数据同步。

但是这个方案的缺点是,增加了采购和订单数据库的存储空间。

四、总结

本篇文章简要介绍了微服务中数据同步的方案,在实际开发中具体使用哪种方案,视情况而定。

使用 Kafka 在两个微服务之间同步数据

【中文标题】使用 Kafka 在两个微服务之间同步数据【英文标题】:Using Kafka for syncing data between two microservices 【发布时间】:2020-02-14 04:43:18 【问题描述】:

我正在尝试使用 kakfa 为两个微服务 A 和 B 同步数据。

A 将公司中一组员工的一些数据存放在数据库表中。然后最终用户将从 UI 触发一个事件到 A 的后端服务,在该服务中它将 kakfa 消息发送到 B 订阅的主题。

B 然后从消息或暂存表中获取数据,对其进行验证并保存到自己的数据库表中。

我的问题是..

    每家公司的员工人数可以从 10 到 1000 人不等,并且可能有多家公司尝试在一年中的某个时间同步数据。所以性能是一个问题。什么是分配负载的好方法?意思是..我应该将信息设计为员工级别的吗?这意味着可能有数千条消息,尽管从设计上讲这将是最简单的。还是应该在公司层面?或公司内的一组员工?微服务没有做太多的处理和持久化到表中。它能够处理负载吗?限制因素是什么?

    我们正在处理的数据是存储在 DB 中的 JSON。有一个临时表并使用消息中的某种主键从 B 查找会更好吗?还是让消息中的所有数据都可以?每个员工的 JSON 数据并没有那么大,但如果汇总到一组员工,比如说 100 人,它可能是 10-100 千字节。我们是否通过从表格中查找数据来购买很多东西?

    我们需要能够跟踪状态/错误,以便最终用户了解任何问题并执行操作以更正数据和/或尝试重新同步。我想到的一些方法是创建一个表,将其称为 BATCH_JOBBATCH_TASK 表以跟踪工作级别的请求(如前所述,一组员工的 UI 事件触发重新同步过程)和任务(员工级别)。还是有更清洁的方法?

任何帮助/设计提示将不胜感激。

【问题讨论】:

为什么 A 不能同时写入一个主题,该主题会被下沉到数据库中? 【参考方案1】:

什么是分配负载的好方法?

简短的回答是使用具有大量分区的自定义分区方案。说 100。

或者您可以为每个公司创建一个主题,具体取决于您是否为每个主题使用不同的记录架构

我们是否通过从表格中查找数据来购买很多东西?

好吧,您不能像查询表格那样轻松地查询主题,所以这就是好处……您还可以使用 KTable 和交互式查询

我们正在处理的数据是存储在 DB 中的 JSON

我假设您不只是将一个 BLOB 列放入数据库(而且您也没有明确说明您使用的是什么数据库)。

就个人而言,我建议您使用 Avro 和 Kafka Connect 将主题放入数据库。这是 Kafka API 中此类任务的推荐解决方案,无需引入其他项目(如 Spark)或编写自己的数据库代码

我们需要能够跟踪状态/错误,以便最终用户了解任何问题并采取措施纠正数据

表可以工作,但是如果您可以将记录写入表,您还可以将事件写入另一个 Kafka 主题并从中获取“通知”

【讨论】:

以上是关于微服务--数据同步的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构常见的分布式事务解决方案

Java高级架构:微服务架构的核心概念

从经典架构项目中透析微服务架构的核心概念和充血模型

从经典架构项目中透析微服务架构的核心概念和充血模型

软件架构---微服务架构

多研究些架构,少谈些框架 -- 论微服务架构的核心概念(转)