你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

确保 Azure Managed Instance for Apache Cassandra 最佳性能的最佳做法

Azure Managed Instance for Apache Cassandra 是针对纯开源 Apache Cassandra 群集的完全托管服务。 该服务还允许重写配置,具体取决于每个工作负载的特定需求。 此功能可根据需要实现最大的灵活性和控制。 本文提供有关如何优化性能的提示。

最佳设置和部署

复制因子、磁盘数、节点数和 SKU

Azure 在大多数区域支持 三个 可用区。 适用于 Apache Cassandra 的 Azure 托管实例将可用性区域映射到机架。 建议选择具有高基数的分区键以避免热分区。 为了获得最佳级别的可靠性和容错性,强烈建议将复制因子配置为 3。 还建议将复制因子的倍数指定为节点数,例如 3、6、9 等。

Azure 在您预配的磁盘数量上使用 RAID 0。 若要获取最佳 IOPS,请检查所选 SKU 上的最大 IOPS 与 P30 磁盘的 IOPS。 例如,Standard_DS14_v2 SKU 支持 51,200 个未缓存的 IOPS,而单个 P30 磁盘的基础性能为 5,000 个 IOPS。 4 个磁盘的 IOPS 数为 20,000,这远远低于计算机的限制。

强烈建议针对 SKU 和磁盘数对工作负载进行广泛的基准测试。 基准测试对于只有 8 个核心的 SKU 尤其重要。 我们的研究表明,8 个核心 CPU 仅适用于要求最低的工作负载。 大多数工作负荷至少需要 16 个核心才能正常运行。

分析工作负载与事务工作负载

事务工作负荷通常需要一个数据中心来优化低延迟,而分析工作负荷通常使用更复杂的查询,这需要更长的时间才能运行。 在大多数情况下,需要单独的数据中心:

  • 一个针对低延迟进行优化
  • 一个针对分析工作负载进行优化

针对分析工作负载进行优化

建议客户对分析工作负荷应用以下 cassandra.yaml 设置。 有关如何应用这些设置的详细信息,请参阅 Update Cassandra 配置

超时

价值 Cassandra MI 默认值 分析工作负载的推荐值
read_request_timeout_in_ms 5,000 1万
range_request_timeout_in_ms 1万 20,000
counter_write_request_timeout_in_ms 5,000 1万
cas_contention_timeout_in_ms 1,000 二千
truncate_request_timeout_in_ms 60,000 120,000
slow_query_log_timeout_in_ms 500 1,000
roles_validity_in_ms 二千 120,000
permissions_validity_in_ms 二千 120,000

缓存

价值 Cassandra MI 默认值 分析工作负载的推荐值
file_cache_size_in_mb 2,048 6,144

更多建议

价值 Cassandra MI 默认值 分析工作负载的推荐值
commitlog_total_space_in_mb 8,192 16,384
column_index_size_in_kb 64 16
compaction_throughput_mb_per_sec 128 256

客户端设置

建议根据服务器上应用的超时来调高 Cassandra 客户端驱动程序超时。

针对低延迟进行优化

我们的默认设置已经适用于低延迟工作负载。 为了确保尾部延迟的最佳性能,我们强烈建议使用支持推测执行的客户端驱动程序并相应地配置客户端。 对于 Java V4 驱动程序,可以找到一个演示,演示了此作的工作原理以及如何 在此示例中启用策略。

监视性能瓶颈

CPU 性能

与每个数据库系统一样,如果 CPU 利用率约为 50%,并且始终不会超过 80%,那么 Cassandra 效果最佳。 可通过门户的“监视”中的“指标”选项卡查看 CPU 指标:

按空闲使用情况划分的 CPU 指标的屏幕截图。

提示

为了获得真实的 CPU 视图,请添加筛选器并按 Usage kind=usage_idle 分割属性。 如果该值低于 20%,则可以应用拆分来获取所有使用类型的使用情况。

按使用情况类型划分的 CPU 指标的屏幕截图。

如果大多数节点的 CPU 永久超过 80%,则数据库将过载,这在多个客户端超时中会出现。 在此方案中,我们建议你执行以下作:

  • 纵向扩展到具有更多 CPU 内核的 SKU,尤其是在核心数仅为 8 或更少时。
  • 通过添加更多节点来水平缩放。 如前所述,节点数应为复制因子的倍数。

如果 CPU 只对几个节点较高,而对其他节点较低,这表明存在一个热分区,这一现象需要进一步调查。

注意

使用 Azure 门户、Azure CLI 和 ARM 模板部署支持更改 SKU。 可以部署或编辑 ARM 模板,并将 SKU 替换为以下值之一:

  • Standard_E8s_v4
  • Standard_E16s_v4
  • Standard_E20s_v4
  • Standard_E32s_v4
  • Standard_DS13_v2
  • Standard_DS14_v2
  • Standard_D8s_v4
  • Standard_D16s_v4
  • Standard_D32s_v4
  • Standard_L8s_v3
  • Standard_L16s_v3
  • Standard_L32s_v3
  • Standard_L8as_v3
  • Standard_L16as_v3
  • Standard_L32as_v3

目前,我们不支持跨 SKU 系列转换。 例如,如果您当前拥有 Standard_DS13_v2 并想要升级到更大的 SKU,例如 Standard_DS14_v2,则此选项不可用。 但是,你可以通过创建支持工单来请求升级到更高的 SKU。

磁盘性能

该服务运行在 Azure P30 管理磁盘上,支持 突增 IOPS。 当涉及到与磁盘相关的性能瓶颈时,需要仔细监视。 在这种情况下,请务必查看 IOPS 指标:

磁盘 I/O 指标的屏幕截图。

如果指标显示以下一个或多个特征,可能需要纵向扩展。

  • 始终高于或等于基本 IOPS。 请记住,将 5,000 IOPS 乘以每个节点的磁盘数来获取该数字。
  • 始终高于或等于 SKU 允许写入操作使用的最大 IOPS 数。
  • 您的 SKU 支持缓存存储(直写缓存),而这个数值小于托管磁盘的 IOPS。 此值是读取 IOPS 的上限。

如果只看到几个节点的 IOPS 数增加,那么你可能有热分区,并需要查看数据是否存在潜在的倾斜。

如果 IOPS 低于 SKU 所支持的水平,但高于或等于磁盘 IOPS,则可以执行以下操作:

  • 添加更多磁盘来提高性能。 要增加磁盘,需要提出支持案例。
  • 通过添加更多节点来纵向扩展数据中心

如果 IOPS 数超过 SKU 支持的最大数,你可以:

有关详细信息,请参阅 虚拟机和磁盘性能

网络性能

在大多数情况下,网络性能已足够。 但是,如果你经常流式处理数据(录入频繁的水平纵向扩展/纵向缩减),或者存在大量的入口/出口数据移动,此性能可能会成为一个问题。 可能需要评估 SKU 的网络性能。 例如, Standard_DS14_v2 SKU 支持 12,000 Mb/秒。 将此值与指标中的字节进入/传出进行比较。

网络指标的屏幕截图。

如果只看到某些节点的网络负载增加,则可能存在热点分区,因此需要检查数据分布和访问模式以识别潜在的偏差。

  • 垂直纵向扩展到支持更多网络 I/O 的其他 SKU。
  • 通过添加更多节点水平纵向扩展群集。

连接的客户端数太多

应规划和预配部署,以支持在应用程序所需的延迟情况下所需的最大并行请求数。 对于给定的部署,在超过最低阈值的情况下向系统引入更多负载会增加总体延迟。 监视连接的客户端数,以确保这种情况不会超过可容忍的限制。

连接客户端指标的屏幕截图。

磁盘空间

在大多数情况下,有足够的磁盘空间。 默认部署针对 IOPS 进行优化,这会导致磁盘利用率较低。 不过,我们建议偶尔查看磁盘空间指标。 Cassandra 会累积大量磁盘,然后在触发压缩时减少它。 请务必在较长时间内查看磁盘使用情况,以确定趋势,例如压缩无法收回空间。

注意

为了确保压缩的可用空间,磁盘利用率应保持在 50% 左右。

如果只看到几个节点的此行为,则可能具有热分区,并且需要查看数据分布和访问模式是否存在潜在的偏差。

  • 添加更多磁盘,但请注意您的 SKU 所施加的 IOPS 限制。
  • 水平纵向扩展群集

JVM 内存

我们的默认公式将虚拟机内存的一半分配给 Jave 虚拟机(JVM),上限为 31 GB。 在大多数情况下,此方法在性能和内存之间是很好的平衡。 某些工作负载,尤其是具有频繁跨分区读取或范围扫描的工作负载,可能会面临内存挑战。

在大多数情况下,Java 垃圾回收器会有效地回收内存,但特别是当 CPU 利用率通常超过 80% 时,没有足够的 CPU 周期可供垃圾回收器使用。 因此在解决内存问题之前,应先解决所有 CPU 性能问题。

如果 CPU 利用率在 70% 以下徘徊,并且垃圾回收无法回收内存,你可能需要更多的 JVM 内存。 如果使用的是具有有限内存的 SKU,则可能需要更多 JVM 内存。 在大多数情况下,除了 CQL 查询中 fetch_size 中选择的内容,还需要查看查询和客户端设置并减少 limit

如果确实需要更多内存,你可以:

  • 向我们提交票证来调高 JVM 内存设置
  • 垂直扩展到具有更多可用内存的 SKU

逻辑删除

我们每隔七天运行一次修复,使用 reaper 工具,删除那些 TTL 已过期的行,这些行被称为 墓碑。 某些工作负载的删除更频繁,并会显示警告(例如 Cassandra 日志中的 Read 96 live rows and 5035 tombstone cells for query SELECT ...; token <token> (see tombstone_warn_threshold)),甚至出现提示由于过多的逻辑删除而无法完成查询的错误。

在查询未得到满足的情况下执行的短期缓解措施是将 Cassandra 配置中的 tombstone_failure_threshold 从默认值 100,000 增加到更高的值。

我们还建议查看密钥空间上的 TTL,并可能每天运行修复,以清除更多的逻辑删除。 如果 TTL 较短(例如不到两天),并且数据流入后很快被删除,则建议查看 压缩策略 并偏好 Leveled Compaction Strategy。 在某些情况下,此类作可能指示需要查看数据模型。

批处理警告

CassandraLogs 和潜在相关故障中可能会看到此警告:

Batch for [<table>] is of size 6.740KiB, exceeding specified threshold of 5.000KiB by 1.740KiB.

在这种情况下,应查看查询,以保持在建议的批大小之下。 在极少数情况下,作为短期缓解措施,您可以将 Cassandra 配置中的batch_size_fail_threshold_in_kb从默认值 50 增加到更高的值。

大型分区警告

CassandraLogs 中可能会看到此警告:

Writing large partition <table> (105.426MiB) to sstable <file>

此消息指示数据模型中存在问题。 有关详细信息,请参阅此 堆栈溢出文章。 此问题可能会导致严重的性能问题,需要解决。

专用优化

压缩

Cassandra 允许在创建表时选择适当的压缩算法。 默认值为 LZ4,非常适合吞吐量和 CPU,但在磁盘上占用更多空间。 使用 Zstd(Cassandra 4.0 及更高版本)可节省约 12% 的空间,且 CPU 开销最小。

优化内存表堆空间

默认设置是将 1/4 的 JVM 堆用于 cassandra.yaml 中的 memtable_heap_space。 对于面向写入的应用程序和/或具有小内存的 SKU,此问题可能会导致频繁的刷新和碎片化的 sstables,这需要更多的压缩。 在这种情况下,将其增加到至少 4048 可能是好的。 此方法需要仔细进行基准比较,以确保其他操作(例如读取)不会受到影响。

后续步骤