热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

双重写入:如何解决微服务分布式系统中数据不一致?Thorben

由于许多新应用程序是作为微服务系统构建的,因此双重写入已成为一个普遍的问题。它们是导致数据不一致的最常见原因之一。更糟的是,许多开发人员甚至都不知道双重写入是什么。什么是双重写入?



由于许多新应用程序是作为微服务系统构建的,因此双重写入已成为一个普遍的问题。它们是导致数据不一致的最常见原因之一。更糟的是,许多开发人员甚至都不知道双重写入是什么。

什么是双重写入?
双重写入描述了您在两个个系统(例如数据库和Apache Kafka)中更改数据时的情况,而没有额外的层来确保两个服务上的数据一致性。


只要两个操作都成功,一切就OK了。即使第一笔交易失败,也还是可以的。但是,如果您成功提交了第一笔交易而第二笔交易失败,则说明您遇到了问题。您的系统现在处于不一致状态,没有容易修复的方法。

分布式事务不再是一种选择
过去,当我们构建整体/.单体/Monolith时,我们使用分布式事务来避免这种情况。分布式事务使用两阶段提交协议。它将事务的提交过程分为两个步骤,并确保所有系统的ACID原则。
但是,如果我们要构建微服务系统,则不会使用分布式事务。这些交易需要锁,并且无法很好地扩展。他们还需要所有涉及的系统同时启动和运行。

那你该怎么办呢?

3个无效的“解决方案”
当我在会议演讲中或在一个研讨会上与与会者讨论此主题时,我经常听到以下3条建议之一:

  1. 是的,我们知道此问题,我们没有解决方案。但这还不错。到目前为止,什么都没有发生。让我们保持原样。
  2. 让我们将与Apache Kafka的交互移动到提交后监听器。
  3. 在提交数据库事务之前,让我们将事件写入Kafka中的主题。

好吧,很明显,建议1的风险很大。它可能在大多数时间都有效。但是迟早,您将在服务存储的数据之间创建越来越多的不一致之处。
因此,让我们集中讨论选项2和3。

2. 在提交后监听器中发布事件
在提交后监听器中发布事件是一种非常流行的方法。它确保仅在数据库事务成功时才发布事件。但是,很难解决Kafka崩溃或任何其他原因阻止您发布事件的情况。
您已经提交了数据库事务。因此,您无法轻松地还原这些更改。当您尝试在Kafka中发布事件时,其他事务可能已经使用并修改了该数据。
您可能会尝试将故障保留在数据库中,并运行常规的清理作业以尝试恢复失败的事件。这可能看起来像是一个合理的解决方案,但是它有一些缺陷:
  1. 仅当您可以将失败的事件保留在数据库中时,它才有效。如果数据库事务失败,或者您的应用程序或数据库崩溃,然后才能存储有关失败事件的信息,则将丢失它。
  2. 仅当事件本身没有引起问题时,它才起作用。
  3. 如果在清除作业恢复失败的事件之前,另一个操作为该业务对象创建了一个事件,则事件将混乱。

这些似乎是假设的情况,但这就是我们正在准备的事情。本地事务,分布式事务和确保最终一致性的方法的主要思想是,绝对要确保您不会造成任何(永久)不一致。
提交后侦听器无法确保这一点。因此,让我们看一下其他选项。

3. 在提交数据库事务之前发布事件
在讨论了为何提交后监听器不起作用之后,通常会建议使用这种方法。如果在提交之后发布事件会导致问题,您只需在提交事务之前发布它,对吗?
好吧,不……让我解释一下……
如果您无法发布事件,则在提交事务之前发布事件使您可以回滚事务。那就对了。
但是,如果数据库事务失败,该怎么办?
您的操作可能违反唯一约束,或者同一数据库记录上可能有2个并发更新。提交期间将检查所有数据库约束,并且不能确保它们都不会失败。数据库事务也彼此隔离,因此如果不使用锁,就无法阻止并发更新。但这带来了新的可伸缩性问题。简而言之,您的数据库事务可能会失败,并且您无能为力,或者对此无能为力。
如果发生这种情况,则您的活动已经发布。其他微服务可能已经观察到它并触发了一些业务逻辑。您无法撤回活动。
如前所述,撤消操作失败的原因相同。您也许可以构建一个大多数情况下都可以使用的解决方案。但是您无法创建绝对安全的东西。

如何避免双重写入?
您可以选择几种方法来避免双重写入。但是您需要知道,如果不使用分布式事务,则只能构建最终一致的系统。
总体思路是将流程分为多个步骤。这些步骤中的每个步骤仅适用于一个数据存储,例如数据库或Apache Kafka。这使您能够使用本地事务,所涉及系统之间的异步通信以及异步的,可能无限的重试机制。
如果您只想在服务之间复制数据或通知其他服务已发生事件,则可以将发件箱模式与Debezium等变更数据捕获实现一起使用。我在以下文章中详细解释了这种方法:


  • 使用Hibernate实现发件箱模式
  • 使用Debezium用CDC实现发件箱模式

而且,如果您需要实施涉及多个服务的一致的写入操作,则可以使用SAGA模式。我将在以下文章之一中对其进行详细说明。

结论
双重写入常常被低估,许多开发人员甚至都不知道潜在的数据不一致。
如本文所述,在没有分布式事务或确保最终一致性的算法的情况下,写入2个或更多系统可能会导致数据不一致。如果使用多个本地事务,则无法处理所有错误情况。
避免这种情况的唯一方法是将通信分为多个步骤,并且在每个步骤中仅写入一个外部系统。SAGA模式和变更数据捕获实现(例如Debezium)使用这种方法来确保对多个系统的一致写入操作或将事件发送到Apache Kafka。


 

推荐阅读
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • Spring Cloud因其强大的功能和灵活性,被誉为开发分布式系统的‘一站式’解决方案。它不仅简化了分布式系统中的常见模式实现,还被广泛应用于企业级生产环境中。本书内容详实,覆盖了从微服务基础到Spring Cloud的高级应用,适合各层次的开发者。 ... [详细]
  • 热璞数据库与云宏达成兼容性互认证,共筑数据安全屏障
    热璞数据库与云宏信息技术有限公司近期宣布完成产品兼容性互认证,旨在提升数据安全性与稳定性,支持企业数字化转型。 ... [详细]
  • 为何我选择了华为云GaussDB数据库
    本文分享了作者选择华为云GaussDB数据库的理由,详细介绍了GaussDB(for MySQL)的技术特性和优势,以及它在金融和互联网行业的应用场景。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 创邻科技成功举办Graph+X生态合作伙伴大会,30余家行业领军企业共聚杭州
    9月22日,创邻科技在杭州举办“Graph+X”生态合作伙伴大会,汇聚了超过30家行业头部企业的50多位企业家和技术领袖,共同探讨图技术的前沿应用与发展前景。 ... [详细]
  • Java多重继承的替代方案及设计考量
    本文探讨了Java为何不支持多重继承,并深入分析了其背后的原理和替代方案。通过理解Java的设计哲学,开发者可以更好地利用接口和其他特性来实现复杂的类结构。 ... [详细]
  • 深入解析Spring Cloud微服务架构与分布式系统实战
    本文详细介绍了Spring Cloud在微服务架构和分布式系统中的应用,结合实际案例和最新技术,帮助读者全面掌握微服务的实现与优化。 ... [详细]
  • 本文探讨了现代分布式架构的多样性,包括高并发、多活数据中心、容器化、微服务、高可用性和弹性架构等,并介绍了与这些架构相关的重要管理技术,如DevOps、应用监控和自动化运维。文章还深入分析了分布式系统的核心概念、主要用途及类型,同时对比了单体应用与分布式服务化的优缺点。 ... [详细]
  • Spring Cloud学习指南:深入理解微服务架构
    本文介绍了微服务架构的基本概念及其在Spring Cloud中的实现。讨论了微服务架构的主要优势,如简化开发和维护、快速启动、灵活的技术栈选择以及按需扩展的能力。同时,也探讨了微服务架构面临的挑战,包括较高的运维要求、分布式系统的复杂性、接口调整的成本等问题。最后,文章提出了实施微服务时应遵循的设计原则。 ... [详细]
  • 迎接云数据库新时代:程序员如何应对变革?
    在数据无处不在的时代,数据库成为了管理和处理数据的核心工具。从早期的信息记录方式到现代的云数据库,数据库技术经历了巨大的变革。本文将探讨云数据库的特点及其对程序员的影响。 ... [详细]
  • 本文探讨了随着并发需求的增长,MySQL数据库架构如何从简单的单一实例发展到复杂的分布式系统,以及每一步演进背后的原理和技术解决方案。 ... [详细]
  • 深入理解Kafka架构
    本文将详细介绍Kafka的内部工作机制,包括其工作流程、文件存储机制、生产者与消费者的具体实现,以及如何通过高效读写技术和Zookeeper支持来确保系统的高性能和稳定性。 ... [详细]
  • PostgreSQL 最新动态 —— 2022年4月6日
    了解 PostgreSQL 社区的最新进展和技术分享 ... [详细]
author-avatar
mobiledu2502909383
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有