热门标签 | 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的高级应用,适合各层次的开发者。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 一面问题:MySQLRedisKafka线程算法mysql知道哪些存储引擎,它们的区别mysql索引在什么情况下会失效mysql在项目中的优化场景&# ... [详细]
  • 数据管理权威指南:《DAMA-DMBOK2 数据管理知识体系》
    本书提供了全面的数据管理职能、术语和最佳实践方法的标准行业解释,构建了数据管理的总体框架,为数据管理的发展奠定了坚实的理论基础。适合各类数据管理专业人士和相关领域的从业人员。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 深入解析Spring Cloud微服务架构与分布式系统实战
    本文详细介绍了Spring Cloud在微服务架构和分布式系统中的应用,结合实际案例和最新技术,帮助读者全面掌握微服务的实现与优化。 ... [详细]
  • 本文探讨了现代分布式架构的多样性,包括高并发、多活数据中心、容器化、微服务、高可用性和弹性架构等,并介绍了与这些架构相关的重要管理技术,如DevOps、应用监控和自动化运维。文章还深入分析了分布式系统的核心概念、主要用途及类型,同时对比了单体应用与分布式服务化的优缺点。 ... [详细]
  • Spring Cloud学习指南:深入理解微服务架构
    本文介绍了微服务架构的基本概念及其在Spring Cloud中的实现。讨论了微服务架构的主要优势,如简化开发和维护、快速启动、灵活的技术栈选择以及按需扩展的能力。同时,也探讨了微服务架构面临的挑战,包括较高的运维要求、分布式系统的复杂性、接口调整的成本等问题。最后,文章提出了实施微服务时应遵循的设计原则。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 科研单位信息系统中的DevOps实践与优化
    本文探讨了某科研单位通过引入云原生平台实现DevOps开发和运维一体化,显著提升了项目交付效率和产品质量。详细介绍了如何在实际项目中应用DevOps理念,解决了传统开发模式下的诸多痛点。 ... [详细]
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • 字节跳动夏季招聘面试经验分享
    本文详细记录了字节跳动夏季招聘的面试经历,涵盖了一、二、三轮面试的技术问题及项目讨论,旨在为准备类似面试的求职者提供参考。 ... [详细]
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社区 版权所有