比如,为了提高可用性,引入了冗余;而冗余又带来了副本之间的一致性问题,所以引入了中心化副本协议(primary/secondary);那么接下来就要考虑primary(节点)故障时候的选举问题。。。
(3)这是一个金字塔结构,或者说,也是一个深度优先遍历的过程。
在这个过程中,我们始终知道自己已经掌握了哪些知识;还有哪些是已经知道,但未了解的知识;也能知道,哪些是空白,即我们知道这里可能有很多问题,但是具体是什么,还不知道。
那么,各个分布式系统如何与这些特征相关联呢?不难发现,每个分布式系统都会或多或少的体现出这些特征,只是使用的方法、算法可能不大一样。所以,我们应该思考,这个问题,在这个系统中是如何解决的。比如元数据管理的强一致性,在MongoDB中是如何实现的,在HDFS中是如何实现的。这也指导了我们如何去学习一个具体的分布式系统:带着问题,只关注关心的部分,而不是从头到尾看一遍。
下面是,到目前为止,我对分布式特征的思维导图
对于上图,需要声明的是,第一:不一定完全正确,第二:不完整。这是因为,我自己也在学习中,可以看到,很多分支很短(比如去中心化副本协议),不是因为这一块没有内容,而是我压根儿还没去了解,还没去学习。
我会持续跟新这幅脑图的!
下一章,介绍一下分布式系统的各个特征。
分布式系统的一般特征任何介绍分布式系统的文章或者书籍都会提到分布式系统的几个特性:可扩展性、高性能、高可用、一致性。这几个特性也是分布式系统的衡量指标,正是为了在不同的程度上满足这些特性(或者说达到这些指标),理论家和实践者才会设计出各种各样的算法、协议,然后根据业务的需求在这些特性间平衡。
那么本章节简单说明,为什么要满足这些特性,要满足这些特性需要解决什么问题,有什么好的解决方案。
可扩展性
Scalability is the capability of a system, network, or process to handle a growing amount of work, or its potential to be enlarged to accommodate that growth.
可扩展性是指当系统的任务(work)增加的时候,通过增加资源来应对任务增长的能力。可扩展性是任何分布式系统必备的特性,这是由分布式系统的概念决定的:
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统
分布式系统的出现是为了解决单个计算机无法完成的计算、存储任务。那么当任务规模增加的时候,必然就需要添加更多的节点,这就是可扩展性。
扩展性的目标是使得系统中的节点都在一个较为稳定的负载下工作,这就是负载均衡,当然,在动态增加节点的时候,需要进行任务(可能是计算,可能是数据存储)的迁移,以达到动态均衡。
那么首先要考虑的问题就是,如何对任务进行拆分,将任务的子集分配到每一个节点,我们称这个过程问题Partition(Sharding)。关于Partition,其实我在《带着问题学习分布式系统之数据分片 》一文中有详细介绍,这里进行归纳总结。
第一:分片分式,即按照什么算法对任务进行拆分常见的算法包括:哈希(hash),一致性哈希(consistency hash),基于数据范围(range based)。每一种算法有各自的优缺点,也就有各自的适用场景。
第二:分片的键,partition keypartition key是数据的特征值,上面提到的任何分片方式都依赖于这个partition key,那么该如何选择呢
based on what you think the primary access pattern will be
partition key会影响到任务在分片之间的均衡,而且一些系统中(mongodb)几乎是不能重新选择partition key的,因此在设计的时候就得想清楚
第三:分片的额外好处提升性能和并发:不同的请求分发到不同的分片
提高可用性:一个分片挂了不影响其他的分片
第四:分片带来的问题如果一个操作需要跨越多个分片,那么效率就会很低下,比如数据中的join操作
第五:元数据管理