30

人人都想学架构(五)

 5 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwOTU4NzM5Ng%3D%3D&%3Bmid=2455771341&%3Bidx=1&%3Bsn=37e02e72d96cc73ae2b2c2e1fce7bfad
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

《人人都想学架构(四)》 讲了分布式理论的CAP原理,接下去描述第八节,讲的是存储高可用性。它的本质就是冗余,复杂性主要是应对复制带来的延迟和一致性问题,在学习相关中间件的时候,考虑几个问题:

  • 数据如何复制

  • 各个节点的职责是什么

  • 如何应对复制延迟

  • 如何应对复制中断

数据集中集群

什么是集中集群呢,它们称为集群的原因是有一大堆机器组合在一块,而集中表示每一个实例的数据都是完整的,其他机器数据只是它的复制结果。比如MySQL就是一个典型的集中式存储系统,集中集群会遇到单机存储空间的限制(比如我们),虽然可以采取分库这样的扩展,但分完后的实例和其他实例本质上还是分离的,并不存在关系。

MySQL集群可以分为主备和主从,备代表备份,不用做线上服务,而从可以提供查询服务,但本质上差不多,都是主库和备库(从库)之间同步数据,所以考虑的时候可以认为是一致的。

既然是复制原理,就会遇到同步延迟、同步中断、主库单点的问题,如何解决呢?

首先要避免延迟,因为一旦有延迟就会影响应用,而且主从倒挂的时候还会出现数据不一致的问题。

其次考虑从库之间的负载均衡问题,这个相对好解决,比如发现从库不能复制数据了、延迟了,就可以摘除,比如DNS就可以,或者SLB(具体还没试验过)。

最复杂的是主从倒挂的问题,比如主库出现故障,如何快速将一台从库提为主库。面临的核心问题:

  • 如何传递状态,就是主从之间如何知道对方是否存活。

  • 状态如何检测,比如MySQL进程不存在了、响应很慢,这个很有讲究,将来可参考一些通用的思路。

一旦有状态检测,就要做出决策:

  • 什么情况下主从倒挂?

    可以自定义,比如主库响应非常慢,而且持续一段时间了,才进行倒挂。

  • 倒挂是需要人工干预还是自动

  • 数据是否有冲突,这个可能是最麻烦的。

如果是主备,检测相对简单,如果是主从,可能就要通过第三方仲裁了,ZK可能就是最常用的解决方案。

对于数据库来说,自动化解决了主从倒挂的问题是最重要的,相比云数据库,自建数据库在这方面要花更多的心思,希望将来实践下。

数据分散集群

这才是真正的集群,就是集群中每台机器都存储一部分数据,可以称为分片,然后每份数据又有复制集做冗余,复杂点在于如何将数据分配到不同的机器上,主要考虑以下几个问题:

  • 均衡性(数据分区要基本平衡)

  • 容错性,原来分配给故障服务器的数据分区分配给其他服务器

  • 可伸缩性,容量不够扩充新的服务器后,能够自动将部分数据分区迁移到新的服务器

对于分散集群来说,核心也会用到ZK这样的软件(分布式一致性算法),在学习ELK、MongoDB的时候,需要深入思考它们如何做到以上几点的,这才是真正的价值。

分布式一致性算法

这是大学问,自己也搞不懂,简单记录下。分布式一致性算法是为了保证一份数据在多个节点的一致性,是为了满足CP要求。

  • Paxos,复杂,难于理解,缺失细节,在工程上只能以它为基础,比如Google的chubby就是一个Paxos-like算法。

  • Raft:

    是为了工程实践而设计的,强调可理解性,主要包含三个子问题(leader选举,日志复制,安全保证)

  • ZAB:

    是ZK系统采用的分布式一致性算法,和raft类似。

分布式事务算法

某些业务场景需要事务来保证数据一致性,对于数据集群来说,数据分布在不同的节点上,这些节点只能通过消息进行通信,因此分布式事务实现起来只能依赖消息通知,但消息本身不可靠,给分布式事务带来了复杂度,一般需要一个“协调者”来处理事务。

它的核心目的是为了保证分散在多个节点上的数据统一提交或回滚。

https://juejin.im/post/5cab6ff95188251af951c82b 这篇文章写的很好,简单列举图加深自己的理解。

1:2PC

(1)Prepare:提交事务请求

参与执行事务操作(例如更新一个关系型数据库表中的记录),并将 Undo(回滚)和 Redo(重做)信息记录事务日志中。

JvIjeyr.jpg!web

(2)Commit:执行事务提交

正常提交事务:

aIZbMv6.jpg!web

中断事务:

V7bUZj7.jpg!web

2PC 的问题:

  • 同步阻塞

  • 协调者有单点问题

  • 数据不一致,比如某个参与者没有收到Commit/Rollback请求(而其他参与者收到了),就会一直阻塞,从而导致数据不一致。

2:3PC

3PC是在2PC的基础上,为了解决2PC的某些缺点而设计的,3PC分为三个阶段:CanCommit,PreCommit 和 doCommit。

(1)CanCommit

QfI32qU.jpg!web

注意参与者没有执行事务。

(2)PreCommit

jQFvAnE.jpg!web

(3)doCommit

YVNjEj2.jpg!web

3PC 的改进和缺点:

  • 降低了阻塞

  • 解决单点故障问题

  • 数据不一致问题仍然是存在的,比如第三阶段协调者发出了 abort 请求,然后有些参与者没有收到 abort,那么就会自动 commit,造成数据不一致

对比MySQL和MongoDB,理解他们的本质,可能就理解了分布式算法的精髓。

QZ3Q3iU.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK