专业的编程技术博客社区

网站首页 > 博客文章 正文

朴朴 APM 用 ClickHouse 替换 ElasticSearch 存储实践

baijin 2024-10-17 07:47:49 博客文章 7 ℃ 0 评论

一、背景

在当今数字化时代,伴随着朴朴业务的快速增长,朴朴全面拥抱微服务、云原生和容器技术,同时,在云原生可观测性方面,朴朴几乎所有的微服务都接入了朴朴 APM 来帮助开发者快速定位、分析和诊断问题。然而,随着业务逻辑和服务接入数量的不断增加,上报给 APM 的数据量也急剧增加,为了缓解数据写入延迟增加以及业务反馈经常出现慢查或者数据查不出来等问题,运维不得不提升 ElasticSearch 服务器的配置或者增加机器的数量,导致运营成本越来越高。

为了积极响应公司在降低成本和提高效益方面的倡导,朴朴平台技术团队成员尝试引入业内公认优秀的在线分析处理(OLAP)列式数据库管理系统 ClickHouse 来解决上述困扰。

二、选择 ClickHouse 的原因

APM 系统对大量数据写入的实时性要求很高,且希望数据的存储成本尽可能低,要求在单表宽表下大数据集的数据实时分析性能尽可能高。ClickHouse 是一个开源的列式数据库管理系统,相比于 ElasticSearch,在同样的成本控制下,能够做到:

  1. 更高效的写入性能:ClickHouse 对于大数据集的数据量写入性能非常高。我们通过测验发现,在控制同样的成本下,ElasticSearch 作为存储,每秒写入 60 万 Span,就会出现大量写入超时;而将 ClickHouse 作为存储,能够稳定支持每秒 100 万 Span 的数据量写入。
  2. 存储压缩效率更高:ClickHouse 对硬件资源的使用效率更高,且压缩率比 ElasticSearch 高,在开启 GZIP 压缩模式下,压缩比可达到 20%。在存储 100 亿的 Span 下,ElasticSearch 需要 4.5T 的存储空间,而 ClickHouse 仅需 2.8T,比 ElasticSearch 节省 38% 存储空间。
  3. 支持数据预聚合:在 APM 中关心的 Metrics 指标,Metrics 希望能够支持到 7 天的维度,我们可以使用 ClickHouse 提供的物化视图,高效的实现数据的预聚合,而数据的预聚合则是 ElasticSearch 不支持的。

基于此,我们选择将 ClickHouse 作为朴朴 APM 的存储,不仅可以极大的降低运营成本,同时用户在数据延迟以及查询性能方面的体验都得到显著提升。

三、ClickHouse 存储实践

我们团队将 ElasticSearch 存储替换 ClickHouse 存储的实践过程中,遇到了很多的问题,并且都一一解决,同时也沉淀了一些比较好的经验。

3.1 应用层读写调优

3.1.1 零停机无缝切数据源为 CK

朴朴作为一个即时生鲜电商平台,在 C 端提供了 7×24 小时的服务能力,而朴朴 APM 作为业务线上稳定性的一个分析和定位问题的工具,为了做到零停机无缝切换数据源,我们采取了如下措施:

  1. 数据双写:同时支持旧的数据源 ElasticSearch 和新的数据源 ClickHouse 的写入,并且持续 7 天。
  2. 对账程序:在进行数据双写的过程中,为了确保 ElasticSearch 数据和 ClickHouse 数据的准确性,我们单独起了一个进程进行数据对账,其内容包括:保证抽样时间区间的总条数一致,抽样时间内的一定数据量的数据两边一致。
  3. 切换 ClickHouse :在完成持续 7 天的双写数据后,可以将数据源切换为 ClickHouse,如果线上用户反馈 ClickHouse 有问题,我们可以立即将数据源切换为 ElasticSearch,这个过程也持续至少 7 天。
  4. 下线 ElasticSearch:在经过 2 个礼拜的程序以及用户的使用没有反馈问题,便可以下线掉 ElasticSearch。

3.1.2 优化写入 ClickHouse 速率

我们知道 ClickHouse 支持大量的数据写入,但是需要合理的写入以及合理的 ClickHouse 参数配置才能支持大批量的写入,否则 ClickHouse 的写入速率会大打折扣,因此,我们对数据写入 ClickHouse 的熟虑进行调优,具体包括:

  1. 选择 TabSeparated 语句插入:为了支持大批量的数据插入,我们选择 TabSeparated 语句插入方式,而不是 VALUES。我们发现当每批的数据量为 25w 时,使用 VALUES 插入需要 15 秒,而使用 TabSeparated 仅需 4 秒即可, 因此我们选择了效率更高的 TabSeparated。
  2. 提高并发插入 ClickHouse 效率:通常业务上报到 APM 的瞬时数据会非常大,为了尽可能降低数据入库延迟,后端服务除了优化每批次写入的的数据量,我们还引入了内存队列来提高并发写入的效率,内存队列工作原理见图 1。

引入内存队列,可以实现业务自定义有限的消费线程都能够快速消费内存队列中的数据,极大的提升数据的插入 ClickHouse 效率。目前,通过引入内存队列,可实现一台 4 核 8 G 的机器,5 秒内实现 25 万的数据写入。

为了保证单个 TraceId 的数据都写入同一个数据分区,我们在 TraceId 中加入创建时间戳,当不同时刻的 Span 到来后,我们可以根据 Span 上的 TraceId 找到对应的时间分区并写入。

3.1.3 优化查询分析 ClickHouse

使用 APM 的用户,除了查看全链追踪的甘特图,还想要查看指定组件的聚合分析情况,比如:查看一段时间的 MySQL 指纹的调用次数、平均 QPS、平均耗时、p90、p95、p99 等指标。如果想支持这类功能,通过写 ClickHouse 的聚合函数来实时查询的话,往往耗时特别久,仅半个小时的数据量的聚合,可能都需要 30 秒以上。为了解决这类问题,我们引入了 ClickHouse 的物化视图,ClickHouse 中的物化视图是一种特殊类型的视图,用于存储查询结果的预计算数据。这些视图在创建时就执行相关的查询,并将结果存储在内部表中。当基础数据发生变化时,物化视图中的数据就会自动更新,从而使得访问这些数据的访问更加高效,如图 2 所示。

通过引入物化视图,在 MySQL 分析的指标聚合查询性能方面,查询最近 30 分钟只需 200ms,最近 6 个小时只需 2 秒,而最近 24 小时只需 5 秒,并且支持用户筛选查询和指标的升降排序。图 3 中展示了朴朴 APM 的 MySQL 分析的示意图。

3.2 线上部署调优

3.2.1 ClickHouse 部署方式选型

  • ClickHouse 部署架构:线上 ClickHouse 集群部署架构图如图 4 所示。

在图 4 中,可以看到,线上的 ClickHouse 集群架构中,包含了数据节点和协调节点,同时,数据存储进行冷热分离,我们通过后台数据统计分析得到,99% 以上的用户使用我们 APM 平台,最关心的是最近 8 小时的数。因此,对于 8 小时内的热数据,我们直接存储到具备高性能云磁盘的 EBS,而超过 8 个小时的数据,使用存储成本更低但是性能较弱的 S3 进行存储,总共存储 7 天的数据,做到用户体验、性能和硬件成本三者的平衡。

  • ClickHouse 冗余字段的设置:在实际的 APM 查询过程中,我们发现业务经常需要自定义上报数据,因此,我们在 ClickHouse 表中设置了一个冗余字段,用来将用户上报的字段 JSON 化后并存储到这个字段,从而满足用户通过其他字段的查询能关联出该字段的信息。

3.2.2 线上 ClickHouse 集群部署问题与解决方法

问题一:一开始我们在线上部署 5 台 32 核 256G ClickHouse 集群配置,但是消费能力只有每秒 55w 个 Segment,这远远达不到我们需要消费 100w 个 Segment 的目标。

解决方法:添加 3 台 48 核 384G 的机器作为协调节点,通过协调节点来分发写操作,同时,设置线程参数(parts 从 300 改为 10,000,max_thread 数从 1 改为 16,线程池从 16 改为 64)。

问题二:解决了问题一,消费能力没有我们预期提升的明显,只提升达到每秒 60w 个 Segment。我们通过 ClickHouse 集群的日志发现,parts 队列显示过多,即操作文件数过多。但是,数据节点 CPU 使用率不高,磁盘和网络 IO 都还未到瓶颈。在排除了硬件的因素后,我们观察到业务写入存在跨天写入对的情况,对于超过 8 小时的数据我们会写入 S3 文件中。

解决方法:通过对上报数据的特点进行分析,发现上报的 Segment 中 包含消费 Kafka 的延迟队列中数据会写入较多的 part,因此,我们将生产和消费的队列进行分离(即:生产的 Span 和消费的 Span 都有各自独立的 TraceId,从而在消费端的 TraceId 中的时间戳是最新的),除此之外,我们也过滤了一些不合理的数据。通过上述措施,操作的 parts 队列过多的情况已被解决,数据处理的速率达到 80w 个 Segment。

问题三:我们发现 ClickHouse 中 CPU 与内存的使用率较低,但是网络带宽却快达到瓶颈。

解决方法:降低协调节点的机器配置 (3 台 48 核 384G => 3 台 32 核 64G ),并且增加数据节点 (5 台 32 核 256G CK => 7 台 32 核 64G)。通过上述调优后,在不提升整体成本情况下,峰值消费速率从每秒 80w Segment 增加到 100w segment,而数据节点 CPU 平均使用率仅为 50%,这个性能已经满足我们线上的要求。

3.3 线上 ElasticSearch 集群与 ClickHouse 集群成本与性能对比

通过上述的优化之后,我们对比了优化前的 ElasticSearch 集群和优化后的 ClickHouse 集群的成本和写入的性能。

  • 成本对比
  • 性能对比

在 ElasticSearch 集群成本比 ClickHouse 成本还高 2.1W/ 月情况下,我们对比了两者的写入性能。

即:写入速率提升了接近 1 倍,但是单位成本却更低了。

四、总结与展望

朴朴 APM 将存储数据源从 ElasticSearch 转为 ClickHouse 的成功实践,不仅提升了写入速率,解决了数据上报入库延迟问题,也极大降低了机器成本。未来,我们打算从数据采样角度(包括:头部采样和尾部采样等)来进一步提升 APM 的性能以及降低运营成本。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表