现在的位置: 首页 > 综合 > 正文

cassandra的存储/更新/检索

2013年12月07日 ⁄ 综合 ⁄ 共 1959字 ⁄ 字号 评论关闭

针对cassandra 0.6系列版本,介绍一下他的存储,更新和检索。

存储

几篇不错的介绍: 

http://wiki.apache.org/cassandra/MemtableSSTable

http://wiki.apache.org/cassandra/ArchitectureSSTable

 

cassandra的存储主要包括:CommitLog, MemStore, SSTable;而且都是以ColumnFamily为单位,即每一个CF都会有自己独立的CommitLog...

Cassandra的写入路径是,数据首先会append到CommitLog文件中,然后在更新到MemStore中,到MemStore达到一定阈值后,刷新到硬盘文件中,成为一个SSTable。

利用这三级存储结构,cassandra把无序的写转变为顺序的写,提高IO效率,而且在系统异常情况下,不会丢失更新。

CommitLog

WAL的commitlog,他会记录写操作,而且实时刷新到硬盘中,作为MemStore中数据的备份;如果Memstore的数据没有刷新到硬盘之前,cassandra进程挂掉或系统down机,重启后就可以从commitlog中恢复数据。 MemStore中的数据刷新成SSTable后,会把数据从commitlog中清除,以避免commitlog无限制膨胀。

关于commitlog的持久化,从性能上考虑,一般不是每次写操作都fsync到硬盘一次,而是聚集一批fsync一次,或每1s fsnyc一次,提高系统性能;这样一来down机还可能丢失少量数据,cassandra通过其他方式来解决,比如read-repair, anti-entropy等。

MemStore

memstore可以理解为一个内存hash表,用户的写操作都在这里进行。cassandra中的memstore有两个配置项,memstore大小和写操作次数,都是用户可配置。 如果memstore超过了配置大小,或者写操作次数超过了配置额,都会触发memstore排序刷新到硬盘成为sstable。这两个配置项,一般要考虑commitlog的大小,内存大小等因素。

SSTable

sstable是数据在硬盘上的表现形式,而且是按照key排序的;每个sstable都包括三个子文件 bloomfilter文件,index文件和数据文件。其中bloomfilter可以高效标记某个key是否存在于这份sstable文件中; index文件记录key在对应数据文件中的位置;数据文件存储的是实际数据,0.6版本里数据是没有压缩的。 三个文件做数据管理,主要是性能上考虑,后面介绍read操作的时候会讲述。由于SSTable是有MemTable flush到硬盘的,一般不大;随着sstable数据变多,会影响读操作的效率。所以cassandra提供了compact功能,有人翻译成压缩,其实很不准确,叫合并更合适。compact会把多个sstable合并成一个大的sstable,同时也清理掉delete数据,或者一个key的多个版本。

读操作&写操作

不错的链接:

http://jonathanhui.com/how-cassandra-read-persists-data-and-maintain-consistency

从系统结构而言,cassandra有个NRW的概念,通过调整这几个参数,可以达到不同的效果,比如R+W>N可以保证Read consistency,R+W<N可以获得高可用性以及高性能等。读写操作可以发给集群内任意一台机器A,这台机器知道集群的拓扑信息,再把读写请求转发给相应处理机器B,C等, 收到B,C的回应后,A再把结果返回给客户端。

为了加速读操作,一般会启用row cache,把memtable+sstable中一些row即key的数据放到row cache中;这样下次读取时,可以直接从row cache中取。row cache不但cache sstable的内容,也会cache memtable的内容,所以用户有更新的时候,更新memtable的同时,如果这个key在rowcache中存在,也需要更新row cache中。目前rowcache的配置是以row的数量为单位的,无法反映内存占用大小,如果row的value大小差不多,还可以估计下;如果相差较大,这种就会有问题。row cache用的jar包,有一个新的版本,可以解决这个问题。

这里还需要提一点,sstable数据文件的读取,支持standard read和mmap两种方式,如果要完全依赖rowcache,建议用standard read模式,避免数据在oscache一次,又在用户进程内cache一次。

抱歉!评论已关闭.