Cassandra
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 key 和 column key 并称为主键 (primary key) [13]。
Cassandra 的 row key 决定了该行数据存储在哪些节点中,因此 row key 需要按哈希来存储,不能顺序的扫描或读取;而一个 row 内的 column key 是顺序存储的,可以进行有序的扫描或范围查找 [13]。
3 存储模型
与 BigTable 和其模仿者 HBase 不同,Cassandra 的数据并不存储在分布式文件系统如 GFS 或 HDFS 中,而是直接存于本地。与 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 = N或R = N时,意味着系统只要有一个节点无响应或宕机,就有一部分数据无法成功写或者读,即失去了 CAP 中的可用性 A。
因此,大多数系统中,都将 N 设为 3,W 和 R 设为 QUORUM,即“过半数”——在 N 为 3 时 QUORUM 是 2。
5 支持的操作
Cassandra 支持对一列数据进行 insert、update、或 delete 操作。其中 insert 和 update 虽然语法略有区别,但语义上等价,即可以针对已经存在的行进行 update 或 insert 一个不存在的行。
5.1 轻量级事务
从 2.0 版开始,Cassandra 支持轻量级事务。这种事务被称为"compare-and-set",简称 CAS。通过 paxos 算法 实现在满足某条件后才修改数据否则不修改。当前支持 insert if not exist、update if col=value、delete if exist 等几种操作。
6 数据类型
Cassandra 在 CQL 语言层面支持多种数据类型 [18]。
| CQL 类型 | 对应 Java 类型 | 描述 |
|---|---|---|
ascii | String | ascii 字符串 |
bigint | long | 64 位整数 |
blob | ByteBuffer/byte[] | 二进制数组 |
boolean | boolean | 布尔 |
counter | long | 计数器,支持原子性的增减,不支持直接赋值 |
decimal | BigDecimal | 高精度小数 |
double | double | 64 位浮点数 |
float | float | 32 位浮点数 |
inet | InetAddress | ipv4 或 ipv6 协议的 ip 地址 |
int | int | 32 位整数 |
list | List | 有序的列表 |
map | Map | 键值对 |
set | Set | 集合 |
text | String | utf-8 编码的字符串 |
timestamp | Date | 日期 |
uuid | UUID | UUID 类型 |
timeuuid | UUID | 时间相关的 UUID |
varchar | string | text 的别名 |
varint | BigInteger | 高精度整型 |
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 参考文献
- PlanetCassandra, Apple Inc.: Cassandra at Apple for Massive Scale, 2015-03-03.
- Comcast messaging infrastructure chooses linearly scaling Apache Cassandra as NoSQL solution. www.planetcassandra.org.
- Facebook's Instagram: Making the Switch to Cassandra from Redis, a 75% 'Insta' Savings. planetcassandra.org.
- Spotify scales to the top of the charts with Apache Cassandra at 40k requests/second. planetcassandra.org.
- PlanetCassandra, eBay: Apache Cassandra Best Practices at Ebay, 2014-10-10.
- Rackspace Monitors the Cloud with Cassandra: 35 Million Writes, 180 Million Samples per Hour. 2013-10-08.
- Case Study: Netflix. DataStax.
- DB-Engines Ranking. 2016-06-27.
- Cassandra Committers. (原始内容 存档于 2014-08-19).
- Cassandra Changes.
- CassandraLimitations. (原始内容 存档于 2014-08-18).
- Cassandra Query Language (CQL) v2.0. (原始内容 存档于 2014-08-15).
- cql document. (原始内容 存档于 2014-08-19).
- Bigtable: A Distributed Storage System for Structured Data (PDF).
- MemtableSSTable. (原始内容 存档于 2014-08-19).
- nosql-performance-benchmarks.
- Amazon. Dynamo: Amazon's Highly Available Key-value Store (PDF).
- cql data types. (原始内容 存档于 2014-09-29).
9 相关阅读
说明:本文内容主要基于 Cassandra 3.11 版本(2017 年发布)及之前的资料整理。Cassandra 后续已发布 4.x 等更新版本,部分特性与架构细节可能已有演进,请以官方最新文档为准。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/cassandra.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。