首页 > 解决方案 > Clickhouse:损坏的数据部分不会从副本中自动恢复

问题描述

我和我的团队一直致力于设置 Clickhouse 集群并将其作为我们分析数据存储的解决方案。作为这项工作的一部分,为了准备推出集群,我们正在进行不同的实验,以便更多地了解行为并为任何意外结果做好准备。其中一项实验是破坏一些数据部分,并观察这些部分是否会从第二个副本中自动恢复。(顺便说一下,只是为了让您了解一下我们的集群的外观——它包含 3 个分片,每个副本有 2 个副本,其中大多数表使用 ReplicatedSummingMergeTree 引擎。)但是,似乎发现了 Clickhouse 中的数据损坏/仅在访问数据时(例如,通过查询)从副本中修复。

当服务器启动(或与 ZooKeeper 建立新会话)时,它只检查所有文件的数量和大小。如果文件大小匹配但字节在中间某处发生了更改,则不会立即检测到,而只会在尝试读取 SELECT 查询的数据时检测到。该查询引发关于不匹配校验和或压缩块大小的异常。在这种情况下,数据部分被添加到验证队列中,并在必要时从副本中复制。 https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replication/#recovery-after-failures

这也得到了我们的验证。我们执行查询以从特定的损坏数据部分提取一些数据,最初,它返回异常:

代码:33。DB::Exception:从 ******.com:9000 接收。DB::Exception: 无法读取所有数据。读取的字节数:22694。预期的字节数:29294。:(在读取 ****** 列时):(从部分 /opt/ch-data/store/719/7191f35e-d754-45f4-b191-f35ed75485f4/1606626000_1_1_3 读取时/ 来自标记 72,max_rows_to_read = 8192):执行 MergeTreeThread 时。

但是第二次尝试成功了,返回的数据集和replica 2返回的一模一样。也确认了损坏的数据部分出现在/detached文件夹中,并在文件系统中恢复。

关键是我们假设恢复将在后台自动启动,而不是在客户端触发某些操作之后。这导致我们开始担心修复过程无法自动识别时可能会完全丢失数据。例如,以下一组情况可能会导致数据完全丢失:

  1. 在时间 t0,replica1 上的数据损坏。
  2. 副本 2 上的相同数据部分稍后会损坏,例如 t0 + 10 天。
  3. 副本 1 上的损坏数据仅在 t0 + 20 天时被访问并尝试从副本 2 中恢复。

显然,如果损坏的数据被快速识别/修复,那么在replica1 有机会修复其数据之前replica2 被损坏的风险很低。然而,实际上,数据可能在很长一段时间内(例如,20 天,如上例所示)都不会被识别为损坏,那么这意味着在整个时间内,我们都在一个单一的、准确的副本上运行,我们有完全丢失数据的风险。

因此,我们想知道 Clickhouse 是否提供任何其他机制/选项来更快地识别损坏的数据。如果没有,有没有人有解决这个问题的经验?任何建议/见解将不胜感激。先感谢您!

标签: clickhouse

解决方案


推荐阅读