Cassandra维护最终一致性 和存储机制 分区策略

维护最终一致性数组

Cassandra 经过4个技术来维护数据的最终一致性,分别为逆熵(Anti-Entropy),读修复(Read Repair),提示移交(Hinted Handoff)和分布式删除。缓存

1)       逆熵数据结构

这是一种备份之间的同步机制。节点之间按期互相检查数据对象的一致性,这里采用的检查不一致的方法是 Merkle Treedom

2)       读修复分布式

客户端读取某个对象的时候,触发对该对象的一致性检查:函数

读取Key A的数据时,系统会读取Key A的全部数据副本,若是发现有不一致,则进行一致性修复。spa

若是读一致性要求为ONE,会当即返回离客户端最近的一份数据副本。而后会在后台执行Read Repair。这意味着第一次读取到的数据可能不是最新的数据;设计

若是读一致性要求为QUORUM,则会在读取超过半数的一致性的副本后返回一份副本给客户端,剩余节点的一致性检查和修复则在后台执行;日志

若是读一致性要求高(ALL),则只有Read Repair完成后才能返回一致性的一份数据副本给客户端。orm

可见,该机制有利于减小最终一致的时间窗口。

3)       提示移交

对写操做,若是其中一个目标节点不在线,先将该对象中继到另外一个节点上,中继节点等目标节点上线再把对象给它:

Key A按照规则首要写入节点为N1,而后复制到N2。假如N1宕机,若是写入N2能知足ConsistencyLevel要求,则Key A对应的RowMutation将封装一个带hint信息的头部(包含了目标为N1的信息),而后随机写入一个节点N3,此副本不可读。同时正常复制一份数据到N2,此副本能够提供读。若是写N2不知足写一致性要求,则写会失败。 等到N1恢复后,本来应该写入N1的带hint头的信息将从新写回N1

4)       分布式删除

单机删除很是简单,只须要把数据直接从磁盘上去掉便可,而对于分布式,则不一样,分布式删除的难点在于:若是某对象的一个备份节点 A 当前不在线,而其余备份节点删除了该对象,那么等 A 再次上线时,它并不知道该数据已被删除,因此会尝试恢复其余备份节点上的这个对象,这使得删除操做无效。

Cassandra 的解决方案是:本地并不当即删除一个数据对象,而是给该对象标记一个hint,按期对标记了hint的对象进行垃圾回收。在垃圾回收以前,hint一直存在,这使得其余节点能够有机会由其余几个一致性保证机制获得这个hint

Cassandra 经过将删除操做转化为一个插入操做,巧妙地解决了这个问题。


分区策略

Token,Partitioner

Cassandra中,Token是用来分区数据的关键。每一个节点都有一个第一无二的Token,代表该节点分配的数据范围。节点的Token造成一个Token环。例如使用一致性HASH进行分区时,键值对将根据一致性Hash值来判断数据应当属于哪一个Token。

 

          3 Token Ring

 

分区策略的不一样,Token的类型和设置原则也有所不一样。 Cassandra (0.6版本)自己支持三种分区策略:

RandomPartitioner:随机分区是一种hash分区策略,使用的Token是大整数型(BigInteger),范围为0~2^127Cassandra采用了MD5做为hash函数,其结果是128位的整数值(其中一位是符号位,Token取绝对值为结果)。所以极端状况下,一个采用随机分区策略的Cassandra集群的节点能够达到2^127+1个节点。采用随机分区策略的集群没法支持针对Key的范围查询。

OrderPreservingPartitioner:若是要支持针对Key的范围查询,那么能够选择这种有序分区策略。该策略采用的是字符串类型的Token。每一个节点的具体选择须要根据Key的状况来肯定。若是没有指定InitialToken,则系统会使用一个长度为16的随机字符串做为Token,字符串包含大小写字符和数字。

CollatingOrderPreservingPartitioner:和OrderPreservingPartitioner同样是有序分区策略。只是排序的方式不同,采用的是字节型Token,支持设置不一样语言环境的排序方式,代码中默认是en_US

分区策略和每一个节点的Token(Initial Token)均可以在storage-conf.xml配置文件中设置。

 

bloom-filter, HASH

Bloom Filter是一种空间效率很高的随机数据结构,本质上就是利用一个位数组来表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter的这种高效是有偏差的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。所以,Bloom Filter不适合那些零错误的应用场合,而在能容忍低错误率的场合下,Bloom Filter经过极少的错误换取了存储空间的极大节省。

原理:位数组 + K个独立hashy)函数。将位数组中hash函数对应的值的位置设为1,查找时若是发现全部hash函数对应位都是1说明存在,很明显这个过程并不保证查找的结果是彻底正确的。

 

Cassandra中,每一个键值对使用1Byte的位数组来实现bloom-filter

 

 

4 Bloom Filter


存储机制

Cassandra的存储机制借鉴了Bigtable的设计,采用MemtableSSTable的方式。

 

CommitLog

HBase同样,Cassandra在写数据以前,也须要先记录日志,称之为Commit Log,而后数据才会写入到Column Family对应的MemTable中,且MemTable中的数据是按照key排序好的。SSTable一旦完成写入,就不可变动,只能读取。下一次Memtable须要刷新到一个新的SSTable文件中。因此对于Cassandra来讲,能够认为只有顺序写,没有随机写操做。

 

MenTable

MemTable是一种内存结构,当数据量达到块大小时,将批量flush到磁盘上,存储为SSTable。这种机制,至关于缓存写回机制(Write-back Cache),优点在于将随机IO写变成顺序IO写,下降大量的写操做对于存储系统的压力。因此咱们能够认为Cassandra中只有顺序写操做,没有随机写操做。

 

SSTable

SSTableRead Only的,且通常状况下,一个CF会对应多个SSTable,当用户检索数据时,Cassandra使用了Bloom Filter,即经过多个hash函数将key映射到一个位图中,来快速判断这个key属于哪一个SSTable

为了减小大量SSTable带来的开销,Cassandra会按期进行compaction,简单的说,compaction就是将同一个CF的多个SSTable合并成一个SSTable。在Cassandra中,compaction主要完成的任务是:

1) 垃圾回收: cassandra并不直接删除数据,所以磁盘空间会消耗得愈来愈多,compaction 会把标记为删除的数据真正删除;

2) 合并SSTablecompaction 将多个 SSTable 合并为一个(合并的文件包括索引文件,数据文件,bloom filter文件),以提升读操做的效率;

3) 生成 MerkleTree:在合并的过程当中会生成关于这个 CF 中数据的 MerkleTree,用于与其余存储节点对比以及修复数据。

相关文章
相关标签/搜索