日志的应用场景可以分成准实时和离线两大类,日志平台需要解决日志采集、日志投递、日志处理、日志存储以及基于日志的监控与告警等核心问题。本文将系统介绍严选日志平台的发展历程以及我们在各个阶段的解决方案,通过剖析日志平台的底层架构来分享架构背后的思考,最后也会介绍一下我们为何选择将日志平台的底层引擎Loggie开源,以及目前开源工作的一些进展,希望可以给大家带来帮助与启发。1. 引言
日志是设备或者程序对自身状态和运作行为的记录(From 维基百科),比较常见的如:
服务器的系统日志
应用的访问日志、业务日志
客户端的埋点日志
……
在严选,开发人员几乎每天都会和日志打交道,我们将日志应用在业务监控、线上问题诊断、用户行为分析、运维审计等各类场景。业务和产品日常使用的数据中有很大一部分也是基于日志生产出来,因此如何使用日志数据以及围绕日志构建的各类基建与产品长期以来一直是一个非常重要的技术话题与研究方向。
总体而言,日志的应用场景可以分成准实时和离线两大类,日志平台需要解决日志采集、日志投递、日志处理、日志存储以及基于日志的监控与告警等核心问题。本文将系统介绍严选日志平台的发展历程以及我们在各个阶段的解决方案,通过剖析日志平台的底层架构来分享架构背后的思考,最后也会介绍一下我们为何选择将日志平台的底层引擎Loggie开源,以及目前开源工作的一些进展,希望可以给大家带来帮助与启发。2. 前世:追求小而美
与大多数初创公司类似,网易严选在早期业务规模还比较小的时候,主要依靠开源社区快速构建了各类日志应用场景。2.1 问题诊断
问题诊断是最常见的日志应用场景,绝大部分的线上问题我们都需要借助日志进行诊断。在这个阶段我们一般需要登陆服务器,使用grep等命令查询想要的信息,如果服务器数量较多,也会配合ansible、pssh等工具,但这种方式有比较明显的弊端:- grep较难实现比较复杂的查询条件,使用门槛较高。
- grep采用全文顺序扫描,在文件较大时查询速度较慢且比较消耗服务器资源。
- grep基于服务器上存储的文件,而服务器磁盘空间有限,文件一般只能保留几天,在应用容器化之后更是加剧了这个问题。
2.2 日志监控
广义的日志监控包含基于日志文本的事件监控以及基于日志的业务指标监控,是最常用的面向业务的监控手段。其中,基于日志文本的事件监控是通过在日志文本中匹配关键字或正则表达式的数量、日志是否滚动等策略来实现,基本能覆盖最简单的业务监控场景,同时,由于其技术门槛相对较低,普及度也更高些。严选在这个阶段使用的就是基于日志文本的事件监控,技术上我们是通过运维agent来实现。这种方式本质上是远程执行脚本,因此,在资源开销、灵活性、易用性以及安全性等方面存在一定的问题,对运维agent的稳定性也提出了比较高的要求,事实上,也确实出现过因监控脚本BUG导致运维agent不可用造成的故障。2.3 业务指标实时统计
业务指标实时统计一般可以基于数据库或者基于日志来完成,但前者会带来额外的数据库负载,影响业务的稳定性,即使有专用的统计数据库,在一些复杂的聚合场景,其性能与灵活性也极大地限制了可应用的范围,也正因此,业务指标实时统计一般情况下都会基于日志来实现。业务指标实时统计需要对日志数据进行切分、筛选与聚合,主要包括两个阶段:- 将日志数据同步到Kafka中暂存:这个阶段主要解决日志采集的问题,在15年前后,Flume无疑是开源社区的最佳选择之一。
- 将Kafka数据源同步到ES(Elasticsearch)中:这个阶段我们引入了ELK stack,Logstash对Kafka中的日志数据进行清洗并保存到ES中,ES存储结构化的日志数据并作为搜索和分析引擎,Kibana则提供数据分析与可视化能力。
虽然基本能满足简单的统计需求,但由于链路长、涉及组件及配置较多且需要多个职能团队进行配合,因此开发联调效率极低,比如统计某个产品的PV/UV,往往需要两周甚至更长的时间。2.4 日志审计、用户行为分析及风控
由于日志可以记录各类变更管理行为及操作记录,因此经常会被用于安全审计、安全事件分析及过程回溯、用户行为分析等场景,同时风控系统也会利用这些用户行为数据来不断改进识别效果。和业务指标实时统计类似,上述这些场景也需要采集日志并暂存到Kafka中,不同的是这些日志最终被存储到数仓(Hive表)中进行离线分析。在这个阶段,我们将日志、Kafka、Hive数据库等都抽象成了数据源,通过DataHub(数据总线)管理这些数据源并对这些数据源产生的数据进行处理与加工,这在很大程度上解决了元数据管理问题、降低了配置的难度。但是,通过DataHub的理念来管理整体链路,也意味着我们没有将日志的采集与应用作为一个整体,需要用户对大数据的基本概念和基建有一定的了解,尤其是在配置、调试、问题排查等环节需要整体流程比较熟悉,无形中也提升了使用门槛。3. 严选为什么需要自建
如果您所在的团队业务规模比较小或者业务发展尚处于早期探索阶段、没有足够的研发资源投入到公共基建,小而美背靠开源的解决方案无疑是上上之选,它的部署门槛较低,仅需要投入少量的定制开发人员以及运维人员即可构建出基础的能力。然而这个解决方案却远非“真香”。以严选为例,随着研发团队规模扩大、业务复杂度提升,基于日志数据的需求越来越多,随之而来的是有大量的研发和运维资源投入在这类低价值的重复的配置工作中,比如比对日志数据完整性、配置或修改日志采集处理脚本等等。显然,我们的工程师们应该把更多的时间投入到更需要创造力的工作中去。因此,我们也在思考一个理想的日志系统应该具备怎样的特质:- 使用便捷高效:提供一个一站式的日志平台,用户可以独立完成日志需求开发测试发布与日常维护,也可以使用日志检索、分析、诊断以及监控报警功能,而系统也应该具备异常自主发现能力,提供产品化的运维工具及自动化的运维能力,帮助系统运营人员实现高效运维。
- 资源消耗低、性能强:严选有1000+的服务,每天会产生PB级的日志,因此减少资源开销和提升性能也意味着我们可以用更少的资源来实现更大的日志吞吐量,可以大大减少硬件方面的成本投入。
- 日志数据质量高:既要求日志链路上的所有组件具备较高的稳定性与可靠性、确保日志不丢失,同时也需要我们能快速的判断采集上来的日志是完整的。
- 支持容器化日志采集:19年严选开始启动应用容器化及业务上云,因此基建需要全面适配混合云场景,现有的解决方案不支持容器化日志采集,也无法满足迅速增加的日志采集、业务诊断以及可观测性等方面的需求。
想清楚了这些问题,接下来我们就可以对现有的一些解决方案进行对比了:- 首先来看一下集团内部的兄弟部门,发展阶段与严选大体一致,其中采集组件的选择存在开源和自研两个方向,开源派以Flume使用最为广泛,自研派比较典型的是Datastream,控制面基本上都与各自的系统有较大的耦合,没有元数据管理,任务驱动,配置无法自动生成与下发,使用与维护成本普遍较高。
- 其次可以看一下开源社区主流的解决方案,绝大部分只具备日志采集能力,同样没有提供元数据管理,运维成本高,很难应对大规模的日志采集与应用场景(下文也会做更进一步的对比)。
- 最后,我们也对比了公有云PaaS(比较有代表性的如阿里云的日志系统),这类系统都依赖公有云的IaaS,同时价格又极其昂贵。
最终在19年年初我们决定自建一个统一的日志平台,提供稳定、高效、便捷的一站式日志解决方案:- 支持PB级的日志采集与处理,提供日志数据采集、解析、投递、数据质量检查、日志分析与检索、可视化及监控告警等功能。
- 可以一键完成从日志采集、投递、处理到存储,屏蔽环境与底层架构的复杂性。
4. 今生:统一的日志平台
接下来,我将从日志生产、采集、存储、维护到消亡的全生命周期管理并结合各类应用场景来介绍严选日志平台的核心功能。4.1 日志元数据统一管理
严选日志平台的基石是对日志元数据进行统一管理,并借助元数据实现了对日志数据质量的管理以及日志平台的全链路管控。
我们调研的大部分解决方案并不提供日志元数据的统一管理能力,主要有两方面的原因:
开源社区中大部分日志采集组件只提供将本地日志传输到各类数据源的功能,对日志的解析、结构化则交给日志处理组件,在此之上缺少可用于统一管理与调度的控制面,这并不是说控制面的实现技术门槛更高,而是因为统一调度要求各类组件遵循相同的标准,同时又与用户的使用场景有着千丝万缕的关联,因此,缺少统一标准与规范的现状使得日志元数据很难被定义。
早期日志被采集后集中存储的最重要目的是用于大数据离线分析,因此日志相关的基建主要面向有大数据背景的工程师,然而日志却往往又是由业务的开发工程师来打印,在这种大背景下,数据开发工程师将日志抽象为类似于MySQL、Kafka之类的数据源、将日志采集和处理的配置抽象为任务来进行管理确实是一个比较不错的通用设计,而基于数据源和任务的通用日志管理模式并不需要日志元数据。
那么,基于数据源和任务的通用日志管理模式是不是理想的日志管理模式呢?数据源与任务是大数据技术的底层概念,这就好比Linux系统的“一切皆文件”,让普通用户去直面底层语义,其使用时的友好程度可想而知。我们认为,日志元信息是屏蔽环境与底层架构的复杂性的关键设计。因此,我们借鉴了DataOps的理念,由日志平台提供产品化的功能来实现敏捷开发、一键测试、一键发布、质量稽核,从而缩短数据开发周期。基于上述思路,我们通过合理的抽象实现了日志元信息可以由日志生产者独立做出判断并完成编辑、可以一键完成独立测试、发布并实时提供信息反馈(如图所示),也可以在实际产生的日志数据与元信息定义的模型不匹配时及时进行告警,通过打通数据血缘,可以在日志元信息被编辑或者删除时(比如关联活跃的业务指标)及时进行阻断与告警。为了实现这些目标,我们将日志元信息抽象为日志归属、文件元信息、数据模型以及扩展信息这四个部分:- 文件元信息:保存日志对应的文件目录、文件名等信息。
- 数据模型:保存日志数据模型,包括字段名、字段描述、类型、约束条件、是否用于索引等信息。
- 扩展信息:保存是否敏感信息、是否是审计日志、日志保留时间等扩展信息。
- 可以结合CMDB数据判断当前登陆用户在各类使用场景下对各类数据的访问权限,确保权限一致性,也省去了繁杂的权限申请流程,比如控制用户可以检索日志的范围、可以查询的业务监控报表等。
- 可以自动生成虚拟机环境、容器环境中各类日志采集配置文件,即使调整日志组件,也可以实现低成本平滑替换。
- 可以自动创建Kafka、数据湖、ES等各类数据源并生成相关配置。
借助产品层日志元信息的统一管理、底层各类组件支持配置动态下发,严选日志平台解决了新增编辑日志采集处理任务需要业务开发、数据开发、数据平台开发等多个职能协同参与的问题,极大提升了配置的效率。实际落地的数据也证明了简化配置与流程带来的意义,严选日志平台上线不到2个月,新增的日志采集任务就超过过去3年的总和。4.2 日志数据质量管理
数据质量管理是大数据技术体系中的一个重要范畴,是数据价值的生命线。数据质量管理(Data Quality Management),是指对数据从计划、获取、存储、共享、维护、应用、消亡生命周期的每个阶段里可能引发的各类数据质量问题,进行识别、度量、监控、预警等一系列管理活动,并通过改善和提高组织的管理水平使得数据质量获得进一步提高。
提升日志数据质量是严选建设日志平台一个非常重要的目标,在此之前,业务对于数据指标经常持怀疑态度,尤其是基于日志统计的业务指标,背后的根本原因是日志采集及处理链路不可靠,经常因组件故障或者应用扩容造成日志数据缺失,进而引起业务指标异常波动。
要提升日志数据质量,需要从生产日志的源头抓起,在此基础上对日志的全生命周期进行管控。
19年初,严选各类系统打印的日志格式五花八门,以访问日志为例,无论是保存的目录、文件名、字段顺序、字段数量等都存在较大的差异,一方面,给日志采集任务的开发和维护额外增加了大量的成本,另一方面,也会时不时出现因日志格式、日志滚动方法调整造成之前的日志采集任务失效。
这些乱象的根源是缺少行之有效的规范以及确保规范得到有效落地的工具或系统。
4.2.1 建立日志规范
规范是治理的基石,没有规范,日志质量便是空谈。因此,管控源头的第一步我们从建立有效的日志规范入手。
结合业务的实际使用诉求,我们将日志分成三类,即访问日志、业务日志和应用日志,同时,为了强化大家的数据质量意识,我们在日志规范中引入了数据湖的概念,访问日志、业务日志进入数据湖,应用日志不进入数据湖,入湖日志数据的保障等级高于不入湖的日志数据,比如变更或者删除的限制、告警等级等。
数据湖(data lake)并不是一个新词,这个概念最早由Pentaho的CTO James Dixon 在2011年提出,最初是为了解决数仓高昂的开发、维护成本以及丢失很多细节数据等问题。与数仓不同的是,数据湖将大量的原始数据保存了下来,而越来越廉价的存储也是数据湖更多的进入了大家的视野。
2019年,数据湖在严选的应用刚刚起步,但考虑到类似业务监控、日志监控、操作审计等场景的日志数据使用数仓显然不太妥帖,因此,我们也是借着日志规范落地,将数据湖的概念推向了更多的人。
当然,从产品功能层面,我们允许全局、租户、产品级别为这三类日志定义规范,我们认为,在一个组织内部,日志是可以而且也应该规范到一种或多种固定的格式。以严选为例,分别为tomcat、nginx等七个不同的服务类型定义了访问日志规范模板,为业务应用定义了两套业务日志规范模板及六套应用日志规范模板。
4.2.2 工具与系统支持
有了规范之后,我们还需要考虑降低规范的落地成本,如果规范落地成本很高,就很难长期有效执行,最终必然会腐化。我们的策略是在日志的全生命周期为开发者提供工具与系统支持:- 提供SDK,辅助打印业务日志和应用日志,技术上最大的挑战是兼容原有的日志打印框架,使开发者可以低成本切换。
- 在日志平台中为开发者提供快速添加日志的入口并提供测试与发布功能。
- 根据日志元数据中定义的数据模型检查实际打印的日志是否符合预期,实时识别异常日志数据。
- 实时监控日志采集延迟及日志采集完整性,业务开发、平台运营以及数据开发可以通过可视化的方式判断目前日志采集的状态。
- 提供日志回溯能力,系统或者用户可以在识别到日志存在丢失的情况下发起日志回溯,通过完整性检查计算出需要回溯的日志片段(offset),容器环境内还需要计算出需要回溯采集的物理机节点,Agent需要支持根据指定offset采集指定文件的对应日志片段。
- 将数据血缘与日志数据源打通,串联上游日志,下游报表,一方面,实现日志平台与大数据平台质量信息联动,另一方面,通过血缘,日志数据源的变更或者删除可以及时准确给出告警,数据开发也可快速正反向查询日志与报表的关联关系,从而提升运维和研发效率。
经过上述一系列的数据治理,严选的日志采集已经可以做到秒级延时,其中基于日志的核心业务指标也可以达到100%的数据准确性。4.3 日志检索
基于日志的分析诊断是线上问题排查的最有效手段,相对于早期日志只存储在各自的应用服务器上,现在我们将日志集中存储,为分析诊断带来了更多的便利。严选日志平台为用户提供了搜索、实时日志流及全链路检索这三种模式。4.3.1 搜索模式
首先介绍下搜索模式,在大部分数据统计或分析诊断场景,开发人员往往已经知道需要查询哪个服务的哪个文件,也就是对应传统grep的方式,比如查询符合某个条件的日志文本,查询匹配的行数、内容或者上下文,最常用的搜索条件是包含(不包含)某个文本、正则匹配或者多条件组合匹配等。我们提供了交互式搜索选择模式和交互式编码模式来提升效率,如图所示:同时也提供了搜索结果排序、按列展示、全屏展示、格式化展示、搜索结果下载、搜索结果分享等辅助功能。4.3.2 实时日志流
第二类比较重要的分析手段是查看实时日志流,即按时序实时查看某个日志正在打印的日志或者基于筛选条件按时序实时查看某个日志正在打印的日志。与搜索模式一样,也支持输出结果按列展示、全屏展示、格式化展示等,如图所示:4.3.3 全链路检索
第三类常用的分析诊断场景是我们拿到了TraceID,需要通过TraceID查询完整的调用链,再追踪到某个服务的某个日志,如下图所示:严选的Trace(分布式链路追踪)是通过严选APM完成,日志打印组件可以通过上下文获取到当前的TraceID,因此通过日志也同样可以跟踪到端到端完整的调用链路。4.4 日志监控
这里提到的日志监控是基于日志文本的事件监控,是目前严选普及度最高的业务监控手段。严选日志平台支持基于日志文件添加日志监控,提供了日志滚动、正则文本匹配、ERROR日志三种监控方式。日志监控添加完成后,用户可以借助日志监控状态图表实时观测监控效果,如图所示:4.5 可拓展的应用场景
除了上述最常用的几个场景之外,我们在开发和运维过程中,也经常需要对以下这类指标进行统计、实时观测或监控报警:- 今天截止到现在总的下单量是多少?总销售额是多少?每个渠道的下单量和销售额是多少?
- 过去一段时间总支付成功率是多少?每个渠道的支付成功率是多少?
- 当前总峰值QPS是多少?下单接口的峰值TPS有多少?流量排名前十的是哪些接口?
这个时候我们就需要用到业务实时监控系统。
严选业务实时监控系统提供了海量数据的实时监控能力,支持日志、Kafka、binlog等多数据源接入、数据模型构建、监控大盘定制和报警配置。
其中日志数据源使用最为广泛,我们基于日志元数据和CMDB的基础数据抽象了语义非常简单极易上手的监控数据模型,包括时间、维度、度量、预聚合指标、计算指标、筛选条件及可见范围(业务域),通过监控数据模型可以生成实时计算任务及聚合索引,并最终通过业务监控大盘呈现。
还有一类在互联网产品中比较常见的应用场景是埋点。
埋点是指针对特定用户的行为或事件进行捕获、处理并最终存储到数仓,一般可以分为服务端埋点和前端(客户端或H5等)埋点两类,以严选为例,服务端埋点记录业务行为操作,可用于审计场景,前端埋点记录用户行为,多用于用户行为分析、风控等场景。
以前端埋点为例,日志平台解决了埋点日志采集和入仓的问题。
另外,我们还将日志数据应用在DevOps平台、APM、全链路排障平台等多个系统,从而构建起了完善的日志应用生态。
5. 架构剖析
严选日志平台的核心功能主要包括面向运维人员的控制面和面向普通用户的产品功能,其中:
接下来我们剖析下的支撑这些核心功能的底层架构(如图所示):
5.1 日志采集
在严选稳步推动应用容器化及业务上云的大背景下,必然会在比较长的时间内出现部分应用部署在虚拟机环境、部分部署在容器环境的情况,这也增加了我们日志采集场景的复杂度。如前文所述,早期严选在虚拟机环境采用Flume Agent采集日志,为了更加平滑地过渡到日志平台,我们沿用了Flume这个选型,并在开源版本的基础上进行了定制开发,实现了日志采集配置可基于日志元数据动态生成与下发、实现了日志文件级别的限流与资源隔离、丰富可观测的指标,同时也用更合理的方式处理文件句柄(FD)及日志滚动轮转,提升了稳定性与可靠性。在容器环境,我们对比了主流的开源日志采集组件,综合考虑到性能、资源占用、生态、社区活跃度等因素,我们选择了Filebeat作为我们容器环境的日志采集组件。然而这个工作也并不是非常顺利,由于Filebeat本身并不支持容器化日志采集、日志级别的资源隔离,可观测指标也不够丰富,与数据路由(基于Flume)之间没有现成的数据传输协议,我们需要投入较多的定制开发,由于Filebeat的架构极其复杂,在我们的应用进入深水区之后,扩展的成本及因此带来的稳定性风险也越来越大,最终我们决定自研新的日志采集组件(Loggie)。Loggie是一款基于Golang的轻量级、高性能、云原生数据采集Agent和中转聚合器,目前我们已经在容器环境中完全替换了Filebeat,表现稳定,资源开销方面的表现也非常优异,CPU消耗仅为Filebeat的1/4,发送吞吐量为Filebeat的1.6~2.6倍,同时也可以基于管道实现日志级别的资源隔离。另外,为了降低采集端Agent替换的成本,我们在设计日志平台架构时,通过标准化接入的方式使Agent插件化,从而实现Agent与日志平台其他组件及产品核心功能解耦。在容器环境,除了明确选型还需要确定部署架构,通常基于Kubernetes有两种方式:- Sidecar:每个业务应用Pod部署的时候增加一个Sidecar用于运行日志采集的Agent,采集该Pod产生的日志。
- DaemonSet:在K8S的每个节点上部署日志采集的Agent,采集节点上所有容器的日志。
我们最终采用的是DaemonSet方式,DaemonSet在稳定性、对业务的侵入性以及资源占用方面有明显优势,比较适合严选这类独立资源、自建集群的架构,同时Loggie在隔离性和性能方面也已能满足需求。5.2 日志缓存
日志被采集后会被暂时保存到消息队列中,从而实现日志数据源与日志处理引擎的解耦,这样设计主要有以下几个方面的好处:- 日志最终会应用到各类场景,比如被转移到数据湖用于离线分析、存储到ES集群用于日志检索或聚合计算各类业务指标等等,通过消息队列可以完美实现日志数据的接收、存储与分发,避免重复采集日志,极大减少资源开销。
- 日志数据与业务的流量波动几乎一致,电商场景有明显的流量峰谷,消息队列可以帮助我们实现削峰填谷。
- 消息队列可以将日志数据保存一段时间,如下游日志处理出现故障或日志数据出现丢失,可以从消息队列中快速恢复数据。
选型方面,我们沿用了Kafka,主要基于以下几点原因:- 高性能:Kafka是一款高吞吐量、低延时的分布式消息订阅中间件,即使用普通的硬件,也可以同时为发布方和订阅方提供每秒百万级别的吞吐量,也可以轻松支持数千个客户端同时读写。
- 容错性:Kafka集群可以在部分节点失效的情况下继续提供稳定服务。
- 高可靠性:消息被持久化到本地磁盘,且支持数据备份防止数据丢失。
当然,Kafka也存在一个比较大的设计缺陷,即在集群的Topic数量达到一定的阈值之后,性能就会和Topic数量成反比衰减,因此一般需要进行针对性的调优或者引入更多的集群,相对而言,Pulsar在这方面做得更加出色,有非常大的潜质在未来被大范围应用在日志流处理场景。5.3 数据路由
首先要回答的是为何需要引入数据路由层以及Kafka集群是否可以扮演数据路由层的角色?很显然,如果日志采集端Agent可以实现将日志数据直接存储到Kafka集群,这种部署架构也更为简单,也少了一层网络传输开销,减少了服务器成本,似乎非常完美,但实际上,在大规模日志采集场景,这种架构存在两个非常重要的缺陷:- 扩展性差:一旦Kafka集群发生变更或者任何配置参数发生变更,所有Agent端的配置都需要修改。
- 稳定性差:如果大量Agent直连Kafka集群,会对Kafka集群造成非常大压力。
- 日志采集端的Agent可以做到轻量级,无需引入太多的处理逻辑(比如日志分流、权限验证等),保证日志采集效率的同时不会占用太多应用服务器资源。
- 避免大量Agent直连Kafka集群,提升稳定性。
- 每个日志都会发送到独立的topic,随着日志数量的不断增加,Kafka集群扩容或者新增集群将是大概率事件,引入数据路由层可以避免日志采集端Agent出现大面积Reload。
- 由于Kafka集群有大量的消费者,通过调整Kafka来实现资源隔离或者流量管控成本太大,而通过数据路由层可以更高效的实现资源隔离或者流量管控,避免让Kafka集群直面突发流量。
数据路由类似于日志数据网关,我们在内部也通常会称它为中转机,在严选日志平台的整体架构中扮演关键作用:- 不仅可以实现日志数据分流、流量削峰填谷、简单的数据校验、协议转换、安全控制等功能。
- 也可以实现全局日志流量与资源的可视化,并在此基础上实现限流、资源隔离、流量调度及扩缩容。
严选曾经多次出现过业务流量突增,造成指标延迟影响决策效率与质量,借助数据路由的设计,可迅速识别到水位异常,进行针对性的扩容以及流量调度,即能迅速缩小采集延迟,又可能避免与其他日志竞争资源。最后谈一下选型,在主流的开源的组件中,Flume架构比较适合做数据路由,可以实现管道级别的资源隔离,同时也可以为每个管道定义不同的输出源,且支持并行处理,但在性能上有一定不足。因此,我们在自研Loggie的时候也考虑了Aggregator这种部署方式用于数据路由。5.4 日志实时处理
接下来,我们需要对采集到Kafka集群中的日志进行实时处理,应用到日志监控、业务监控、日志检索等准实时应用场景,在19年年初,我们主要有两个选择:- Logstash即ELK中的L,可以将日志切分成结构化的日志数据后再存储到ES中,是严选19年之前的解决方案,已经部署了一个小集群,但Logstash性能较差,并不适合大规模部署。
- Flink是一款大数据流式处理引擎,满足大数据规模、高吞吐、低延时、易于扩展、故障后可快速恢复等特点,当时已经比较成熟并在严选内部正逐步扩大应用规模,因此资源上相对也比较宽裕。
最终我们选择了基于Flink来实现日志的实时处理,主要基于以下几个方面的考虑:- Flink任务可以很轻松的实现日志格式检查、文本匹配、业务指标聚合等扩展功能,也可以实现日志存储(存储到数据湖、ES),而Logstash的功能职责则比较单一,因此,Flink更符合我们的使用需求。
- Flink是严选大数据实时计算平台的底层引擎,和大数据共用实时计算集群可以实现资源的最大化利用,相对而言,Logstash的使用场景则会非常单一,会造成很大的资源浪费。
如果没有部署Flink集群,Loggie也提供了基础的日志处理能力。5.5 日志存储
日志平台提供了三个最常用的数据源:Hbase集群(数据湖)、检索ES集群及聚合指标ES集群。
离线场景的日志数据都会进入Hbase集群,比如埋点分析、日志审计、日志归档等,这里不做进一步展开。
在准实时应用场景,主要以检索和监控场景为主,其中检索场景我们选择了ES,监控场景我们主要从Hbase、ES和TSDB中做了选型,我们从灵活性、稳定性以及团队的运维经验综合考量,最终也选择了ES。
无论是检索还是监控场景都会建立大量的索引,且在索引创建阶段往往很难预测未来的数据量,这也给ES集群的稳定性以及性能调优带来了非常大的挑战,目前我们主要基于峰值流量等数据设置分片数、刷盘频率等来进行优化。
存储这块未来还有比较大的探索和优化空间,也可以根据特定场景的需要引入类似ClickHouse等新的存储引擎。
6. 面临哪些挑战
19年底,严选日志平台的功能已基本成型,然而要做到真正好用却并不容易,在冰山之下,我们需要解决大量的核心技术问题,比如如何高效率的采集和处理大规模日志并确保稳定性、如何持续提升性能降低延迟、如何降低运维成本等等。
接下来,我会从三个方面来谈一谈我们面对这些挑战的一些实践与思考。
6.1 限流与资源隔离
无论是Flume Agent还是Filebeat Agent要提升日志采集的吞吐量,都需要消耗更多的CPU和内存,这样显然会形成与业务系统之间的资源竞争。以我们压测的数据为例,48C、256G的物理机上通过DaemonSet的方式部署Filebeat,在不打开数据压缩及限流的情况下,极限日志采集速率为80MB/s,最高消耗CPU达到了11C,这种情况很容易造成业务应用的容器被驱逐,从而影响业务的稳定性。另外,日志采集场景有三个比较典型的特点:日志文件多、文件大小各异、日志打印源头难以管控,如果不加以有效干预,非常容易出现由于某个不重要的日志打印量突增,造成服务器CPU飙升,其他重要日志被阻塞采集。因此,我们需要在性能与资源之间寻找一个平衡点,限流、资源隔离以及Agent性能调优是三个核心策略,这里重点说下限流与资源隔离。6.1.1 限流
Flume可通过扩展Interceptor来限制单位时间内每个日志文件采集的行数,因此,如果一台服务器采集的日志数量比较多、日志打印的总量又比较大时,仍然有可能会出现CPU和Load较高的情况出现。不过从严选生产环境的实际情况来看,这种情况极少出现,而且一般出现之后,即使没有日志采集Agent,日志打印也同样会给磁盘和IO的较大的压力,所以,我们认为Flume的这种限流策略配合上监控报警仍然是有效的。
而Filebeat在解决限流问题的理念则完全不同,它通过背压敏感协议可以灵活的根据下游日志的消费速度来调节Agent的读取速率,这种方式会极致的利用采集端的CPU和内存,因此,我们需要同步限制Agent最大可使用的CPU和内存以达到更好的限流效果。
Loggie则汲取了两者的优势,我们可以根据场景需要向配置文件中注入不同的Interceptor来灵活启用限流或背压敏感协议,同时也可以利用容器化的优势限制CPU和内存。
6.1.2 资源隔离
在Flume架构(如下图所示)中,Channel可以将Source和Sink连接在一起,可以确保数据收发的一致性,不同的Channel之间可以做到逻辑上的隔离,因此,在日志采集端,我们为每一个日志文件抽象为一组独立的Source-Channel-Sink,从而实现了日志文件级别的资源软隔离。
但Filebeat就没有这么幸运了,Filebeat只有一个Queue,只能支持一个Output(6.0之前的版本支持发送到多个不同类型的Output,6.0之后只支持发送到一个Output),这样会导致:- 同一个Filebeat不能将数据同时发送到多个不同的Kafka集群,也不能同时发送到Kafka集群、ES集群或其他Output。
- 如果某个日志的日志量剧增造成中转机的某一条链路阻塞,会造成Filebeat Agent所在节点上所有的日志全部发送失败、Queue堆积。
我们猜测Filebeat这么设计背后应该是考虑到了和Logstash定位的差异化,导致很难通过扩展实现资源隔离。再来看Loggie,它通过多管道的设计来实现资源隔离,每个管道支持发送多个不同日志文件(数据源),日志平台也可以按需将日志分配或调度到不同的管道中,这样就可以避免部分节点故障或者阻塞的情况下也不会影响重要日志的采集与处理。6.2 全链路可观测与可管控
- 在日志平台查询到的日志、配置的日志监控或者业务监控延迟有多大?
- 日志是完整的吗?如果不完整的话,是在哪个环节出现异常了?如何补全?
假如你是日志平台的运维工程师,面对如此长的链路、各类可能异常的组件以及成千上万个节点,如果没有提供可观测能力的工具,排障将是极其困难的,如果没有产品化运维能力,定位问题之后的恢复也将是一件非常耗时的工作。因此,要做到运维提效就需要实现日志平台全链路可观测与可管控,主要有三个步骤:- 首先是采集全链路各组件的运行状态,主要包括为每一类组件定义出标准化的metrics,并结合实际运维过程中遇到的问题,定义出丰富的异常码以辅助问题快速定位,基于这些数据或事件,可以构建独立的系统监控闭环:
- 不仅可以实时观测各个节点上各个组件的运行状态,比如采集Agent是否存活、是否存在阻塞、是否存在采集异常以及存在哪种异常等等。
- 也可以从全链路的视角来实现异常的自主发现,比如通过Agent上报的文件校验信息与实际采集的日志信息可以判断采集延迟、当前采集进度以及判断当前日志是否存在丢失等。
- 其次是数据路由网关化,前文提到,我们在架构中引入了数据路由(即中转机),借鉴API网关的设计理念,通过管道将服务器的资源网格化,通过平台控制面规则配置可灵活控制资源隔离的粒度,通过监控管道的流量实现对全局水位的监控和预警。
- 最后是实现全链路资源可管控,日志平台通过自带的控制面可直接管控采集端Agent和数据路由的资源,控制流速及水位,通过运维工具来管控Kafka、Flink和ES的资源,比如调整Kafka的分区、合并Flink任务、调整ES的分片等。
6.3 自动化运维
具备了全链路可管控的运维能力之后,我们也对自动化运维进行了探索和尝试,以应对电商场景的突发流量、提升资源的利用率,而这其中,价值最大的当属资源的弹性伸缩、大日志自动巡检和日志自动清理。6.3.1 资源弹性伸缩
每个日志的流量很难提前预测,需要根据实际业务的运行情况不断进行调整,否则就会带来资源浪费或者采集处理延迟,通过实现资源的弹性伸缩,一方面可以提升日志的采集和处理速度,降低各类应用场景的延迟,另一方面,也可以极大提升资源的利用率,降低成本。这里重点讲下数据路由(中转机)和实时计算平台(Flink)的弹性伸缩策略。- 主要包括三个等级的日志:需要重保的日志、进入数据湖的业务日志和访问日志、应用日志,一般情况下应用日志可以被降级采集,降级将带来全链路资源的释放,包括数据路由、Kafka、Flink、ES等等。
- 根据不同的日志等级配置不同的资源超售,减少重点日志的资源竞争。
- 通过控制面设置每个管道的基础配额与上限配额,基于水位、预警线等信息进行弹性伸缩。
- 重保日志设置为高优先级,支持资源独占,低优先级可被降级(如大促峰值到来前)。
- 一个Flink任务同时处理一组日志,同时允许动态调整分组。
- 结合Flink任务资源使用率、日志流量等信息,自动调整资源。
6.3.2 大日志自动巡检与日志自动清理
大日志打印是生产环境的重要隐患,尤其在高并发场景下,极容易造成磁盘IO、CPU、LOAD飙升的情况,严重时甚至直接导致服务宕机。另外,大量的日志打印也会造成磁盘空间不足,带来稳定性隐患,尤其在应用上云之后,每个Pod分配的云盘资源更少,这种情况也更容易发生。- 大日志打印:日志采集时会同步计算每行日志的大小,因此,可以借助自动化巡检工具,轻松发现大日志。
- 传统的方法是发现磁盘不足后,根据时间序列删除更早的文件或者根据文件大小删除较大的文件,这样带来的隐患是日志可能还没有备份,影响问题排查或者指标计算。
- 而日志平台可以判断日志是否已经被完全采集,在判定采集完成(日志不活跃N天)之后,根据配置的保留时间或者容器迁移、销毁事件,触发自动清理。
7. 未来:反哺社区
严选日志平台在持续的迭代和运营过程中,我们切身感受到了开源社区主流日志组件存在的问题与痛点,并不是每家公司都像网易一样有足够强的研发力量去深度定制这些开源组件,因此,在20年底,我们与网易数帆的同事一起,正式开始筹备开源,希望将我们的工作成果可以更多的反哺给社区,这个想法也得到了集团内部和CNCF中国区的欢迎与支持。21年3月,日志开源项目正式在网易内部立项,从此它也有了新的名字:Loggie。经过了一年多的筹备,Loggie(项目地址:https://github.com/loggie-io/loggie)在今年3月正式正式开源,相比于开源社区目前主流的日志采集组件,在很多方面具备明显优势:- 强隔离:多管道设计,减少互相干扰,可同时发送多个不同数据源,也可实现管道级别的Reload。
- 轻量级、高性能:基于Golang,并充分发挥了Golang的性能优势,实现了极少的资源占用与强大的吞吐性能,我们与同样基于Golang的Filebeat进行了压测性能对比,CPU消耗仅为Filebeat的1/4,发送吞吐量为Filebeat的1.6~2.6倍。
- 灵活的可插拔和可扩展能力:使用了微内核、组件化的架构,可以通过配置不同的Source(输入端)、Interceptor(拦截器)、Sink(输出端),快速拥有数据路由、过滤、解析、切分、日志报警等能力,开发者也可以根据自己的需求快速开发新的Source、Interceptor、Sink。
- 更好的云原生支持、开箱即用:支持Kubernetes容器日志采集,支持Agent和Aggregator两种形态,支持Sidecar和Daemonset等多种部署架构,兼容Filebeat配置,支持动态配置下发,可轻松接入到各类容器云平台。
- 更好的稳定性、更完善的可观测性、更便捷的排障方式:
- 通过配置interceptor可支持限流、背压,通过配置不同的管道可实现日志级别的资源隔离。
- 结合我们在生产环境中出现的各类实际问题,沉淀了丰富的可观测指标,可快速发现文件异常增长、发生延迟等常见问题。
- 支持原生Prometheus metrics,无需额外部署exporter;同时提供了完善的Grafana监控图表,可以方便快速接入使用。
现在,Loggie已在传媒、邮箱等集团内多个兄弟事业部落地,也吸引了10多位来自不同公司的Contributor参与开源贡献,相信在大家的共同努力下,未来Loggie可以发展到新的高度。
8. 写在最后
严选日志平台从2019年3月正式发布已过去三年有余,现在已经是我们日常开发和运维过程中最常用的系统之一。回顾过去几年,曾经有十多位同学带着对技术的热爱先后加入了日志平台项目组,或许这也是严选存续时间最久的虚拟项目组,虽然绝大部分同学是兼职参与,但这份热爱是百分之百的,也正因此,我们走过来的每一步都格外踏实。现在,我们携手数帆的同事将日志平台的底层引擎Loggie正式向社区开源,也希望将这份热爱传递给更多的人。
本文由作者授权严选技术团队发布