了解性能

本页介绍了 Bigtable 在最佳条件下可提供的大致性能、可能会影响性能的因素,以及测试和排查 Bigtable 性能问题的提示。

典型工作负载下的性能

Bigtable 可提供高度可预测的线性扩缩性能。如果您避免了下文所述的性能下降的原因,则每个 Bigtable 节点都可提供以下大致吞吐量,具体取决于集群使用的存储空间类型:

存储空间类型 读取   写入   扫描
SSD 每秒最多 17,000 行 每秒最多 14,000 行 最多 220 MB/秒
HDD 每秒最多 500 行 每秒最多 10000 行 最多 180 MB/秒

这些估算值假设每行包含 1 KB 的数据。

一般来说,集群的性能会随着集群中节点数量的增加而线性提升。例如,如果您创建一个具有 10 个节点的 SSD 集群,则在典型的只读或只写工作负载下,该集群最多可以支持每秒 14 万行读取或写入。

规划 Bigtable 容量

在规划 Bigtable 集群时,请确定您是要针对延迟时间还是吞吐量进行优化。例如,对于批量数据处理作业,您可能会更关注吞吐量,而不那么关注延迟时间。相比之下,对于处理用户请求的在线服务,低延时的优先级可能高于吞吐量。当您优化吞吐量时,可以实现典型工作负载下的性能部分中的数字。

CPU 利用率

在几乎所有情况下,我们都建议您使用自动扩缩功能,以便 Bigtable 根据您的使用情况添加或移除节点。如需了解详情,请参阅自动扩缩

配置自动扩缩目标或选择手动节点分配时,请遵循以下准则。无论您的实例有多少个集群,这些准则都适用。对于采用手动节点分配的集群,您必须监控集群的 CPU 利用率,以便将 CPU 利用率保持在这些值以下,从而实现最佳性能。

优化目标 最大 CPU 利用率
吞吐量 90%
延迟时间 60%

如需详细了解监控,请参阅 Monitoring

存储空间利用率

容量规划的另一个考虑因素是存储。集群的存储容量由存储类型和集群中的节点数决定。当集群中存储的数据量增加时,Bigtable 会通过将数据量分配到集群中的所有节点来优化存储。

您可以通过将集群的存储空间利用率(字节)除以集群中的节点数来确定每个节点的存储空间用量。例如,假设一个集群具有三个 HDD 节点和 9 TB 数据。每个节点存储大约 3 TB,即每个节点 16 TB 的 HDD 存储空间的 18.75%。

当存储空间利用率增加时,即使集群有足够的节点来满足整体 CPU 需求,工作负载也会遇到查询处理延迟时间的增加。这是因为每个节点的存储空间越大,需要执行更多后台工作(例如编制索引)。增加处理后台存储空间的工作量会增加延迟时间并降低吞吐量。

配置自动扩缩设置时,请先从以下几点入手。如果您选择手动节点分配,请监控集群的存储用量,并添加或移除节点以维护以下内容。

优化目标 存储空间利用率上限
吞吐量 70%
延迟时间 60%

如需了解详情,请参阅每个节点的存储空间

针对 Bigtable 运行典型工作负载

在进行容量规划时,请始终针对 Bigtable 集群运行您自己的典型工作负载,以便确定应用的最佳资源分配。

Google 的 PerfKit Benchmarker 使用 YCSB 对云服务进行基准测试。您可以按照 Bigtable 的 PerfKitBenchmarker 教程为您自己的工作负载创建测试。进行上述操作时,您应调整基准配置 yaml 文件中的参数,以确保生成的基准反映生产环境中的以下特性:

  • 表的总大小。您可以按比例设置,但至少为 100 GB。
  • 行数据形状(行键大小、列数、行数据大小等)
  • 数据访问模式(行键分布)
  • 读取与写入的混合

如需了解更多最佳做法,请参阅使用 Bigtable 测试性能

性能下降的原因

以下几个因素可能会导致 Bigtable 的执行速度低于以上所示估算值:

  • 在单个读取请求中读取大量非连续行键或行范围。Bigtable 会扫描表并按顺序读取所请求的行。这种并行性影响会影响总体并造成任何命中热节点可增加尾巴延迟时间。如需了解详情,请参阅读取和性能
  • 表架构的设计不正确。为了使 Bigtable 实现良好性能,您需要设计一个可以将读写操作均匀分布到每个表的架构,这至关重要。此外,一个表中的热点问题可能也会影响同一实例中其他表的性能。如需了解详情,请参阅架构设计最佳实践
  • Bigtable 表中的行包含大量数据。以上所示性能估计假设每行包含 1 KB的数据。您可以每行读取和写入更多数据,但增加每行的数据量也会减少每秒的行数。
  • Bigtable 表中的行包含大量单元格。Bigtable 需要一些时间来处理一行中的每个单元格。此外,每个单元格也会对存储在表中并通过网络发送的数据量增加一些开销。例如,如果您要存储 1 KB(1024 字节)的数据,那么将这些数据存储在一个单元格中,要比将数据分布在 1024 个均包含一个字节的单元格中更具空间效率。如果您将数据拆分到超出必要数量的单元格中,则可能无法获得最佳性能。 如果行包含大量单元,因为列包含多个带时间戳的数据版本,请考虑仅保留最新值。对于现有表,另一个选项是在每次重写时发送先前所有版本的删除。
  • 集群没有任何节点。集群的节点为集群提供计算功能,以处理传入的读取和写入、跟踪存储以及执行压缩等维护任务。您需要确保您的集群具有足够的节点,以满足计算和存储的推荐限制。可以使用监控工具检查集群是否过载。

    • 计算 - 如果 Bigtable 集群的 CPU 过载,则添加更多节点可以通过将工作负载分布到更多节点来提高性能。
    • 存储 - 如果每个节点的存储空间使用率高于建议,则需要添加更多节点以维持最佳延迟时间和吞吐量,即使集群有足够的 CPU 来处理请求。这是因为每个节点增加存储空间会增加每个节点的后台维护工作量。如需了解详情,请参阅存储空间用量和性能之间的权衡
  • Bigtable 集群最近扩大或缩小了规模。增加集群中的节点数后,负载条件下的集群可能需要长达 20 分钟的时间才能表现出性能大幅提升。Bigtable 会根据集群负载扩缩集群中的节点。

    当您减少集群中的节点数量进行纵向缩容时,请尽量不要在 10 分钟内将集群大小降低 10% 以上,以最大限度地减少延迟时间急剧增加的情况。

  • Bigtable 集群使用 HDD 磁盘。在大多数情况下,您的集群应使用 SSD 磁盘,其性能明显优于 HDD 磁盘。如需了解详情,请参阅在 SSD 和 HDD 存储空间之间进行选择

  • 网络连接存在问题。网络问题可能会降低吞吐量,并导致读写时间比通常要长。具体而言,如果您的客户端与 Bigtable 集群运行的地区不同,或者您的客户端在 Google Cloud 外部运行,则可能会出现问题。

  • 您使用的是复制功能,但应用使用的是过时的客户端库。如果您发现启用复制功能后延迟时间有所增加,请确保应用使用的 Cloud Bigtable 客户端库是最新的。旧版客户端库可能未经过优化,无法支持复制功能。请参阅 Cloud Bigtable 客户端库以查找客户端库的 GitHub 代码库,您可以在其中检查版本并在需要时进行升级。

  • 您已启用复制功能,但未向集群添加更多节点。在使用复制功能的实例中,除了处理从应用接收的负载之外,每个集群还必须处理复制工作。预配不足的集群可能会导致延迟时间增加。您可以通过在 Google Cloud 控制台中查看实例的 CPU 使用率图表来验证这一点。

由于性能会因工作负载的不同而发生变化,因此您应该使用自己的工作负载进行测试以获取最准确的基准。

冷启动和 QPS 较低

冷启动和 QPS 较低可能会增加延迟时间。Bigtable 最适合频繁访问的大型表。因此,如果您在空闲一段时间后开始发送请求(冷启动),则可能会在 Bigtable 重新建立连接时观察到高延迟。当 QPS 较低时,延迟时间也会更长。

如果您的 QPS 较低,或者您知道自己有时会在处于非活跃状态一段时间后向 Bigtable 表发送请求,则可以尝试以下策略来保持连接预热,从而防止出现这种高延迟。

在 QPS 较低期间,Bigtable 返回的错误数量比返回错误的操作百分比影响更大。

客户端初始化时冷启动。 如果您使用的 Java 版 Cloud Bigtable 客户端版本低于 2.18.0,则可以启用通道刷新。在较高版本中,频道刷新功能默认处于启用状态。渠道刷新有两个作用:

  • 客户端在初始化时会先准备通道,然后再发送第一个请求。
  • 服务器每小时断开长连接。频道预处理会提前替换即将过期的频道。

不过,这并不能让通道在无活动期保持活跃状态。

Bigtable 如何实时优化您的数据

为了存储每个表的基础数据,Bigtable 会将数据分成多个片,您可以在 Bigtable 集群的各节点之间移动这些片。这种存储方法使 Bigtable 能够在长时间运行过程中,使用以下两种不同的策略来优化您的数据:

  1. Bigtable 尝试在每个 Bigtable 节点上存储大致相同数量的数据。
  2. Bigtable 尝试在所有 Bigtable 节点中平均分配读取和写入操作。

有时候这些策略会相互冲突。例如,如果一个片所对应的行被读取的频率极高,则 Bigtable 可能会将该片存储在其自己的节点上,即使这会导致一些节点存储比其他节点更多的数据。

在此过程中,Bigtable 可能还会将片拆分成两个或更多个更小的片,以减小片的大小或隔离现有片中的常用行。

以下部分对这些策略分别进行了更为详细的介绍。

将数据量分配到各节点

随着您向 Bigtable 表中写入的数据越来越多,Bigtable 会将表中的数据分成若干片。每个片包含表中一定范围的连续行。

如果您将大小在数个 GB 以内的数据写入表中,Bigtable 会将所有片都存储在您集群内的同一个节点上:

单个节点上包含四个片的集群。

随着累积的片越来越多,Bigtable 会将部分片移至集群的其他节点,以使数据量在整个集群中更均匀地分布:

其他片分布在多个节点上。

将读写操作均匀分布到各节点

如果您已经正确地设计您的架构,那么读写操作应会相当均匀地分配到整个表中。但在某些情况下,您无法避免比其他人更频繁地访问某些行。Bigtable 会在将片平均分配到各节点时考虑读写操作,从而可帮助您应对这些情况。

例如,假设 25% 的读取内容将进入集群的少量片中,并且读取操作均匀分布在所有其他片中:

总共 48 个片中,25% 的读取针对 3 个片。

Bigtable 将重新分配现有的片,以便读取操作尽可能均匀地分布在整个集群中:

三个常用片被隔离到各自的节点上。

使用 Bigtable 测试性能

如果您要对依赖于 Bigtable 的应用运行性能测试,请在规划和执行测试时遵循以下准则:

  • 使用足够的数据进行测试
    • 如果生产实例中的表包含的每个节点的总数据量不超过 100 GB,请使用数据量相同的表进行测试。
    • 如果表包含的每个节点的数据超过 100 GB,请使用每个节点至少包含 100 GB 的数据的表进行测试。例如,如果您的生产实例具有一个四节点集群,并且实例中的表总共包含 1 TB 的数据,请使用至少 400 GB 的表运行测试。
  • 使用单个表进行测试
  • 每个节点保持低于建议的存储空间利用率。如需了解详情,请参阅每个节点的存储空间利用率
  • 在测试之前,请先运行几分钟重载预测试。此步骤旨在让 Bigtable 可以根据其所遵循的访问模式使您的各节点之间的数据保持平衡。
  • 运行您的测试至少 10 分钟。此步骤旨在让 Bigtable 能够进一步优化您的数据,并有助于确保您的测试将包括对磁盘数据的读取以及内存中缓存数据的读取。

性能问题排查

如果您觉得 Bigtable 可能在您的应用中造成了性能瓶颈,请务必进行以下所有检查:

  • 检查您的表的 Key Visualizer 扫描。适用于 Bigtable 的 Key Visualizer 工具每 15 分钟生成一次新的扫描数据,其中显示了集群中每个表的使用模式。Key Visualizer 可以检查您的使用模式是否会导致不良结果,例如特定行上的热点或 CPU 利用率过高。了解如何开始使用 Key Visualizer
  • 尝试注释掉用于执行 Bigtable 读写操作的代码。如果性能问题消失,则说明 Bigtable 的使用方式可能导致性能欠佳。如果性能问题依然存在,则说明问题可能与 Bigtable 无关。
  • 确保您创建尽可能少的客户端。为 Bigtable 创建客户端的成本相对较高。因此,您应该尽可能创建最少的客户端:

    • 如果您使用复制功能,或者您使用应用配置文件来识别路由到实例的不同类型的流量,请为每个应用配置文件创建一个客户端,并在整个应用中共享客户端。
    • 如果您不使用复制或应用配置文件,请创建单个客户端并在整个应用中共享该客户端。

    如果您使用的是 Java 版 HBase 客户端,您需要创建 Connection 连接对象而非客户端,因此您应该创建尽可能少的连接。

  • 确保您从表中读取和写入的是许多不同的行。当读写操作均匀分布在整个表中时,Bigtable 性能最佳,这有助于 Bigtable 将工作负载分布到集群的所有节点上。如果读取和写入操作不能分布在所有 Bigtable 节点上,性能则将受到影响。

    如果发现只读取和写入了少量行,您可能需要重新设计您的架构,以使读写操作更加均匀地分布。

  • 验证 Cloud Bigtable 所呈现的读取和写入性能大致相同。如果您发现读取速度比写入速度快得多,那么说明可能是您正在尝试读取的行键不存在或部分行键仅包含少量行。

    为了在读取和写入操作之间进行有效的比较,至少 90% 的读取操作应返回有效结果。另外,如果您读取的行键范围比较大,应根据该范围内的实际行数来衡量性能,而不是根据可能存在的最大行数。

  • 使用正确类型的数据写入请求。选择最佳数据写入方式有助于保持高性能。

  • 检查单行的延迟时间。如果您在发送 ReadRows 请求时观察到意外延迟,则可以检查请求第一行的延迟时间,以缩小原因的范围。默认情况下,ReadRows 请求的整体延迟时间包括请求中每一行的延迟时间以及各行之间的处理时间。如果整体延迟时间较高,但第一行延迟时间较低,这表明延迟时间是由请求数量或处理时间所致,而不是 Bigtable 问题导致。

    如果您使用的是 Java 版 Bigtable 客户端库,则可以在启用客户端指标之后,在 Google Cloud 控制台 Metrics Explorer 中查看 read_rows_first_row_latency 指标。

  • 为每个工作负载使用单独的应用配置文件。如果您在添加新工作负载后遇到性能问题,请为新工作负载创建新的应用配置文件。然后,您可以单独监控应用配置文件的指标,以进一步排查问题。如需详细了解使用多个应用配置文件是最佳实践的原因,请参阅应用配置文件的工作原理

  • 启用客户端指标。您可以设置客户端指标,以帮助优化和排查性能问题。例如,由于 Bigtable 最适合均匀分布的高 QPS,因此一小部分请求的 P100(最大)延迟时间增加并不一定表示 Bigtable 存在较大的性能问题。通过客户端指标,您可以深入了解请求生命周期的哪个部分可能导致延迟。

后续步骤