饭宝 发表于 2023-3-8 13:02:23

稳撑30+PB数据,携程10年日志系统治理演进之路

https://img2023.cnblogs.com/blog/27422/202303/27422-20230307195635364-63423988.jpg
本文将从以下五部分切入,讲述日志系统的演进之路:携程日志的背景和现状、如何搭建一套日志系统、从 ElasticSearch 到 Clickhouse 存储演进、日志3.0重构及未来计划。
 
一、日志背景及现状
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFjuhiaXOzXM10ZzEazMLVuBurcPaEp1DyrUiat9xFU5v6YwTwxh8Qy2FQ/640?wx_fmt=png
图1
 
2012年以前,携程的各个部门日志自行收集治理(如图1)。这样的方式缺乏统一标准,不便治理管控,也更加消耗人力和物力。
 
从2012年开始,携程技术中心推出基于 ElasticSearch 的日志系统,统一了日志的接入、ETL、存储和查询标准。随着业务量的增长,数据量膨胀到 4PB 级别,给原来的 ElasticSearch 存储方案带来不少挑战,如 OOM、数据延迟及负载不均等。此外,随着集群规模的扩大,成本问题日趋敏感,如何节省成本也成为一个新的难题。
 
2020年初,我们提出用 Clickhouse 作为主要存储引擎来替换 ElasticSearch 的方案,该方案极大地解决了 ElasticSearch 集群遇到的性能问题,并且将成本节省为原来的48%。2021年底,日志平台已经累积了20+PB 的数据量,集群也达到了数十个规模(如图2)。
 
2022年开始,我们提出日志统一战略,将公司的 CLOG 及 UBT 业务统一到这套日志系统,预期数据规模将达到 30+PB。同时,经过两年多的大规模应用,日志集群累积了各种各样的运维难题,如集群数量激增、数据迁移不便及表变更异常等。因此,日志3.0应运而生。该方案落地了类分库分表设计、Clickhouse on Kubernetes、统一查询治理层等,聚焦解决了架构和运维上的难题,并实现了携程 CLOG 与 ESLOG 日志平台统一。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFL4ohPbFD3E8Swd4HsLUxswkIAe4gE2liccjpxomlNmPAmQQuNRqsTQw/640?wx_fmt=png
图2
 
二、如何搭建日志系统
 
2.1 架构图
 
从架构图来看(如图3),整个日志系统可以分为:数据接入、数据 ETL、数据存储、数据查询展示、元数据管理系统和集群管理系统。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFp1WfZ1aIERWicF1ctCDeFxMk0styXGKhDoXibtAzqgnbviasBKibMEVSFA/640?wx_fmt=png
图3
 
2.2 数据接入
 
数据接入主要有两种方式:
 
第一种是使用公司框架 TripLog 接入到消息中间件 Kafka(Hermes协议)(如图4)。
 
https://img2023.cnblogs.com/blog/27422/202303/27422-20230307195655807-263531000.png
图4
 
第二种是用户使用 Filebeat/Logagent/Logstash 或者写程序自行上报数据到 Kafka(如图5),再通过 GoHangout 写入到存储引擎中。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFCibjKG23ybDKaqKF7rTq0z21tlhaYpDSl2qNAf2z9ChOWic9BQDicC9Mg/640?wx_fmt=png
图5
 
2.3  数据传输ETL(GoHangout)
 
GoHangout 是仿照 Logstash 做的一个开源应用(Github链接),用于把数据从 Kafka 消费并进行 ETL,最终输出到不同的存储介质(Clickhouse、ElasticSearch)。其中数据处理 Filter 模块包含了常见的 Json 处理、Grok 正则匹配和时间转换等一系列的数据清理功能(如图6)。GoHangout 会将数据 Message 字段中的 num 数据用正则匹配的方式提取成单独字段。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFODmOOflGftgE7j8ZeOcqib3ib72A4KC2gzbgdvd8ObSsfAQIWJ7Xzypw/640?wx_fmt=png
图6
 
2.4 ElasticSearch 数据存储
 
早期2012年第一版,我们使用 ElasticSearch 作为存储引擎。ElasticSearch 存储主要由 Master Node、Coordinator Node、Data Node 组成(如图7)。Master 节点主要负责创建或删除索引,跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关的节点;Coordinator 节点主要用于处理请求,负责路由请求到正确的节点,如创建索引的请求需要路由到 Master 节点;Data 节点主要用于存储大量的索引数据,并进行增删改查,一般对机器的配置要求比较高。
 
https://img2023.cnblogs.com/blog/27422/202303/27422-20230307195655736-2147128043.png
图7
 
2.5  数据展示
 
数据展示方面我们使用了 Elastic Stack 家族的 Kibana(如图8)。Kibana 是一款适合于 ElasticSearch 的数据可视化和管理工具,提供实时的直方图、线形图、饼状图和表格等,极大地方便日志数据的展示。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFjpxYgPJQbNlCpF6K5tv9kaibictIHQTib861t2P1NTcg114L48C3xDKMQ/640?wx_fmt=png
图8
 
2.6  表元数据管理平台
 
表元数据管理平台是用户接入日志系统的入口,我们将每个 Index/ Table 都定义为一个Scenario(如图9)。我们通过平台配置并管理 Scenario 的一些基础信息,如:TTL、归属、权限、ETL 规则和监控日志等。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFXLARlDboyCLxZ2L4QkZT9NZbB5LiboBriamEPV152P3hPkvB0ON6SdJQ/640?wx_fmt=png
图9
 
三、  从Elasticsearch到Clickhouse
 
我们将会从背景、Clickhouse 简介、ElasticSearch 对比和解决方案四方面介绍日志从 ElasticSearch 到 Clickhouse 的演进过程。2020年初,随着业务量的增长,给 ElasticSearch 集群带来了不少难题,主要体现在稳定性、性能和成本三个方面。
 
(1)稳定性上:
 
ElasticSearch 集群负载高,导致较多的请求 Reject、写入延迟和慢查询。
每天 200TB 的数据从热节点搬迁到冷节点,也有不少的性能损耗。
节点间负载不均衡,部分节点单负载过高,影响集群稳定性。
大查询导致 ElasticSearch 节点 OOM。
 
(2)性能上:
 
ElasticSearch的吞吐量也达到瓶颈。
查询速度受到整体集群的负载影响。
 
(3)成本上:
 
倒排索引导致数据压缩率不高。
大文本场景性价比低,无法保存长时间数据。
 
3.1 Clickhouse 简介与 Elasticsearch 对比
 
Clickhouse 是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。Yandex 在2016年开源,使用 C++ 语法开发,是一款PB级别的交互式分析数据库。包含了以下主要特效:列式存储、Vector、Code Generation、分布式、DBMS、实时OLAP、高压缩率、高吞吐、丰富的分析函数和 Shared Nothin g架构等。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFczg3rianibibKlMNh1SN8W1j8AfNayRn6qNs2ibiaM5xEl7KB3jImqY2b0Q/640?wx_fmt=png
图10
 
Clickhouse采用的是 SQL 的交互方式,非常方便上手。接下来,我们将简单介绍一下 Clickhouse 的类 LSM、排序键、分区键特效,了解 Clickhouse 的主要原理。
 
首先,用户每批写入的数据会根据其排序键进行排序,并写入一个新的文件夹(如201905_1_1_0),我们称为 Part C0(如图10)。随后,Clickhouse 会定期在后台将这些 Part 通过归并排序的方式进行合并排序,使得最终数据生成一个个数据顺序且空间占用较大的 Part。这样的方式从磁盘读写层面上看,能充分地把原先磁盘的随机读写巧妙地转化为顺序读写,大大提升系统的吞吐量和查询效率,同时列式存储+顺序数据的存储方式也为数据压缩率提供了便利。201905_1_1_0与201905_3_3_0合并为201905_1_3_1就是一个经典的例子。
 
另外,Clickhouse 会根据分区键(如按月分区)对数据进行按月分区。05、06月的数据被分为了不同的文件夹,方便快速索引和管理数据。
 
https://img2023.cnblogs.com/blog/27422/202303/27422-20230307195656018-201368498.png
图11
 
我们看中了 Clickhouse 的列式存储、向量化、高压缩率和高吞吐等特效(如图11),很好地满足了我们当下日志集群对性能稳定性和成本的诉求。于是,我们决定用Clickhouse来替代原本 ElasticSearch 存储引擎的位置。
 
3.2 解决方案
 
有了存储引擎后,我们需要实现对用户无感知的存储迁移。这主要涉及了以下的工作内容(如图12):自动化建表、GoHangout 修改、Clickhouse 架构设计部署和 Kibana 改造。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktF7ibWBZHL5CMlcpXQPCT2Bicz5grmRh3MW4bBF1icgbd4Rdtn29RmHJeZA/640?wx_fmt=png
图12
 
(1)库表设计
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFGejx8XGibn6ZkcboFaeyc1E28QzpcVcgjTpbauFicjkiabLj4GpnI0hJA/640?wx_fmt=png
图13
 
我们对ck在日志场景落地做了很多细节的优化(如图13),主要体现在库表设计:
 
我们采用双 list 的方式来存储动态变化的 tags(当然最新的版本22.8,也可以用map和新特性的 json 方式)。
按天分区和时间排序,用于快速定位日志数据。
Tokenbf_v1 布隆过滤用于优化 term 查询、模糊查询。
_log_increment_id 全局唯一递增 id,用于滚动翻页和明细数据定位。
ZSTD 的数据压缩方式,节省了40%以上的存储成本。
 
(2)Clickhouse 存储设计
 
Clickhouse 集群主要由查询集群、多个数据集群和 Zookeeper 集群组成(如图14)。查询集群由相互独立的节点组成,节点不存储数据是无状态的。数据集群则由Shard组成,每个 Shard 又涵盖了多个副本 Replica。副本之间是主主的关系(不同于常见的主从关系),两个副本都可以用于数据写入,互相同步数据。而副本之间的元数据一致性则有 Zookeeper 集群负责管理。
 
 
https://img2023.cnblogs.com/blog/27422/202303/27422-20230307195655936-87917045.png
图14
 
(3)数据展示
 
为了实现用户无感知的存储切换,我们专门实现了 Kibana 对 Clickhouse 数据源的适配并开发了不同的数据 panel(如图15),包括:chhistogram、chhits、chpercentiles、chranges、chstats、chtable、chterms 和 chuniq。通过 Dashboard 脚本批量生产替代的方式,我们快速地实现了原先 ElasticSearch 的 Dashboard 的迁移,其自动化程度达到95%。同时,我们也支持了使用 Grafana 的方式直接配置 SQL 来生成日志看板。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFibt8OOriaEMBxUPBCw2amHpEebrvo76093ThQUqOEuElLhmZic8I4icR1g/640?wx_fmt=png
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFy2WtpEGjbQbtXRyVdnQqMboAHL8nCdeUFIR0mpE7icIvVyS7JlkF8nA/640?wx_fmt=png
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFq7UDcvPoWgnF7Zib453CPOxkTCz16ibQnjkWRVdxOQSXuDvN4mZoxBxA/640?wx_fmt=png
图15
 
(4)集群管理平台
 
为了更好地管理 Clickhouse 集群,我们也做了一整套界面化的 Clickhouse 运维管理平台。该平台覆盖了日常的 shard 管理、节点生成、绑定/解绑、权重修改、DDL 管理和监控告警等治理工具(如图16)。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFZUe6qz9JX6ZHAibKWqrbIV0V6r2r5fOdT7nIJBOxRDfniazRQLFtWlzg/640?wx_fmt=png
图16
 
3.3 成果
 
迁移过程自动化程度超过95%,基本实现对用户透明。
存储空间节约50+%(如图17),用原有ElasticSearch的服务器支撑了4倍业务量的增长。
 
查询速度比ElasticSearch快4~30倍,查询P90小于300ms,P99小于1.5s。
  
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFcwUULpcrqXicpaBOSvdibjnUIrVpHqO9Ljw5MW2AZMZtBH16WXbvO8lA/640?wx_fmt=png
图17
 
四、日志3.0构建
 
时间来到2022年,公司日志规模再进一步增加到 20+PB。同时,我们提出日志统一战略,将公司的 CLOG 及 UBT 业务统一到这套日志系统,预期数据规模将达到 30+PB。另外,经过两年多的大规模应用,日志系统也面临了各种各样的运维难题。
 
(1)  性能与功能痛点
 
单集群规模太大,Zookeeper 性能达到瓶颈,导致 DDL 超时异常。
当表数据规模较大时,删除字段,容易超时导致元数据不一致。
用户索引设置不佳导致查询慢时,重建排序键需要删除历史数据,重新建表。
查询层缺少限流、防呆和自动优化等功能,导致查询不稳定。
 
(2)  运维痛点
 
表与集群严格绑定,集群磁盘满后,只能通过双写迁移。
集群搭建依赖 Ansible,部署周期长(数小时)。
Clickhouse 版本与社区版本脱节,目前集群的部署模式不便版本更新。
 
面对这样的难题,我们在2022年推出了日志3.0改造,落地了集群 Clickhouse on Kubernetes、类分库分表设计和统一查询治理层等方案,聚焦解决了架构和运维上的难题。最终,实现了统一携程 CLOG 与 ESLOG 两套日志系统。
 
4.1  ck on k8s
 
我们使用 Statefulset、反亲和、Configmap 等技术实现了 Clickhouse 和 Zookeeper 集群的 Kubernetes 化部署,使得单集群交付时间从2天优化到5分钟。同时,我们统一了部署架构,将海内外多环境部署流程标准化。这种方式显著地降低了运维成本并释放人力。更便利的部署方式有益于单个大集群的切割,我们将大集群划分为多个小集群,解决了单集群规模过大导致 Zookeeper 性能瓶颈的问题。
 
4.2 类分库分表设计
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktF8uxUL6hw308SzkRMoLrafyrsKY8mPpdyL8ZR8JYPPIFQlXF5iaPCGqQ/640?wx_fmt=png
图18
 
(1)数据跨如何跨集群
 
假设我们有三个数据集群1、2、3和三个表A、B、C(如图18)。在改造之前,我们单张表(如A)只能坐落在一个数据集群1中。这样的设计方式,导致了当集群1磁盘满了之后,我们没有办法快速地将表A数据搬迁到磁盘相对空闲的集群2中。我们只能用双写的方式将表A同时写入到集群1和集群2中,等到集群2的数据经过了TTL时间(如7天)后,才能将表A从数据集群1中删除。这样,对我们的集群运维管理带来了极大的不方便和慢响应,非常耗费人力。
 
于是,我们设计一套类分库分表的架构,来实现表A在多个集群1、2、3之间来回穿梭。我们可以看到右边改造后,表A以时间节点作为分库分表的切换点(这个时间可以是精确到秒,为了好理解,我们这里以月来举例)。我们将6月份的数据写入到集群1、7月写到集群2、8月写到集群3。当查询语句命中6月份数据时,我们只查询集群1的数据;当查询语句命中7月和8月的数据,我们就同时查询集群2和集群3的数据。
 
我们通过建立不同分布式表的方式实现了这个能力(如:分布式表tableA_06/tableA_07/tableA_08/tableA_0708,分布式表上的逻辑集群则是是集群1、2、3的组合)。这样,我们便解决了表跨集群的问题,不同集群间的磁盘使用率也会趋于平衡。
 
(2)如何修改排序键不删除历史数据
 
非常巧妙的是,这种方式不仅能解决磁盘问题。Clickhouse 分布式表的设计只关心列的名称,并不关心本地数据表的排序键设置。基于这种特性,我们设计表A在集群2和集群3使用不一样的排序键。这样的方式也能够有效解决初期表A在集群2排序键设计不合理的问题。我们通过在集群3上重新建立正确的排序键,让其对新数据生效。同时,表A也保留了旧的7月份数据。旧数据会在时间的推移一下被TTL清除,最终数据都使用了正确的排序键。
 
(3)如何解决删除大表字段导致元数据不一致
 
更美妙的是,Clickhouse 的分布式表设计并不要求表A在7月和8月的元数据字段完全一致,只需要有公共部分就可以满足要求。比如表A有在7月有11个字段,8月份想要删除一个弃用的字段,那么只需在集群3上建10个字段的本地表A,而分布式表 tableA_0708 配置两个表共同拥有的10个字段即可(这样查分布式表只要不查被删除的字段就不会报错)。通过这种方式,我们也巧妙地解决了在数据规模特别大的情况下(单表百TB),删除字段导致常见的元数据不一致问题。
 
(4)集群升级
 
同时,这种多版本集群的方式,也能方便地实现集群升级迭代,如直接新建一个集群4来存储所有的09月的表数据。集群4可以是社区最新版本,通过这种迭代的方式逐步实现全部集群的升级。
 
4.3 元数据管理
 
为了实现上述的功能,我们需要维护好一套完整的元数据信息,来管理表的创建、写入和 DDL(如图19)。该元数据包含每个表的版本定义、每个版本数据的数据归属集群和时间范围等。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFdmaGBsdYIYkIRON7x3ZKoX0sE9MdQPY5qOSM6oNdh49B1MkZsziavUw/640?wx_fmt=png
图19
 
4.4  统一查询治理层
 
(1)Antlr4 的 SQL 解析
 
在查询层,我们基于 Antlr4 技术,将用户的查询 SQL 解析成 AST 树。通过 AST 树,我们能够快速地获得 SQL 的表名、过滤条件、聚合维度等(如图20)。我们拿到这些信息后,能够非常方便地对 SQL 实时针对性的策略,如:数据统计、优化改写和治理限流等。
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFDoWbdnO3eLoxQrFev9S9gabaGibnsHyZYboqk4W3VBgIkYCcXML2iaOA/640?wx_fmt=png
图20
 
(2)查询代理层
 
https://mmbiz.qpic.cn/mmbiz_png/ufWcjcomw8bvIwqgnzEbCB448dpNtktFTHzrSFDDoYUzOXyM1Obiagdv1SwN8YTRkYmoibP4yP1qoTrCc1HBOPLQ/640?wx_fmt=png
图21
 
我们对所有用户的SQL查询做了一层统一的查询网关代理(如图21)。该程序会根据元数据信息和策略对用户的 SQL 进行改写,实现了精准路由和性能优化等功能。同时,该程序会记录每次查询的明细上下文,用于对集群的查询做统一化治理,如:QPS 限制、大表扫描限制和时间限制等拒绝策略,来提高系统的稳定性。
 
五、未来计划
 
通过日志3.0的构建,我们重构了日志系统的整体架构,实现集群 Kubernetes 化管理,并成功地解决了历史遗留的 DDL 异常、数据跨集群读写、索引重构优、磁盘治理和集群升级等运维难题。2022年,日志系统成果地支撑了公司 CLOG 与 UBT 业务的数据接入,集群数据规模达到了30+PB。
 
当然,携程的日志系统演进也不会到此为止,我们的系统在功能、性能和治理多方面还有不少改善的空间。在未来,我们将进一步完善日志统一查询治理层,精细化地管理集群查询与负载;推出日志预聚合功能,对大数据量的查询场景做加速,并支持 AI智能告警;充分地运用云上能力,实现弹性混合云,低成本支撑节假日高峰;推到日志产品在携程系各个公司的使用覆盖等。让我们一起期待下一次的日志升级。
 
作者丨 Dongyu
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 稳撑30+PB数据,携程10年日志系统治理演进之路