Cassandra - A Decentralized Structured Storage System 论文总结

前言

  前段时间写了一篇关于Dynamo 的论文笔记。最近两天看了看何其不少类似的Cassandra 论文,在此做个总结。希望可以便人便己。

ps:因为这篇论文内容比较少,而且很多知识和Dynamo略有重复。所以大体的框架将不再采用和论文条目一样的格式,而是采用总结对比的形式,阐述重点内容。


一、Overview

在这里插入图片描述

  从某种程度上来说,Cassandra是dynamo的一个开源实现。听说是从aws跳槽到facebook的两名工程师做的,所以其设计和实现上和dynamo有很多类似的地方。

  总的来说,cassandra是一个松散的分布式存储系统,其设计的目标在于实现Inbox Search ,旨在提供一个scaled storage system以解决快速增长的数据问题。也就是可以处理高吞吐量,满足可拓展性以及高可用性。

二、Data Model

  对于dynamo来说,其是一个KV数据库,数据模型比较简单,采用的是key-value pair store。对于cassandra来说,虽然从某种程度上来说,它也是一个kv数据库,但是其数据模型是有点类似bigtable的column oriented key-value store。 它们的存储结构如下图一和下图二所示。
在这里插入图片描述
图一 dynamo的数据模型示意图

在这里插入图片描述
图二 cassandra的数据模型示意图


  从上面的示意图中可以看出来,dynamo是普通的kv存储,其对应的映射是key->value。 而cassandra 算是一个半结构化的kv存储,其对应的映射是(key+columnName)->column value。 虽然说cassandra有结构化的特性,但是其schema并不是向结构化sql数据库那样提前定义好的,而是可以随时添加变动(nosql 的特性也可以从这里看出来)。

  抽象的看,可以把cassandra的数据模型定义如下:
  Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

  cassandra的这种数据模型和时序数据库influxDB是很相像的,后者的数据模型是
  Map<Key,SortedMap<timestamp,value>>。

  和cassandra 的抽象定义是不是很像? 只不过后者的Key其实还包括serieskey+fieldKey,看起来更复杂些。

二、Partitioning

在这里插入图片描述

  为了达到线性扩展的目的,cassandra也采用了一致性hash的partition方式。关于一致性hash在dynamo中有过介绍,这里就不赘述了。不过对于一致性hash的固有缺点,即可能会存在非均匀的数据分布问题(non-uniform data and load distribution)和未充分考虑每个node的性能情况,dynamo采用的是一个node分配多个虚拟节点的方式,而cassandra采用的是分析负载情况,让node在hash ring 上所对应的key 进行移动,以达到均衡负载的效果。

  对于dynamo采用的虚拟节点的改进方式,从某种程度上来说,变动一个新的结点后又会影响到多个相邻的结点了(因为一个实际的node对应多个虚拟节点);而且根据【1】中的说法,如果一个实际结点的数据量比较大(TB),那么在进行数据迁移的时候,会对资源(disk IO,network io,cpu等)有很大的开销花费。(需要迁移的数据量比较大,都会有很大的开销吧?)

  对于cassandra采用的改进方式,如果节点在ring上的移动将很频繁,【1】中也说了其存而控制混乱,手动维护繁重的问题。

三、Replication

在这里插入图片描述

  为了达到high availability 和 durability的目的,cassandra采用了多副本的方式。系统给客户端提供了三种副本策略:
(1) Rack Unaware。
(2) Rack Aware 。
(3) Datacenter Aware。

  其中第一种直接在key 所对应的coordinator中顺延选取N-1个node。后面两种要根据不同node结点所对应的的位置进行选择,如副本需在不同机架、不同的数据中心等。


  对于cassandra来说,不同node之间元数据(每个node负责的range 范围,node属性等信息)是通过一个zookeeper结点来控制的。 (对于dynamo来说,它是通过gossip协议来进行信息互通)那这个ZK算不算是中心化的一个结点呢,但是很多文章中又说到cassandra是一个非中心化的系统,这是不是就有点小矛盾了?

  是这样,所谓中心化的副本控制协议指的是由一个中心节点来协同控制副本数据的更新、进行并发控制,协调副本间的一致性。 而这里的zk只是存储了一部分的元数据,从某种程度上来说相当于各个数据结点的网络共享存储,但是其并不负责维护数据的更新和协调副本间的一致性(副本间的一致性是通过gossip算法来实现的),所以确切的说不应该算作中心化的结点。

四、Consistency

在这里插入图片描述

  一旦涉及到多副本replication机制,就免不了其副本间的一致性问题。对于副本间的一致性来说,cassandra来说使用的是和dynamo类似,支持用户总是可写,而解决一致性冲突留给了读操作。

  它们使用了可调节的quorum机制。其基本思路是对于quorum中的N,W,R 。 一般要求需要保证W+R>N. 如果W设置的大些,那么说明在写时需要多花功夫; 如果R设置的大些,说明在读时需要多读几个replication。 前者偏向更强的一致性,后者更强调写性能。 如下图三所示。
在这里插入图片描述
图三 quorum调节示意图


  文章【1】中又指明了cassandra系统中采用这种一致性的一些问题,这里就不多探究了,感兴趣的可以研究研究。

五、Persistence

  对于anssandra系统来说,其数据的持久化本质上采用的是LSM-Tree机制。以牺牲一部分的读性能,来大大提高写性能,在我看来其最基本的原理就是把大量的随机写变成顺序写。详细的细节网上有很多,这里就不赘述了。

下面两张图说明了读写LSM的读写流程和其示意图。
在这里插入图片描述
图四 LSM读写流程

在这里插入图片描述
图五 LSM示意图


参考

【1】、Cassandra VS Dynamo(扩展篇)
【2】、深入研究Cassandra后 重读Dynamo Paper (Document Transcript)
【3】、LSM学习分享——LSM读写流程

猜你喜欢

转载自blog.csdn.net/plm199513100/article/details/122211604