Understanding the architecture-I
Gossip 是一个对等网络通信协议,节点间断性的交换他们自身的状态信息以及其他它们知道的节点信息。gossip 每中和集群中最多三个节点交换信息。不仅交换他们自身信息,而且还交换通过之前的gossip了解的其他节点信息,因此所有的节点能够很快的了解集群中的其他节点状况。一条gossip 信息会有一个相关联的版本号,因此当进行gossip交换的时候,对于一个特定的节点,它的老信息就会被最新的状态所覆盖。
为了阻止gossip通信可能出现的问题,集群中所有的节点都有相同的seed nodes列表。这一点在一个节点第一次启动的时候尤其重要。默认情况下,一个节点在随后的重启过程中会记住已经gossip的其他节点。seed node就是为了新加入到集群中的节点bootstrapping the gossip process使用的。不是为了单点失败,也没有其他特别的目的。(我理解是说种子节点的作用是:每个node都是一样的种子节点,当一个新的节点加入时,它是没有任何其他节点的信息,因此它通过种子节点拿到其他节点的信息,之后 重启之类的就不需要和种子节点通信了,因为会序列化自己之前gossip到的信息,重启时会replay,只有新加入的node,啥也不知道因此需要通过种子节点知道,种子节点可以解决2个节点同时加入 可能出现 A不知道B, B不知道A的情况)
注意:
在多数据中心的集群,确保每个数据中心至少有一个节点在seed list中。为了容错建议每个数据中心指派多个seed node,否则当一个节点bootstrap时,需要同其他数据中心进行gossip。
不建议把每个节点都设置为seed node,因为会增加维护的成本以及降低了gossip的性能。gossip优化并不是特别重要,但是建议使用一个小的seed 列表(每个数据中心3个节点最佳)
Failure detection and recovery
失败检测是从gossip的状态和历史获取信息,判断系统中的一个节点是否down了或者已经恢复了。Cassandra 利用这个信息避免将客户端的请求路由到任何时候有可能不可到达的节点。同时 Cassandra 通过Dynamic Snitch 避免将客户端请求路由到那些存活的但是性能比较差的节点上。
gossip过程能够跟踪其他节点的状态,通过直接(直接与某个节点gossip)或非直接(通过二手,三手等)方式。相比于一个固定的阈值来标记一个节点为fail,Cassandra 把网络、负载、历史状况等因素综合考虑,用累加(accrual)检测机制来计算每个节点的阈值。当进行gossip交换时,每个节点维护了其他节点gossip信息到达的滑动窗口时间。可以通过配置phi_convict_threshold属性来调节失败检测的敏感性。值越低,一个没有应答的节点更有可能被标记为down。大部分情况下,默认值就可以了。但是在Amazon EC2上需要增加到10或者12.(因为常常会遇到网络拥堵),在不稳定的网络环境中(比如EC2),提高值到10或者12可以避免错误的失败检测。不建议使用高于12,或者低于5的值。
节点失败可能有各种各样的原因造成的,比如硬件失败,网络故障。节点故障一般时间比较短,但是也有可能持续很长时间的。因为一个节点故障并不意味着永久地离开集群,不会自动从集群ring中移除。其他的节点会周期性的尝试和失败的节点重新建立联系,看它们是否已经回归。想要永久的改变集群节点的membership,需要管理员通过nodetool utility工具明确的将节点添加进来或者移除出集群。
当一个节点宕机后重新回归,那么宕机这段时间,它上面的副本miss了需要写入的数据。一些repair机制可以恢复这些数据,比如hinted handoffs以及通过nodetool repair手动repair。根据节点down掉的时间有多长来决定通过哪种repair机制来恢复数据,保持数据的一致性。