走进cassandra之七:最终一致性

时间:2021-09-30 04:50:13

关于这个最终一致性,我们还是举打仗的那个例子。
一个师,下辖三个团,一个独立营。
大家知道,在战斗的时候,突发事件很多,时间也很紧迫。
来自师部的作战命令,可能没有办法及时到达各个营。
尤其是在八路的军队里,通讯基本靠吼,通讯员去传令的时候,说不定走在半路就被打死了。
得想办法应对此类问题。

这个跟cassandra是一个样的,它也有很多节点,多个节点,同时在向外服务,它也需要通讯员去传达命令给各个节点,通讯员在半路遇到打劫的怎么办呢?死掉了怎么办呢?节点没反应了怎么办呢?

针对这些问题, cassandra是有一套自己的机制的。
1.Read Repair
2.Anti-Entropy Node Repair
3.Hinted Handoff

#1 read repair.
coordinator 发送给每一个 replica的读请求,有两种:
direct read request
background read repair request

direct read request 会送给谁呢?
你的一致性level所规定的那些节点(one,quorum,all)

background read repair request 送给谁呢?
送给剩余的那些节点(direct read request没有送到的节点)

读取Key A的数据时,系统会读取Key A的所有数据副本,如果发现有不一致,则进行一致性修复。
如果读一致性要求为ONE,会立即返回离客户端最近的一份数据副本。然后会在后台执行Read Repair。这意味着第一次读取到的数据可能不是最新的数据。
如果读一致性要求为QUORUM,则会在读取超过半数的一致性的副本后返回一份副本给客户端,剩余节点的一致性检查和修复则在后台执行。
如果读一致性要求高(ALL),则只有Read Repair完成后才能返回一致性的一份数据副本给客户端。
该机制有利于减少最终一致的时间窗口

2.Anti-Entropy Node Repair
有一个叫node tool的东东,专门负责管理维护各个节点,它的任务之一就是通过Anti-Entropy这种办法,来进行node repair,把不一致的数据弄成一致的。
数据的最终一致性由AntiEntropy(逆熵)所生成的MerkleTrees对比来发现数据复制的不一致,通过org.apache.cassandra.streaming来进行完整的一致性修复。
Merkle Tree是一种Hash Tree,叶子节点是Key的hash值,父节点是所有子节点值的hash值,通过判断父节点的异同可以知道所有子节点的异同。
通过判断root的异同可以快速判断所有叶子节点数据的异同。
执行nodetool?repair可以启动Anti-Entropy,此操作需要扫描所有数据,对系统的IO有较大压力,建议在业务低峰期定期执行

3.Hinted Handoff
Writes are always sent to all replicas for the specified row regardless of theconsistency level
specified by the client. If a node happens to be down at the time of write, itscorresponding replicas will save hints
about the missed writes, and then handoff the affected rows once the node comesback online。
举例来说:
Key A按照规则首要写入节点为N1,复制到N2
假 如N1宕机,如果写入N2能满足ConsistencyLevel要求,则Key A对应的RowMutation将封装一个带hint信息的头部(包含了目标为N1的信息),然后随机写入一个节点N3,此副本不可读。同时正常复制一份 数据到N2,此副本可以提供读。如果写N2不满足写一致性要求,则写会失败。
N1恢复后,原本应该写入N1的带hint头的信息将重新写回N1。
HintedHandoff是实现最终一致性的一个优化措施,可以减少最终一致的时间窗口。