参考 datastax doc cassandra internals
主要介绍了cassandra的读写机制和一致性支持
读写机制
- write
和hbase的区别不大,基本思路都是先写到cache和WAL(防止挂机数据丢失),到一定大小再flush到磁盘
- maintain
和hbase也很相似,有compaction的机制来合并细小的sstable(hbase的hfile),同时将过期的数据版本和标记来tombstone的数据删除。cassandra在做compaction的时候,新的sstable就已经可以用了
- update
也是和hbase差不多,使用upsert来更新数据,如果有相同primary key的行,则看作一个行的更新来操作。做compaction的时候,如果遇到两个不同版本的数据,更加新的版本会保留,旧版本的不会被丢弃。由于compaction在每个node中都是独立完成的,所以会出现有写node做来compaction有的还没有做,所以会出现有些node中的旧版本还存在的情况,所以在client读数据的时候,会有另一个一个比较的过程,即会读取多个relipca,并比较它们的版本,只取timestamp最新的那个返回给client
- delete
和hbase相似,也是插入一条tombstone记录来标记数据被删除,tombstone有一个expire date,当期限到了之后,数据会在compaction中被删除。在cassandra里会有一个问题,因为数据是多份地保存在多个节点上,当一个节点接收到删除命令的时候,会在本地插入tombstone,然后将tombstone传递给其他replicas,假如这个时候有其中一个replica挂了,一直接收不到tombstone,而在一段时候后compaction机制将其他node上的数据删除了,这样,挂了的node上还存在着一份旧版本的数据,如果挂了的node这时候又活过来了,cassandra会认为这是一条新的数据,然后又同步到其他节点上做replica,这条数据就是zombie,就是出现了明明数据已经删除了,但过了一段时候又蹦出来的情况,僵尸复活了。cassandra有一个grace period来,一般是10天,给挂了的节点来复活。另外,如果节点挂来的话,需要运行在挂过的节点运行nodetool repair来修复数据防止僵尸的出现。
- index
有内置的二级索引,存放在本地node的一个隐藏表内,由后台进程来维护。就算已经建立来二级索引,但是如果查询的时候没有指定partition的话,查询会所有的节点发出,这样的话会很耗时,不建议在生产环境使用,所以搜索的时候要带上partition key,指定在哪个partition里做二级索引的搜索。二级索引的使用要谨慎,例如按年龄来排序的时候(年龄不在主键上),更好的方法是使用materialized view或者additional table that is ordered by age
- read
和hbase相似,通过各种的cache来减少磁盘读来加快读的速度
一致性支持
- 可以调节的读写一致性
Tunable consistency - 默认是一个AP系统,注重的是可用性,但如果业务需要,则可以调整参数来让它成为CP系统。读写的一致性是可以去到每个调用级别的。
Linearizable consistency - 线性的一致性,使用的是lightweight transactions来防止并发插入同一条数据时候所造成的数据不一致,例如有两个写操作同时插入具有同一个primary key的数据,(由于在cassandra中可以有多个节点来接收写操作,所以会出现这种并发写的问题)如果没有lightweight transactions支持的话,数据库里会出现两条相同primary key的数据,lightweight transactions就是(compare and set)CAS的过程,在执行像INSERT xxx IF NOT EXIST的语句的时候在后台做来很多事情
如何计算一致性
R + W > N,R是读时候要读多少个replica,W是写的时候接收多少个replica的回应才算写成功,N是replica的数量,当公式成立的时候则是强一致性,不成立的时候就需要cassandra在后台来同步数据做最终一致性
- lightweight transactions
轻量级事务,就是上面说的用来处理并发插入的时候使得插入能够按顺序来执行,防止出现并发的时候插入或者更新同一个数据所造成的不一致的情况出现,具体可以参考文章1,文章2。(所以还是不支持跨调用,跨表的事务)
- read时候的一致性
大概流程是这样的,读的时候coordinator会找到符合consistency level个的replica,然后replica返回结果到coordinator,coordinator再在内存中比较各个结果,取出最新版本的那个结果,再发送给client。然后coordinator会发送digest request到那些剩下的replica,(不再consistency level个数范围内的replicas)read repair过程会将版本不一致的情况修复,就是版本旧的数据更新为版本新的数据
- write时候的一致性
大概流程是这样的,coordinator会发送写请求到全部的replicas,但是会等待consistency level个的replica响应,只有符合consistency level个的replica响应了,才认为写成功,否则返回异常。当符合consistency level个的replica响应了之后,假如剩下的replica没有写入成功,则built-in repair mechanisms(hinted handoff, read repair, or anti-entropy node repair)会修复这些replica的写入
网友评论