在 Apache Cassandra 中定义和优化数据分区

Apache Cassandra 专为速度和可扩展性而构建;以下是如何充分利用这些优势。
81 位读者喜欢这篇文章。
Person standing in front of a giant computer screen with numbers, data

Opensource.com

Apache Cassandra 是一个数据库。但它不仅仅是一个普通的数据库;它是一个复制数据库,专为可扩展性、高可用性、低延迟和高性能而设计和调整。Cassandra 可以帮助您的数据在区域性中断、硬件故障以及许多管理员认为过多的数据量的情况下幸存下来。

深入了解数据分区使您能够实现卓越的 Cassandra 集群设计、性能和可扩展性。在本文中,我将探讨如何定义分区以及 Cassandra 如何使用它们,以及您应该了解的最关键的最佳实践和已知问题。

为了说明背景:分区是数据块,作为关键数据库相关功能的原子单元,例如数据分发、复制和索引。分布式数据系统通常将传入数据分发到这些分区中,使用简单的数学函数(例如标识或哈希)执行分区,并使用“分区键”按分区对数据进行分组。例如,考虑服务器日志作为传入数据到达的情况。使用“标识”分区函数和每个日志的时间戳(四舍五入到小时值)作为分区键,我们可以对这些数据进行分区,以便每个分区保存一小时的日志。

Cassandra 中的数据分区

Cassandra 作为分布式系统运行,并遵守上述数据分区原则。对于 Cassandra,数据分区依赖于在集群级别配置的算法以及在表级别配置的分区键。

Cassandra data partition

Cassandra 查询语言 (CQL) 使用熟悉的 SQL 表、行和列术语。在上图的示例中,表配置在其主键中包含分区键,格式为:主键 = 分区键 + [聚簇列]。

Cassandra 中的主键表示唯一的数据分区和分区内的数据排列。数据排列信息由可选的聚簇列提供。每个唯一的分区键代表一组在服务器中管理的表行,以及管理其副本的所有服务器。

在 CQL 中定义主键

以下四个示例演示了如何在 CQL 语法中表示主键。这些定义产生的一组行通常被认为是一个分区。

定义 1(分区键:log_hour,聚簇列:无)

CREATE TABLE server_logs(
   log_hour timestamp PRIMARYKEY,
   log_level text,
   message text,
   server text
   )

在这里,所有共享 log_hour 的行都进入同一个分区。

定义 2(分区键:log_hour,聚簇列:log_level)

CREATE TABLE server_logs(
   log_hour timestamp,
   log_level text,
   message text,
   server text,
   PRIMARY KEY (log_hour, log_level)
   )

此定义使用与定义 1 相同的分区键,但此处每个分区中的所有行都按 log_level 升序排列。

定义 3(分区键:log_hour, server,聚簇列:无)

CREATE TABLE server_logs(
   log_hour timestamp,
   log_level text,
   message text,
   server text,
   PRIMARY KEY ((log_hour, server))
   )

在此定义中,所有行都共享每个不同 serverlog_hour 作为一个分区。

定义 4(分区键:log_hour, server,聚簇列:log_level)

CREATE TABLE server_logs(
   log_hour timestamp,
   log_level text,
   message text,
   server text,
   PRIMARY KEY ((log_hour, server),log_level)
   )WITH CLUSTERING ORDER BY (column3 DESC);

此定义使用与定义 3 相同的分区,但按 log_level 降序排列分区内的行。

Cassandra 如何使用分区键

Cassandra 依靠分区键来确定将数据存储在哪个节点上,以及在需要时在哪里查找数据。Cassandra 通过查看表中的分区键,并使用令牌(范围为 -2^63 到 +2^63-1 的长整型值)进行数据分发和索引来执行这些读取和写入操作。这些令牌通过分区器映射到分区键,分区器应用分区函数将任何分区键转换为令牌。通过这种令牌机制,Cassandra 集群的每个节点都拥有一组数据分区。然后,分区键在每个节点上启用数据索引。

Cassandra cluster with 3 nodes and token-based ownership

具有三个节点和基于令牌所有权的 Cassandra 集群。这是一个简化的表示形式:实际实现使用 Vnodes

数据分区对 Cassandra 集群的影响

仔细的分区键设计对于为用例实现理想的分区大小至关重要。正确的设计允许均匀的数据分发和强大的 I/O 性能。分区大小对 Cassandra 集群有几个影响,您需要注意:

  • 读取性能——为了在磁盘上的 SSTables 文件中查找分区,Cassandra 使用包括缓存、索引和索引摘要的数据结构。过大的分区会降低维护这些数据结构的效率,并因此对性能产生负面影响。Cassandra 版本在这方面取得了进展:特别是,Cassandra 引擎的 3.6 及更高版本引入了存储改进,为大型分区提供更好的性能,并提高了对内存问题和崩溃的弹性。
  • 内存使用——大型分区给 JVM 堆带来更大的压力,增加其大小,同时也降低了垃圾回收机制的效率。
  • Cassandra 修复——大型分区使 Cassandra 更难以执行其修复维护操作,这些操作通过比较跨副本的数据来保持数据一致性。
  • 墓碑回收——不像听起来那么可怕,Cassandra 使用称为“墓碑”的唯一标记来标记要删除的数据。如果没有适当的数据删除模式和压缩策略,大型分区可能会使删除过程更加困难。

虽然这些影响可能使人想要简单地设计产生特别小分区的分区键,但数据访问模式对理想的分区大小也具有很大的影响(有关更多信息,请阅读这篇深入的 Cassandra 数据建模指南)。数据访问模式可以定义为如何查询表,包括表的所有 select 查询。理想情况下,CQL select 查询的 where 子句中应该只有一个分区键——也就是说,当查询可以从单个分区而不是许多较小的分区获取所需数据时,Cassandra 的效率最高。

分区键设计的最佳实践

遵循分区键设计的最佳实践有助于您获得理想的分区大小。作为经验法则,Cassandra 中的最大分区大小应保持在 100MB 以下。理想情况下,它应该在 10MB 以下。虽然 Cassandra 3.6 及更高版本使更大的分区大小更可行,但必须对每个工作负载执行仔细的测试和基准测试,以确保分区键设计支持所需的集群性能。

具体而言,在任何分区键设计中都应考虑以下最佳实践:

  • 分区键的目标必须是在每个分区中容纳理想的数据量,以支持其访问模式的需求。
  • 分区键应禁止无界分区:那些可能随着时间推移无限增长的分区。例如,在上面的 server_logs 示例中,使用 server 列作为分区键将创建无界分区,因为服务器日志的数量会持续增加。相反,使用 log_hour 将每个分区限制为一个小时的数据。
  • 分区键还应避免创建分区倾斜,即分区增长不均匀,并且有些分区能够随着时间推移无限制地增长。在 server_logs 示例中,在某个服务器生成的日志比其他服务器多得多的情况下使用 server 列将产生分区倾斜。为了避免这种情况,一个有用的技术是从表中引入另一个属性来强制均匀分布,即使有必要创建一个虚拟列来做到这一点。
  • 使用以时间元素以及其他属性作为分区键来分区时间序列数据很有帮助。这可以防止无界分区,使访问模式能够在查询特定数据时使用时间属性,并允许进行时间限制的数据删除。上面的每个示例都通过使用 log_hour 时间属性来演示了这一点。

有多种工具可用于帮助测试、分析和监控 Cassandra 分区,以检查所选模式是否高效且有效。通过仔细设计分区键以使其与手头解决方案的数据和需求良好对齐,并遵循最佳实践来优化分区大小,您可以利用数据分区,从而更充分地发挥 Cassandra 部署的可扩展性和性能潜力。

接下来阅读什么
User profile image.
Anil Inamdar 是 Instaclustr 美国咨询和交付主管,该公司提供 Apache Cassandra、Apache Spark、Elasticsearch 和 Apache Kafka 等开源技术的托管服务平台。Anil 在数据和分析领域拥有 20 多年的经验。

1 条评论

您好。

一家数据分析公司给了我一项任务,即创建架构并用图表解释它们。这项任务有两个问题。问题 1 与选择正确的技术和使用 NoSQL 云数据库的数据分区策略有关。还需要减少计算时间,以便整个计算负载可以在几个小时内完成。

关于问题 2。一家卡车运输公司每天处理大量发票(每天 40000 张)。目前,所有人都可以看到与他们无关的所有发票。您将如何设计一个系统以经济高效的方式存储所有这些数据。您将如何设计一个授权系统以确保组织只能看到与其自身相关的发票。

我看到了您关于 Cassandra 中数据分区的博客。我想您可以帮助我,因为您可能已经知道解决方案。

谢谢
Prakash Saswadkar
孟买,手机:+91-981 941 5206

-- 从 Word 文档复制粘贴 --
问题 1

一家大型快餐连锁店希望您为该快餐连锁店的 2000 家餐厅生成预测。每家餐厅销售近 500 种商品。
该快餐连锁店提供过去 3 年的门店、商品、日级别的数据。要求是提供未来一年的预测。
假设数据是静态的。数据科学家查看了这个问题,并找到了一个提供最佳预测的解决方案。
数据科学家构建了一个算法,该算法获取所有门店级别的数据,并生成门店级别的预测输出。
处理每个门店需要 15 分钟。

问题
1) 假设输入数据是静态的。存储数据的正确技术是什么?分区策略应该是什么?
2) 每个门店需要 15 分钟,您将如何设计系统以更快地编排计算 - 以便整个计算可以在 < 5 小时内完成

在您设计解决方案时,可以做出任何假设并说明它们,并且不必担心分析部分。假设分析
部分是一个黑匣子。

问题 2

一家卡车运输公司每天处理接近 40,000 张发票。监管要求需要存储 7 年的数据。
卡车司机在交货点使用其移动设备扫描发票。图像识别程序扫描发票并添加
从图像中捕获的元信息。元信息将包括发货地和收货地以及其他信息。
卡车运输公司可以看到其所有发票,发货组织可以查看所有发货地与其匹配的发票,
类似的规则适用于收货地。

问题
您将如何设计一个系统以经济高效的方式存储所有这些数据。
您将如何设计一个授权系统以确保组织只能根据上述规则查看发票。
使解决方案在全球范围内可用的设计考虑因素是什么?
-- --

© . All rights reserved.