Apache Cassandra

目录

1 历史

Cassandra 的名称来源于 希腊神话,是 特洛伊 的一位悲剧性的女先知的名字,因此项目的 Logo 是一只放光的眼睛。

该项目由就职于 Facebook 的 Avinash Lakshman(也是 Amazon Dynamo(英语:Amazon\_DynamoDB)的作者之一)和 Prashant Malik 在为 Facebook 的 Inbox 编写。2008 年,Facebook 将项目开源,Cassandra 在 2009 年成为了 Apache 软件基金会 的 Incubator 项目,并在 2010 年 2 月走出孵化器,成为正式的基金会项目。当前这个项目主要由专门进行 Cassandra 商业化运作的 DataStax 公司来开发,也有一些来自其他公司或独立的开发者 [9]

1.1 主要版本和主要改进

  • 0.6(2010 年 4 月发布):支持内置的缓存。
  • 0.7(2011 年 1 月发布):支持按列建二级索引 (secondary indexes) 及在线修改表的结构定义。
  • 0.8(2011 年 6 月发布):支持 CQL 语言和零停机的在线升级。
  • 1.0(2011 年 10 月发布):支持数据压缩、level compaction 和提高读取性能。
  • 1.1(2012 年 4 月发布):支持 SSD 和机械硬盘混合使用。
  • 1.2(2013 年 1 月发布):支持虚拟节点 (一个机器在一致性哈希环中拥有多个节点)、原子性的批处理。
  • 2.0(2013 年 9 月发布):支持轻量级事务、触发器、改进 compaction 性能,强制使用 Java7
  • 2.1(2014 年 9 月 10 日发布)。
  • 2.2(2015 年 7 月 20 日发布)。
  • 3.0(2015 年 11 月 11 日发布)。
  • 3.1:同样 3.10 版本,使用类 tick-tock 发布模式,每月发布一次;偶数编号版本提供新功能和错误修正,而奇数编号版本只包括错误修正。
  • 3.11(2017 年 6 月 23 日发布):作为稳定的 3.11 版本系列,修复了上一个 tick-tock 功能版本的错误 [10]

2 数据模型

Cassandra 使用了 Google 设计的 BigTable 的数据模型。与面向行 (row) 的传统 关系型数据库键值存储 的 key-value 数据库不同,Cassandra 使用的是 宽列存储模型 (Wide Column Stores) [8]。每行数据由 row key 唯一标识之后,可以有最多 20 亿个列 [11],每个列有一个 column key 标识,每个 column key 下对应若干 value。这种模型可以理解为是一个二维的 key-value 存储,即整个数据模型被定义成一个类似 map<key1, map<key2, value>> 的类型。

旧版的 Cassandra 与客户端交互的方法是通过 thrift,而当前新版本的 Cassandra 采用与 SQL 语言类似的 CQL 语言 [12] 来实现数据模型的定义和数据的读写。其中 BigTable 中的列族 (Column Family) 在 Cassandra 中被称作类似关系型数据库中的称呼——表 (table),而 Cassandra/BigTable 中的 row keycolumn key 并称为主键 (primary key) [13]

Cassandra 的 row key 决定了该行数据存储在哪些节点中,因此 row key 需要按哈希来存储,不能顺序的扫描或读取;而一个 row 内的 column key 是顺序存储的,可以进行有序的扫描或范围查找 [13]

3 存储模型

与 BigTable 和其模仿者 HBase 不同,Cassandra 的数据并不存储在分布式文件系统如 GFSHDFS 中,而是直接存于本地。与 BigTable 一样,Cassandra 也是日志型数据库,即把新写入的数据存储在内存的 Memtable 中并通过磁盘中的 CommitLog 来做持久化,内存填满后将数据按照 key 的顺序写进一个只读文件 SSTable 中,每次读取数据时将所有 SSTable 和内存中的数据进行查找和合并 [14] [15]。这种系统的特点是写入比读取更快 [16],因为写入一条数据是顺序计入 commit log 中,不需要随机读取磁盘以及搜索。

4 分布式架构

Cassandra 的系统架构与 Dynamo 类似,是基于 一致性哈希 的完全 P2P 架构,每行数据通过哈希来决定应该存在哪个或哪些节点中 [17]。集群没有 master 的概念,所有节点都是同样的角色,彻底避免了整个系统的单点问题导致的不稳定性,集群间的状态同步通过 Gossip 协议 来进行 P2P 的通信。每个节点都把数据存储在本地,每个节点都接受来自客户端的请求。每次客户端随机选择集群中的一个节点来请求数据,对应接受请求的节点将对应的 key 在一致性哈希的环上定位是哪些节点应该存储这个数据,将请求转发到对应的节点上,并将对应若干节点的查询反馈返回给客户端。

在一致性、可用性和分区耐受能力(CAP)的折衷问题上,Cassandra 和 Dynamo 一样比较灵活。Cassandra 的每个 keyspace 可配置一行数据会写入多少个节点 (设这个数为 N),来保证数据不因为机器宕机或磁盘损坏而丢失数据,即保证了 CAP 中的 P。用户在读写数据时可以指定要求成功写到多少个节点才算写入成功 (设为 W),以及成功从多少个节点读取到了数据才算成功 (设为 R)。可推理得出:

  • W + R > N 时,读到的数据一定是上一次写入的,即维护了 强一致性,确保了 CAP 中的 C。
  • W + R <= N 时,数据是 最终一致性,因为存在一段时间可能读到的并不是最新版的数据。
  • W = NR = N 时,意味着系统只要有一个节点无响应或宕机,就有一部分数据无法成功写或者读,即失去了 CAP 中的可用性 A。

因此,大多数系统中,都将 N 设为 3,WR 设为 QUORUM,即“过半数”——在 N 为 3 时 QUORUM 是 2。

5 支持的操作

Cassandra 支持对一列数据进行 insertupdate、或 delete 操作。其中 insertupdate 虽然语法略有区别,但语义上等价,即可以针对已经存在的行进行 updateinsert 一个不存在的行。

5.1 轻量级事务

从 2.0 版开始,Cassandra 支持轻量级事务。这种事务被称为"compare-and-set",简称 CAS。通过 paxos 算法 实现在满足某条件后才修改数据否则不修改。当前支持 insert if not existupdate if col=valuedelete if exist 等几种操作。

6 数据类型

Cassandra 在 CQL 语言层面支持多种数据类型 [18]

CQL 类型对应 Java 类型描述
asciiStringascii 字符串
bigintlong64 位整数
blobByteBuffer/byte[]二进制数组
booleanboolean布尔
counterlong计数器,支持原子性的增减,不支持直接赋值
decimalBigDecimal高精度小数
doubledouble64 位浮点数
floatfloat32 位浮点数
inetInetAddressipv4 或 ipv6 协议的 ip 地址
intint32 位整数
listList有序的列表
mapMap键值对
setSet集合
textStringutf-8 编码的字符串
timestampDate日期
uuidUUIDUUID 类型
timeuuidUUID时间相关的 UUID
varcharstringtext 的别名
varintBigInteger高精度整型

7 与类似开源系统的比较

7.1 Apache HBase

HBase 是 Apache Hadoop 项目的一个子项目,是 Google BigTable 的一个克隆,与 Cassandra 一样,它们都使用了 BigTable 的列族式的数据模型,但是:

  • 架构角色:Cassandra 只有一种节点,而 HBase 有多种不同角色。除了处理读写请求的 region server 之外,其架构在一套完整的 HDFS 分布式文件系统之上,并需要 ZooKeeper 来同步集群状态,部署上 Cassandra 更简单。
  • 一致性策略:Cassandra 的数据一致性策略是可配置的,可选择是强一致性还是性能更高的最终一致性;而 HBase 总是强一致性的。
  • 负载均衡:Cassandra 通过一致性哈希来决定一行数据存储在哪些节点,靠概率上的平均来实现负载均衡;而 HBase 每段数据 (region) 只有一个节点负责处理,由 master 来动态分配一个 region 是否大到需要拆分成两个,同时会将过热的节点上的一些 region 动态的分配给负载较低的节点,因此实现动态的负载均衡。
  • 单点问题:因为每个 region 同时只能有一个节点处理,一旦这个节点无响应,在系统将这个节点的所有 region 转移到其他节点之前这些数据便无法读写,加上 master 也只有一个节点,备用 master 的恢复也需要时间,因此 HBase 在一定程度上有单点问题;而 Cassandra 无单点问题。
  • 性能:Cassandra 的读写性能优于 HBase [16]

8 参考文献

  1. PlanetCassandra, Apple Inc.: Cassandra at Apple for Massive Scale, 2015-03-03.
  2. Comcast messaging infrastructure chooses linearly scaling Apache Cassandra as NoSQL solution. www.planetcassandra.org.
  3. Facebook's Instagram: Making the Switch to Cassandra from Redis, a 75% 'Insta' Savings. planetcassandra.org.
  4. Spotify scales to the top of the charts with Apache Cassandra at 40k requests/second. planetcassandra.org.
  5. PlanetCassandra, eBay: Apache Cassandra Best Practices at Ebay, 2014-10-10.
  6. Rackspace Monitors the Cloud with Cassandra: 35 Million Writes, 180 Million Samples per Hour. 2013-10-08.
  7. Case Study: Netflix. DataStax.
  8. DB-Engines Ranking. 2016-06-27.
  9. Cassandra Committers. (原始内容 存档于 2014-08-19).
  10. Cassandra Changes.
  11. CassandraLimitations. (原始内容 存档于 2014-08-18).
  12. Cassandra Query Language (CQL) v2.0. (原始内容 存档于 2014-08-15).
  13. cql document. (原始内容 存档于 2014-08-19).
  14. Bigtable: A Distributed Storage System for Structured Data (PDF).
  15. MemtableSSTable. (原始内容 存档于 2014-08-19).
  16. nosql-performance-benchmarks.
  17. Amazon. Dynamo: Amazon's Highly Available Key-value Store (PDF).
  18. cql data types. (原始内容 存档于 2014-09-29).

9 相关阅读


说明:本文内容主要基于 Cassandra 3.11 版本(2017 年发布)及之前的资料整理。Cassandra 后续已发布 4.x 等更新版本,部分特性与架构细节可能已有演进,请以官方最新文档为准。