百亿级日志系统架构设计及优化'

本文将从海量日志系统在优化、部署、监控方向如何更适应业务的需求入手,重点从多种日志系统的架构设计对比;后续调优过程:横向扩展与纵向扩展,分集群,数据分治,重写数据链路等实际现象与问题展开。前端

日志系统架构基准

有过项目开发经验的朋友都知道:从平台的最初搭建到实现核心业务,都须要有日志平台为各类业务保驾护航。程序员

clipboard.png

如上图所示,对于一个简单的日志应用场景,一般会准备 master/slave 两个应用。咱们只需运行一个 Shell 脚本,即可查看是否存在错误信息。面试

随着业务复杂度的增长,应用场景也会变得复杂。虽然监控系统可以显示某台机器或者某个应用的错误。算法

然而在实际的生产环境中,因为实施了隔离,一旦在上图下侧的红框内某个应用出现了 Bug,则没法访问到其对应的日志,也就谈不上将日志取出了。数据库

另外,有些深度依赖日志平台的应用,也可能在日志产生的时候就直接采集走,进而删除掉原始的日志文件。这些场景给咱们日志系统的维护都带来了难度。后端

clipboard.png

参考 Logstash,通常会有两种日志业务流程:缓存

正常状况下的简单流程为:应用产生日志→根据预约义的日志文件大小或时间间隔,经过执行 Logrotation,不断刷新出新的文件→按期查看→按期删除。安全

复杂应用场景的流程为:应用产生日志→采集→传输→按需过滤与转换→存储→分析与查看。性能优化

clipboard.png

咱们能够从实时性和错误分析两个维度来区分不一样的日志数据场景:服务器

实时,通常适用于咱们常说的一级应用,如:直接面向用户的应用。咱们能够自定义各种关键字,以方便在出现各类 error 或 exception 时,相关业务人员可以在第一时间被通知到。

准实时,通常适用于一些项目管理的平台,如:在须要填写工时的时候出现了宕机,但这并不影响工资的发放。

平台在几分钟后完成重启,咱们能够再登陆填写,该状况并不形成原则性的影响。所以,咱们能够将其列为准实时的级别。

除了直接采集错误与异常,咱们还须要进行分析。例如:仅知道某人的体重是没什么意义的,可是若是增长了性别和身高两个指标,那么咱们就能够判断出此人的体重是否为标准体重。

也就是说:若是能给出多个指标,就能够对庞大的数据进行去噪,而后经过回归分析,让采集到的数据更有意义。

此外,咱们还要不断地去还原数字的真实性。特别是对于实时的一级应用,咱们要能快速地让用户明白他们所碰到现象的真实含义。

例如:商家在上架时错把商品的价格标签 100 元标成了 10 元。这会致使商品立刻被抢购一空。

可是这种现象并不是是业务的问题,很难被发现,所以咱们只能经过日志数据进行逻辑分析,及时反馈以保证在几十秒以后将库存修改成零,从而有效地解决此问题。可见,在此应用场景中,实时分析就显得很是有用。

最后是追溯,咱们须要在获取历史信息的同时,实现跨时间维度的对比与总结,那么追溯就可以在各类应用中发挥其关联性做用了。

clipboard.png

上述说起的各个要素都是咱们管理日志的基准。如上图所示,咱们的日志系统采用的是开源的 ELK 模式:

ElasticSearch(后简称 ES),负责后端集中存储与查询工做。

单独的 Beats 负责日志的搜集。FileBeat 则改进了 Logstash 的资源占用问题;TopBeat 负责搜集监控资源,相似系统命令 top 去获取 CPU 的性能。

因为日志服务对于业务来讲仅起到了维稳和保障的做用,并且咱们须要实现快速、轻量的数据采集与传输,所以不该占用服务器太多资源。

在方式上咱们采用的是插件模式,包括:input 插件、output 插件、以及中间负责传输过滤的插件。这些插件有着不一样的规则和本身的格式,支持着各类安全性的传输。

日志系统优化思路

clipboard.png

有了上述日志的架构,咱们针对各类实际的应用场景,进一步提出了四个方面的优化思路:

基础优化

内存:如何分配内存、垃圾回收、增长缓存和锁。

网络:网络传输序列化、增长压缩、策略、散列、不一样协议与格式。

CPU:用多线程提升利用率和负载。

此处利用率和负载是两个不一样的概念:

利用率:在用满一个核后再用下一个内核,利用率是逐步升高的。

负载:一会儿把八个核全用上了,则负载虽然是满的,可是利用率很低。即,每核都被占用了,可是所占用的资源却很少,计算率比较低下。

磁盘:尝试经过文件合并,减小碎片文件的产生,并减小寻道次数。同时在系统级别,经过修改设置,关闭各类无用的服务。

平台扩展

作加减法,或称替代方案:不管是互联网应用,仍是平常应用,咱们在查询时都增长了分布式缓存,以有效提高查询的效率。另外,咱们将不被平台使用到的地方直接关闭或去除。

纵向扩展:如增长扩展磁盘和内存。

横向扩展:加减/平行扩展,使用分布式集群。

数据分治

根据数据的不一样维度,对数据进行分类、分级。例如:咱们从日志中区分error、info、和 debug,甚至将 info 和 debug 级别的日志直接过滤掉。

数据热点:例如:某种日志数据在白天的某个时间段内呈现暴涨趋势,而晚上只是平稳产生。咱们就能够根据此热点状况将它们取出来单独处理,以打散热点。

系统降级

咱们在对总体业务进行有效区分的基础上,经过制定一些降级方案,将部分不重要的功能停掉,以知足核心业务。

在此我向你们推荐一个架构学习交流群。交流学习群号:478030634 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

日志系统优化实践

clipboard.png

面对持续增加的数据量,咱们虽然增长了许多资源,可是并不能从根本上解决问题。

特别体如今以下三方面:

日志产生量庞大,天天有几百亿条。

因为生产环境隔离,咱们没法直接查看到数据。

代理资源限制,咱们的各类日志采集和系统资源采集操做,不可超过业务资源的一个核。

一级业务架构

clipboard.png

咱们日志系统的层次相对比较清晰,可简单分为数据接入、数据存储和数据可视化三大块。

具体包括:

Rsyslog,是目前咱们所接触到的采集工具中最节省性能的一种。

Kafka,具备持久化的做用。固然它在使用到达必定数据量级时,会出现 Bug。

Fluentd,它与 Rsyslog 相似,也是一种日志的传输工具,可是它更偏向传输服务。

ES 和 Kibana。

clipboard.png

该架构在实现上会用到 Golang、Ruby、Java、JS 等不一样的语言。在后期改造时,咱们会将符合 Key-Value 模式的数据快速地导入 HBase 之中。

基于 HBase 的自身特色,咱们实现了它在内存层的 B+ 树,而且持久化到咱们的磁盘之上,从而达到了理想的快速插入的速度。这也正是咱们愿意选择 HBase 做为日志方案的缘由。

二级业务架构

clipboard.png

咱们直接来看二级业务架构的功能图,它是由以下流程串联而成的:

在完成了数据采集以后,为了节省本身占用磁盘的空间,许多应用会彻底依赖于咱们的日志系统。所以在数据采集完之后,咱们增长了一个持久缓存。

完成缓存以后系统执行传输。传输的过程包括:过滤和转换,这个过程能够进行数据抽稀。值得强调的是:若是业务方尽早合做并给予咱们一些约定的话,咱们就可以经过格式化来实现结构化的数据。

随后执行的是分流,其主要包括两大块:一种是 A 来源的数据走 A 通道,B 来源的数据走 B 通道。另外一种是让 A 数据流入到咱们的存储设备,并触发保护机制。即为了保障存储系统,咱们额外增长了一个队列。

例如:队列为 100,里面的一个 chunk 为 256 兆,咱们如今设置高水位为 0.七、低水位为 0.3。

在写操做的堆积时,因为咱们设置了 0.7,即 100 兆赫。那么在一个 256 兆会堆积到 70 个 chunk 时,咱们往该存储平台的写速度就已经跟不上了。

此时高水位点会被触发,不容许继续写入,直到整个写入过程把该 chunk 消化掉,并降至 30 个时,方可继续往里写入。咱们就是用该保护机制来保护后台以及存储设备的。

接着是存储,因为整个数据流的量会比较大,所以在存储环节主要执行的是存储的索引、压缩、和查询。

最后是 UI 的一些分析算法,运用 SQL 的一些查询语句进行简单、快速地查询。

clipboard.png

一般从采集(logstash/rsyslog/heka/filebeat)到面向缓存的 Kafka 是一种典型的宽依赖。

所谓宽依赖,是指每一个 App 均可能跟每一个 Broker 相关联。在 Kafka 处,每次传输都要在哈希以后,再把数据写到每一个 Broker 上。

而窄依赖,则是其每个 Fluentd 进程都只对应一个 Broker 的过程。最终经过宽依赖过程写入到 ES。

采集

如 Rsyslog 不但占用资源最少,并且能够添加各类规则,它还能支持像 TSL、SSL 之类的安全协议。

Filebeat 轻量,在版本 5.x 中,Elasticsearch 具备解析的能力(像 Logstash 过滤器)— Ingest。

这也就意味着能够将数据直接用 Filebeat 推送到 Elasticsearch,并让 Elasticsearch 既作解析的事情,又作存储的事情。

Kafka

clipboard.png

接着是 Kafka,Kafka 主要实现的是顺序存储,它经过 topic 和消息队列的机制,实现了快速地数据存储。

而它的缺点:因为全部的数据都向 Kafka 写入,会致使 topic 过多,引起磁盘竞争,进而严重拖累 Kafka 的性能。

另外,若是全部的数据都使用统一标签的话,因为不知道所采集到的数据具体类别,咱们将很难实现对数据的分治。

所以,在后面的优化传输机制方面,咱们改造并本身实现了顺序存储的过程,进而解决了必定要作持久化这一安全保障的需求。

Fluentd

clipboard.png

Fluentd 有点相似于 Logstash,它的文档和插件很是齐全。其多种插件可保证直接对接到 Hadoop 或 ES。

就接入而言,咱们能够采用 Fluentd 到 Fluentd 的方式。即在原有一层数据接入的基础上,再接一次 Fluentd。同时它也支持安全传输。固然咱们在后面也对它进行了重点优化。

ES+Kibana

clipboard.png

最后咱们用到了 ES 和 Kibana。ES 的优点在于经过 Lucene 实现了快速的倒排索引。

因为大量的日志是非结构化的,所以咱们使用 ES 的 Lucene 进行包装,以知足普通用户执行非结构化日志的搜索。而 Kibana 则基于 Lucene 提供可视化显示工具。

问题定位与解决

下面介绍一下咱们碰到过的问题和现象,以下这些都是咱们着手优化的出发点:

传输服务器的 CPU 利用率低下,每一个核的负载不饱满。

传输服务器 Full gc 的频次太高。因为咱们是使用 Ruby 来实现的过程,其内存默认设置的数据量有时会过大。

存储服务器出现单波峰现象,即存储服务器磁盘有时会忽然出现性能直线骤升或骤降。

频繁触发高水位。如前所述的高水位保护机制,一旦存储磁盘触发了高水位,则再也不提供服务,只能等待人工进行磁盘“清洗”。

若是 ES 的一台机器“挂”了,则集群就 hang 住了。即当发现某台机器没法通信时,集群会认为它“挂”了,则快速启动数据恢复。而若是正值系统繁忙之时,则此类数据恢复的操做会更加拖累系统的总体性能。

clipboard.png

因为全部数据都被写入 Kafka,而咱们只用到了一个 topic,这就形成了每一类数据都要通过不必定与之相关的规则链,并进行不必定适用的规则判断,所以数据的传输效率总体被下降了。

Fluentd 的 host 轮询机制形成高水位频发。因为 Fluentd 在与 ES 对接时遵循一个默认策略:首选前五台进行数据写入,即与前五台的前五个接口交互。

在咱们的生产环境中,Fluentd 是用 CRuby 写的。每个进程属于一个 Fluentd 进程,且每个进程都会对应一个 host 文件。

而该 host 文件的前五个默认值即为 ES 的写入入口,所以全部机器都会去找这五个入口。

假若有一台机器宕机,则会轮询到下一台。如此直接形成了高水位的频繁出现、和写入速度的降低。

众所周知,对日志的查询是一种低频次的查询,即只有在出现问题时才会去查看。可是在实际操做中,咱们每每经过检索的方式所有取出,所以意义不大。

另外 ES 为了达到较好的性能,会将数据存储在 raid0 中,存储的时间跨度每每会超过 7 天,所以其成本也比较高。

经过对数据的实时线分析,咱们发现并未达到写入/写出的平衡状态。

为了提升 Fluentd 的利用率,咱们用 Kafka 去数据的时候提升了量,原来是 5 兆,如今咱们改到了 6 兆。

若是只是单纯传输,不论计算的话,其实能够改更高。只不过由于咱们考虑到这里包含了计算的一些东西,因此只提到了 6 兆。

咱们的 Fluentd 是基于 JRuby 的,由于 JRuby 能够多线程,可是咱们的 CRuby 没有任何意义。

为了提升内存,我把 Ruby 全部的内存机制了解了一下,就是散列的一些 host 文件,由于咱们每一个进程都选前五列就能够了,我多开了几个口。ES 的优化这一块,在上 ES 以前,咱们已经有人作过一次优化了。

由于基于我刚才说的有时候日志量很高,有时候日志量不多。咱们会考虑作动态配置。

由于 ES 就是支持动态配置的,因此它动态配置的时候,咱们在某些场景下能够提升它的写入速度,某些场景下能够支持它的这种查询效率。咱们能够尝试去作一些动态配置负载。

改造一:存储下降

clipboard.png

clipboard.png

下降存储在总体架构上并无太大变化,咱们只是在传输到 Fluentd 时把天数降下来,改为了一天。

同时,咱们直接进行了分流,把数据往 Hadoop 里写,而把一些符合 Kibana 的数据直接放入 ES。

上面提过,日志查询是低频次的,通常须要查询两天以上数据的可能性很小,所以咱们下降存储是很是有意义的。

改造二:数据分治

clipboard.png

咱们在日志文件节点数较少(机器数量小于 5 台)的状况下,去掉了 Kafka 层。因为 Fluentd 能够支持数据和大文件存储,所以数据可以被持久化地存入磁盘。

咱们给每一个应用都直接对应了一个 tag,以方便各个应用对应到本身的 tag、遵循本身的固定规则、并最终写入 ES,这样就方便了出现问题的各自定位。

另外,咱们运用延迟计算和文件切分也能快速地找到问题的根源。所以咱们节约了 Kafka 和 ES 各类计算资源。

在实际操做中,因为 HBase 不用去作 raid,它本身彻底可以控制磁盘的写入,所以咱们进行了数据压缩。就其效果而言,ES 的存储开销大幅下降。

在后期,咱们也尝试过一种更为极端的方案:让用户直接经过客户端的 Shell 去查询数据,并采用本地缓存的留存机制。

优化效果

clipboard.png

优化的效果以下:

服务器资源的有效利用。在实施了新的方案以后,咱们省了不少服务器,并且单台服务器的存储资源也节省了 15%。

单核处理每秒原来可以传输 3000 条,实施后提高到了 1.5~1.8 万条。并且,在服务器单独空跑,即不加任何计算时,单核每秒能传输近 3 万条。

不多触发 ES 保护机制。缘由就是咱们已把数据分流出来了。

之前历史数据只能存 7 天,因为咱们节省了服务器,所以咱们如今能够存储更长时间的数据。并且,对于一些他人查询过的日志,咱们也会根据最初的策略,有选择性地保留下来,以便追溯。

日志系统优化总结

clipboard.png

clipboard.png

clipboard.png

关于日志平台优化,我总结了以下几点:

因为日志是低频次的,咱们把历史数据存入了廉价存储之中,普通用户须要的时候,咱们再导到 ES 里,经过 Kibana 的前端界面即可快速查询到。而对于程序员来讲,则不须要到 ES 即可直接查询到。

数据存在的时间越长,则意义越小。咱们根据实际状况制定了有效的、留存有意义数据的策略。

顺序写盘替代内存。例如:区别于日常的随机写盘,咱们在操做读写一个流文件时采起的是按顺序写数据的模式。

而在存储量大的时候,则应当考虑 SSD。特别是在 ES 遇到限流时,使用 SSD 能够提高 ES 的性能。

提早定制规范,从而可以有效解决后期分析等工做。

日志格式

clipboard.png

如上图所示,经常使用的日志格式类型包括:uuid、timestamp、host 等。

特别是 host,因为日志会涉及到几百个节点,有了 host 类型,咱们就能断定是哪台机器上的标准。而图中其余的环境变量类型,则可以有效地追溯到一些历史的信息。

在此我向你们推荐一个架构学习交流群。交流学习群号:478030634 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

日志方案

clipboard.png

如上图所示,咱们经过 Rsyslog 能够直接将采集端的数据写入文件或数据库之中。

固然,对于一些暂时用不上的日志,咱们不必定非要实施过滤传输的规则。

clipboard.png

如上图,Fluentd 也有一些传输的规则,包括:Fluentd 能够直接对接 Fluentd,也能够直接对接 MongoDB、MySQL 等。

另外,咱们也有一些组件能够快速地对接插件和系统,例如让 Fluentd 和 Rsyslog 可以直接连到 ES 上。

这是我我的给你们定制的一些最基本的基线,我认为日志从采集、缓存、传输、存储,到最终可视化,分红了三套基线。

采集到存储是最简单的一个,像 Rsyslog 到 hdfs 或者其余 filesystem,咱们有这种状况。

比较常见的状况,就是从采集、传输、到存储可视化,而后造成最终咱们如今最复杂的一套系统,你们能够根据实际状况取舍。

最后是我考虑到一个实际状况,假如这个案例,咱们尽量少的占有服务器,而后传输须要过滤转换,日志能够比较简单,符合这种 Key value(KV)格式。

咱们能够按照取了一个 Rsyslog、取了一个 Fluentd、取了一个 Hbase,取了一个 echars 等这么一个方式作一个方案就能够了。

我以为 Rsyslog、Fluentd、heka 这些均可以作采集。而后传输这块有 Fluentd 传输,由于 Fluentd 和 Kafka 到插件很是灵活能够直接对接咱们不少存储设备,也能够对应不少的文件、连 ES 均可以。

可视化能够用 Kibana,主要是跟 ES 结合得比较紧密,它们结合在一块儿须要一点学习成本。

你们以为文章对你仍是有一点点帮助的,你们能够点击下方二维码进行关注。 《Java烂猪皮》 公众号聊的不只仅是Java技术知识,还有面试等干货,后期还有大量架构干货。你们一块儿关注吧!关注烂猪皮,你会了解的更多..............

原文链接:https://blog.csdn.net/yunzhaj...

相关文章
相关标签/搜索