本文已迁移到我的新博客地址:blog.favorstack.io 欢迎访问~
本文主要翻译自Datastax公司的在线文档,Cassandra版本为2.1。由于水平有限,翻译不当之处还请大家指正。
Gossip协议是一种P2P通信协议,节点用来周期性的交换彼此的状态信息,包括它们知道的其他节点。Gossip进程每秒钟运行一次,并且与集群中最多3个其他节点交换状态信息。节点交换彼此的信息,并且还会交换那些它们已经进行过通信的节点的信息。这样,所有的节点都能迅速的学习了解集群中其他的节点。Gossip消息有一个与之相关的版本,这样在消息交换过程中,对于一个特定的节点,老版本的信息会被最近的版本覆盖。
为了解决Gossip通信中的问题,我们在集群中的所有节点使用相同的种子节点列表。这在一个节点第一次启动时非常关键。默认情况下,一个节点会记住它曾经通信过的节点,即便后来又重启过。种子节点的设计并无特殊目的,只是为了新加入集群中的节点启动流言进程。在集群操作中,除了用于启动节点,种子节点既不是为了单节点故障,也没有其他特殊的目的。
注意:在多数据中心的集群中,种子列表应该包含每个数据中心(副本组)的至少一个节点。
为了容错,推荐每个数据中心有一个以上的种子节点。否则当启动一个节点时,需要与其他数据中心进行Gossip通信。不推荐将所有节点都作为种子节点。因为这增加了维护成本和降低了Gossip的性能。Gossip的优化并不是必须的,但是推荐使用一个小的种子列表(大约每个数据中心3个)。
故障检测和恢复
故障检测是指系统中另一个节点宕掉或恢复后,用于本地确定流言状态和历史的方法。Cassandra使用此信息来尽可能地避免将客户端请求路由到无法到达的节点上。(Cassandra也可以避免将客户端请求路由到存活的节点上,但是表现不佳,这依赖于动态Snitch)。
Gossip进程通过直接和间接的方式追踪其他节点的状态。而不是通过一个固定的阈值来标记节点的死亡。Cassandra使用一种Phi增量故障检测机制来计算每个节点的阈值,这里考虑到了网络环境的波动性,负载及过去一段时间内的状况。Gossip交换信息期间,每个节点都维护着一个来自集群中其他节点的Gossip消息的动态列表(every node maintains a sliding window of inter-arrival times ofgossip messages from other nodes in the cluster.)。通过配置phi_convict_threshold 属性来调整故障检测的灵敏度。较低的值将会增加故障的嫌疑,反应迟钝的节点将被标记为离线;较高的值则会降低故障的嫌疑级别,短暂的故障将会标记一个节点为离线。默认值适用于大部分情况,对于亚马逊的EC2,建议设置为10或12(由于网络阻塞比较频繁)。在不稳定的网络环境中(如EC2那样),调高该值到10或12能够降低错误的故障率。不推荐将该值设置高于12或低于5。
很多情况都会导致节点故障,如硬件故障,网络中断。节点中断往往是短暂的,但这种状态可以持续很长时间。节点的短暂中断并不代表它永久地脱离了集群,因此它不会自动地从环中被永久移除。其他节点会定期的尝试重新联系这些失败的节点,看它们是否已经恢复。想永久地改变一个节点在集群中的成员关系,管理员必须明确地通过nodetool 工具或OpsCenter往集群中添加或移除节点。
当一个节点从中断中恢复并重新在线,它可能错过了一些本应由它负责的副本数据。提示移交(hinted handoff)开启的情况下,一旦故障检测到一个节点宕掉,要往该节点写的数据信息(提示,hint)会暂时由其他节点托管。如果一个节点离线超过max_hint_window_in_ms值(默认3小时),提示将不再保存。死亡的节点可能存储了未移交的提示信息,所以在恢复一个离线很长时间的节点后,需要运行修复工具。此外,你应该经常在所有节点上运行nodetool repair,以确保它们的数据保持一致。
原文地址:http://docs.datastax.com/en/cassandra/2.1/cassandra/architecture/architectureGossipAbout_c.html
本文已迁移到我的新博客地址:blog.favorstack.io 欢迎访问~