钝化副本有的应用有很强的随机读取要求,这就需要把所有数据放在内存里。在这种情况下,将数据分片并把每个分片主从复制通常需要两倍以上的内存,因为每个数据都要在主节点和从节点上各有一份。为了在主节点失效的时候起到代替作用,从节点上的内存大小应该和主节点一样。如果系统能够容忍节点失效的时候出现短暂中断或性能下降,也可以不要分片。 下面的图描绘了4个节点上的16个分片,每个分片都有一份在内存里,副本存在硬盘上: 灰色箭头突出了节点2上的分片复制。其他节点上的分片也是同样复制的。红色箭头描绘了在节点2失效的情况下副本怎样加载进内存。集群内副本的均匀分布使得只需要预留很少的内存就可以存放节点失效情况下激活的副本。在上面的图里,集群只预留了1/3的内存就可以承受单个节点的失效。特别要指出的是副本的激活(从硬盘加载入内存)会花费一些时间,这会造成短时间的性能下降或者正在恢复中的那部分数据服务中断。 系统协调在这部分我们将讨论与系统协调相关的两种技术。分布式协调是一个比较大的领域,数十年以来有很多人对此进行了深入的研究。这篇文章里只涉及两种已经投入实用的技术。关于分布式锁,consensus协议以及其他一些基础技术的内容可以在很多书或者网络资源中找到,也可以去看参考资料[17, 18, 21]。 故障检测故障检测是任何一个拥有容错性的分布式系统的基本功能。实际上所有的故障检测协议都基于心跳通讯机制,原理很简单,被监控的组件定期发送心跳信息给监控进程(或者由监控进程轮询被监控组件),如果有一段时间没有收到心跳信息就被认为失效了。除此之外,真正的分布式系统还要有另外一些功能要求:
所谓的累计失效检测器[12]可以解决前两个问题,Cassandra[16]对它进行了一些修改并应用在产品中。其基本工作流程如下:
根据重要程度不同来分层次组织监控区,各区域之间通过谣言传播协议或者中央容错库同步,这样可以满足扩展性的要求,又可以防止心跳信息在网络中泛滥[14]。如下图所示(6个故障检测器组成了两个区域,互相之间通过谣言传播协议或者像ZooKeeper这样的健壮性库来联系): 协调者竞选协调者竞选是用于强一致性数据库的一个重要技术。首先,它可以组织主从结构的系统中主节点的故障恢复。其次,在网络隔离的情况下,它可以断开处于少数的那部分节点,以避免写冲突。 Bully 算法是一种相对简单的协调者竞选算法。MongoDB 用了这个算法来决定副本集中主要的那一个。Bully 算法的主要思想是集群的每个成员都可以声明它是协调者并通知其他节点。别的节点可以选择接受这个声称或是拒绝并进入协调者竞争。被其他所有节点接受的节点才能成为协调者。节点按照一些属性来判断谁应该胜出。这个属性可以是一个静态ID,也可以是更新的度量像最近一次事务ID(最新的节点会胜出)。 |