如何建设高吞吐量的日志平台

7 月 24 日晚上 8 点,七牛云高级大数据架构师王珂在飞马网进行了题为《如何快速搭建智能化的统一日志管理系统》的音频直播,和大家探讨了日志平台建设中需要考虑的要点,并分享了七牛云在提高日志平台吞吐量上的实践经验。本文是对直播内容的整理。
日志样例
上图列举了一些日志的例子,方便大家了解日志 概念,这里简单解释一下前两项。
第一项是某网站的用户行为日志,以这条日志为例,包含了两类信息:一类是用户信息,例如「city」 这个是用户 访问来源地点 ,「useAgent」 用户的浏览器版本 ;还有一类是程序信息,例如 「pageSize」 还有 「pageView」表示页面尺寸。
第二项是一个典型的 nginx 服务的日志,「remote_addr」 是请求来源地址,「request」是请求内容,「status」 是请求状态码。
三个基础问题
关于日志有三个基础的问题。
第一个问题,什么是日志?
维基百科上的描述是:日志是设备或者程序对自身状态和运作行为的记录。这里我的理解是,现在设备和程序会按预先定义好的模式输出自身的事件信息,这些事件信息被写入到文件或者数据库中就形成了日志;所以,日志实际上是对于事件信息的记录,上例中的nginx日志就是对一次请求事件的记录。
第二个问题,为什么需要日志?
为什么需要日志呢?因为设备和程序通过事件输出了运行状况相关的关键信息,例如服务器是否出现过异常,出现了什么异常,这些事件是设备和程序在设计时候预先定义好的,用来帮助使用者进行维护的。日志记录了事件,通过日志就可以看到设备和程序运行的历史信息,通过这些信息,可以了解设备和程序运行情况的变化,以更好的对于设备和程序进行维护。
第三个问题,什么时间需要日志?
主要是在系统出现问题的时候,通过对于运行过程中发生的历史事件,可以查找问题出现的原因。另外,统计系统的运行指标时也需要日志。
日志平台建设探讨
ELK 方案介绍
业内最常见的日志采集方案就是 ELK,ELK 分别是方案中 3 个组件的缩写。
• E 是 Elasticsearch,它是一个开源的实时分布式搜索引擎,它主要被用作日志数据的存储和搜索。
• L 是 Logstash,这个组件是日志解析工具,用于通过正则表达式解析,将日志中的字段分解出来再传入 Elasticsearch 中。
• K 是 Kibana,这个组件是展示工具。用于展示保存 Elasticsearch 中的日志数据,通过可视化的图表可以清楚了解到一段时间内日志中新进入了多少条记录,即发生了多少个事件,还可以看到不同类型的事件数目随时间的波动情况。
在 ELK 出来之前,日志管理基本上都是通过登陆日志所在机器然后使用 Linux 命令或人为查看和统计 ,这样是非常没有效率的。ELK 有三个优点:快速、易上手、可扩展 :快速,ELK 将日志统一存储在 Elasticsearch 中,通过搜索查询日志的速度要比登陆机器上查询要快速的多;易上手,ELK 本身部署方便,通过官网上的教程就可以搭建起一套简单的 ELK;可扩展,Elasticsearch 和 Kibana 都有一些扩展插件,扩展插件提供了很多新的功能可以使用,和 Logstash 与 Kibana 具有相同功能的开源组件也有不少,可以按照使用的场景进行替换。
其他日志相关组件介绍
除了 Logstash 还有几种常用日志采集工具。
• Rsyslog 一般用于收集系统的 syslog 日志;
• Fluentd 主要用于容器日志收集;
• Filebeat go 语言编写,专注于文件日志收集;
• Flume 在传输链路中增加了 Channel 组件作为数据缓存,可以把数据保存到磁盘上以避免数据丢失。
收集日志时除了收集工具还会用到缓存组件,主要的缓存组件有 2 个:Kafka 消息队列和 Redis 内存数据库。
• Redis 主要用于小数据量低延迟要求的场景,多数情况下和 Storm 联用来处理实时数据。
• Kafka 是通用的消息队列组件,适合场景比较多,类似 Kafka 的消息队列组件还有几种。
构建日志采集方案的三要素和四原则
使用接入工具和缓存组件构建日志采集方案时,我们需要考虑的三个要素:时效性、数量级和复杂度。
• 时效性就是日志是否需要保障低时间延迟的传输,即我的设备和程序发生的事件需要在最短时间内拿到,还是可以允许有延迟,允许多长时间的延迟,几分钟还是几小时、或者半天也行。在方案制定过程中,时效性决定了是否要选择 Storm 实时流式方案。并作为测试过程的硬指标发挥作用,在模拟测试环节判断方案是否可用。
• 数量级是对于日志条目数和空间大小的衡量要素。运行出错才做事件记录的程序日志和每秒收集一次传感器日志在数据条目和文件占用的磁盘空间上是有很大区别的,进行采集的时候对于采集组件的要求也是不同的。数量级影响采集工具和缓存组件的选择,在方案制定过程中,每天采集的条目数超过百万时候就需要增加缓存组件了,条目数过亿时候就需要考虑如何平衡数据写入和数据查询的资源了。
• 最后一个要素就是复杂度,采集方案复杂度的产生主要由于原因:数量级、网络环境和采集工具。在数量级要求下,我们不得不添加缓存组件,把日志先写到 Kafka,再把日志写到 ES,增加一个 Kafka,就需要考虑 Kafka 的高可用问题和数据丢失问题,方案复杂度就提升了。方案的复杂度会影响方案的实施难度和维护难度,复杂度太高的方案即使设计出来也比较难落地。
考虑到这三种因素,我们在选择日志采集方案的时候要考虑到四个原则。
• 时效性要求不高,数量级也不大的情况优先采集文件,因为文件是最简单的也是最好采集的。
• 在日志生成的过程中解决解析问题,而不是在传输过程中,也就是在日志生成的过程中就约束它的格式,而不是考虑在传输过程中统一它的格式。大部分的采集工具都支持中间改写日志信息,增加内容或者拆分内容,这些操作实际上增加了采集方案的复杂度,也使得替换采集工具的成本增加,需要尽量避免。
• 不同的日志都有它的特点,那么是不是我们每一个具体的场景,都要选择不同的工具呢 ?我觉得是需要比较这个工具的特点带来的收益和增加工具来的的复杂度变化,如果新增工具不会对于原来的组件产生影响,也不会新增开发内容,运维上也能接受;那么是可以增加工具的,否则工具数量越少越好。
• 如果数据量比较大的话,就要考虑多级的缓存处理。引入缓存主要就是为了分离上下游操作,在不影响 ES 性能的情况下,写入更多的数据。
规划容器日志采集方案的要点题
由于现在容器概念比较热,单独和大家聊一下容器日志采集需要考虑的内容。
01 采集方式
• 现在主流容器分配管理都是用的 K8s 架构,K8s 日志数据的收集比较简单,可以直接从 var/log/containers 下按照文件的形式获取;内部应用日志使用 Daemonset 的方式部署日志收集工具就可以完成收集。
• 如果没有使用 K8s,仅使用了 Docker ,日志数据的收集会稍微麻烦一些,容器自身的 stdout 可以通过 Docker 自带的 logdriver 去归集。容器内部的应用日志,可以通过 Docker 自带的一些命令查看,或者使用第三方组件,比如 fluend-pilot 可以收集这部分日志。对于七牛云的实践来说,你也可以把容器内的日志投递出去。
02 常见业务需求点
• 避免容器迁移中日志丢失:在 K8s 中用 PVC 做持久化存储,将日志都写进去即可。 但带来的额外问题是,需要管理这个持久化存储。
• 支持多种日志采集工具:每种日志采集工具配置不同的 Pod,然后用 Daemonset 去调用。
• 在容器内应用日志中体现容器信息:K8s 1.7 里面提供了一个功能,在启动容器时可以把容器的信息写成容器内的公有变量。另一种方式在 Daemonset 里还是能够拿到容器系统变量的。
七牛云日志平台面临的挑战

七牛云日志平台日志主要有三个来源,第一是七牛云存储系统的日志,第二个是七牛云容器平台的日志,第三个是使用七牛云智能日志管理平台的客户上传的私有日志。现在日均数据流入量超 250 TB,3650 亿条,其中最大的客户日均数据流入量超过 45 TB。
七牛云日志平台面临的主要挑战如下:
• 数据量大,需要稳定支持大量数据的写入和查询;
• 数据来源多,需要支持多种数据源的数据采集,并且采集过程要稳定可监控;
• 平台用户功能需求多,需要支持丰富的扩展功能;
• 平台用户大部分是企业用户,需要支持多租户场景,并提供用户权限管理功能。
其中最大挑战,就是如何把大量的数据,高效的存储下来,保障数据不丢失的同时尽可能减少资源占用。
七牛云日志平台架构介绍
七牛云平台在技术选型阶段对于 ELK 方案进行了深度的使用和测试,具体实践中发现 ELK 方案主要有以下 4 点问题:
• ELK 方案达不到七牛云在超大规模数据量的情况下系统稳定性及数据处理性能的要求;
• ELK 方案达不到七牛云在多种数据源采集稳定性上的要求;
• ELK 方案达不到七牛云用户多租户的要求;
• ELK 方案达不到七牛云在机器学习等拓展功能方面的要求。
最终评估的结果是 ELK 方案并不能解决七牛云面临的挑战,所以七牛云走上了自研的道路,当前七牛云的日志平台架构描述如下。
• Logkit:统一采集日志数据,支持上百种数据源(包括文件、MySQL、MSSQL、ElasticSearch、MongoDB、AWS CloudTrail 等);支持在采集端完成对数据格式的解析与字段转换;内置 Channel 组件保证传输过程中数据不丢失;可以通过管理界面查看采集任务状态并管理任务配置。
• Pipeline:日志平台统一的入口,可以接收从 log 文件、SDK、Web 端、IOT、云存储上通过 API 传输过来的数据。数据进入 Pipeline 后,我们基于 Kafka 做了实时计算组件,支持自定义的计算过程,计算的结果我们通过 Export 组件,根据不同情况将数据传输到后台 3 种存储组件当中。
• Insight 集群:七牛云基于深度定制的 ES 开发的日志存储组件,主要用于支持超大规模日志数据的检索查询。另外,Insight 集群可以支持多租户的使用要求,并且集成了监控告警、报表和机器学习等拓展功能;
• 七牛云的对象存储:七牛云通用存储组件,用于存储过了搜索期的冷数据,并支持自定义离线计算过程进行数据分析;
七牛云经验分享-吞吐量问题
七牛云是如何解决日志平台吞吐量的挑战的呢?
首先,Pipeline 的 Kafka 集群通过扩展,是能够承接百 TB 级别的数据的;那么问题的瓶颈就变成了如何将百 TB 量级的数据从 Kafka中写入到 ES 上。由于原始数据进入到 Pipeline 中可能存在计算流程,负责写入 ES 的 Export 组件是不能直接从 Kafka 中拉取数据的,只能等待 Pipeline 的调用,即 Export 不能自主的安排写入进度而是必须要和用户的数据操作保持一致。在这样的情况下,Export 是不能直接去写 ES,因为可能同时出现多个用户的数据需要执行写入操作的情况,如果 Export 直接去写入,会产生资源竞争和阻塞。
数据传输优化思路

七牛云对数据传输优化主要分为 2 部分。首先,我们把获取 Kafka 数据、数据格式转换和过滤操作放在 Export 中操作,保持 Export 操作完成后的数据是可以直接写入 ES 中的;基于客户任务的调度的操作也放在 Export 这里,跟踪 Export 的状态就可以把数据接入的情况实时的反馈给客户。然后,在 Export 下面,我们做了一层传输队列层,通过传输队列提供缓存,数据先进入传输队列,然后根据当前 ES 的情况非对称的写入,保障数据写入过程不影响客户的查询检索,并且设计了一些故障恢复的措施。
传输队列架构图

传输队列的实现是基于内存队列和本地文件队列,这就跟 Flume 的 Channel 是相似的概念。但是在实现的过程中,还对它做了一些额外的分装。首先是 agent 组件,agent 可以理解为 scheduler 组件,它负责任务的创建和分配;第二个是 transaction 事务池,这个内存队列的入队和出队,都是通过 transaction 的事务池去处理的。为什么这里要用事务的概念?因为我们在写入 ES 的时候,如果写 200 条数据,会告诉我们有 150 条数据写进去了,有 50 条数据没有写进去,它不会区分是哪 50 条没有写进去。所以说,在这里使用 transaction 的意义就在于,如果真实的情况下,我们遇到这种情况,可以这 50 条数据重新发回 memary queue 里面,让内存队列继续写这 50 条数据。
事务池的设计

这是 transaction 内部的一个情况,当数据进入 Channel 的时候,如果有空间进,就会正常的写入数据;如果没有空间进,会返回 503 的错误。当数据出 Channel 以后,通过 transaction 保证数据的写入是完整的,如果这一次写入不成功,会将一些没有写入的数据回滚到 Channel 中。当数据需要停止的时候,会先停止下游的 sink ,并且启动一些磁盘的 sink ,将数据回滚到 Channel ,再通过磁盘 sink 写入到本地磁盘中。最后启动的时候,会直接先从本地磁盘把数据写入到 Channel 里面,然后再从正常的数据流中去写 Channel。
通过传输队列层的设计七牛云实现了大量数据的稳定写入,整体上看传输队列通过多级缓存和任务分解机制实现了动态资源调配,将任务不断的分解,然后根据 ES 的情况,逐步把分解后的小数据块写入到 ES 中,避免了 ES 因为大量写入而崩溃;同时从 Kafka 取出数据后操作一直在内存中进行也保证了数据传输的速度。
七牛云智能日志管理平台

七牛云智能日志管理平台 能力全景图
基础功能

前边分享了我们的架构设计和实践经验,而在功能细节上,我们也针对传统方案的缺陷,比如 ELK 无法解决的需求点,进行了自主研发调优。
• 数据采集层面,logkit 可以实现可视化的数据采集;并且在采集数据的过程中,可以看到实时流量和细分到每台机器的情况。
• 日志搜索层面,我们支持多用户与用户权限管理;,可自动完成 Reblance 操作,无需用户过多关注,不会影响用户的查询效率;对于 ES 写入也做了深度的优化,可以在大量数据写入的同时保证 ES 的查询效率。
• 数据可视化层面, 我们提供了用户体验极佳的搜索界面,并且提供了完整的报表体系,轻松满足用户的所有报表需求。另一方面,除了原生支持监控告警外,我们也支持对接第三方可视化工具,如 Grafana。
智能化组件

考虑到未来数据智能的趋势,我们还为用户提供了机器学习组件。组件的操作门槛很低,只要选定对应的索引和关注的指标 ,就能自动对指标曲线做学习建模;实现通过监控指标数据,智能发现异常值比如及时发现漏报情况;同时基于历史数据的全面学习我们也支持未来趋势的预测,可按时间纬度给出未来的预测曲线。
七牛云智能日志管理平台覆盖了数据的全生命周期,适用于运维监控、安全审计及业务数据分析等场景,致力于降低用户的心智负担,帮助客户数字化升级。
牛人说
「牛人说」专栏致力于技术人思想的发现,其中包括技术实践、技术干货、技术见解、成长心得,还有一切值得被发现的内容。我们希望集合最优秀的技术人,挖掘独到、犀利、具有时代感的声音。