️This article has been over 1 years since the last update.
本文总结一下常见的分布式与高可用方案
什么是分布式系统
定义一:A distributed system is a collection of autonomous computing elements that appears to its users as a single coherent/koˈhɪrǝnt/ system.
翻译过来,就是对用户看起来是单体,但是实际上是由独立自治的计算组件聚合而成的系统。
- autonomous: having the freedom to act independently.
- computing elements: node, can be HPC, VM, Thread and more.
- collection: is often organized as an overlay network. Eg: p2p, TCP/IP
- coherent: a distributed system is coherent if it behaves according to the expectations of its users. 注意这里是用户对主观现象的观测,而非客观的定义,如果换个较真的人观察出破绽,那么它就是不是"单体"了。
定义二:A distributed system consists of a collection of distinct processes which are spatially separated, and which com- municate with one another by exchanging messages
一个分布式系统是多个空间上分离,使用内部通信的独立流程组合的集合。
从这里的定义可以看出,分布式系统是一个经验归纳大于理论演绎的定义。它涉及到了同一(identity)关系的哲学问题(忒修斯之船),与时间颗粒度息息相关。
机房里的CPU换了2次,内存换了3次,它还是这套集群吗?虚拟机通过热迁移技术切换到另一个机柜的设备中,它还是你的VM吗?
可靠和可用
High availability (HA) is a characteristic of a system which aims to ensure an agreed level of operational performance, usually uptime, for a higher than normal period.
分布式系统一般讨论的是高可用中的可靠性的组合场景,比如冗余或者切片。
分布式不等于高可用(availability),不等于高可靠(durability),不等于弹性伸缩,不等于冗余,不等于克服了单点故障,也不提供掉电保护。
硬件分布式系统分类
硬件上主要体现在冗余性,虚拟直通,存算分离上
上述可以确保VM与内存数据几乎不会丢失,但是VM中运行的软件本身仍然可能挂掉。
软件分布式系统分类
理论的维度
假如需要进行专业的体系化CS课程,至少半年,可以参考如下
Distributed Computing Systems(cs230)
时间:物理时间(比如ntp同步)与逻辑时间(比如term)
状态:全局状态与快照
Distributed Coordination and Resource Management
Messaging and Communication in Distributed Systems
Fault Tolerance in Distributed Systems
Security in Distributed Systems
Distributed Database Management and Transaction Processin(cs223)
Distributed Objects and Middleware Platforms(cs237)
这里理论比工程更重要,而且是存粹的理论。
工程上的规格
假如只是进行概念的理解,如下即可
一致性:强一致性、最终一致性
需要分布管理的内容:比如
- 元数据(比如k-v、状态、健康)
- 二进制(比如S3/Git/SVN/Lustre/边缘SDN)
协商方向:
- Push:下游需要全量数据时才使用,比如Database streaming/mirroring,RAFT
- Pull:下游需要部分数据即可,如二进制增量缓存/看门狗等场景
- Proxy:比如Gitlab geo的写入方案,cloudflare的Worker读写方案
节点角色:广义上也可以看作政治权利,比如说“不”的权利。
故障转移时间RTO:一般商用需要为10s
按照组网架构分类
常见组网架构如下
上述方案假设在高速LAN中横向通信,不含容灾。上述成本基本上都比托管的服务更高,也不包含硬件存储架构方案。
事实上云服务厂商的硬件实现的分布式存储才是最简方案。
工程经验类方法
工程实践的核心思路是将本侧的分布式难题交给下游供应商,进而提高收益,比如
将业务分解为meta/worker/proxy等无状态的服务,比如sonarqube的ComputeEngine
用硬件的RDMA/NFS转换问题,比如Oracle RAC就强制要求超高性能内网,否则直接停机。
用软件的数据库/Raft,基于元数据实现分片,比如在三个数据中心搭建
2+2+1的高可用的quorum用云服务,比如FSFO(by Oracle),或者GaussDB参考,用Aurora把难题扔给AWS。然而云服务事实上并不兜底,最多赔偿一点代金券,相对业务损失不值一提。
主备方案介绍
大部分有状态的主备份方案为冗余方案(hot standby),难点在同步复制协议(Primary/Replica)。它要求的性能与可用性(断电前写入存储介质)中取得平衡
- 协议:主要为基于Journaling的checkpoint和reply的方案
- 强一致类型:写入IO性能变弱,可以实现读写分离,任意一台挂掉需要人工介入
- 最终一致类型:基本上就是靠事件+定时同步,可以容灾
常见如下
| 类型 | 复制协议 | Monitoring node | 自动恢复 | 读写分离 |
|---|---|---|---|---|
| Jenkins | NFS/rsync innotify | 0 | 需要手动 | NA |
| GitLab(unofficial) | NFS/rsync innotify | keepalived | Y | 勉强够用 |
| MySQL | Async Binlog | 0 | 需要手动 | N |
| pg-pool | WAL | 1 | 需要手动 | Y |
| Redis | Async AOF/RDB | 0 | 需要手动 | N |
| Redis(Sentinel) | Async AOF/RDB | 1~3(Sentinel) | Y,比如5s | N |
| Artifactory-Remote | Pull | NA | NA | NA |
从我个人实践的角度,热主备方案投资收益极为鸡肋
- 大部分都无法扩容,中间的代理层导致应用定位复杂(需要额外的Client/Agent 来判活,比如pg-pool的连接池在项目中出现2次大故障,定位起来资料困乏)
- 冗余框架出了问题仍然要手动维修,万一真挂了,重启也修不好
- 自动切换需要客户端适配协商,引入繁琐的非业务用例,比如需要做“监控的监控”
上述方案其实意义有限,甚至整体恢复时间不如单机版+极速备份回滚
三台以上高可用方案
一致性与过期(consistance and stale)的定义
谈到一致性,很多人就想到了被阿里带歪的CAP八股文,我们要先明确
- 一致需要同时考虑客户端与服务端的配置,你搭建三台号称强一致性的ZK,并不代表业务就有了强一致性
- CAP并不是要求三选二,而是大部分情况“我全都要”,而且主要是客户端自己决定
举一些例子
- 当etcd挂了,K8S里的应用服务仍然能跑,Calico也勉强能用,客户端缓存还在,只是部分控制域的功能丢失
- Consul既支持客户端绕一圈获取协商结果(network roundtrips,耗时长),也支持直接读取单节点数据,甚至客户端/Sidecar节点本身就有一定缓存
- Oracle RAC是集群数据库,它需要处理转账等强一致业务,一旦RDMA集群间断网就直接停机。
- 你在两个数据中心部署了2+3个zk,然后部署三台的机房突然停电,另外两台也照样完蛋。
基于元数据管理的方案
元数据既可以通过集中管理,也可以通过分散管理
- 分散:区块链、GlusterFS与DHT BT下载等场景,以及跨DC的Github Spokes 服务
- 集中:常见的BT的tracker协议,以及RAFT/Paxo/Gossip(这里讨论)
我们首先要明确,在中心化的一致性元数据管理中,并没有实现扩容
- 用于数据面(比如分片)与控制面(比如路由)的元数据存储仍然需要中心化的权威存储介质(have a single primary copy at any moment.),并基于强一致性实现多机冗余。就算是DHT表,也不会同步到所有客户端机器。
- 剩余节点是无状态运算机,可以扩容
跨WAN的Region场景,默认是不可靠的,一般要最终一致性,这种流程可以简化容灾,跨Site同步等流程。
路由与失败检查(Failure Models)
这里主要需要纠结pull和push,超时和失败的定义。
总结
只要是异步系统(无法区分超时),共识在有限时间内不能完美地完成
作为技术人员,不要因为面试八股文就陷入100%分布式高可用、弹性伸缩、容灾且完美调度等理想模型中,而是意识到理论的不完美、技术的局限性,现实的不确定性,才能更好地理解分布式系统。
扩容是系统工程,物理机房的密度,交换机的插孔,功耗等都会限制最大值,上述方案最终实现的也不过是“昂贵的数据孤岛”。甚至你在专心搞高可用时,你的友商投入人力做Demo已经把项目拿下了。