本专栏的标题为日志系统构建之路,但在我们踏上这条路之前先稍等片刻,看看这条路的“路基”——日志。

相信能看到这篇文章的人应该对日志都不陌生,日志是开发者与程序系统沟通的桥梁,程序开发者或运维人员可以通过日志了解系统的具体操作,分析在线系统在具体环境的真实运行情况,或还原单独某一特殊场景下用户的线上访问情况。

但随着移动互联网的兴起,单个应用的访问量急剧增加,日志量也随之增加,想从成千上万甚至上亿条的日志数据中寻找到有价值的信息逐渐变的困难起来,同时现在各个企业对于日志的分析往往要加入时间的维度,更多关注latest的数据,也就是说日志需要有时效性,同时也需要对日志中的各种维度进行分析,需要通过对时序数据进行更深入的聚合、分类,并按需进行数据可视化,并能够做各种关联分析等。

在如今的互联网世界里,日志已经不是单独的一条文本记录,而是流动的事件记录,我们要在流动的日志之河中快速的寻找到自己关注的信息,并快速的做出响应。这就对日志系统的构建有了较高的要求,那么在构建日志系统时我们主要需要关注哪些问题呢?我大概总结了如下几个方面的内容:

一:日志收集端的选型

日志收集端的选型主要关注如下几个方面。

1.组件的轻量级:组件要足够轻量级,并且对服务的侵入较小,同时在性能方面要满足业务的需要。

2.自身的容错性:容错性对于收集格外重要,比如当下游出现服务宕机或网络问题时,日志收集端可以做到很好容错,日志收集端可以通过对日志的缓存或写临时文件等方式对日志的转发进行容错,保证日志可以在故障时不丢失。

3.组件多样化可扩展:组件的多样化也很重要,在真实的工作中可能需要日志收集器能适应各种场景下的日志收集,比如从网络读取数据,从文件读取数据,或从其他db系统读取数据,同时也可以进行自定义的扩展。

4.运维友好:这点往往是大家忽视的内容,比如某一组件可能在测试环境中有很好的性能,但是它本身却很难监控,同时配置相关文档又不是很完善,如果一旦在线上环境中出现了棘手的问题,可能一时无法解决,这都是运维不友好的体现。

二:日志传输队列的选择

1.是否需要队列:我们可能常常在看别人写的文档或教程时一上来就画出了一个有队列的架构图,但是我们是否思考过队列存在的意义到底是什么?我们的场景是否需要队列?这一点我先不在此展开讲解,我的专栏会有一章通过几个场景来讲解这个问题。

2.分布式与可扩展:当日志量逐渐变大时,我们往往需要易于扩展的组件,比如在扩展性方面Kafka可能会优于Redis。当然具体的问题还是要看具体的场景,在某些规模比较小的场景下可能我们不需要把架构搞的太过于复杂,那么我们可能更倾向于选择redis来作为队列。

3.性能与资源使用

4.运维友好:这一点与前文的要求基本一致。

三:日志解析组件的选择

当我们来构建一个日志系统时,我们有一个步骤是永远无法避免的,那就是日志的解析与格式化。在日志解析的选择上我们需要关注如下几点:

1.性能与资源的使用:这一点已经是老生常谈的问题,在此就不展开讲了。

3.2.易于配置与文档详细:相信做过日志解析的人应该都清楚这一点的重要性,如果配置语法晦涩难懂,同时文档又不详细,那么对于日志解析人员来讲就是一个灾难。

3.可扩展性与组件多样化:组件多样化的问题前文已经讲了,下面我们关注一下可扩展性方面的问题。笔者在实际工作中遇到的日志格式可谓千奇百怪,很难有一个组件在最开始就能满足我所有的需求,这就需要这个组件提供相应可扩展的方式,比如提供可以自己扩展编写解析程序的接口,或者有方法开发自己的解析插件,所以日志解析的可扩展性对于我们来说至关重要。

4.运维友好:这一点与前文类似,在此不展开了。

四:日志存储系统的调优与监控

1.内部原理的理解:对于一个开源组件的调优一定是以对内部原理的理解为基础的。比如我们以Elasticsearch为例,refresh interval参数是不是调的越大越好?如果你对于refresh和flash等操作没有很深入的了解你是很难回答这个问题的。当然可能不需要源码级别的理解,但在调优前我们还是需要去了解这个组件的一些基本原理。只有这样才能在看到眼花缭乱的参数之后还能游刃有余的去调整系统的参数。

2.先监控,再调优: 在此我们还以Elasticsearch为例,之前笔者帮助过很多人对Elasticsearch进行过调优,我常常发现某些人遇到的问题往往只是直观上的感受,比如“我的系统为什么变慢了?”。那么“慢”这个直观感受到底该怎么量化?这就涉及到系统的监控,所以在我看来想要调优必须要有完善的监控,监控的存在有两方面的功能,一个是发现具体的可量化的问题,比如请求的rt变慢,比如内存减少,比如上下游问题等。另一个是作为调优后的度量,比如我们调优后要去看相应的监控指标是否有下降。所以在没有监控之前调优是没有意义的。

3.场景化调优: 我相信很多人和我的感受一样,就是在Google中搜索Elasticsearch调优,出来一堆各式各样的配置项调优Tips,但这种文章往往比较坑人,也没有什么意义。我个人认为调优一定是要在具体的场景中的,我们要看具体的问题是什么,比如针对于Elasticsearch来讲写入型和搜索型的优化思路就完全不一样。所以我们也需要关注具体的场景到底是什么,我们根据场景去调整具体的参数。

五:架构的选择

针对于日志系统来讲,日志架构的选择关注的往往是上下游的连接,也就是我们用什么方式或组件来连接上下游,比如我们是选择同步架构还是异步架构?需不需要加入队列等等,这些问题都是我们需要关注的问题。这个问题在此先不展开,我的专栏中会进行详细的讲解。

六:数据传输的准确性检验

这一点是日志传输架构的核心KPI,我们需要思考如何保证日志传输的安全性与可靠性,这就需要引入各种数据准确性校验的指标,来证明日志传输系统是可靠的。比如发送端、接收端日志的tps,日志流量,日志条数对数等,都是数据传输系统的校验指标。

七:日志格式与传输规范

日志格式和传输规范如果在一开始就规范好,对于后期的日志解析入库等步骤就会轻松很多。日志格式的选择主要关注于格式的统一与规范,比如日志中通用的字段内容(uid,时间戳,日志来源标记),是否使用相同的分隔符,或者采用key value格式等等。

在进行日志转发时是否对日志进行分级,对线上的业务相关、运维监控相关、线上开放临时调试相关的不同日志进行分级,分级的好处在于可以方便我们提供不同的业务保障级别,在遇到大范围系统故障时我们可以根据不同的日志级别进行日志传输的降级和优先恢复。

上述就是我总结的一些问题,我根据这些提出的问题大概把专栏分为18节,在第二节我将讲解一下笔者现在工作的公司的日志架构方面的实践。由于logstash的内容在诸多的专栏中都有介绍,所以第3~7节笔者以Rsyslog这个同样具有很好性能的组件为例,详细的介绍了Rsyslog的一些使用与配置事例,并在通过一些实战案例把Rsyslog放到具体的场景中帮助大家更好的理解它。

在10~11节主要关注日志队列方面的问题,介绍了队列的选择,并介绍了zookeeper和Kafka的使用。在第12~14节以Elasticsearch为核心讲解了Elasticsearch的监控与场景化调优的问题,在第16节中讲解了大家比较关心的Elasticsearch权限管理系统Search-guard的配置和搭建。

同时加入几节实战去强化相关章节的内容。在大纲之外如果课程关注度相对比较高的话还会针对具体提出的问题发布一些番外篇,比如大家可能比较关注新版Kibana的相关内容,那么可能还会加入一些针对于Kibana新功能的讲解,当然跳过这些番外篇的内容,并不会影响大纲的主线内容。

八:附大纲

1.写在最前面:日志在企业运维中的重要性与专栏介绍
2.常见企业日志系统架构介绍与数据驱动运维的实践
3.一个实例讲解日志收集与解析的利器:Rsyslog
4.Rsyslog的基础概念之属性、template、与RainerScript
5.Rsyslog的输出与输入模块详解
6.Rsyslog的解析模块详解与如何构建自己的日志解析
7.Rsyslog进阶:内部队列机制与如何监控Rsyslog
8.使用Plog与Rsyslog构建日志分析数据管道
9.【实战】使用Rsyslog、Plog、Zabbix、statsD构建实时监控系统
10.日志传输的异步化之路:为什使用Kafka解耦
11.Kafka、Zookeeper介绍与构建数据订阅系统
12.Elasticsearch写入组件的选择:Logstash,Rsyslog,Hangout
13.【实战】Rsyslog,Kafka,Hangout与Elasticsearch构建日志监控系统
14.Elasticsearch的监控与核心基础概念refresh&flush&translog详解
15.【实战】Elasticsearch几个场景下的调优与问题排查
16.Elasticsearch权限管理的开源解决方案:Search Guard详解
17.【实战】如何通过服务日志构建服务链路监控系统
18.终章与回顾