0%

Cassandra 简介

Apache Cassandra 是一个大规模可扩展的分布式开源NoSQL数据库

概览

Apache Cassandra 是一个大规模可扩展的分布式开源NoSQL数据库,完美适用于跨数据中心/云端的结构化数据、半结构化数据和非结构化数据,同时,Cassandra 高可用、线性可扩展、高性能、无单点。

特点

  • Scalable,线性可扩展
  • Fault-Tolerant,且没有单点(peer-to-peer)
  • Column-Oriented Database & Partitioned Row Store Database
  • Distribution Design 基于 Amazon 的 Dynamo
  • Data Model 基于 Google 的 Bigtable
  • 灵活的数据存储,支持结构化、半结构化、非结构化数据
  • 支持事务
  • 写性能好

基本概念

CAP 定理

Cassandra 是专注于可用性和分区容错性的解决方案的最佳选择。

CAP 代表“一致性、可用性和分区容错性”。CAP 定理由 Eric Brewer 在 2000 年首次提出,该定理表明,在任何共享数据系统中,最多只能获得这些属性中的两个。所以您必须选择两个属性;不能选择所有属性。我将大体介绍一下该定理,要获取更多信息,请参阅下面的“相关主题”。

CAP 定理与 Cassandra 相关,所以理解该定理很重要,因为它可能帮助您判断 Cassandra 是不是您的 NoSQL 数据库解决方案的最佳选择。在任何情况下,都应该首先考虑您的解决方案在一致性和可用性方面的约束,这很有帮助。

依据 CAP 定理,对于任何分布式系统,都必须为它选择两种最重要的保证(参见图 1)。您可以拥有 Cassandra 中的所有 3 种保证,但不能同时拥有它们。因此,在您想要获得一个不会宕机且高度可用的数据库,而且不想遭遇偶然的硬件故障时,Cassandra 是专注于可用性和分区容错性的解决方案的最佳选择。

这与传统关系数据库管理系统 (RDBMS)(比如 MySQL、DB2®、Oracle 和 Sybase)的 ACID(原子性、一致性、隔离性、耐久性)属性相反。我并没有暗示在 Cassandra 中没有原子操作,以及 Cassandra 数据不是隔离的或耐久的。我的意思是说,这些不是 Cassandra 的主要关注点。该数据库天生就是分布式的,能随着数据和应用程序事务的增长而轻松扩展。

分布式数据库

Cassandra 实质上是一个分布式数据库。这意味着它被设计为在计算机节点网络中以服务器形式运行,不同部分在不同机器上运行,没有任何特定的硬件或软件需要管理或协调。所有节点的协调和数据分布都是在它们自己的架构内完成的。 Cassandra 网络之所以比其他常见关系数据库系统更容易水平扩展且更便宜,这就是原因之一。

典型的 Cassandra 网络拓扑结构包含一个节点集群(也称为 Cassandra 环),每个节点在不同物理服务器上的不同网络地址中运行。

此特性提高了网络在节点发生故障时的可用性。每个节点都可以协调客户端的请求,而不需要主节点,因此没有单点故障。您还能设置不同的配置战略来让数据知道不同节点的位置,从而进一步提高系统可用性。

下图包含 8 个节点的 Cassandra 集群收到一个客户端连接,
该连接将数据写入一个配置了复制系数 3 的键空间中。

所有数据都依据一个哈希算法均匀分布在 Cassandra 环(节点)中,以创建所需的副本(也称为复制品)数量。复制系数是集群配置的一个重要方面。该系数是通过一个键空间或模式配置来定义的。

关于集群数据、拓扑结构、节点可用性和性能的所有信息都通过 gossip 协议(一种对等协议)在节点之间进行交换。可使用此信息向客户端发出关于哪个节点最适合在给定时间写入或读取任何数据的连接建议。

Cassandra 客户端可通过两种协议与服务器进行通信:CQL 二进制协议或一种称为 thrift 的 RPC 协议。CQL 二进制协议是一种较新的协议,该协议优先于 thrift。Cassandra 查询语言 (CQL) 是一种类似于 SQL 的语言,Cassandra 使用它创建处理其模式结构和数据(DDL 和 DML)的命令。

CQL

CQL (Cassandra Query Language)是用于 Cassandra 的查询语言,可类比用于关系型数据库的 SQL ,注意,虽然 CQL 和 SQL 看起来比较相似,但二者内部原理完全不同。

基本数据结构和建模

Cassandra 的一个重要且有时很难处理的方面是它的数据建模方法。首先,您需要了解如何在其架构内组织它的数据,然后如何建模您的应用程序的数据结构,以便获得其最高性能。

在 Cassandra 中,所有数据都通过一个主键(或行键)按分区进行组织,这使您能访问所有列或键/值对集合,如下图所示。

Cassandra 数据结构分区

对于每一个 column family,不要想象成关系型数据库的表,而要想像成一个多层嵌套的排序散列表(Nested sorted map)。这样能更好地理解和设计 Cassandra 的数据模型。

散列表可用提供高效的键值查找,排序的散列表可提供高效的范围查找,在 Cassandra 里,我们可以使用 primary key 和 column key 做高效的键值查询和范围查询,而且,在 Cassandra 中,列的名称可以直接包含数据,也就是说,有的列可以只有列名没有列值。

1
Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Cassandra 是一个 column-oriented database,也就是说,不用像关系型数据库一样事先定义好列,在 Cassandra 中,不同行的列可以不一样。

在 Cassandra 中,数据模型由 keyspaces、column families、primary key 和 columns 组成,对比关系型数据库,如下表:

关系型数据库 Cassandra
Database Keyspace
Table CF(column family)
Primary Key Primary Key
Column Name Key / Column Name
Column Value Column Value

在 Cassandra 中,Primary Key 包括 partition key 和 cluster key 两部分,其中 cluster key 可选,partition key 确定数据行分发到哪个 node,cluster key 用于 node 内部数据排序。

当您在 Cassandra 中创建一个表时,您使用了一条与以下命令类似的 CQL 命令:

1
2
CREATE TABLE movie_catalog (category text, year int, title text, 
PRIMARY KEY (category));

第一列被隐式地视为 movie_catalog 表的分区键。没有集群键。但是,假设您在主键中添加了 year 列,如下所示:

1
2
CREATE TABLE movie_catalog (category text, year int, title text, 
PRIMARY KEY (category,year))

现在,category 继续作为分区键,而 year 列是集群键。两列都是主键的一部分。

所有 Cassandra 表都必须有一个主键来确定数据位于集群中的哪个节点。该键至少要包含一个分区键。如上所示,用于定位节点(分区)中的数据的集群键也可以是主键的一部分。

所以对于建模问题,必须小心选择分区键,使 Cassandra 能高效地将数据分布到节点中。将所有应用程序数据(行)放在一个分区中不是一个好主意。出于同样的原因,您还可以拥有许多分区。因此,您需要在对数据进行分组时找到一个很好的平衡点,以满足您的应用程序需求。

在 Cassandra 中建模的最常用技术称为基于查询的建模。此方法需要您考虑应用程序用户发出的查询。然后,您可以根据这些查询对表进行建模。