如何解决微服务的数据一致性分发问题?

介绍

系统架构微服务化以后,根据微服务独立数据源的思想,每个微服务一般具有各自独立的数据源,但是不同微服务之间难免需要通过数据分发来共享一些数据,这个就是微服务的数据分发问题。Netflix/Airbnb等一线互联网公司的实践[参考附录1/2/3]表明,数据一致性分发能力,是构建松散耦合、可扩展和高性能的微服务架构的基础。

本文解释分布式微服务中的数据一致性分发问题,应用场景,并给出常见的解决方法。本文主要面向互联网分布式系统架构师和研发经理。

为啥要分发数据?场景?

数据分发场景

我们还是要从具体业务场景出发,为啥要分发数据?有哪些场景?在实际企业中,数据分发的场景其实是非常多的。假设某电商企业有这样一个订单服务Order Service,它有一个独立的数据库。同时,周边还有不少系统需要订单的数据,上图给出了一些例子:

一个是缓存系统,为了提升订单数据的访问性能,我们可以把频繁访问的订单数据,通过Redis缓存起来;

第二个是Fulfillment Service,也就是订单履行系统,它也需要一份订单数据,借此实现订单履行的功能;

第三个是ElasticSearch搜索引擎系统,它也需要一份订单数据,可以支持前台用户、或者是后台运营快速查询订单信息;

第四个是传统数据仓库系统,它也需要一份订单数据,支持对订单数据的分析和挖掘。

当然,为了获得一份订单数据,这些系统可以定期去订单服务查询最新的数据,也就是拉模式,但是拉模式有两大问题:

一个是拉数据通常会有延迟,也就是说拉到的数据并不实时;

如果频繁拉的话,考虑到外围系统众多(而且可能还会增加),势必会对订单数据库的性能造成影响,严重时还可能会把订单数据库给拉挂。

所以,当企业规模到了一定阶段,还是需要考虑数据分发技术,将业务数据同步分发到对数据感兴趣的其它服务。除了上面提到的一些数据分发场景,其实还有很多其它场景,例如:

第一个是数据复制(replication)。为了实现高可用,一般要将数据复制多分存储,这个时候需要采用数据分发。

第二个是支持数据库的解耦拆分。在单体数据库解耦拆分的过程中,为了实现不停机拆分,在一段时间内,需要将遗留老数据同步复制到新的数据存储,这个时候也需要数据分发技术。

第三个是实现CQRS,还有去数据库Join。这两个场景我后面有单独文章解释,这边先说明一下,实现CQRS和数据库去Join的底层技术,其实也是数据分发。

第四个是实现分布式事务。这个场景我后面也有单独文章讲解,这边先说明一下,解决分布式事务问题的一些方案,底层也是依赖于数据分发技术的。

其它还有流式计算、大数据BI/AI,还有审计日志和历史数据归档等场景,一般都离不开数据分发技术。

总之,波波认为,数据分发,是构建现代大规模分布式系统、微服务架构和异步事件驱动架构的底层基础技术。

双写?

如何保证双写的事务性?

对于数据分发这个问题,乍一看,好像并不复杂,稍有开发经验的同学会说,我在应用层做一个双写不就可以了吗?比方说,请看上图右边,这里有一个微服务A,它需要把数据写入DB,同时还要把数据写到MQ,对于这个需求,我在A服务中弄一个双写,不就搞定了吗?其实这个问题并没有那么简单,关键是你如何才能保证双写的事务性?

请看上图左边的代码,这里有一个方法updateDbThenSendMsgInTransaction,这个方法上加了事务性标注,也就是说,如果抛异常的话,数据库操作会回滚。我们来看这个方法的执行步骤:

第一步先更新数据库,如果更新成功,那么result设为true,如果更新失败,那么result设为false;

第二步,如果result为true,也就是说DB更新成功,那么我们就继续做第三步,向mq发送消息

如果发消息也成功,那么我们的流程就走到第四步,整个双写事务就成功了。

如果发消息抛异常,也就是发消息失败,那么容器会执行该方法的事务性回滚,上面的数据库更新操作也会回滚。

初看这个双写流程没有问题,可以保证事务性。但是深入研究会发现它其实是有问题的。比方说在第三步,如果发消息抛异常了,并不保证说发消息失败了,可能只是由于网络异常抖动而造成的抛异常,实际消息可能是已经发到MQ中,但是抛异常会造成上面数据库更新操作的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/424710.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

京东云硬钢阿里云:承诺再低10%

关注卢松松,会经常给你分享一些我的经验和观点。 阿里云刚刚宣布史上最大规模的全线产品降价20%,这热度还没过,京东云当晚就喊话:“随便降、比到底!,全网比价,击穿低价,再低10%”,并…

求最短路径之BF算法

介绍 全称Bellman-Ford算法,目的是求解有负权边的最短路径问题。 考虑环,根据环中边的边权之和的正负,将环分为零环、正环、负环。其中零环、正环不会影响最短路径的求解,而负环会影响最短路径的求解。 可用BF算法返回一个bool值…

Redis之十:Spring Data Redis --- CrudRepository方式

SpringData Redis CrudRepository方式 Spring Data Redis 的 CrudRepository 是 Spring Data 框架中用于提供基础 CRUD(创建、读取、更新和删除)操作的一个接口。在与 Redis 集成时,尽管 Redis 是一个键值存储系统,并没有像关系型…

【达梦数据库】如何使用idea antrl4插件方式dm sql

使用idea中的antrl插件进行分析 1.打开IDEA,在File—Settings—Plugins中,安装ANTLR v4 grammar plugin插件。 2.加载达梦的语法文件 3.配置生成路径和目录(可采用默认) 4.编译DmSqlParser.g4 DmSqlLexer.g4 5.输入SQL/输入文件 …

用Flutter开发App:助力您的移动业务腾飞

一、Flutter简介 Flutter是Google推出的用于构建多平台应用程序的开源UI框架。它使用Dart语言编写,可以编译为原生机器代码,从而提供卓越的性能和流畅的用户体验。 二、Flutter的优势 一套代码,多平台部署:Flutter可以使用一套代…

electron安装最后一部卡住了?

控制台如下错误 不是的话基本可以划走了 这个很可能是镜像出现问题了,不一定是npm镜像 打开npm的配置文件添加下述 electron_mirrorhttps://cdn.npmmirror.com/binaries/electron/ electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-build…

将本地的镜像上传到私有仓库

使用register镜像创建私有仓库 [rootopenEuler-node1 ~]# docker run --restartalways -d -p 5000:5000 -v /opt/data/regostry:/var/lib/registry registry:2[rootopenEuler-node1 ~]# docker images REPOSITORY TAG IMAGE…

JAVAEE初阶 JVM(二)

垃圾回收和双亲委派模型 1.双亲委派模型2.垃圾回收机制(1) 识别垃圾1.引用计数2.可达性分析 (2) 销毁垃圾1.标记清除2.复制算法3.标记整理 3.分代回收 1.双亲委派模型 描述了如何查找.class文件的策略. 同时JVM中有专门进行类加载的操作,有一个模块,叫做类加载器. 上述就是为了…

Linux(CentOS为例)环境下 Git提交代码加速,使用FastGithub,运行报错解决

当你的在服务器上使用Git进行推送时,时常会出现超时错误。这里使用FastGithub 首先下载FastGithub 这个软件作者不是为什么删除了GithUb的仓库,这个链接还有。下载Linux版本的 FastGithub Linux,Windows版本 下载完毕后解压 ./fastgithu…

Stable Diffusion WebUI API http://127.0.0.1:7860/docs空白

在尝试调用Stable Diffusion WebUI API的时候,打开http://127.0.0.1:7860/docs遇到了以下页面 网络诊断是这样的原因: 修bug,改来改去遇到了以下两种页面: 此时http://127.0.0.1:7860可以如下正常显示: 查资料的时候找…

重学SpringBoot3-@EnableConfigurationProperties注解

重学SpringBoot3-EnableConfigurationProperties注解 1. 引言2. EnableConfigurationProperties 的作用3. 使用示例4. 总结 1. 引言 Spring Boot 提供了一种便捷的方式来管理和校验应用程序的配置,即通过类型安全的配置属性。EnableConfigurationProperties 注解在…

【详识JAVA语言】数组的定义与使用

数组的基本概念 为什么要使用数组 假设现在要存5个学生的javaSE考试成绩,并对其进行输出,按照之前掌握的知识点,我么会写出如下代码: public class TestStudent{public static void main(String[] args){int score1 70;int sc…

【AI绘画】免费GPU Tesla A100 32G算力部署Stable Diffusion

免责声明 在阅读和实践本文提供的内容之前,请注意以下免责声明: 侵权问题: 本文提供的信息仅供学习参考,不用做任何商业用途,如造成侵权,请私信我,我会立即删除,作者不对读者因使用本文所述方法…

简单的shell 脚本练习

编写函数,实现打印绿色OK和红色FAILED,判断是否有参数,存在为Ok,不存在为FAILED (1)编写脚本 (2)更改权限测试 编写函数,实现判断是否无位置参数,如无参数&a…

wordpress外贸独立站

WordPress外贸电商主题 简洁实用的wordpress外贸电商主题,适合做外贸跨境的电商公司官网使用。 https://www.jianzhanpress.com/?p5025 华强北面3C数码WordPress外贸模板 电脑周边、3C数码产品行业的官方网站使用,用WordPress外贸模板快速搭建外贸网…

【机器学习】实验5,AAAI 会议论文聚类分析

本次实验以AAAI 2014会议论文数据为基础,要求实现或调用无监督聚类算法,了解聚类方法。 任务介绍 每年国际上召开的大大小小学术会议不计其数,发表了非常多的论文。在计算机领域的一些大型学术会议上,一次就可以发表涉及各个方向…

RK3568笔记十八:MobileNetv2部署测试

若该文为原创文章,转载请注明原文出处。 记录MobileNetv2训练测试 一、环境 1、平台:rk3568 2、开发板: ATK-RK3568正点原子板子 3、环境:buildroot 4、虚拟机:正点原子提供的ubuntu 20 二、MobileNetv2简介 MobileNet &…

前端面试练习24.3.2-3.3

HTMLCSS部分 一.说一说HTML的语义化 在我看来,它的语义化其实是为了便于机器来看的,当然,程序员在使用语义化标签时也可以使得代码更加易读,对于用户来说,这样有利于构建良好的网页结构,可以在优化用户体…

Python【初识】

一、Python简介 Python是一种高级的解释型编程语言,以其简洁、易学和强大的库支持而闻名。它最初由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python的设计理念强调优雅、明确和简单,旨…

Google 地图 API 教程--干货(1/2)

Google Maps API 教程 在本教程中我们将学习如何使用谷歌地图API V3创建交互式地图。 什么是 API? API = 应用程序编程接口(Application programming interface)。 API(Application Programming Interface,应用编程接口)其实就是操作系统留给应用程序的一个调用接口,…