Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩展性,被Digg、Twitter等知名Web 2.0网站所采纳,成为了一种流行的分布式结构化数据存储方案。Cassandra于2009年被纳入Apache孵化器,并自2010年2月以来成为一个Apache顶级项目。
Apache Cassandra是一个高度可扩展的高性能分布式数据库,旨在处理许多商用服务器上的大量数据,提供高可用性而没有单点故障。它是NoSQL数据库的一种。
1 基本介绍
1.1 NoSQL数据库
NoSQL数据库(有时称为“Not Only SQL”)是一种数据库,它提供了一种存储和检索关系数据库中使用的表格关系以外的数据的机制。这些数据库是无模式的,支持简单的复制,具有简单的API,最终是一致的,并且可以处理大量数据。
NoSQL数据库的主要目标是:
- 设计简单
- 水平缩放
- 更好地控制可用性
与关系数据库相比,NoSql数据库使用不同的数据结构。它使NoSQL中的某些操作更快。给定NoSQL数据库的适用性取决于它必须解决的问题。除了Cassandra,还有以下两种非常流行的NoSQL数据库:
(1)Apache HBase是一种以Google的BigTable建模的开源,非关系,分布式数据库,并使用Java编写。它是Apache Hadoop项目的一部分,在HDFS之上运行,为Hadoop提供类似BigTable的功能。
(2)MongoDB是一个跨平台的面向文档的数据库系统,它避免使用传统的基于表的关系数据库结构,而是使用具有动态模式的类似JSON的文档,从而使数据在某些类型的应用程序中的集成更加容易和快捷。
1.2 Cassandra特点
Apache Cassandra是一个开源,分布式和分散/分布式存储系统(数据库),用于管理分布在世界各地的大量结构化数据。它提供高可用性服务,没有单点故障。Cassandra 具有以下几大特性:开源、分布式、去中心化、可扩展性、高可用、容错性、可配置的一致性等。
(1)弹性可扩展性:Cassandra具有高度可扩展性;它允许添加更多硬件,以根据需求容纳更多客户和更多数据。
(2)始终在线:Cassandra没有单点故障,并且可以连续用于无法承受故障的关键业务应用程序。
(3)快速的线性规模性能:Cassandra具有线性可扩展性,即随着集群中节点数量的增加,它可以提高吞吐量。因此,它保持了快速的响应时间。
(4)灵活的数据存储:Cassandra可容纳所有可能的数据格式,包括:结构化,半结构化和非结构化。它可以根据需要动态适应对数据结构的更改。
(5)轻松进行数据分发:Cassandra通过在多个数据中心之间复制数据,提供了在所需位置分发数据的灵活性。
(6)事务支持:Cassandra支持原子性,一致性,隔离性和持久性(ACID)等属性。
(7)快速写入:Cassandra旨在在廉价的商品硬件上运行。它执行快速的写入,并且可以存储数百TB的数据,而不会牺牲读取效率。
1.3 Cassandra架构
Cassandra的设计目标是在多个节点上处理大数据工作负载而不会出现任何单点故障。 Cassandra在其节点之间具有对等分布式系统,并且数据分布在集群中的所有节点之间。
(1)集群中的所有节点都扮演相同的角色。每个节点都是独立的,并同时互连到其他节点。
(2)集群中的每个节点都可以接受读写请求,而不管数据实际位于集群中的何处。
(3)当某个节点发生故障时,可以从网络中的其他节点处理读/写请求。
1.4 Cassandra 组件
Cassandra组成部分如下:
(1)Node:它是存储数据的地方。
(2)Data center:它是相关节点的集合。
(3)Cluster:是包含一个或多个数据中心的组件。
(4)Commit log:是Cassandra中的崩溃恢复机制。每个写操作都会写入commit log。
(5)Mem-table:内存表是驻留内存的数据结构。commit log后,数据将被写入内存表。有时,对于single-column family,将有多个内存表。
(6)SSTable:它是一个磁盘文件,当其内容达到阈值时,会将数据从内存表中刷新到该磁盘文件中。
(7)Bloom filter:这些仅是用于测试元素是否为集合成员的快速,不确定性算法。这是一种殊的缓存。每次查询后都会访问Bloom筛选器。
1.5 Cassandra 查询语言
用户可以使用Cassandra查询语言(CQL)通过其节点访问Cassandra。 CQL将数据库Keyspace视为表。程序员使用cqlsh进行查询。
客户端接近任何节点以进行读写操作。该节点(协调器)在客户端和保存数据的节点之间扮演代理角色。
(1)写操作:节点的每个写入活动均由写入节点中的commit logs捕获。之后,将捕获数据并将其存储在mem-table中。每当mem-table已满时,数据将被写入SStable数据文件中。所有写入将自动分区并在整个集群中复制。Cassandra定期合并SSTable,丢弃不必要的数据。
(2)读操作: 在读取操作期间,Cassandra从mem-table中获取值,并检查Bloom筛选器以找到保存所需数据的适当SSTable。
1.6 Cassandra和RDBMS的数据模型对比
下表列出了区分Cassandra的数据模型和RDBMS的数据模型的要点。
RDBMS |
Cassandra |
RDBMS 处理结构化数据。 |
Cassandra 处理非结构化数据。 |
它具有固定的模式。 |
Cassandra 具有灵活的架构。 |
在 RDBMS 中,表是一个数组的数组。 (ROW x COLUMN) |
在 Cassandra 中,表是“嵌套的键值对”的列表。 (ROW x COLUMN 键 x COLUMN 值) |
数据库是包含与应用程序对应的数据的最外层容器。 |
Keyspace 是包含与应用程序对应的数据的最外层容器。 |
表是数据库的实体。 |
表或列族是键空间的实体。 |
Row 是 RDBMS 中的单个记录。 |
Row 是 Cassandra 中的一个复制单元。 |
列表示关系的属性。 |
Column 是 Cassandra 中的存储单元。 |
RDBMS 支持外键的概念,连接。 |
关系是使用集合表示。 |
2 如何正确的建模
2.1 分区键的设计
开发人员在构建Cassandra数据库时犯的一个主要错误是分区键的选择不佳。
Cassandra是分布式的。这意味着需要有一种方法来跨节点分布数据。Cassandra通过散列每个表的主键(称为分区键)的一部分并将散列值token分配给集群中的特定节点来完成此操作。选择分区键时,请务必考虑以下规则:
(1)应该有足够的分区键值,以便在群集中的所有节点之间均匀地分布数据。
(2)最好单个分区涵盖一次读所想拿到的数据
(3)不要让分区太大。Cassandra可以处理大于100MB的大分区,但效率不高。此外,如果划分的分区很大,则数据分发也不太可能是均匀的。
(4)理想情况下,所有分区的大小大致相同。典型的真实世界分区键是用户ID,设备ID,帐号等。为了管理分区大小,通常将诸如年,月或年的时间修饰符添加到分区键。
2.2 理想的cassandra使用场景
每个数据库服务器都是为满足特定的设计目标而构建,这些设计目标定义了数据库适合和不适合的场景。
Cassandra的设计目标如下:
(1)分布式:在多个服务器节点上运行。
(2)线性扩展:通过添加节点实现水平扩容
(3)全球分布:群集可以在地理上分布。
(4)写优于读:写入比读取快一个数量级。
(5)民主对等架构:没有主/从。
(6)支持分区容忍度和可用性而不是一致性:最终一致性
(7)通过主键支持快速目标读取:关注主键读取,其他路径次优。
(8)支持具有生命周期的数据:Cassandra数据库中的所有数据都具有已定义的生命周期,生命周期到期后自动删除数据。
事实证明,Cassandra对某些应用程序非常有用。理想的Cassandra应用程序具有以下特征:
(1)写入大幅度超出读。
(2)数据很少更新,并且在进行更新时它们是幂等的。
(3)通过主键查询,非二级索引。
(4)可以通过partitionKey均匀分区。
(5)不需要Join或聚合。
推荐使用Cassandra的一些场景是:
(1)交易日志:购买,测试分数,观看的电影等。
(2)存储时序数据。
(3)跟踪几乎任何事情,包括订单状态,包裹等。
(4)存储健康追踪数据。
(5)气象服务历史。
(6)物联网状态和事件历史。
(7)汽车的物联网数据。
(8)电子邮件
3 Cassandra查询语言CQL
默认情况下,Cassandra提供一个提示Cassandra查询语言shell(cqlsh),允许用户与它通信。使用此shell,可以执行Cassandra查询语言(CQL)。
使用cqlsh可以:定义模式、插入数据和执行查询。
3.1 CQL数据定义命令
CREATE KEYSPACE:在Cassandra中创建KeySpace。
CREATE KEYSPACE <identifier> WITH <properties>
USE:连接到已创建的KeySpace。
ALTER KEYSPACE:更改KeySpace的属性。
DROP KEYSPACE:删除KeySpace。
CREATE TABLE:在KeySpace中创建表。
ALTER TABLE:修改表的列属性。
DROP TABLE:删除表。
TRUNCATE:从表中删除所有数据。
CREATE INDEX:在表的单个列上定义新索引。
DROP INDEX:删除命名索引。
3.2 CQL数据操作指令
INSERT:在表中添加行的列。
可以使用命令INSERT将数据插入到表中行的列中。下面给出了在表中创建数据的语法
INSERT INTO <tablename>
(<column1 name>, <column2 name>....)
VALUES (<value1>, <value2>....)
USING <option>
UPDATE:更新行的列。
UPDATE是用于更新表中的数据的命令。在更新表中的数据时使用以下关键字:
(1)Where:此子句用于选择要更新的行。
(2)Set:使用此关键字设置值。
(3)Must:包括组成主键的所有列。
在更新行时,如果给定行不可用,则UPDATE创建一个新行。下面给出了UPDATE命令的语法:
UPDATE <tablename>
SET <column name> = <new value>
<column name> = <value>....
WHERE <condition>
DELETE:从表中删除数据。
DELETE FROM <identifier> WHERE <condition>;
BATCH:一次执行多个DML语句。
BEGIN BATCH
<insert-stmt>/ <update-stmt>/ <delete-stmt>
APPLY BATCH
3.3 CQL字句
SELECT:此子句从表中读取数据
SELECT子句用于从Cassandra中的表读取数据。使用此子句,可以读取整个表,单个列或特定单元格。下面给出了SELECT子句的语法。
SELECT FROM <tablename>
WHERE:where子句与select一起使用以读取特定数据。
使用WHERE子句,可以对必需的列设置约束。其语法如下:
SELECT FROM <table name> WHERE <condition>;
ORDERBY:orderby子句与select一起使用,以特定顺序读取特定数据。
3.4 CQL数据类型
CQL提供了一组丰富的内置数据类型,包括集合类型。除了这些数据类型,用户还可以创建自己的自定义数据类型。
3.4.1 内置数据类型
下表提供了CQL中可用的内置数据类型的列表。
数据类型 |
常量 |
描述 |
ascii |
strings |
表示ASCII字符串 |
bigint |
bigint |
表示64位有符号长 |
blob |
blobs |
表示任意字节 |
Boolean |
booleans |
表示true或false |
counter |
integers |
表示计数器列 |
decimal |
integers, floats |
表示变量精度十进制 |
double |
integers |
表示64位IEEE-754浮点 |
float |
integers, floats |
表示32位IEEE-754浮点 |
inet |
strings |
表示一个IP地址,IPv4或IPv6 |
int |
integers |
表示32位有符号整数 |
text |
strings |
表示UTF8编码的字符串 |
timestamp |
integers, strings |
表示时间戳 |
timeuuid |
uuids |
表示类型1 UUID |
uuid |
uuids |
表示类型1或类型4 UUID |
varchar |
strings |
表示uTF8编码的字符串 |
varint |
integers |
表示任意精度整数 |
3.4.2 集合数据类型
Cassandra查询语言还提供了一个集合数据类型。下表提供了CQL中可用的集合的列表。
集合 |
描述 |
list |
列表是一个或多个有序元素的集合。 |
map |
地图是键值对的集合。 |
set |
集合是一个或多个元素的集合。 |
3.4.3 用户定义的数据类型
Cqlsh为用户提供了创建自己的数据类型的工具。下面给出了处理用户定义的数据类型时使用的命令。
CREATE TYPE:创建用户定义的数据类型。
ALTER TYPE:修改用户定义的数据类型。
DROP TYPE:删除用户定义的数据类型。
DESCRIBE TYPE:描述用户定义的数据类型。
DESCRIBE TYPES:描述用户定义的数据类型。
参考文献
什么是Cassandra? - 知乎 (zhihu.com)
阿帕奇卡桑德拉|Apache Cassandra Documentation