Cassandra 复制策略和分区
1. 概述
在本文中,我们将了解Apache Cassandra 如何在集群中的节点之间分区和分布数据。此外,我们将了解 Cassandra 如何将复制的数据存储在多个节点中以实现高可用性。
2. 节点
在 Cassandra 中,单个节点在服务器或虚拟机 (VM) 上运行。Cassandra 是用 Java 语言编写的,这意味着 Cassandra 的运行实例是一个 Java 虚拟机 (JVM) 进程。Cassandra 节点可以存在于云中、本地数据中心或任何磁盘中。对于数据存储,根据建议,我们应该使用本地存储或直连存储,而不是 SAN。
Cassandra 节点负责它以分布式哈希表的形式存储的所有数据。Cassandra 提供了一个名为nodetool的工具来管理和检查节点或集群的状态。
3. 令牌环
Cassandra 将集群中的每个节点映射到连续环形式上的一个或多个令牌。默认情况下,令牌是 64 位整数。因此,令牌的可能范围是从 -2 63到 2 63 -1。它使用一致的散列技术将节点映射到一个或多个令牌。
3.1. 每个节点单个令牌
对于每个节点单个令牌的情况,每个节点负责一个令牌范围的值小于或等于分配的令牌并大于前一个节点的分配令牌。为了完成环,具有最低令牌值的第一个节点负责小于或等于分配的令牌并大于具有最高令牌值的最后一个节点的分配令牌的值范围。
在数据写入时,Cassandra 使用哈希函数从分区键计算令牌值。将此令牌值与每个节点的令牌范围进行比较,以识别数据所属的节点。
让我们看一个例子。下图显示了一个八节点集群,其复制因子 ( RF ) 为 3,并且为每个节点分配了一个令牌:
RF=3的集群意味着每个节点都有三个副本。
上图中最内圈代表主要数据令牌范围。
每个节点使用单个令牌的缺点是在将节点添加到集群或从集群中删除时创建的令牌不平衡。
假设,在 N 个节点的哈希环中,每个节点拥有相同数量的令牌,例如 100。此外,假设现有节点 X 拥有范围为 100 到 200 的令牌。现在,如果我们将新节点 Y 添加到在节点 X 的左边,那么这个新节点 Y 现在拥有节点 X 的一半代币。
也就是说,现在节点 X 将拥有 100 - 150 的令牌范围,节点 Y 将拥有 151 - 200 的令牌范围。来自节点 X 的一些数据必须移动到节点 Y。这导致数据从一个移动节点 X 到另一个节点 Y。
3.2. 每个节点多个令牌 (vnodes)
从 Cassandra 2.0 开始,虚拟节点 (vnodes) 已默认启用。在这种情况下,**Cassandra 将令牌范围分解为更小的范围,并将这些更小的范围中的多个分配给集群中的每个节点。**默认情况下,一个节点的令牌数是256——这是在cassandra.yaml文件的num_tokens属性中设置的——这意味着一个节点中有 256 个 vnode。
这种配置使得使用不同计算资源的机器维护 Cassandra 集群变得更加容易。这意味着我们可以通过将num_tokens属性设置为更大的值,将更多的 vnode分配给具有更多计算能力的机器。另一方面,对于计算能力较小的机器,我们可以将num_tokens设置为较小的数字。
使用 vnode 时,我们必须预先计算令牌值。否则,我们必须预先计算每个节点的令牌值并将其设置为num_tokens属性的值。
下图显示了一个四节点集群,每个节点分配了两个令牌:
这种设置的优点是,当添加新节点或删除现有节点时,数据会发生在多个节点之间/从多个节点重新分配。 当我们在哈希环中添加一个新节点时,该节点现在将拥有多个令牌。这些令牌范围以前由多个节点拥有,因此添加后的数据移动来自多个节点。
4. 分区器
分区器确定数据在 Cassandra 集群中的节点之间的分布方式。基本上,分区器是一个散列函数,通过散列行数据的分区键来确定令牌值。然后,此分区键令牌用于确定和分配环内的行数据。
Cassandra 提供了不同的分区器,它们使用不同的算法来计算分区键的哈希值。我们可以通过实现IPartitioner接口来提供和配置我们自己的分区器。
Murmur3Partitioner是自 Cassandra 1.2 版以来的默认分区器。它使用MurmurHash函数创建分区键的 64 位散列。
在Murmur3Partitioner之前,Cassandra 将RandomPartitioner作为默认值。它使用MD5算法来散列分区键。
Murmur3Partitioner和RandomPartitioner都使用令牌在整个环中均匀分布数据。然而,两个分区器之间的主要区别是RandomPartitioner使用加密散列函数,而Murmur3Partitioner使用非加密散列函数。**通常,密码散列函数是非性能的并且需要更长的时间。
5. 复制策略
**Cassandra 通过在集群中的节点间复制数据来实现高可用性和容错。**复制策略决定了副本在集群中的存储位置。 集群中的每个节点不仅拥有指定令牌范围内的数据,还拥有不同范围数据的副本。如果主节点出现故障,则此副本节点可以响应对该范围数据的查询。
**Cassandra 在后台异步复制数据。**复制因子 ( RF ) 是决定有多少节点在集群中获得相同数据的副本的数字。例如,环中的三个节点将拥有相同数据的副本,其中*RF=3。*我们已经在令牌环部分的图表中看到了数据复制。
Cassandra 通过允许AbstractReplicationStrategy类的不同实现来提供可插入的复制策略。开箱即用,Cassandra 提供了几个实现,SimpleStrategy和NetworkTopologyStrategy。
一旦分区器计算出令牌并将数据放置在主节点中,SimpleStrategy会将副本放置在环周围的连续节点中。
另一方面,NetworkTopologyStrategy允许我们为每个数据中心指定不同的复制因子。在数据中心内,它将副本分配给不同机架中的节点,以最大限度地提高可用性。
NetworkTopologyStrategy是生产部署中键空间的推荐策略,无论是单个数据中心还是多个数据中心部署。 复制策略是为每个键空间独立定义的,并且是创建键空间时的必需选项。
6. 一致性级别
一致性意味着我们正在读取我们刚刚在分布式系统中写入的相同数据。Cassandra 为读写查询提供了可调整的一致性级别 。换句话说,它为我们提供了可用性和一致性之间的细粒度权衡。
更高级别的一致性意味着更多的节点需要响应读取或写入查询。这样,Cassandra 通常会读取刚才写入的相同数据。
对于读取查询,一致性级别指定在将数据返回给客户端之前需要响应多少副本。对于写入查询,一致性级别指定在向客户端发送成功消息之前需要多少个副本来确认写入。
由于 Cassandra 是一个最终一致的系统,RF确保写入操作在后台异步发生在其余节点上。
7. Snitch
Snitch 者提供有关网络拓扑的信息,以便 Cassandra 可以有效地路由读/写请求。Snitch确定哪个节点属于哪个数据中心和机架。它还确定集群中节点的相对主机邻近度。
复制策略使用此信息将副本放置到单个数据中心或多个数据中心内的集群中的适当节点中。