学习分布式系统跟学习其它技术非常不一样,分布式系统涵盖的面非常广,具体来说涵盖如下几方面:
服务调度,涉及服务发现、配置管理、弹性伸缩、故障恢复等。
资源调度,涉及对底层资源的调度使用,如计算资源、网络资源和存储资源等。
流量调度,涉及路由、负载均衡、流控、熔断等。
数据调度,涉及数据复本、数据一致性、分布式事务、分库、分表等。
容错处理,涉及隔离、幂等、重试、业务补偿、异步、降级等。
自动化运维,涉及持续集成、持续部署、全栈监控、调用链跟踪等。
所有这些形成了分布式架构的整体复杂度,也造就了分布式系统中的很多很多论文、图书以及很多很多的项目。要学好分布式系统及其架构,我们需要大量的时间和实践才能真正掌握这些技术。
这里有几点需要你注意一下。
分布式系统之所以复杂,就是因为其太容易也太经常出错了。这意味着,你要把处理错误的代码当成正常功能的代码来处理。
开发一个健壮的分布式系统的成本是单体系统的几百倍甚至几万倍。这意味着,我们要自己开发一个,需要能力很强的开发人员。
非常健壮的开源的分布式系统并不多,或者说基本没有。这意味着,如果你要用开源的,那么你需要 hold 得住其源码。
管理或是协调多个服务或机器是非常难的。这意味着,我们要去读很多很多的分布式系统的论文。
在分布式环境下,出了问题是很难 debug 的。这意味着,我们需要非常好的监控和跟踪系统,还需要经常做演练和测试。
在分布式环境下,你需要更科学地分析和统计。这意味着,我们要用 P90 这样的统计指标,而不是平均值,我们还需要做容量计划和评估。
在分布式环境下,需要应用服务化。这意味着,我们需要一个服务开发框架,比如 SOA 或微服务。
在分布式环境下,故障不可怕,可怕的是影响面过大,时间过长。这意味着,我们需要花时间来开发我们的自动化运维平台。
总之,在分布式环境下,一切都变得非常复杂。要进入这个领域,你需要有足够多的耐性和足够强的心态来接受各式各样的失败。当拥有丰富的实践和经验后,你才会有所建树。这并不是一日之功,你可能要在这个领域花费数年甚至数十年的时间。
分布式架构入门
学习如何设计可扩展的架构将会有助于你成为一个更好的工程师。系统设计是一个很宽泛的话题。在互联网上,关于架构设计原则的资源也是多如牛毛。所以,你需要知道一些基本概念,对此,这里你先读一下下面两篇文章,都非常不错。
目前这个仓库收集到了好些系统架构和设计的基本方法。其中包括:CAP 理论、一致性模型、可用性模式、DNS、CDN、负载均衡、反向代理、应用层的微服务和服务发现、关系型数据库和 NoSQL、缓存、异步通讯、安全等。
我认为,上面这几篇文章基本足够可以让你入门了,因为其中基本涵盖了所有与系统架构相关的技术。这些技术,足够这世上 90% 以上的公司用了,只有超级巨型的公司才有可能使用更高层次的技术。
分布式理论
下面,我们来学习一下分布式方面的理论知识。
首先,你需要看一下 An introduction to distributed systems。 这只是某个教学课程的提纲,我觉得还是很不错的,几乎涵盖了分布式系统方面的所有知识点,而且辅以简洁并切中要害的说明文字,非常适合初学者提纲挈领地了解知识全貌,快速与现有知识结合,形成知识体系。这也是一个分布式系统的知识图谱,可以让你看到分布式系统的整体全貌。你可以根据这个知识图 Google 下去,然后你会学会所有的东西。 然后,你需要了解一下拜占庭将军问题(Byzantine Generals Problem)。这个问题是莱斯利·兰波特(Leslie Lamport)于 1982 年提出用来解释一致性问题的一个虚构模型(论文地址)。拜占庭是古代东罗马帝国的首都,由于地域宽广,守卫边境的多个将军(系统中的多个节点)需要通过信使来传递消息,达成某些一致的决定。但由于将军中可能存在叛徒(系统中节点出错),这些叛徒将努力向不同的将军发送不同的消息,试图会干扰一致性的达成。拜占庭问题即为在此情况下,如何让忠诚的将军们能达成行动的一致。 对于拜占庭问题来说,假如节点总数为 N,叛变将军数为 F,则当 N >= 3F + 1 时,问题才有解,即拜占庭容错(Byzantine Fault Tolerant,BFT)算法。拜占庭容错算法解决的是,网络通信可靠但节点可能故障情况下一致性该如何达成的问题。
最早由卡斯特罗(Castro)和利斯科夫(Liskov)在 1999 年提出的实用拜占庭容错(Practical Byzantine Fault Tolerant,PBFT)算法,是第一个得到广泛应用的 BFT 算法。只要系统中有 2/3 的节点是正常工作的,则可以保证一致性。PBFT 算法包括三个阶段来达成共识:预准备(Pre-Prepare)、准备(Prepare)和提交(Commit)。
这里有几篇和这个问题相关的文章,推荐阅读。
拜占庭容错系统研究中有三个重要理论:CAP、FLP 和 DLS。
网络是稳定的。
网络传输的延迟是零。
网络的带宽是无穷大。
网络是安全的。
网络的拓扑不会改变。
只有一个系统管理员。
传输数据的成本为零。
整个网络是同构的。
下面分享几篇一致性方面的论文。
其实,在很多时候,我们并不需要强一致性的系统,所以后来,人们争论关于数据一致性和可用性时,主要是集中在强一致性的 ACID 或最终一致性的 BASE。当时,BASE 还不怎么为世人所接受,主要是大家都觉得 ACID 是最完美的模型,大家很难接受不完美的 BASE。在 CAP 理论中,大家总是觉得需要"三选二",也就是说,P 是必选项,那"三选二"的选择题不就变成数据一致性 (consistency)、服务可用性 (availability) 间的"二选一" ?
然而,现实却是,P 很少遇到,而 C 和 A 这两个事,工程实践中一致性有不同程度,可用性也有不同等级,在保证分区容错性的前提下,放宽约束后可以兼顾一致性和可用性,两者不是非此即彼。其实,在一个时间可能允许的范围内是可以取舍并交替选择的。
Base: An Acid Alternative (中译版),本文是 eBay 的架构师在 2008 年发表给 ACM 的文章,是一篇解释 BASE 原则,或者说最终一致性的经典文章。文中讨论了 BASE 与 ACID 原则的基本差异, 以及如何设计大型网站以满足不断增长的可伸缩性需求,其中有如何对业务做调整和折中,以及一些具体的折中技术的介绍。一个比较经典的话是——“在对数据库进行分区后, 为了可用性(Availability)牺牲部分一致性(Consistency)可以显著地提升系统的可伸缩性 (Scalability)”。 Eventually Consistent ,这篇文章是 AWS 的 CTO 维尔纳·沃格尔(Werner Vogels)在 2008 年发布在 ACM Queue 上的一篇数据库方面的重要文章,阐述了 NoSQL 数据库的理论基石——最终一致性,对传统的关系型数据库(ACID,Transaction)做了较好的补充。
小结
好了,总结一下今天分享的内容。文章的开头,我给出了学习分布式架构需要注意的几个关键点,然后列出了入门学习的资源,基本涵盖了所有与系统架构相关的技术。随后讲述了拜占庭容错系统研究中有三个重要理论:CAP、FLP 和 DLS,以及 8 条荒谬的分布式假设,从理论和认知等角度让你更为清楚地理解分布式系统。最后分享了几篇一致性相关的论文,很实用很经典,推荐阅读。
下篇文章中,我将推荐一些分布式架构的经典图书和论文,并给出了导读文字,几乎涵盖了分布式系统架构方面的所有关键的理论知识。敬请期待。
下面是《程序员练级攻略(2018)》系列文章的目录。