0
182
0
0
首页/专栏/ 客户案例/ 查看内容

Trip.com 如何从 Elasticsearch 迁移到 ClickHouse 并构建了 50PB 的日志解决方案 ...

 admin   发表于  2024-10-15 15:09
专栏 客户案例


在 Trip.com,我们为用户提供广泛的数字产品,包括酒店和机票预订、景点、旅游套餐、商务旅行管理和与旅行相关的内容。正如你所猜的那样,我们需要一个可扩展、可靠且快速的日志平台,这对于我们的运营至关重要。

在我们开始之前,为了激起你的好奇心,让我展示一些我们在 ClickHouse 上构建的平台的关键数据:

这篇博客文章将讲述我们日志平台的故事,包括为什么我们最初构建它、我们使用的技术,以及我们在 ClickHouse 上利用 SharedMergeTree 等功能对其未来的规划。

以下是我们在旅程中将讨论的不同主题:

  • 我们如何构建一个集中的日志平台

  • 我们如何扩展日志平台并从 Elasticsearch 迁移到 ClickHouse

  • 我们如何改进我们的运营体验

  • 我们如何在阿里云上测试 ClickHouse Cloud

为了简化,让我们把这些内容放在一个时间线上:


构建一个集中的日志平台

每个伟大的故事都始于一个巨大的挑战。在我们的案例中,这个项目起源于 2012 年之前,因为 Trip.com 没有统一或集中的日志平台。每个团队和业务单元(BU)各自收集和管理自己的日志,这带来了许多不同的问题:

  • 需要大量人力来开发、维护和操作所有这些环境,不可避免地导致了大量重复工作。

  • 数据治理和控制变得复杂。

  • 公司内部没有统一的标准。

基于这些问题,我们意识到需要构建一个集中和统一的日志平台。

2012 年,我们推出了第一个平台。它建立在 Elasticsearch 之上,开始定义 ETL、存储、日志访问和查询的标准。

尽管我们不再使用 Elasticsearch 作为我们的日志平台,但值得探讨我们当初是如何实现这个解决方案的。它驱动了我们后来的许多工作,这是我们在后续迁移到 ClickHouse 时必须考虑的。


存储

我们的 Elasticsearch 集群主要由主控节点、协调节点和数据节点组成。


主控节点

每个 Elasticsearch 集群至少由三个主控节点组成。其中一个将被选为主节点,负责维护集群状态。集群状态是包含有关各种索引、分片、副本等信息的元数据。任何修改集群状态的操作都会由主控节点执行。


数据节点

数据节点存储数据并用于执行增删改查(CRUD)操作。它们可以分为多个层次:热层、暖层等。


协调节点

这种类型的节点没有其他功能(如主控、数据、摄取、转换等),并通过考虑集群状态作为智能负载均衡器。如果协调节点接收到带有 CRUD 操作的查询,它会被发送到数据节点。相反,如果接收到添加或删除索引的查询,它会被发送到主控节点。


可视化

基于 Elasticsearch 我们使用 Kibana 作为可视化层。你可以在下方看到一个可视化示例:


日志插入

我们的用户有两种方式将日志发送到平台:通过 Kafka 和通过代理。


通过 Kafka

第一种方法是使用公司的框架 TripLog 将数据导入 Kafka 消息代理(使用 Hermes)。

private static final Logger log = LoggerFactory.getLogger(Demo.class);
public void demo (){ TagMarker marker = TagMarkerBuilder.newBuilder().scenario("demo").addTag("tagA", "valueA").addTag("tagA", "valueA").build(); log.info(marker, "Hello World!");}

这为用户提供了一个轻松将日志发送到平台的框架。


通过代理工具

另一种方法是使用代理工具,如 Filebeat、Logstash、Logagent 或定制客户端,直接写入 Kafka。你可以在下面看到一个 Filebeat 配置示例:

filebeat.config.inputs:  enabled: true  path: "/path/to/your/filebeat/config"filebeat.inputs:  - type: log    enabled: true    paths:      - /var/log/history.log      - /var/log/auth.log      - /var/log/secure      - /var/log/messages    harvester_buffer_size: 102400    max_bytes: 100000    tail_files: true    fields:      type: os    ignore_older: 30m    close_inactive: 2m    close_timeout: 40m    close_removed: true    clean_removed: trueoutput.kafka:  hosts: ["kafka_broker1", "kafka_broker2"]  topic: "logs-%{[fields.type]}"  required_acks: 0  compression: none  max_message_bytes: 1000000processors:  - rename:      when:        equals:          source: "message"          target: "log_message"


ETL

无论用户选择哪种方法,数据最终都会进入 Kafka,然后可以通过 gohangout 管道传输到 Elasticsearch。

Gohangout 是由 trip.com 开发和维护的开源应用程序,作为 Logstash 的替代方案。它旨在从 Kafka 获取数据,执行 ETL 操作,最终将数据输出到各种存储介质中,如 ClickHouse 和 Elasticsearch。Filter 模块中的数据处理包括常见的数据清洗功能,如 JSON 处理、Grok 模式匹配和时间转换(如下所示)。在下面的示例中,GoHangout 使用正则表达式匹配从 Message 字段提取 num 数据,并将其存储为单独的字段。


达到瓶颈

许多人使用 Elasticsearch 进行可观测性,在处理较小数据量时表现出色。它提供易于使用的软件、无模式体验、广泛的功能和流行的 Kibana 界面。然而,当我们这种大规模部署时,它存在一些众所周知的挑战。

当我们在 Elasticsearch 中存储 4PB 数据时,我们开始面临集群稳定性的多个问题:

  1. 集群上的高负载导致许多请求被拒绝、写入延迟和查询缓慢

  2. 每日将 200 TB 数据从热节点迁移到冷节点导致显著的性能下降

  3. 分片分配是一个挑战,导致一些节点过载

  4. 大查询导致内存不足 (OOM) 异常

关于集群性能

  1. 查询速度受到整体集群状态的影响

  2. 由于摄取过程中高 CPU 使用率,我们难以提高插入吞吐量

最后,关于成本

  1. 数据量大、数据结构复杂且缺乏压缩导致需要大量存储空间

  2. 较弱的压缩率对业务产生影响,迫使我们缩短保留期

  3. Elasticsearch 的 JVM 和内存限制导致更高的 TCO(总体拥有成本)

所以,在意识到以上所有问题后,我们寻找替代方案,于是 ClickHouse 出现了!


ClickHouse vs Elasticsearch

Elasticsearch 和 ClickHouse 之间存在一些基本差异;让我们来看看它们。


查询 DSL vs SQL

Elasticsearch 依赖于一种特定的查询语言,称为查询 DSL(领域专用语言)。尽管现在有更多的选项,但这仍然是主要语法。另一方面,ClickHouse 依赖于 SQL,这是一种非常主流且非常用户友好的语言,并且与许多不同的集成和 BI 工具兼容。

内部机制

Elasticsearch 和 ClickHouse 在内部行为上有一些相似之处,Elasticsearch 生成段,而 ClickHouse 写入部分。虽然两者都会随着时间的推移异步合并,创建更大的部分和段,但 ClickHouse 通过列式模型区分自己,其中数据通过 ORDER BY 键排序。这允许构建稀疏索引,从而实现快速过滤和高效的存储使用,因为压缩率很高。你可以在这篇出色的指南中了解更多关于此索引机制的信息。

索引 vs 表

Elasticsearch 中的数据存储在索引中,并分解为分片。这些需要保持在相对较小的大小范围内(在我们使用时,推荐的是大约 50GB 的分片)。相比之下,ClickHouse 的数据存储在显著更大的表中(在 TB 范围内,如果不受磁盘大小限制的话,还可以更大)。除此之外,ClickHouse 允许你创建分区键,这会将数据物理上分隔到不同的文件夹中。如果需要,可以高效地操作这些分区。

总体而言,我们对 ClickHouse 的功能和特性印象深刻:它的列式存储、向量化查询执行、高压缩率和高插入吞吐量。这些满足了我们对日志解决方案在性能、稳定性和成本效益方面的需求。因此,我们决定使用 ClickHouse 来替换我们的存储和查询层。

下一个挑战是如何无缝地从一种存储迁移到另一种存储而不中断服务。


日志平台 2.0:迁移到 ClickHouse

在决定迁移到 ClickHouse 之后,我们确定了需要完成的几个任务:


表设计

这是我们当时确定的初始表设计(请记住,那是几年前的事了,当时 ClickHouse 还没有现在的所有数据类型,例如 maps):

CREATE TABLE log.example(  `timestamp` DateTime64(9) CODEC(ZSTD(1)),  `_log_increment_id` Int64 CODEC(ZSTD(1)),  `host_ip` LowCardinality(String) CODEC(ZSTD(1)),  `host_name` LowCardinality(String) CODEC(ZSTD(1)),  `log_level` LowCardinality(String) CODEC(ZSTD(1)),  `message` String CODEC(ZSTD(1)),  `message_prefix` String MATERIALIZED substring(message, 1, 128) CODEC(ZSTD(1)),  `_tag_keys` Array(LowCardinality(String)) CODEC(ZSTD(1)),  `_tag_vals` Array(String) CODEC(ZSTD(1)),  `log_type` LowCardinality(String) CODEC(ZSTD(1)),   ...   INDEX idx_message_prefix message_prefix TYPE tokenbf_v1(8192, 2, 0) GRANULARITY 16,   ...)ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/example', '{replica}')PARTITION BY toYYYYMMDD(timestamp)ORDER BY (log_level, timestamp, host_ip, host_name)TTL toDateTime(timestamp) + toIntervalHour(168)
  • 我们使用双数组方法来存储动态变化的标签(我们计划未来使用 maps),即有两个数组分别存储键和值。

  • 按天分区以便于数据操作。对于我们的数据量,每日分区是合适的,但大多数情况下,较高的粒度如每月或每周更好。

  • 根据你在查询中使用的过滤器,你可能希望有一个与上表不同的 ORDER BY 键。上面的键是针对使用 log_level时间的查询进行优化的。例如,如果你的查询不使用 log_level,那么在键中只包含时间列是有意义的。

  • Tokenbf_v1 布隆过滤器用于优化关键词查询和模糊查询。

  • _log_increment_id 列包含一个全局唯一的增量 ID,以实现高效的滚动分页和精确的数据定位。

  • ZSTD 数据压缩方法,节省了超过 40% 的存储成本。


集群设置

鉴于我们在 Elasticsearch 上的历史设置和经验,我们决定复制一个相似的架构。我们的 ClickHouse-Keeper 实例充当主节点(类似于 Elasticsearch)。部署了多查询节点,这些节点不存储数据,而是持有指向 ClickHouse 服务器的分布式表。这些服务器托管数据节点,存储和写入数据。以下显示了我们最终的架构:


数据可视化

在迁移到 ClickHouse 后,我们希望为用户提供无缝体验。为此,我们需要确保所有的可视化和仪表板都能使用 ClickHouse。这带来了一个挑战,因为 Kibana 是一个最初在 Elasticsearch 上开发的工具,不支持其他存储引擎。因此,我们必须对其进行自定义,以确保它能够与 ClickHouse 接口。这需要我们在 Kibana 中创建新的数据面板,可以与 ClickHouse 一起使用:chhistogramchhitschpercentileschrangeschstatschtablechterms chuniq

然后,我们创建了脚本,将 95% 的现有 Kibana 仪表板迁移到使用 ClickHouse。最后,我们增强了 Kibana,使用户可以编写 SQL 查询。


Triplog

我们的日志管道是自助服务,允许用户发送日志。这些用户需要能够创建索引并定义所有权、权限和 TTL 策略。因此,我们创建了一个名为 Triplog 的平台,为用户提供管理表、用户和角色的接口,监控其数据流,并创建警报。


回顾

现在一切都已迁移完毕,是时候看看我们平台的新性能了!尽管我们自动化了 95% 的迁移并实现了无缝过渡,但回顾我们的成功指标并查看新平台的表现仍然很重要。两个最重要的指标是查询性能和总体拥有成本(TCO)。


TCO

我们最初成本的一个重要组成部分是存储。让我们比较一下 Elasticsearch 和 ClickHouse 在相同数据样本上的存储情况:

存储空间节省超过 50%,使现有的 Elasticsearch 服务器能够支持 4 倍的数据量增加。


查询性能

查询速度比 Elasticsearch 快 4 到 30 倍,P90 小于 300 毫秒,P99 小于 1.5 秒。


日志 3.0:改进基于 ClickHouse 的平台

路过

雷人

握手

鲜花

鸡蛋

版权声明:本文为 clickhouse 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
返回顶部