华为资深架构师:Cloud Native架构一致性问题及解决方案

内容来源:2017年12月2日,华为资深架构师王启军在“NJSD互联网架构峰会”进行《Cloud Native架构一致性问题及解决方案》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:2092 | 6分钟阅读

摘要

在开发或软件架构的过程中,经常会遇到一致性的问题,那么如何去解决权衡。我们先从理论入手,然后进一步讨论强一致性和最终一致性的解决方案。

嘉宾演讲视频及PPT回顾:http://suo.im/tPQXc

基础理论

Cloud Native的组成

关于这个概念很多人都有不同的看法,我认为Cloud Native主要是由架构、组织、工程三部分组成的。大部分公司可能主要是关注架构部分,其实组织方面也是非常重要的,它的价值在于能够实现更快的速度、更好的用户交互体验以及更稳当的系统。

Cloud Native-架构

Cloud Native架构主要包含两部分,一个是基础设施这块,另一个是微服务架构方面。围绕着微服务又扩展出了可用性、一致性以及扩展性部分。

一致性的分类

在学术界一般将一致性分为两类,一类是以数据为中心,一类以用户为中心。以数据为中心的,无论有多少个节点都是从整体上来看一致性。而以用户为中心,是从客户端的节点来看待一致性的。

严格一致性

严格一致性要求任何写操作都能立刻同步到其他所有进程,任何读操作都能读取到最新的修改。比如说有三个节点,当某一个节点的数据a变成1的时候,另外两个节点的a就需要同步改变。

顺序一致性

严格一致性需要有一个全局时钟才能实现,但是这个全局时钟是很难实现的。于是顺序一致性放弃了它,转而改用分布式逻辑时钟来实现。

顺序一致性是指所有的进程以相同的顺序看到所有的修改,读操作未必能及时得到此前其他进程对同一数据的写更新,但是每个进程读到的该数据的不同值得顺序是一致的。

因果一致性

因果一致性是一种弱化的顺序一致性,如果两个数据之间存在因果关系,那么在后续的所有操作都应该基于这一关系。所有的进程必须以相同的顺序看到具有潜在因果关系的写操作。不同进程可以以不同的顺序看到并发的写操作。

如何实现强一致性

两阶段提交

提到强一致性,相信大家首先想到的就是两阶段提交。也就是整个交互过程分为两个阶段。第一阶段协调者先向参与者提问是否可以提交,同时锁定数据,第二阶段参与者提交。

这里面存在几个问题,第一阶段锁定数据之后,如果协调者挂掉了,将没有角色去通知参与者是否应该提交,这个数据会被一致锁定。如果第二阶段参与者1提交成功,参与者2提交失败,此时协调者不知道该如何处理,因为参与者1已经提交成功,外部可以访问了。

三阶段提交

三阶段提交其实是把两阶段提交的第一阶段分为了两个阶段,这是为了降低原来第一阶段的死锁的概率。三阶段的第一阶段在询问是否提交的时候并没有锁定数据,而是在准备提交的时候才锁定数据。

实际上使用三阶段提交,性能上会有更多的消耗,交互会越来越多,可扩展性也很差。

如何实现最终一致性

调试失败怎么办

假设有一个服务M需要去调用另外的两个服务A、B,在调用的过程中失败了话,最常见的做法就是重试。这时就需要去考虑重试的次数、超时时间、间隔时间以及间隔时间的衰减度,而重试没有做好的话就很容易造成系统的负担。

改进方案

其实完全可以添加一个日志,并且可以收集到远端。通过收集系统收集到分布式文件系统内,这样就可以不断的去检测这个系统是否有问题。

还有一种解决方案——可靠事件,服务在调用失败后,通过另一种方式将数据传输到消息队列,然后要被调用的服务去读取消息队列。

对于最终一致性来说,要么全部成功,要么全部失败。

如何保证写后读一致

这需要在写消息的同时,去写一个事件日志。如果一旦失败的可以通过补偿服务不断的遍历事件的这张表,最终拿到消息再去发送时间

长事务一致性

Sage事务模型

Sgae是一个比较早期的事务模型,它的核心思想是将一个长事务拆分为多个本地事务。而process manageer就是负责处理事务拆封的,然后再去调用不同的服务。

这是一个具体的事务处理流程,这里面需要定时的去做检查判断是否失败,失败了就要发送消息,正向调用时写回退日志。

TCC

在做系统的时候你会发现服务是很容易的去扩展的,数据库往往会出现瓶颈,那么如何去平衡压力,有很多的解决方案,TCC就是其中的一种。

TCC的优势在于将数据库的操作,放到业务层处理,平衡了数据库的压力。但同时也付出了一定代价,它增加了业务的复杂度,需要提供相应的Try、Confirm、Cancel接口,而且接口还是幂等性的。

如何保障幂等

第一种就是通过数据加锁的方式,第二种是分布式锁,不过这种锁不能保障绝对一致性,第三种方案可以去做唯一约束,在唯一约束无效的情况下可以增加流水表这也是第四种方案。

今天的分享就到这里,喜欢本次分享请给我点赞~谢谢大家!有什么问题可以在评论区讨论。

原文发布于微信公众号 - IT大咖说(itdakashuo)

原文发表时间:2018-04-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JAVA高级架构

日处理20亿数据,实时用户行为服务系统架构实践

携程实时用户行为服务作为基础服务,目前普遍应用在多个场景中,比如猜你喜欢(携程的推荐系统)、动态广告、用户画像、浏览历史等等。 以猜你喜欢为例,猜你喜欢为应...

1572
来自专栏BeJavaGod

我们是否需要升级到JDK8?

JDK8发布至今已经很久了,很多开发人员,公司都还是使用的JDK6或者JDK7,看到很多人的评论,那么我们到底要不要升级到JDK8呢? Oracle这个婊子早已...

4277
来自专栏Golang语言社区

如何使用 Go 语言写游戏服务器?

之前先后用Erlang,nodejs做过tcp,http的游戏服务器。接触了golang一两个月(纯新手),想在最近的tcp网游项目中使用,但又担心以下问题: ...

7814
来自专栏架构师之路

多key业务,数据库水平切分架构一次搞定

数据库水平切分是一个很有意思的话题,不同业务类型,数据库水平切分的方法不同。 本篇将以“订单中心”为例,介绍“多key”类业务,随着数据量的逐步增大,数据库性能...

4257
来自专栏Java后端技术栈

图解分布式架构的演进过程!

透明性:是指每一个数据库分布节点对用户的应用来说都是透明的,看不出是本地还是远程。

1342
来自专栏企鹅号快讯

如何改善遗留的代码库

作者 | Jacques Mattheij 译者 | aiwhj 在每一个程序员、项目管理员、团队领导的一生中,这都会至少发生一次。原来的程序员早已离职去度假了...

1947
来自专栏Golang语言社区

如何使用 Go 语言写游戏服务器?

之前先后用Erlang,nodejs做过tcp,http的游戏服务器。接触了golang一两个月(纯新手),想在最近的tcp网游项目中使用,但又担心以下问题: ...

5646
来自专栏用户2442861的专栏

大数据并发问题

http://blog.csdn.net/u014421556/article/details/50964505

2350
来自专栏互联网技术栈

读《大型网站技术架构》

《大型网站技术架构》是自己接触的第一本架构知识的书籍,还是在14年时买的实体书,前后读了几遍,颇有所得,后来实体书被朋友借走再没归还,也就没再翻过。

1202
来自专栏携程技术中心

干货 | 携程实时用户行为系统实践

作者简介 陈清渠,毕业于武汉大学,多年软件及互联网行业开发经验。14年加入携程,先后负责了订单查询服务重构,实时用户行为服务搭建等项目的架构和研发工作,目前负责...

3616

扫码关注云+社区

领取腾讯云代金券