前言
星巴克中国技术部日志平台团队经过近1年的日志集群迁移和升级,将维护支持星巴克中国的日志平台多个日志集群,数PB的数据,从ES版本从7.8.X、7.9.X跨大版本无缝升级至8.X,从虚拟机架构部署模式迁移至云原生祼金属k8s平台部署模式。完成日志平台组件升级的过程中,也完成了日志平台的架构升级。从开始计划到执行完成,中间也遇到了很多的阻力和问题。经过团队技术攻坚,跨团队配合,新资源支持等方式解决了相关困难,完成之后我们回顾一路走来的付出和成就,确实有很多值得思考的地方,分享出来供大家参考。
2024年9月开始计划,在不改变用户查询和提升用户体验的前提下,到2025年6月完成所有日志平台组件架构升级和版本迁移。在这中间的过程中,经历了mapping不兼容、字段类型冲突、查询上下文失效、重复消费误告警等诸多业内普遍存在的难题,最终实现了单机查询性能提升80%,整体cpu下降30%,写入tps提升 200%,用户也明显感觉到了查询性能提升带来的快感。本次分享从以下几个方面进行展开。
一、背景
在数字化业务高速发展的当下,日志作为系统运行状态的 “全景镜像”,承载着业务监控、故障排查、安全审计、数据分析等核心场景需求。星巴克日志平台从2017年开始建设以来,存在一些架构设计不合理,日志查询缓慢,超时,丢日志等情况,用户体验不好。传统架构下的日志平台逐渐暴露出性能瓶颈:查询延迟超10秒、存储成本年增长率达30%、跨集群数据协同效率低,难以满足业务对 “实时性”“低成本”“高可用” 的诉求。为此,技术团队启动全方位升级优化,通过架构重构、引擎升级、智能调度等手段,实现平台从 “能用” 到 “好用” 的跨越,为万亿级数据场景下的日志服务树立新标杆。
自2024年以来,日志平台团队开始逐步接手相关的平台建设工作,从日志采集组件(filebeat)、日志接收(logstash producer)、kafka 、日志消费组件(logstash consumer)、ES 集群、数据存储模式、日志查询组件(kibana)、ES多集群查询组件(CCS)等层面进行了逐个优化,下图为日志集群没有优化之前的架构模式图:
此架构存在以下问题:
1)ES 集群依赖远程网络存储,写入能力受到远程存储IO资源限制。当时的数据量场景下,存储IO带宽已经处于满载运行的状态,且扩容麻烦周期较长;
2)logstash-producer 和 logstash-consumer 单节点处理能力有限。两者占用了大量的计算资源,需进行优化或者技术演进,以提高效率和节约计算资源;
3)远程存储容量即将达到安全线内使用上限。如果不进行优化,无法承接更多的业务日志接入,用户体验也经常收到业务反馈查询超时,日志延迟等投诉建议。
各组件都是虚拟机部署,运维成本高,集群的可观测性,稳定性得不到保证。
在稳定性方面,因历史原因,日志数据的数据清洗和存储方面没有最佳实践,没有合理的索引的模版结构和生命周期管理,索引分片和大小配置也没经过合理的优化。这样造成了数据查询超时,甚至部分节点内存溢出,资源使用倾斜情况等,用户体验非常不好。其次,存储使用的是远程网络存储,受远程存储性能的限制,造成 ES 集群写入和查询的资源受限,经常出现数据堆积,ES 查询队列居高不下,查询缓慢的情况;
基于以上原因,日志平台技术伙伴从技术层面和成本管理层面来考虑。经过团队对现有硬件资源情况、日志每天增量情况、早晚高峰期流量情况等方面的评估,在同等硬件资源的情况下,进行日志平台技术架构升级,能够让日志的查询效率、日志高峰流量写入得到显著提升,可以缓解高峰时日志写入延迟,提高 ES 的写入能力方面等到优化,因此日志平台伙伴对日志平台进行了升级改造。
二、计划目标及面临的挑战
1、目标
日志平台伙伴根据实际的技术调研,跨团队配合情况,设定了详细的日志平台升级计划,保障每个关键节点实现相关里程碑成就,主要包括以下几点:
1)所有日志涉及的环境组件统一都迁移至云原生祼金属 k8s 平台引擎之上,即:日志平台涉及到的所有组件都需要容器化部署。
2)统一日志平台各组件的运行版本和交付标准, 实现日志数据采集、日志规则解析,数据入库等流程化体系建设。
3)资源分配合理化使用,对不同索引根据流量大小,高峰流量情况,业务活动情况,从采集,接入,解析,存储进行资源的精细化控制。
4)提升日志平台的接入能力,保证业务高峰期及活动保障期间不会有数据堆积和丢失情况。
5)提升用户数据查询服务体验,目标是 p99 查询 < 5s,改善用户对日志平台一些不好的看法。
日志平台改造架构图如下:
与此前架构设计相比,本架构所具有的优势为:
1)所有组件都是容器化部署,运维相对简单,由之前在虚拟机上部署组件变为 operator 快速制备 pod, 组件交付效率提升 90% 以上;
2)producer 和 consumer 的组件由之前的 logstash 替换为 vector, 同等硬件资源下数据处理能力提升 2 倍以上;
3)ES 集群采用冷热角色部署,热节点使用本地磁盘,提高查询和存储速率,冷盘使用远程网络存储,可以最大程度使用已有资源,节约存储采购成本;
4)计算资源可以集中化管理和调度,提升资源利用率的同步,也使用资源可以快速的支持需要重保的组件;
2、挑战
1)如何保障用户体验?
在实际的集群升级过程中不允许有数据丢失的情况,包括历史数据及新接入数据,用户查询界面也不能更换。即要在一个界面上进行新旧集群的日志查询,不能出现新集群数据在新界面查询,旧集群数据在旧界面查询的情况。另外,当时日志查询经常超时,用户经常反馈日志平台查询不到数据、查询缓慢、平台难用的情况,如何优化用户体验成为了日志平台伙伴面临的一个非常棘手的挑战。
2)如何解决数据积压问题?
远程网络存储IO带宽已经达到写入瓶颈,IO带宽资源支持最高 4Gb/s,但是高峰期已经超过这个流量,直接制约了ES集群的写入能力,这也是造成日志经常堆积,日志数据延迟的主要原因。
3)如何提升单个消费节点的写入能力?
消费组件 logstash-consumer 的规则解析比较多,单个节点的平均写入大约 1w/s 左右。而且单个节点占用资源为 32c 64g 的配置,涉及到大量的规则解析,所以性能受到严重影响,流量高峰期间需要启动大量消费节点进行数据写入,是日志集群除 ES 节点外最大的资源消耗组件。如何提升单个节点的写入能力,降低资源消耗成为技术伙伴攻关的主要挑战。
4)如何提升集群的存储能力?
集群硬件存储资源总共数PB ,但是当时日志增量为每天百TB ,日志保留时长一般为 30 天,有些业务日志由于业务原因需要保留60天或者90天,所以存储资源当时已经处于饱和的状态,总共数据量达到万亿级别。如何在不增加存储容量的情况下进行存储资源的优化,也是技术伙伴面临的重大挑战。
5)如何解决业务日志接入流程长的问题?
之前业务日志接入是按照业务组件名称,要从采集侧开始配置,再手动配置生产者,kafka 的 topic, 消费者及写入的索引名称,分片数量,查询别名及索引生命周期管理等,这一套流程手动操作下来要2小时左右,这也是在伙伴对流程比较熟练的情况下。但是我们接收到的新的日志接入每天大概3-4个,消耗在日志接入方面的人力成本非常多,如何优化日志接入流程成为了平台伙伴需要面临的挑战。
以上为主要面临的挑战,还有一些比如:业务组件如何对应索引名称和管理?人力资源有限的情况下,如何进行多集群的高效运维和管理?面对组件容器化之后,针对 ES 节点,kafka 节点等有状态节点出现故障之后如何快速恢复?集群各组件的可观测能力,告警能力,故障自动恢复能力等等,都是在集群升级过程中要面临的问题和挑战。
三、执行步骤
在开始实施前,我们按照以上问题的优先级进行了执行步骤的制定,对每个步骤的实施方案,期望达到的效果及预计的完成时间进行了详细的技术讨论,拆分如下:
1、迁移过程中如何保障用户体验
实施方案:
预期效果:
使用本地磁盘代替远程网络存储的收益如下:
在单节点的性能优化中,我们主要优化了以下几个方面:
以下是单个物理机在20w/eps时的iostat性能图:
从上图可以看出,使用本地磁盘存储代替远程存储,磁盘IO性能得到了指数级提升。
2、如何解决数据积压问题
实施方案:
经过团队内部仔细梳理,发现在业务高峰期导致日志积压的因素有多种,具体归纳如下:
针对以上发现的问题,团队在进行集群迁移升级的过程,对集群的吞吐能力从不同组件的维度进行了优化,具体实施步骤如下:
kafka 集群设置:
topic 分区设置规则:针对业务应用日志量大的 topic 分区,设置45个 (9个 kakfa 节点,保证是9的倍数),日志 topic 默认分区设置9个。
kafka 参数主要参考批次大小,参数过大,导致cpu、内存异常告警,设置过小导致 filebeat 事件活跃数高,日志写入延迟。
fetch.max.bytes: 30000000
max.request.size: 31457280
message.max.bytes: 41943040
vector 写入 ES 参数设置:
主要针对日志量大的业务,减少日志写入提交频次,降低 ES 写入队列:
batch:
max_events: 2000
max_bytes: 20971520
timeout_secs: 5
compression: "zstd"
ES 索引模版参数优化设置:
"refresh_interval": "73s",
"mode": "logsdb",
"codec": "best_compression",
"routing": { "total_shards_per_node": "1" }
预期效果:
3、如何提升单个消费节点的写入能力
实施方案:
在 ELK 的架构体系中,logstash 组件扮演着数据管道的角色,把数据从 filebeat 写入 kafka, 再把数据从 kafka 经过解析或者清洗写入 ES, 这种组件集群的方式在业界使用非常广泛。但是 logstash 是 java 实现,在进行大数据量处理时经常需要占用更多的cpu和内存资源,日志平台总资源只有数十台物理机,平台提供给 logstash 的计算资源达到 10 台,一半以上的计算资源被锁在 logstash-producer 及 logstash-consumer 上,其实也没有存在资源浪费的情况,只是数据处理的性能低下。1 个 32c64g 的生产者可以每秒发送 3-4w 条数据到 kafka, 而消费者的处理和写入能力也只有 1w/s。因为要处理大量的日志数据字段解析,所以性能比不上生产者。
结合以上情况,团队伙伴决定做技术演进。在技术调研的过程中,新兴组件 vector 进入了我们的视野。据官方压测数据,其性能是 logstash 的数倍以上,所以我们决定引入 vector 取代 logstash 组件作为集群中的管道组件,具体实施步骤如下:
从上图可以看出,在每一组内如果消费堆积,不会影响其它组的消费,只需要解决堆积的那个组的问题就可以,也可以对重点保障的业务所在的组投入更多的消费资源,做到了消费资源的精细化控制,也可以在活动期间对活动涉及到的业务组进行重点保障工作。
预期效果:
4、如何提升集群的存储能力
实施方案:
日志集群的总存储资源在团队接手管理时存储容量已经使用 85% 以上,而且每天不断有新增的业务组件需要接入日志集群。在存储硬件资源受限以及业务日志保存时长不受影响的情况下,如何对现有的存储逻辑进行优化,释放更多的存储空间,进而承接更多的业务日志接入也成为了团队需要亟待解决的问题。经过团队伙伴的共同努力,发现可以进行存储优化的点有两处:
预期效果:
下表是使用不同 ES 版本索引同一份数据的存储空间测试对比:
从表中数据可以看出,开启压缩前后在不同的 ES 版本中存储容量均有明显下降。
5、如何解决业务日志接入流程长的问题
实施方案:
日志接入从应用到 ES 需要经过多个组件,涉及到业务应用跟 topic 映射配置,topic 跟日志索引映射配置,针对不同的应用日志需要设置单独的索引生命周期,分片数,索引模版以及查询模版。整个日志接入流程下来,需要大概花费耗时 2 小时。原来整体日志接入流程如下:
在经过日志索引规范治理后,团队对日志接入流程进行了分析以及流程优化,基本能实现日志流程接入自动化。实施步骤如下:
预期效果:
四、成果与体会
1、成果总结
经过3个月的升级与验证,日志平台的性能、成本、可用性均实现显著突破,核心指标如下:
2、体会与感悟
日志系统升级初期面临诸多问题,业务所有告警策略全部都是通过查询日志索引,稍有考虑不到地方就可能会引起大量误告警,给日志升级方案设计带来了很大的挑战。同时还要兼顾业务诉求,平台使用无感,数据不能丢失等,需要考虑诸多因素,团队伙伴在保障日志平台平滑升级过程中付出了诸多努力。
因为星巴克的业务场景原因,日志平台所有的升级动作都必须要在晚上 10:00 以后进行,不能影响正常白天业务日志的查询。为此,团队伙伴经常作业到凌晨以后,现在回头再看,正是团队伙伴兢兢业业的奉献,才能使日志平台升级工作顺利完成;正是团队伙伴熬过的每一个夜晚,才换来了业务伙伴对日志平台体验提升的一次次肯定。
日志平台是一个多组件构成的复杂系统,升级优化需要考虑每个组件在流程中的贡献和作用,以及可能的优化空间,各组件的参数使用需要上下游连动,全流程优化也需要考虑整个系统的木板效应,过程复杂且具有挑战性,只有坚实地做好每一项的优化,才能得到整个系统的性能提升。
五、未来发展规划
作者丨星巴克中国技术部日志平台团队
来源丨公众号:InfoQ(ID:infoqchina)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721