当前位置: 首页 > 科技观察

携程日志系统治理演进路径

时间:2023-03-18 01:45:26 科技观察

本文将从以下五个部分入手,讲述日志系统的演进路径:携程日志的背景与现状,如何构建日志系统,从ElasticSearch演进以Clickhouse存储、日志3.0重架构和未来计划。一、日志背景及现状图12012年之前,携程各部门自行收集管理日志(图1)。这种方式缺乏统一的标准,不便治理和控制,消耗较多的人力物力。从2012年开始,携程技术中心推出了基于ElasticSearch的日志系统,统一了日志访问、ETL、存储、查询标准。随着业务量的增长,数据量膨胀到4PB级别,给原有的ElasticSearch存储方案带来了OOM、数据延迟、负载不均等诸多挑战。另外,随着集群规模的扩大,成本问题变得越来越敏感,如何节约成本成为新的问题。2020年初,我们提出了以Clickhouse作为主要存储引擎来替代ElasticSearch的方案。该方案极大地解决了ElasticSearch集群遇到的性能问题,成本降低至48%。到2021年底,日志平台累计数据量20+PB,集群规模达到几十个(如图2)。从2022年开始,我们提出了日志统一策略,将公司的CLOG和UBT业务统一到这个日志系统中,预计数据量会达到30+PB。同时,日志集群经过两年多的大规模应用,积累了集群数量激增、数据迁移不便、表异常变更等各种运维问题。因此,日志记录3.0应运而生。本方案实现类分库分表、ClickhouseonKubernetes、统一查询管理层等设计,重点解决架构和运维方面的问题,实现携程CLOG和ESLOG日志平台的统一.图22.如何搭建日志系统2.1架构图从架构图上(如图3所示),整个日志系统可以分为:数据访问、数据ETL、数据存储、数据查询展示、元数据管理系统和集群管理系统。图32.2数据访问数据访问主要有两种方式:第一种是使用公司框架TripLog访问消息中间件Kafka(Hermes协议)(如图4所示)。图4中的第二种是用户使用Filebeat/Logagent/Logstash或者自己编写程序向Kafka上报数据(如图5所示),然后通过GoHangout写入存储引擎。图52.3数据传输ETL(GoHangout)GoHangout是一个基于Logstash(Github链接)的开源应用程序,用于从Kafka消费数据并进行ETL,最终输出到不同的存储介质(Clickhouse、ElasticSearch)。数据处理Filter模块包括常用Json处理、Grok正则匹配、时间转换等一系列数据清洗功能(如图6所示)。GoHangout会通过正则匹配将数据的Message字段中的num数据提取到一个单独的字段中。图62.4ElasticSearch数据存储2012早期版本,我们使用ElasticSearch作为存储引擎。ElasticSearch存储主要由MasterNode、CoordinatorNode和DataNode组成(图7)。Master节点主要负责创建或删除索引,跟踪哪些节点是集群的一部分,并决定将哪些分片分配给相关节点;Coordinator节点主要用于处理请求,负责将请求路由到正确的节点,比如创建索引的请求需要路由到Master节点;Data节点主要用于存储大量的索引数据,并进行增删改查。一般对机器配置要求比较高。图72.5数据展示在数据展示方面,我们使用ElasticStack家族的Kibana(如图8所示)。Kibana是一款适用于ElasticSearch的数据可视化和管理工具,提供实时的直方图、折线图、饼图和表格等,极大方便了日志数据的展示。图82.6表元数据管理平台表元数据管理平台是用户访问日志系统的入口。我们将每个Index/Table定义为一个Scenario(如图9所示)。我们通过平台配置和管理Scenario的一些基本信息,例如:TTL、属性、权限、ETL规则和监控日志等。图93.从Elasticsearch到Clickhouse我们将介绍日志从ElasticSearch到Clickhouse的演进过程从四个方面:背景、Clickhouse介绍、ElasticSearch对比及解决方案。2020年初,随着业务量的增长,给ElasticSearch集群带来了很多问题,主要体现在稳定性、性能和成本三个方面。(1)稳定性:ElasticSearch集群负载高,导致请求拒绝、写入延迟、查询慢等现象较多。每天有200TB的数据从热节点迁移到冷节点时,也会有很大的性能损失。节点间负载不均衡,部分节点单体负载过高,影响集群稳定性。大查询导致ElasticSearch节点OOM。(2)性能:ElasticSearch的吞吐量也到了瓶颈。查询速度受整个集群负载的影响。(3)成本:倒排索引导致数据压缩率低。大文本场景性价比高,无法保存长期数据。3.1Clickhouse与Elasticsearch简介Clickhouse是一个用于在线分析(OLAP)的列式数据库管理系统(DBMS)。Yandex于2016年开源,使用C++语法开发。是PB级交互式分析数据库。包含以下主要特效:列式存储、Vector、CodeGeneration、分布式、DBMS、实时OLAP、高压缩比、高吞吐量、丰富的分析功能和SharedNothing架构等。图10Clickhouse采用SQL交互方式,即使用起来非常方便。下面简单介绍一下Clickhouse的LSM-like、sortkey、partitionkey的作用,了解Clickhouse的主要原理。首先,用户在每批中写入的数据会根据其排序键进行排序,写入一个新的文件夹(如201905_1_1_0),我们称之为PartC0(如图10所示)。然后,Clickhouse会在后台周期性的对这些Parts进行归并排序,使得最终的数据会生成数据时序、占用空间大的Parts。从磁盘读写的角度来看,这种方式可以将磁盘原来的随机读写完全转化为顺序读写,大大提高了系统的吞吐量和查询效率。同时,列式存储+顺序数据的存储方式也为数据压缩比提供了便利。201905_1_1_0和201905_3_3_0合并成201905_1_3_1就是一个经典的例子。另外,Clickhouse会根据partitionkey(比如partitionbymonth)按月对数据进行分区。05和06的数据分为不同的文件夹,便于快速索引和数据管理。在图11中,我们看中了Clickhouse的列式存储、向量化、高压缩比、高吞吐等特效(如图11所示),很好地满足了我们目前日志集群对性能稳定性和成本的需求。因此,我们决定使用Clickhouse来替代原来的ElasticSearch存储引擎。3.2解决方案借助存储引擎,我们需要实现非用户感知的存储迁移。这主要涉及以下工作(如图12所示):自动建表、修改GoHangout、Clickhouse架构设计与部署、Kibana改造。图12(1)数据库表设计图13我们对日志场景下ck的很多细节进行了优化(如图13所示),主要是在库表设计上:我们使用双列表的方式来存储动态变化的标签(当然最新版本22.8也可以使用map的json方法和新特性)。按天分区和时间排序,用于快速定位日志数据。Tokenbf_v1布隆过滤器用于优化词条查询和模糊查询。_log_increment_id全局唯一增量id,用于详细数据的滚动和定位。ZSTD数据压缩方式节省40%以上的存储成本。(2)Clickhouse存储设计Clickhouse集群主要由查询集群、多个数据集群和Zookeeper集群组成(如图14所示)。查询集群由相互独立的节点组成,节点不存储数据,是无状态的。数据集群由分片组成,每个分片覆盖多个副本。副本之间的关系是master-master(区别于常见的master-slave关系)。两个副本都可以用于数据写入并相互同步数据。副本之间的元数据一致性由Zookeeper集群管理。图14(3)数据展示为了实现用户无感知的存储切换,我们专门实现了Kibana对Clickhouse数据源的适配,开发了不同的数据面板(如图15所示),包括:chhistogram、chhits、chpercentiles、changes、chstats、chtable、chterms和chuniq。通过Dashboard脚本的量产替换,我们快速实现了原有ElasticSearchDashboard的迁移,自动化程度达到95%。同时我们也支持使用Grafana直接配置SQL生成日志仪表盘。图15(4)集群管理平台为了更好的管理Clickhouse集群,我们还搭建了一套完整的基于接口的Clickhouse运维管理平台。该平台涵盖日常分片管理、节点生成、绑定/解绑、修改权重、DDL管理、监控告警等治理工具(图16)。图163.3成就迁移过程自动化程度超过95%,对用户基本透明。存储空间节省50+%(如图17所示),支持原有ElasticSearch服务器4倍的业务量增长。查询速度比ElasticSearch快4~30倍,查询P90小于300ms,P99小于1.5s。图174、日志3.0建设时间来到2022年,公司日志规模进一步提升至20+PB。同时,我们提出了日志统一策略,将公司的CLOG和UBT业务统一到这个日志系统中,预计数据量将达到30+PB。另外,经过两年多的大规模应用,日志系统也面临着各种运维问题。(1)性能和功能痛点单个集群规模过大,Zookeeper性能达到瓶颈,导致DDL异常超时。当表数据规模较大时,删除字段可能会导致超时和元数据不一致。当由于用户索引设置不当导致查询变慢时,重建排序键需要删除历史数据并重建表。查询层缺少限流、防呆、自动优化等功能,导致查询不稳定。(2)运维痛点表与集群严格绑定。当集群磁盘满时,只能通过双写进行迁移。集群搭建依赖Ansible,部署周期长(数小时)。Clickhouse版本与社区版本脱节,目前的集群部署方式不方便版本更新。面对这样的问题,我们在2022年启动了日志3.0改造,并在Kubernetes上实现集群Clickhouse、类分库分表设计、统一查询管理层等解决方案,重点解决架构和运维方面的问题维护。最终统一了携程CLOG和ESLOG这两个日志系统。4.1ckonk8s我们使用Statefulset、anti-affinity、Configmap等技术实现了Clickhouse和Zookeeper集群基于Kubernetes的部署,将单集群交付时间从2天优化到5分钟。同时我们统一了部署架构,规范了国内外多环境的部署流程。这种方式大大降低运维成本,释放人力。更方便的部署方式有利于单个大集群的划分。我们将大集群划分为多个小集群,解决了单个集群规模大带来的Zookeeper性能瓶颈问题。4.2类分库分表的设计图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分布式表的设计只关心列名,不关心本地数据表的sortkey设置。基于这个特点,我们设计表A在簇2和簇3使用不同的sortkey。这种方法也能有效解决簇2初始表A的sortkey设计不合理的问题。我们让它工作在通过在簇3上重新建立正确的排序键来获取新数据。同时,表A还保留了旧的7月数据。随着时间的推移,旧数据将被TTL清除,最终数据将使用正确的排序键。(3)如何解决删除大表字段导致的元数据不一致更妙的是,Clickhouse的分布式表设计并不要求A表7月和8月的元数据字段完全一致,只需要公共部分就可以满足Require。比如表A在7月份有11个字段,8月份要删除一个deprecated字段,只需要在集群3上建一个本地表A有10个字段,分布式表tableA_0708配置两表共享10个字段就够了(这样只要不检查分布式表中删除的字段就不会报错)。这样,我们也巧妙地解决了在数据规模特别大(单表几百TB)时删除字段导致的元数据不一致的常见问题。(4)集群升级同时,这种多版本集群的方式也可以方便的实现集群升级迭代,比如直接新建一个集群4来存放2009年9月的所有表数据。集群4可以是最新版本的集群社区,通过这种迭代的方式逐步实现所有集群的升级。4.3元数据管理为了实现上述功能,我们需要维护一套完整的元数据信息来管理表的创建、写入和DDL(图19)。元数据包括每个表的版本定义、每个版本数据的数据归属簇和时间范围等。图194.4统一查询管理层(1)Antlr4SQL解析在查询层,我们基于Antlr4技术,将用户的查询SQL解析成AST树。通过AST树,我们可以快速获取SQL表名、过滤条件、聚合维度等(图20)。得到这些信息后,我们就可以非常方便的对SQL进行实时的针对性策略,比如:数据统计、优化重写、治理节流等。图20(2)查询代理层图21我们为所有用户的SQL查询做了一个统一的查询网关代理层(如图21所示)。程序根据元数据信息和策略重写用户的SQL,实现精准路由、性能优化等功能。同时,程序会记录每次查询的详细上下文,用于集群查询的统一管理,例如QPS限制、大表扫描限制、时间限制等拒绝策略,提高系统稳定性。5.未来计划通过日志3.0的构建,重构了日志系统的整体架构,实现了集群Kubernetes管理,成功解决了历史DDL异常、跨集群数据读写、索引重构优化、磁盘治理与集群等问题升级等运维问题。2022年日志系统将成功支撑公司CLOG和UBT业务的数据接入,集群数据规模达到30+PB。当然,携程日志系统的进化不会就此止步。我们的系统在功能、性能和治理方面还有很大的改进空间。未来我们将进一步完善日志统一查询管理层,精细化管理集群查询和负载;上线日志预聚合功能,加速大数据查询场景,支持AI智能告警;充分利用云能力,实现弹性混合云,低成本支撑节假日高峰;推送日志产品,覆盖携程系统各家公司的使用等,让我们期待下一次日志升级。