数据冗余一致性优化 迈不过友情╰ 2022-05-21 01:12 159阅读 0赞 原文地址:https://mp.weixin.qq.com/s?\_\_biz=MjM5ODYxMDA5OQ==&mid=403963671&idx=1&sn=51a2d2fd70212451cd5f22bbe2c6f8d6&scene=21\#wechat\_redirect 本文主要讨论四个问题: (1)为什么会有冗余表的需求 (2)如何实现冗余表 (3)正反冗余表谁先执行 (4)冗余表如何保证数据的一致性 一、需求缘起 互联网很多业务场景的数据量很大,此时数据库架构要进行水平切分,水平切分会有一个patition key,通过patition key的查询能够直接定位到库,但是非patition key上的查询可能就需要扫描多个库了。 例如订单表,业务上对用户和商家都有订单查询需求: Order(oid, info\_detail) T(buyer\_id, seller\_id, oid) 如果用buyer\_id来分库,seller\_id的查询就需要扫描多库。 如果用seller\_id来分库,buyer\_id的查询就需要扫描多库。 这类需求,为了做到高吞吐量低延时的查询,往往使用“数据冗余”的方式来实现,就是文章标题里说的“冗余表”: T1(buyer\_id, seller\_id, oid) T2(seller\_id, buyer\_id, oid) 同一个数据,冗余两份,一份以buyer\_id来分库,满足买家的查询需求; 一份以seller\_id来分库,满足卖家的查询需求。 二、冗余表的实现方案 【方法一:服务同步写】 ![640_wx_fmt_png_tp_webp_wxfrom_5_wx_lazy_1][] 顾名思义,由服务层同步写冗余数据,如上图1-4流程: (1)业务方调用服务,新增数据 (2)服务先插入T1数据 (3)服务再插入T2数据 (4)服务返回业务方新增数据成功 优点: (1)不复杂,服务层由单次写,变两次写 (2)数据一致性相对较高(因为双写成功才返回) 缺点: (1)请求的处理时间增加(要插入次,时间加倍) (2)数据仍可能不一致,例如第二步写入T1完成后服务重启,则数据不会写入T2 如果系统对处理时间比较敏感,引出常用的第二种方案 【方法二:服务异步写】 数据的双写并不再由服务来完成,服务层异步发出一个消息,通过消息总线发送给一个专门的数据复制服务来写入冗余数据,如上图1-6流程: (1)业务方调用服务,新增数据 (2)服务先插入T1数据 (3)服务向消息总线发送一个异步消息(发出即可,不用等返回,通常很快就能完成) (4)服务返回业务方新增数据成功 (5)消息总线将消息投递给数据同步中心 (6)数据同步中心插入T2数据 优点: (1)请求处理时间短(只插入1次) 缺点: (1)系统的复杂性增加了,多引入了一个组件(消息总线)和一个服务(专用的数据复制服务) (2)因为返回业务线数据插入成功时,数据还不一定插入到T2中,因此数据有一个不一致时间窗口(这个窗口很短,最终是一致的) (3)在消息总线丢失消息时,冗余表数据会不一致 如果想解除“数据冗余”对系统的耦合,引出常用的第三种方案 【方法三:线下异步写】 数据的双写不再由服务层来完成,而是由线下的一个服务或者任务来完成,如上图1-6流程: (1)业务方调用服务,新增数据 (2)服务先插入T1数据 (3)服务返回业务方新增数据成功 (4)数据会被写入到数据库的log中 (5)线下服务或者任务读取数据库的log (6)线下服务或者任务插入T2数据 优点: (1)数据双写与业务完全解耦 (2)请求处理时间短(只插入1次) 缺点: (1)返回业务线数据插入成功时,数据还不一定插入到T2中,因此数据有一个不一致时间窗口(这个窗口很短,最终是一致的) (2)数据的一致性依赖于线下服务或者任务的可靠性 上述三种方案各有优缺点,但不管哪种方案,都会面临“究竟先写T1还是先写T2”的问题?这该怎么办呢? 三、究竟先写正表还是反表 对于一个不能保证事务性的操作,一定涉及“哪个任务先做,哪个任务后做”的问题,解决这个问题的方向是: 【如果出现不一致】,谁先做对业务的影响较小,就谁先执行。 以上文的订单生成业务为例,buyer和seller冗余表都需要插入数据: T1(buyer\_id, seller\_id, oid) T2(seller\_id, buyer\_id, oid) 用户下单时,如果“先插入buyer表T1,再插入seller冗余表T2”,当第一步成功、第二步失败时,出现的业务影响是“买家能看到自己的订单,卖家看不到推送的订单” 相反,如果“先插入seller表T2,再插入buyer冗余表T1”,当第一步成功、第二步失败时,出现的业务影响是“卖家能看到推送的订单,卖家看不到自己的订单” 由于这个生成订单的动作是买家发起的,买家如果看不到订单,会觉得非常奇怪,并且无法支付以推动订单状态的流转,此时即使卖家看到有人下单也是没有意义的。 因此,在此例中,应该先插入buyer表T1,再插入seller表T2。 however,记住结论:【如果出现不一致】,谁先做对业务的影响较小,就谁先执行。 四、如何保证数据的一致性 从二节和第三节的讨论可以看到,不管哪种方案,因为两步操作不能保证原子性,总有出现数据不一致的可能,那如何解决呢? 【方法一:线下扫面正反冗余表全部数据】 如上图所示,线下启动一个离线的扫描工具,不停的比对正表T1和反表T2,如果发现数据不一致,就进行补偿修复。 优点: (1)比较简单,开发代价小 (2)线上服务无需修改,修复工具与线上服务解耦 缺点: (1)扫描效率低,会扫描大量的“已经能够保证一致”的数据 (2)由于扫描的数据量大,扫描一轮的时间比较长,即数据如果不一致,不一致的时间窗口比较长 有没有只扫描“可能存在不一致可能性”的数据,而不是每次扫描全部数据,以提高效率的优化方法呢? 【方法二:线下扫描增量数据】 每次只扫描增量的日志数据,就能够极大提高效率,缩短数据不一致的时间窗口,如上图1-4流程所示: (1)写入正表T1 (2)第一步成功后,写入日志log1 (3)写入反表T2 (4)第二步成功后,写入日志log2 当然,我们还是需要一个离线的扫描工具,不停的比对日志log1和日志log2,如果发现数据不一致,就进行补偿修复 优点: (1)虽比方法一复杂,但仍然是比较简单的 (2)数据扫描效率高,只扫描增量数据 缺点: (1)线上服务略有修改(代价不高,多写了2条日志) (2)虽然比方法一更实时,但时效性还是不高,不一致窗口取决于扫描的周期 有没有实时检测一致性并进行修复的方法呢? 【方法三:实时线上“消息对”检测】 这次不是写日志了,而是向消息总线发送消息,如上图1-4流程所示: (1)写入正表T1 (2)第一步成功后,发送消息msg1 (3)写入反表T2 (4)第二步成功后,发送消息msg2 这次不是需要一个周期扫描的离线工具了,而是一个实时订阅消息的服务不停的收消息。 假设正常情况下,msg1和msg2的接收时间应该在3s以内,如果检测服务在收到msg1后没有收到msg2,就尝试检测数据的一致性,不一致时进行补偿修复 优点: (1)效率高 (2)实时性高 缺点: (1)方案比较复杂,上线引入了消息总线这个组件 (2)线下多了一个订阅总线的检测服务 however,技术方案本身就是一个投入产出比的折衷,可以根据业务对一致性的需求程度决定使用哪一种方法。我这边有过好友数据正反表的业务,使用的就是方法二。 ==【完】== [640_wx_fmt_png_tp_webp_wxfrom_5_wx_lazy_1]: /images/20220521/c1f1f2bb97a447518e67fbfacc63d66e.png
相关 解析和优化Java中的冗余代码 在Java中,冗余代码通常是指多次使用的相似逻辑。这种代码不仅增加了代码量,还可能导致维护困难和错误传播。 以下是几种优化冗余代码的方法: 1. **重构**:将重复的代码 女爷i/ 2024年09月20日 09:09/ 0 赞/ 7 阅读
相关 代码优化挑战:减少Java代码冗余实例 在Java编程中,冗余代码通常意味着重复的工作或者逻辑。优化的目标是消除这些重复,提高代码的可读性和维护性。以下是一些减少Java代码冗余的例子: 1. **使用方法和变量* 小灰灰/ 2024年09月10日 09:24/ 0 赞/ 19 阅读
相关 优化重复冗余代码的8种方式 前言 日常开发中,我们经常会遇到一些重复代码。大家都知道重复代码不好,它主要有这些缺点:可维护性差、可读性差、增加错误风险等等。最近呢,我优化了一些系统中的重复代码,用了 太过爱你忘了你带给我的痛/ 2023年10月15日 08:54/ 0 赞/ 69 阅读
相关 优化重复冗余代码的8种方式! 日常开发中,我们经常会遇到一些重复冗余的代码。大家都知道重复代码不好,它主要有这些缺点:可维护性差、可读性差、增加错误风险等等。最近呢,我优化了一些系统中的重复代码,用了好几种 布满荆棘的人生/ 2023年10月15日 08:12/ 0 赞/ 77 阅读
相关 优化重复冗余代码的8种方式! 前言 日常开发中,我们经常会遇到一些重复冗余的代码。大家都知道重复代码不好,它主要有这些缺点:可维护性差、可读性差、增加错误风险等等。最近呢,我优化了一些系统中的重复代码 墨蓝/ 2023年10月15日 08:01/ 0 赞/ 77 阅读
相关 C++ 编码优化 | 减少冗余拷贝或赋值 ![1a578cde9b6ef8a178b1a526cbf8d20a.gif][] 置顶/星标公众号????,硬核文章第一时间送达! 链接 | http://www.708 旧城等待,/ 2022年10月12日 01:56/ 0 赞/ 118 阅读
相关 细聊冗余表数据一致性 本文主要讨论四个问题: (1)为什么会有冗余表的需求 (2)如何实现冗余表 (3)正反冗余表谁先执行 (4)冗余表如何保证数据的一致性 一、需求缘起 互联网很 朱雀/ 2022年09月29日 14:49/ 0 赞/ 146 阅读
相关 数据冗余一致性优化 原文地址:https://mp.weixin.qq.com/s?\_\_biz=MjM5ODYxMDA5OQ==&mid=403963671&idx=1&sn=51a2d2fd 迈不过友情╰/ 2022年05月21日 01:12/ 0 赞/ 160 阅读
相关 分布式数据一致性(数据多份副本一致性) 前言 分布式数据库的数据一致性管理是其最重要的内核技术之一,也是保证分布式数据库满足数据库最基本的ACID特性中的 “一致性”(Consistency)的保障。在分布式技 比眉伴天荒/ 2022年01月29日 15:59/ 0 赞/ 375 阅读
还没有评论,来说两句吧...