8c6fdc44caba6c1ce36257c5ef91108d
漫谈分布式系统(8) -- 可用性?上副本!

这是《漫谈分布式系统》系列的第 8 篇,预计会写 30 篇左右。欢迎订阅,听我娓娓道来。也欢迎转发朋友圈分享给更多人。

第二个核心问题

前面几篇文章,我们集中探讨了分布式的核心问题之一 -- 扩展性。解决了这个问题,分布式系统才能真正的持续分布下去。

扩展性让数据能存的下,让计算能跑的动,这是分布式系统要解决的核心问题。解决这个问题之后,要考虑的就是,怎样让这个服务稳定运行下去,让我们能持续受益于分布式的能力。

也就是常说的可用性,只有一个高可用性、高 SLA 的系统,才是值得信赖的系统。

接下来几篇文章,我们就一起探讨下,分布式系统的另一个核心问题 -- 可用性。

高可用的唯一选择

一个系统要想拥有高可用性,有且只有一个办法 -- 副本(replication)。

原因非常简单:物理故障是无法避免的

软件层面你设计的再先进,实现的再完备,也顶不住服务器突然宕机了,机房突然停电了,网线突然被施工队挖断了。

而物理故障的影响时间是不可预计的,网络抖动可能毫秒级就恢复了,服务器宕机可能几分钟重启就好了,硬盘损坏可能永远修不好了。即使同样是服务器宕机,可能重启就能恢复,也可能需要返厂维修。

所以只能多弄一个副本(replica),时刻准备着。一旦发生故障,立刻切换到备份上,来保证服务不中断。

除了对数据做副本外,对服务(service)做副本往往也是必要的。

说白了,就是拿钱换可用性

副本策略当然不是分布式系统独创的,在传统领域早有很成熟的实践。比如磁盘数据用 RAID 做备份;微服务的多实例也是对服务的备份,等等。

当然,物理故障的影响范围倒是可以预估的,服务器宕机就只影响那一台机器,机房断电不会影响到其他地方的机房。这对我们采取不同的副本策略是有帮助的。

Replication 里的主从

通常做副本,最容易想到的,就是 standby 一个新副本。平时都是原来的副本提供服务,standby 的副本对外没有存在感。只有当原来的副本出现故障的时候,才切换(failover)到新副本提供服务。

所以,很自然的,分出了主和从。(leader & follower,master & slave,active & standby,等等,不同系统有不同的叫法)。而 failover 动作也带来了主从角色的状态转换。

其实,replication 里的主从可以用很多种玩法。

single leader replication

就是上面已经提到的架构,非常简单直白。也不会有太多的隐患。

所以很多分布式系统都是采用这种方式。包括我们前面文章提到的 HDFS(NameNode)、YARN(Resource Manager)。

但也有很多系统没有采用这种方式,比如 HDFS 里的 DataNode,数据有多个副本,但无所谓谁主谁从,每个都是对等的。

既然这么好,为什么又有些地方不采用 single leader 呢?

  • 一方面,failover 的生效是需要过程的,哪怕只有几秒,这期间的响应都会被阻塞或丢弃在客户端。
  • 另一方面,既然都为了可用性花了额外的钱了,为什么不让副本也发挥点作用呢,比如提供读操作来缓解下系统的性能压力。

multi-leader replication

于是有了多 leader 的副本策略,每个副本都可以对外提供服务。

这种方式在数据库领域早有实践,也就是所谓的 master-master 模式。

如果把对外提供的服务细分成读和写,又可以把 multi-leader replication 里的角色细分成只读和读写两种。

  • 完全对等的 multi-leader,例如 MySQL + Tungsten 的组合。
  • read-and-write leader 和 read-only leader,例如 HDFS NameNode 里的 Observer NameNode 就属于 read-only leader。

然而,多主,尤其是对等可读写的主,很容易导致冲突和混乱 -- 或者,用我们后面会提到的更专业的说法 -- 一致性问题

想象在并发的情况下,数据库里的同一行数据,同时被两个不同的 leader 接收到的请求改成了两个不同的值。这个时候应该接受哪个值呢?

这个问题并没有统一的答案,因为两个请求在对应 leader 那里都得到了修改成功的返回。(你可能会很快反应过来,可以用时间戳啊,先写的被后写的覆盖掉。后面我们会看到,事情并没有这么简单。)

即使有这样可能很严重的问题,多主复制这种架构依然是有价值的。

典型的比如多 IDC 下的数据库。

无论是出于灾备、容量,还是响应延时的考虑,很多时候同一种数据会存在物理上相距很远的机房。每个机房都有各自的 master-slave 结构,机房内相对独立,数据复制采取 single leader replication 的方式,但机房间的数据复制采取 multi-leader 的方式。

top Created with Sketch.