Gossip协议是一个点对点协议,Cassandra用于两个节点间相互交换他们的状态信息,以及他们所知道的其它节点的信息。Gossip线程每秒执行一次随机和集群内其它三个节点进行信息交换。交换的信息包括他们自己的信息,以及他们知道的其他节点的信息,所以所有节点很快就可以得到整个集群节点的信息。每个交换的gossip信息都有一个版本号,所以交换过程中较新的信息就会覆盖老的信息。
为了避免通信异常,请确保每个节点的种子节点列表都一样,这对于一个节点的第一次启动很重要。通常一个几点会通过gossip记住所有后面启动的节点。种子节点的设计除了引导新加入集群的新节点启动gossip进程以外,没有其它目的。种子节点不是单点故障,除了引导新节点启动外,没有任何其它特殊目的。
注意:在多数据中心的集群里,种子列表应该包含每个数据中心的至少一个节点(建议每个数据中心多于一个节点,用于容错),因为节点启动的时候还需要和另外数据中心的节点进行通信。不推荐把每个节点都作为种子节点,因为这增加了维护成本还降低了gossip性能。gossip方面的优化不是很重要,但是还是建议使用一个较小的种子列表(每个数据中心三个节点差不多了)
集群内节点故障检测和恢复都是通过gossip实现的.
故障检测是本节点通过gossip状态和历史信息确定集群中另外一个节点是挂掉了还是恢复了的一种方法。Cassandra从而避免把客户端的请求路由到不可达的节点上。(Cassandra还可以根据动态的策略,避免把消息发送到负载高的节点上)。
Gossip线程可以直接或者间接的跟踪其它节点的状态。(就是说这些节点状态的信息,可能是对应节点直接发给它的,也有可能是通过别的节点转发过来的二手,三手信息)。
Cassandra并不是通过一个固定的阈值来判断一个节点挂掉了。而且有一套动态的检测机制来计算每个节点的阈值,考虑了网络、负载、历史状态等因素。在gossip信息交换的过程中,每个节点都记录了从其它节点获取到的消息的时间窗口信息。配置文件里的phi_convict_threshold配置项可以调节失败检测的灵敏度。这个值越小,一个节点被标记为DOWN状态的几率就越大,值越大反而减少一个节点因为瞬间故障被标记为Down状态的概率。大多数情况下这个值保持默认就可以。但是在亚马逊云E2上可以把它提高到10~12,(亚马逊云经常有网络拥塞)。对于不稳定的网络环境(比如E2),提高到10~12可以减少故障误判。不推荐这个值大于12或者小于5。
节点故障可能是多种原因造成的,比如硬件故障,网络中断。节点中断往往是临时性的,但可能持续很长时间。节点中断通常并不意味着它永久脱离集群,所以cassandra并不会自动把故障的节点从集群hash环中删除掉,其它节点会定时的尝试联系这个节点以判断它是否恢复。如果想是永久性的操作,管理员必须使用nodetool工具或者从opscenter上明确的添加或者删除某个节点。
当一个节点从中断中恢复,他可能错过了很多写操作。一旦一个节被检测为故障中断,数据的其它副本所在的节点会帮它记录错过的写操作(记作hints)一段时间,前提是这个功能已配置启用。不过一个节点挂掉的时间太久,超过了max_hint_window_in_ms配置的值(默认3小时),hints就不再记录。那些挂掉的节点也有可能存储了一些未送达的hints。所以在恢复一个挂掉很久的节点后,请执行repair操作。而且,你应该定期执行noodtool repair命令以保证节点间数据一致性。
在cassandra中,数据的分布和副本要一起看,数据通过一个个的表组织起来,由一个主键确定数据存储在哪个节点上。副本就是一行数据的多个拷贝,当数据第一次写入的时候,其实我可以称为一个副本。
影响数据副本分布的因素包括:
虚拟节点:用于数据和物理节点映射关系。
分区:对集群中的数据进行分区
副本策略:确定每行数据的副本数
告密者: 对集群中节点拓扑关系的一种定义,副本策略根据它来放置副本。
Cassandra采用一致性hash算法来计算数据如何在节点上分布。使用一致性hash的目的是就是当增加或者移动一个节点的时候,只要移动很小的数据就可以完成数据的再均衡。
每条数据的第一个主键叫分区主键,分区主键的hash值落在哪个节点内,这条数据就分布在哪个节点。其它副本就落在hash环上的下一个节点上。
除非注明,赵岩的博客文章均为原创,转载请以链接形式标明本文地址
本文地址:https://zhaoyanblog.com/archives/1017.html
感谢分享!已推荐到《开发者头条》:https://toutiao.io/posts/tb59j0 欢迎点赞支持!
欢迎订阅《fdr的闲聊铺》https://toutiao.io/subjects/80898