为什么以及如何构建 ClickHouse 的主副本架构

我们使用人工智能和机器学习技术优化汽车保险和贷款的比价和购买流程。随着数据不断增长,AWS Redshift 开始出现速度慢、成本高的缺陷。改用 ClickHouse 后,查询性能显著提升,成本大幅降低。然而,我们随之遇到了存储相关的挑战,如磁盘故障和数据恢复。为了减少维护工作,我们引入了高 wydaj 分布式文件系统 JuiceFS,并创新地利用其快照功能为 ClickHouse 建立了主副本架构。此架构保证了数据的分布和稳定,同时大大提高了系统性能和数据恢复能力。一年多的运行显示,该架构没有宕机或复制错误,达到了预期的性能效果。

为什么以及如何构建 ClickHouse 的主副本架构

我们公司使用人工智能 (ai) 和机器学习来简化汽车保险和汽车贷款的比较和购买流程。随着数据的增长,aws redshift 出现了问题,它速度慢且成本高。改用 clickhouse 后,我们的查询性能更快,成本也大大降低。但这也带来了磁盘故障和数据恢复等存储挑战。

为了避免大量的维护工作,我们采用了高性能的分布式文件系统 JuiceFS,并创新性地利用其快照功能为 ClickHouse 实现了主副本架构。该架构在保证数据高可用和稳定性的同时,大幅提升了系统性能和数据恢复能力。运行一年多来,没有宕机和复制错误,达到了预期的性能。

在这篇文章中,我将深入探讨我们在应用方面面临的挑战、我们找到的解决方案以及我们的未来计划。我希望这篇文章能为初创公司和大公司的小团队提供宝贵的见解。

数据架构:从 Redshift 到 ClickHouse

最初,我们选择 Redshift 进行分析查询。然而,随着数据量的增长,我们遇到了严重的性能和成本挑战。例如,在生成漏斗和 A/B 测试报告时,我们面临长达数十分钟的加载时间。即使在合理大小的 Redshift 集群上,这些操作也太慢了。这导致我们的数据服务不可用。

因此,我们寻求一种更快、更具成本效益的解决方案,尽管 ClickHouse 在实时更新和删除方面存在局限性,但我们还是选择了它。改用 ClickHouse 带来了显著的好处:

  • 报告加载时间从几十分钟缩短到几秒钟。我们能够更高效地处理数据。

  • 总支出被削减至不超过原来的25%。

我们的设计以 ClickHouse 为中心,Snowflake 作为 ClickHouse 无法处理的 1% 数据处理的备份。这种设置实现了 ClickHouse 和 Snowflake 之间的无缝数据交换。

为什么以及如何构建 ClickHouse 的主副本架构

杰瑞数据架构

ClickHouse 部署和挑战

我们最初维持独立部署的原因如下:

  • 性能: 单机部署避免了集群的开销,在同等计算资源的情况下,性能表现良好。

  • 维护成本: 独立部署的维护成本最低,不仅包括集成维护成本,还包括应用数据设置、应用层暴露维护成本。

  • 硬件能力:当前硬件可以支持大规模独立 ClickHouse 部署。例如,我们现在可以在 AWS 上获得具有 24 TB 内存和 488 个 vCPU 的 EC2 实例。这在规模上超过了许多已部署的 ClickHouse 集群。这些实例还提供满足我们计划容量的磁盘带宽。

因此,从内存、CPU、存储带宽等方面考虑,独立的ClickHouse是一个可以接受的解决方案,并且在可预见的未来将是有效的。

但是,ClickHouse 方法存在一些固有问题:

  • 硬件故障可能会导致 ClickHouse 长时间停机。这会威胁应用程序的稳定性和连续性。

  • ClickHouse数据迁移和备份仍然是一项艰巨的任务。它们需要一个可靠的解决方案。

我们在部署ClickHouse之后,遇到了以下问题:

  • 扩展和维护存储:由于数据的快速扩展,维持适当的磁盘利用率变得困难。

  • 磁盘故障: ClickHouse 的设计目标是尽可能地利用硬件资源,以提供最佳的查询性能。因此,读写操作会频繁发生。它们经常会超出磁盘带宽。这会增加磁盘硬件故障的风险。当发生此类故障时,恢复可能需要几个小时到十几个小时。这取决于数据量。我们听说其他用户也有类似的经历。虽然数据分析系统通常被认为是其他系统数据的副本,但这些故障的影响仍然很大。因此,我们需要为任何硬件故障做好准备。数据迁移、备份和恢复是极其困难的操作,需要花费更多的时间和精力才能成功完成。

我们的解决方案

我们选择 JuiceFS 来解决我们的痛点,原因如下:

  • JuiceFS 是唯一可以在对象存储上运行的 POSIX 文件系统。

  • 无限容量:自从开始使用它以来,我们就不必担心存储容量。

  • 显著节省成本:使用 JuiceFS 的费用比使用其他解决方案的费用要低得多。

  • 强大的快照功能:JuiceFS 在文件系统层面有效实现了 Git 的分支机制。当两个不同的概念如此无缝地融合时,它们往往会产生极具创意的解决方案。这使得以前具有挑战性的问题变得更容易解决。

构建 ClickHouse 的主副本架构

我们产生了将 ClickHouse 迁移到基于 JuiceFS 的共享存储环境的想法。《探索 ClickHouse 的存储计算分离》这篇文章给了我们一些启发。

为了验证这个方案,我们进行了一系列的测试,结果显示开启缓存后,JuiceFS 的读取性能已经接近本地磁盘,和本文的测试结果类似。

虽然写入性能下降到了磁盘写入速度的10%到50%,但这对我们来说是可以接受的。

我们针对 JuiceFS 挂载做的调优调整如下:

  • 为了异步写入并防止可能出现的阻塞问题,我们启用了写回功能。

  • 在缓存设置中,我们设置attrcacheto为“3,600.0 秒”和cache-size“2,300,000”。我们启用了元缓存功能。

  • 考虑到 JuiceFS 上的 I/O 运行时间可能比本地驱动器更长,我们引入了块中断功能。

提高缓存命中率是我们的优化目标,我们使用 JuiceFS 云服务将缓存命中率提升到 95%。如果需要进一步提升,我们会考虑增加更多磁盘资源。

ClickHouse 和 JuiceFS 的结合,大大减轻了我们的运维负担,不再需要频繁扩容磁盘,而是专注于监控缓存命中率,大大缓解了扩容磁盘的紧迫性。而且,一旦发生硬件故障,也不需要进行数据迁移,大大降低了可能的风险和损失。

JuiceFS 快照功能提供的便捷数据备份和恢复选项让我们受益匪浅。借助快照,我们可以查看数据的原始状态,并在将来的任何时间恢复数据库服务。这种方法通过在文件系统级别实施解决方案来解决以前在应用程序级别处理的问题。此外,快照功能非常快速且经济,因为只存储一份数据副本。JuiceFS 社区版用户可以使用克隆功能实现类似的功能。

此外,由于无需迁移数据,停机时间也大幅减少。我们可以快速响应故障,或者让自动化系统在另一台服务器上挂载目录,确保服务连续性。值得一提的是,ClickHouse 的启动时间仅为几分钟,这进一步提高了系统恢复速度。

此外,迁移后我们的读取性能保持稳定。整个公司都没有发现任何差异。这证明了该解决方案的性能稳定性。

最后,我们的成本大幅降低。

为何要建立主副本架构

迁移到 ClickHouse 后,我们遇到了几个问题,导致我们考虑构建主副本架构:

  • 资源争用导致性能下降。在我们的设置中,所有任务都在同一个 ClickHouse 实例上运行。这导致提取、转换和加载 (ETL) 任务与报告任务之间频繁发生冲突,从而影响整体性能。

  • 硬件故障导致停机。我们公司需要随时访问数据,因此长时间的停机是不可接受的。因此,我们寻求解决方案,最终找到了主副本架构的解决方案。

JuiceFS 支持在不同位置挂载多个挂载点,我们尝试将 JuiceFS 文件系统挂载到其他地方,并在同一位置运行 ClickHouse,但在实施过程中遇到了一些问题:

  • ClickHouse 通过文件锁定机制限制一个文件只能由一个实例运行,这带来了挑战。幸运的是,这个问题很容易解决,只需修改 ClickHouse 源代码来处理锁定即可。

  • 即使在只读操作期间,ClickHouse 也会保留一些状态信息,例如写入时缓存。

  • 元数据同步也是一个问题。在 JuiceFS 上运行多个 ClickHouse 实例时,某个实例写入的某些数据可能无法被其他实例识别。修复该问题需要重启实例。

因此我们使用 JuiceFS 快照来设置主副本架构。此方法的工作方式与常规的主备份系统类似。主实例处理所有数据更新,包括同步和提取、转换和加载 (ETL) 操作。副本实例专注于查询功能。

为什么以及如何构建 ClickHouse 的主副本架构

ClickHouse 主副本架构

如何为 ClickHouse 创建副本实例

1. 创建快照

我们使用 JuiceFS 快照命令从主实例上的 ClickHouse 数据目录创建一个快照目录,并在此目录上部署一个 ClickHouse 服务。

2.暂停Kafka消费者队列

在启动 ClickHouse 实例之前,我们必须停止使用来自其他数据源的有状态内容。对我们来说,这意味着暂停 Kafka 消息队列,以避免与主实例争用 Kafka 数据。

3. 在快照目录上运行 ClickHouse

启动ClickHouse服务后,我们注入了一些元数据,向用户提供有关ClickHouse创建时间的信息。

4.删除ClickHouse数据变异

在副本实例上,我们删除了所有数据变异以提高系统性能。

5. 执行连续复制

快照仅保存创建时的状态。为了确保读取最新数据,我们会定期用副本实例替换原始实例。此方法简单易用且高效,因为每个副本实例都以两个副本和一个指向副本的指针开始。即使我们需要十分钟或更长时间,我们通常每小时运行一次以满足我们的需求。


我们的 ClickHouse 主副本架构已经稳定运行了一年多,无一失败,完成了超过 2 万次复制操作,可靠性非常高。负载隔离和数据副本的稳定性是提升性能的关键。我们成功将整体报表可用性从不到 95% 提升到了 99%,而且没有做任何应用层优化。此外,该架构支持弹性伸缩,灵活性大大提升, 让我们可以按需开发和部署新的 ClickHouse 服务,无需复杂的操作。

下一步

我们未来的计划:

  • 我们将开发一个优化的控制界面来自动化实例生命周期管理、创建操作和缓存管理。

  • 我们还计划优化写入性能,从应用层来说,由于对 Parquet 开放格式的支持非常到位,我们可以将大部分负载直接写入 ClickHouse 之外的存储系统,更加方便访问,这样就可以使用传统方式实现并行写入,从而提升写入性能。

  • 我们注意到一个新项目 chDB,它允许用户直接在 Python 环境中嵌入 ClickHouse 功能,而无需 ClickHouse 服务器。将 CHDB 与我们当前的存储解决方案相结合,我们可以实现完全无服务器的 ClickHouse。这是我们目前正在探索的方向。

路由网(www.lu-you.com)您可以查阅其它相关文章!

未经允许不得转载:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权!路由网 » 为什么以及如何构建 ClickHouse 的主副本架构