任何出现显著增长的服务最终都需要扩展。这意味着扩大基础设施(在计算、存储和网络方面),以便在基础设施上运行的应用程序可以同时为更多的人服务。以确保数据完整性的方式进行缩放是至关重要的。在开始之前,您需要了解这些限制,以确定哪种解决方案为您提供了最大的好处。在性能和可用性方面,扩展操作很容易变得昂贵和复杂。
在Contentsquare,我们决定扩大我们的集群。在ClickHouse中,缩放操作由两部分组成。您首先需要重新硬处理(添加新的碎片),然后重新平衡(将现有数据分布到所有这些碎片上)。
需要重新平衡,才能真正从规模扩张中获益。如果不重新平衡数据,新数据将分布在新拓扑中,但现有和当前数据仍存储在以前的配置中。您将不会从扩展的改进中受益,也不会在所有碎片的存储方面保留容量规划。
我们面临的问题是ClickHouse没有';当我们添加新碎片时,不会自动重新平衡集群中的数据。
尽管如此,ClickHouse附带了一些实用程序,可以帮助您重新平衡数据。根据您的数据拓扑和大小,它们在性能和可用性方面都有其局限性。
在Contentsquare,随着我们每天向ClickHouse添加的数据量的增加,我们保持100%的数据完整性而不影响生产速度是至关重要的。本文介绍了我们在构建自己的系统之前探索的所有方法。我们希望它能帮助您更好地理解权衡,并选择对您的情况有最大好处的权衡。
我们探索的第一个想法是使用卡夫卡将重新平衡数据的过程具体化。卡夫卡是我们数据管道的重要组成部分,我们已经广泛使用它。
ClickHouse可以在本机上阅读卡夫卡主题的消息。它使用Kafka表引擎和物化视图来获取消息并将其推送到ClickHouse目标表。ClickHouse还可以通过插入卡夫卡表来写入卡夫卡。这使我们能够使用卡夫卡作为基础设施工具,在两个ClickHouse集群之间重新平衡数据。
--Kafka表引擎在源集群和目标集群中创建表[src | dest]_TABLE_队列(name1[type1],name2[type2],…)ENGINE=KafkaSETTINGS kafka#u broker#u list=&39;主机名:端口号',卡夫卡主题列表=';主题1,主题2' 卡夫卡大学组(u name=#39 ;;组名',卡夫卡形式=';数据格式';卡夫卡(kafka)_max_block_size=N;——在目标集群中创建MV创建物化视图dest_table_queue_MV到dest_table AS SELECT*FROM dest_table_queue;——将数据从源表传输到目标表插入src_table_队列从src_table选择*;
每个卡夫卡主题都将包含“准备好”插入重新平衡的目标集群的数据。
--n是每个src_shard的目标集群中的碎片数:对于每个src_表:对于每个日期分区:对于每个dest_shard(i:0..n-1):插入到src_表_队列(主题i)从src_表中选择*,其中日期=日期分区和碎片键%n=i——这部分对于每个dest_shard是完全自动的:对于每个dest_表:是使用物化视图将定义的dest_table_队列附加到kakfa主题
卡夫卡的这个解决方案很有希望。因为它被外部化到卡夫卡,我们可以自动调整摄取流量和资源。但是,我们决定不使用它。至少还没有。我们认为ClickHouse中的卡夫卡桌面引擎不够成熟。具体来说,它缺少很多日志功能,我们不想在生产中运行它,而不想在需要时对其进行密切监视和调试。
clickhouse copier是标准clickhouse server分发版的一部分,它将数据从一个集群中的表复制到另一个(或同一个)集群中的表。Zookeeper用于同步副本和跟踪更改。
场景#1:我们考虑构建一个全新的集群,然后使用clickhouse copier将数据从源集群迁移到目标集群。
该解决方案运行良好,但由于它直接在生产集群上运行(在迁移期间),因此会对我们的生产性能产生影响。我们认为这太冒险了,所以我们寻找了一个替代方案。
场景#2:然后我们考虑使用clickhouse copier,在同一集群中创建一个包含更多碎片的新数据库。我们会将数据从源数据库复制到目标数据库。这被称为原地重装,因为我们待在同一个集群中。
这种就地重装解决方案功能强大且经济高效:在迁移过程中使用单个集群。然而,我们没有使用它,因为它将在我们的生产服务器上运行。然而,它并没有被完全忽略,因为我们确实在内置解决方案中使用了它。
我们尝试的所有解决方案都有缺点。我们想要一些简单的理由,这样就可以很容易地实现自动化和监控。它还必须具有可扩展性(即使有大量数据也应该快速运行)和健壮性(因此可以随时停止和重新启动)。最后,我们还需要它具有成本效益。
在我描述我们的解决方案之前,重要的是要介绍一个我们每天在Contentsquare中使用的重要工具:clickhouse备份/恢复机制,它可以通过云存储支持轻松保存和恢复我们的日常数据。
我们想出的方法使用clickhouse复印机,以及我们的日常备份。我们称之为ClickHouse炊具,因为它就像一个锅,我们把配料(我们的备份)放在里面,让它们煮一段时间,然后我们从中提取新的、重新平衡的备份。我们在探索上述所有想法的基础上得出了这一结论。
让';我们来煮吧!下面是将ClickHouse集群从n个碎片扩展到m个碎片的“秘诀”
ClickHouse resharding-cooker:创建ClickHouse集群(m个碎片),其中包含两个空数据库:源数据库安装在n个碎片上,默认数据库安装在m个碎片上(n<;m)
对于表数据的每个分区#键#步骤1[点击房屋客户端]删除/截断源#数据库和默认数据库中的数据#步骤2[点击房屋备份]将数据从外部#存储恢复到源#数据库#步骤3[点击房屋复印机]将数据从源#数据库迁移到默认数据库#步骤4[点击房屋客户端]检查源#默认(确保源数据库中的所有数据都已完全迁移到默认数据库)#第5步[点击房屋备份]将默认数据备份到外部存储
完成数据库所有日期的上一个循环操作(新拓扑中的每日备份就绪)后,需要:
这个解决方案是完全可扩展的:您可以部署几个集群(每个集群有m个实例),并在一个循环中执行上述日常操作。
探索这么多不同的想法是值得的,因为我们最终找到了一个我们满意的想法。它非常简单,可以自动化并水平缩放。正因为如此,它的成本也不高,我们可以根据需要调整它的速度。
感谢令人惊叹的DT团队,尤其是Ryad每天都大力支持这一反思,感谢所有团队的支持:Vincent、Nir和Aryeh。谢谢蒂姆帮我写这篇文章。