跳到主要内容

解决 ClickHouse 中 “Too Many Parts” 错误

·3 分钟阅读
了解如何通过优化插入速率、配置 MergeTree 设置和有效管理分区来解决 ClickHouse 中的 “Too many parts” 错误。

DB::Exception: Too many parts (600). Merges are processing significantly slower than inserts

您已达到 MergeTree 表上的 `parts_to_throw_insert` 设置。

您可以使用以下命令监控给定表的活动 parts 数量

select count(*) from system.parts where table = '<table_name>' and active == 1

关于插入 Clickhouse 的主要要求:您不应每秒发送过多的 `INSERT` 语句。理想情况下 - 每秒/每几秒一次插入。

因此,您可以每秒插入 10 万行,但只能使用一个大型批量 `INSERT` 语句。当您每秒向 *MergeTree 表发送数百/数千个插入语句时,您总是会遇到一些错误,并且无法通过调整某些设置来更改它。

如果您无法在外部将大量插入组合成一个大型批量插入语句 - 那么您应该在 *MergeTree 表之前创建 Buffer 表。

  1. 每次插入都会在 `/var/lib/clickhouse/.../table_name/` 中创建一个文件夹。在该文件夹内,每列有两个文件 - 一个包含数据(压缩),第二个包含索引。数据在这些文件中按主键物理排序。这些文件夹称为 ‘parts’。

  2. ClickHouse 在后台将这些较小的 parts 合并为较大的 parts。它根据一些规则选择要合并的 parts。合并两个(或多个)parts 后,会创建一个更大的 part,旧的 parts 排队等待删除。您列出的设置允许微调 parts 合并的规则。合并过程的目标 - 是为每个分区保留一个大的 part(或每个分区几个大的 parts,因为它们太大而不值得合并)。另请查看 评论

  3. 如果您创建新 parts 的速度太快(例如,通过进行大量小插入),并且 ClickHouse 无法以适当的速度合并它们(因此新 parts 的速度快于 ClickHouse 合并它们的速度) - 那么您会收到异常“Merges are processing significantly slower than inserts”。您可以尝试增加限制,但您可能会遇到文件系统问题,这是由文件/目录数量过多引起的(例如 inodes 限制)。

  4. 如果您一次插入到许多分区,则问题会乘以受插入影响的分区数。

  5. 您可以尝试使用列出的设置之一或 max_insert_block_size / max_block_size / insert_format_max_block_size / max_client_network_bandwidth 来调整 clickhouse 的行为。但是:更好的解决方案是以预期的节奏插入数据。预期的节奏是:每 1-2 秒一次插入,每次插入包含 1 万到 50 万行数据

  6. 因此,解决 “Merges are processing significantly slower than inserts” 错误的正确解决方案是调整每秒插入的次数和每次插入的行数。如果数据逐行到达,请使用批量插入将小的插入组合成一个更大的插入。如果您一次要插入的数据太多,请限制大型插入。不要更改 clickhouse 内部结构,除非您真正了解它们的含义。

  7. 如果您的数据速度超过每秒 50 万行 - 很可能您需要在集群中添加更多服务器来服务该流量,而不是调整设置。

  8. 后台合并的速度通常取决于存储速度、使用的压缩设置、MergeTree 选项(合并算法 - 普通合并/聚合/求和/折叠等)以及使用的排序键。