最近在看 Martin Fowler 网站上的Patterns of Distributed Systems系列文章,突然想到,是不是也写一篇文章简单梳理一些分布式系统的学习框架,方便以后查阅,于是就有了这篇文章。下篇文章将会编译Patterns of Distributed Systems系列文章,大家可以与这篇文章对比下,选择自己合适的方式学习。
分布式系统已经成为了现在软件行业的标配,毕竟随着大数据技术的流行,分布式系统不再束之高阁,仅限于学术圈的讨论,而是真正有了一系列开源软件帮助开发者实现分布式系统。似乎每个人都在讨论分布式系统,但是分布式系统到底是什么?我认为分布式系统分为下面几个类型:
这些都是分布式系统,它们都有着共同点,那就是
“未虑胜,先思败”,在实现一个分布式系统时,首先要考虑会遇上什么麻烦,这样麻烦出现时才不会手忙脚乱。同样的,在学习一个分布式系统时,边读文档,边思考这个分布式系统或者是这个应用是如何解决分布式系统常见的麻烦的。
总的来说,经过这么多年的实践,分布式系统常遇见的麻烦可以归类为下面几种:
当一台机器无法存储应用的所有数据时,就势必要把数据进行切分,分散到多台机器上进行存储,这就是所谓的分区。分区的方法大致上来说有两种:
在分区后,随着时间的推移,还需要考虑数据热点,比如某一个分区上的数据远远多于其它分区的数据,这时候就需要负载均衡,把热点数据打散。
分布式系统由很多台服务器组成,那么其中一台故障的话,里面的数据会出现丢失的风险,就需要对数据进行备份,或者说数据复制。这也自然就会牵扯到如何让不同的数据副本保持一致。一般来说,常用方法就是区分领导者和跟随者,根据领导者的个数,可以把数据复制的方法分为三种:
在数据复制时,跟随者宕机了好处理,只要将领导者的数据重复一遍就可以了,但是领导者的数据就不好处理了,因为领导者宕机可能是机器真的故障了,也有可能是网络发生了延迟,如果是网络延迟导致的,然后服务器之间又选举了新的领导者,那么就会出现脑裂现象,也就是新旧领导者共存。
当然除了数据复制本身,为了保证各副本的一致,就需要解决下面的问题:
并由此引申出一系列算法,比如 Raft。
在分布式系统里除了这些内容外,还需要考虑数据存储和数据计算,这些内容其实和单机系统所要处理的并无太大不同,便不多叙述。