前言
随着Devops、云计算、微服务、容器等理念的逐步落地和大力发展,机器越来越多,应用越来越多,服务越来越微,应用运行基础环境越来多样化,容器、虚拟机、物理机不一而足。
面对动辄几百上千个虚拟机、容器,数十种要监控的对象,现有的监控系统还能否支撑的住?来自于容器、虚拟机、物理机的应用日志、系统服务日志如何采用同一套方案快速、完整的收集和检索?怎样的架构、技术方案才更适合如此庞大繁杂的监控需求呢?本文主要从以下几个方面来分享下笔者在日志监控方面的一些经验。
目录
一、DevOps浪潮下带来的监控挑战
二、统一监控平台架构解析
三、日志监控的技术栈
四、日志监控经典方案ELK
五、微服务+容器云背景下的日志监控实践Journald+fluentd+elasticsearch
六、如何选择适合自己的日志监控方案?
一、DevOps浪潮下带来的监控挑战
现在Devops、云计算、微服务、容器等理念正在逐步落地和大力发展,机器越来越多,应用越来越多,服务越来越微,应用运行基础环境越来多样化,容器,监控面临的压力越来越大。挑战主要有:
-
监控源的多样化挑战
业务、应用、网络设备、存储设备、物理机、虚拟机、容器、数据库、各种系统软件等等,需要监控的对象越来越多,指标也多种多样,如何以一个统一的视角,监控到所有的数据?
-
海量数据的分析处理挑战
设备越来越多,应用越来越多,要监控的数据自然也排山倒海般袭来,怎样的监控系统才能应对大数据的采集、存储和实时分析展现呢?
-
软硬件数据资源的管理分析挑战
数据是采集到了,采集全了,那么如何对他们进行分析呢?应用、系统软件和运行环境、网络、存储设备的关联关系是否能准确体现呢,某个点发生了故障、问题影响的链路是否能快速找到并进行处理呢?监控离不开和软硬件资源管理的结合。
面对这些挑战,是否感觉压力山大呢?一个监控平台,拥有哪些能力才能满足如此大的挑战呢?
一个好的统一监控平台,应当具备如图所示的能力:
-
高度抽象模型,扩展监控指标:正如之前所说,监控源、指标的多样化,要求我们必须要进行监控模型的高度抽象,并且针对于指标可以动态扩展,这样才能保证监控平台的健壮性和可扩展性。
-
多种监控视图:监控数据自然不能只是简单的表格展现,饼图、柱状图、折线图、仪表盘等等,监控的数据需要结合实际情况选择最佳的图标展现。
-
强大的数据加工能力:海量的数据必须要有足够强大的数据加工、分析处理能力才能得到直观的结果
-
多种数据采集技术:数据源的不同决定了采集的技术也是有区别的。
-
多种报警机制:短信、邮件、企业内部通讯工具等等,结合不同场景选择不同的报警机制。
-
全路径问题跟踪:一个请求有可能牵扯到数个系统、数十个接口的调用,出了问题有可能是其中任何一个环节,也有可能是应用所处运行环境、网络、存储的问题,所以问题的定位离不开全路径的跟踪。
二、统一监控平台架构解析
统一监控平台由七大角色构成:监控源、数据采集、数据存储、数据分析、数据展现、预警中心、CMDB(企业软硬件资产管理)。
监控源
从层次上来分,大致可以分为三层,业务应用层、中间件层、基础设施层。业务应用层主要包括应用软件、企业消息总线等,中间件层包括数据库、缓存、配置中心、等各种系统软件,基础设施层主要有物理机、虚拟机、容器、网络设备、存储设备等等。
数据采集
数据源如此多样,数据采集的任务自然轻松不了。数据采集从指标上划分可以分为业务指标、应用指标、系统软件监控指标、系统指标。
应用监控指标如:可用性、异常、吞吐量、响应时间、当前等待笔数、资源占用率、请求量、日志大小、性能、队列深度、线程数、服务调用次数、访问量、服务可用性等,业务监控指标如大额流水、流水区域、流水明细、请求笔数、响应时间、响应笔数等,系统监控指标如:CPU负载、内存负载、磁盘负载、网络IO、磁盘IO、tcp连接数、进程数等。
从采集方式来说通常可以分为接口采集、客户端agent采集、通过网络协议主动抓取(http、snmp等)
数据存储
采集到的数据一般都会存储到文件系统(如HDFS)、索引系统(如elasticsearch)、指标库(如influxdb)、消息队列(如kafka,做消息临时存储或者缓冲)、数据库(如mysql)
数据分析
针对采集到的数据,进行数据的处理。处理分两类:实时处理和批处理。技术包括Map/Reduce计算、全日志检索、流式计算、指标计算等,重点是根据不同的场景需求选择不同的计算方式。
数据展现
将处理的结果进行图表展现,在多屏时代,跨设备的支持必不可少。
预警
如果在数据处理过程发现了问题,则需要进行异常的分析、风险的预估以及事件的触发或告警。
CMDB(企业软硬件资产管理)
CMDB在统一监控平台中是很重要的一环,监控源虽然种类繁多,但是他们大都有着关系,如应用运行在运行环境中,应用的正常运行又依赖网络和存储设备,一个应用也会依赖于其他的应用(业务依赖),一旦其中任何一个环节出了问题,都会导致应用的不可用。CMDB除了存储软硬件资产外,还要存储这样一份资产间的关联关系,一个资产发生了故障,要能根据这个关系迅速得知哪些其他的资产会被影响,然后逐一解决问题。
三、日志监控的技术栈
既然前面讲了整个监控系统的架构,下面就按照架构中的角色来分类看看有哪些常用的开源技术。由于篇幅原因,这里无法详细描述每一个技术的细节,大家感兴趣的话,可以一一了解下。
日志源
首先谈谈日志的来源,日志的一般存储在三个位置:数据库、操作系统日志、日志文件。一般操作日志会习惯于存储在数据库中,在这里暂且不提。Syslog、Rsyslog、Journald都是linux系统的日志服务。
syslog 守护进程的任务是记录系统日志。它从应用程序和服务中获取格式各异的日志消息并保存到磁盘上,消息的元数据是组件名、优先级、时间戳、进程标签和 PID,日志格式很是宽泛,没有定义结构化的格式,所以系统的分析和日志消息处理也就变得十分混乱,同时性能和其他的一些缺点随着时间推移也慢慢被放大,后来慢慢被Rsyslog所取代。
Rsyslog可以说是Syslog的升级版,它涵盖SysLog的常用功能,不过在功能和性能上更为出色。
Red Hat Enterprise Linux 7与SUSE Linux Enterprise Server 12这些新一代的Linux发行版本使用systemd管理服务。
journal是systemd的一个组件,由journald处理。Journald是为Linux服务器打造的新系统日志方式,它标志着文本日志文件的终结,它不再存储日志文件,而是将日志信息写入到二进制文件,使用journalctl阅读。它捕获系统日志信息、内核日志信息,以及来自原始RAM磁盘的信息,早期启动信息以及所有服务中写入STDOUT和STDERR数据流的信息。Journald快速改变着服务器如何处理日志信息与管理员如何访问的方式。
数据采集
日志的采集工作大都是通过客户端进行,客户端除了一些直接可用的工具(如fluentd、flume、logstash)外,还可以通过log4j的appender、自行写脚本实现等。
fluentd是开源社区中流行的日志收集工具,fluentd基于CRuby实现,并对性能表现关键的一些组件用C语言重新实现,整体性能相当不错。优点是设计简洁,pipeline内数据传递可靠性高。缺点是相较于logstash和flume,其插件支持相对少一些。
flume是由JAVA实现的一个分布式的、可靠的、高性能、可扩展的的日志收集框架,Flume比较看重数据的传输,使用基于事务的数据传递方式来保证事件传递的可靠性,几乎没有数据的解析预处理。仅仅是数据的产生,封装成event然后传输。同时使用zookeeper进行负载均衡,不过JVM带来的问题自然是内存占用相对较高。
Logstash相比大家都比较熟悉了,是ELK中的L,logstash基于JRuby实现,可以跨平台运行在JVM上。logstash安装简单,使用简单,结构也简单,所有操作全在配置文件设定,运行调用配置文件即可。同时社区活跃,生态圈提供了大量的插件。早期Logstash并不支持数据的高可靠传递,所以在一些关键业务数据的采集上,使用logstash就不如flume更加可靠。不过在5.1.1版本发布了持久化队列的beta版,显然logstash也在快速改进自己的缺陷。
数据缓冲
在大批量的监控数据涌过来后,考虑到网络的压力和数据处理的瓶颈,一般会在存储前先经过一层数据缓冲,将采集到的数据先放置到消息队列中,然后再从分布式队列中读取数据并存储。这张图是新浪的日志检索系统的架构图,可以看到数据采集后,经过kafka缓冲,然后再使用logstash去读取kafka中的数据并存储到es中:
关于分布式队列这里就不详细讲解了,常用有kafka,rabbitmq,zeromq等。
数据存储&分析
存储和分析息息相关,监控数据的处理通常分为实时处理和非实时处理(如大数据的批处理框架hadoop等),如Elasticsearch就是一个实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析。
除了ES外,还有一些流式大数据处理框架可以做到实时或者准实时的处理大数据流。如Spark和Storm。关于大数据处理的内容因为本人也没有多少实践经验,就不在此多做分享了。后面主要还是针对于Elasticsearch这一框架进行介绍。
数据展现
Kibana和Elasticsearch可以说是无缝衔接,再加上Logstash,组成的ELK赫赫有名,很多企业都会直接采用这一种框架。
Kibana确实也能满足大部分的监控需求,但是其毕竟只能依靠现有的数据进行展现,如果需要和外部数据结合处理,就会无法满足了,并且在自己构建一个统一监控平台时,需要将日志和性能等监控数据结合CMDB、预警中心、等统一展现,所以对于kibana的替换就无法避免了。我们是通过使用JAVA去查询Elasticsearch的数据,结合其他数据统一分析,将展现的结果进行滚动展现或者用图表显示。
四、ELK-日志监控经典方案
ELK stack :是一个实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析。以Elasticsearch、Logstash、Kibana组成的数据处理工具链,在实时数据检索和分析场合,三者通常是配合共用,而且又都先后归于 Elastic.co 公司名下,故有此简称。
优点:
-
处理方式灵活:Elasticsearch是实时全文检索,不需要像storm那样预先编程才能使用。
-
配置简易上手:Elasticsearch全部采用JSON接口,LogStash是Ruby DSL设计,都是目前业界最通用的配置语法设计。
-
检索性能高效:Elasticsearch的优秀设计和实现基本可以达到百亿级数据查询的秒级响应。
-
集群线性扩展:不管是Elasticsearch集群还是Logstash集群都是可以线性扩展的。
-
前端展现绚丽:Kibana为 Elasticsearch 提供分析和可视化的 Web 平台。它可以在 Elasticsearch 的索引中查找,交互数据,并生成各种维度的表图。
-
开源:三个软件全部开源,便于自主掌控。
-
三个工具相互紧密结合:由同一个公司提供,并且作为一套解决方案ELK Stack对外提供,不管是部署还是功能的整合,三者无缝衔接,便于安装和使用。
Logstash
logstash是一个开源的、服务端的数据流转管道,支持从多个目标中收取数据、转换并且发送,在logstash中,包含三个阶段:inputs、filters、outputs。
Inputs用来产生事件数据,Filters用来定义、过滤数据事件,outputs用来把事件数据发送到外部。Inputs和Outputs支持通过codecs在管道中对数据进行编码和反编码。Logstash提供了强大的插件机制,每一个角色都包含了多种插件,易于扩展和选择。比较典型的插件如下:
Input plugins:beats、file、syslog、http、kafka、github、jmx、…
Filter plugins:grok、json、csv、…
Output plugins:file、http、jira、kafka、elasticsearch、mongodb、opentsdb、rabbitmq、zeromq、…
Codec plugins:json、msgpack、plain、…
若想了解更多关于logstash的插件,可以到官网去自行了解:https://www.elastic.co/guide/en/logstash/5.2/index.html
Elasticsearch
Elasticsearch 是一个实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析。它是一个建立在全文搜索引擎 Apache Lucene 基础上的搜索引擎,使用 Java 语言编写。据说Elasticsearch最初的目的只是为了给作者当时正在学厨师的妻子做一个菜谱的搜索引擎,不过到目前这个菜谱搜索引擎仍然没有面世。
主要特点如下:
-
实时分析
-
分布式实时文件存储,并将每一个字段都编入索引
-
文档导向,所有的对象全部是文档
-
高可用性,易扩展,支持集群(Cluster)、分片和复制(Shards 和 Replicas)
-
接口友好,支持 JSON
-
检索性能强大,ES基于lucene,对于每个新写入的数据,会针对于每个字段都创建索引
Kibana
如官网所述,Kibana是ELK的窗口,专门针对于Elasticsearch进行数据分析展现。它提供的诸如面板、仪表盘、可视化功能等能力,基本上承载了对es的查询和分析能力。
五、微服务+容器云背景下的日志监控实践
Journald+fluentd+elasticsearch
下面给大家介绍下我们在微服务+容器云背景下的日志监控实践,首先要介绍下我们的DevOps平台架构,平台运行在由kubernetes+docker构建的容器云中,kubernetes、docker等服务运行在IaaS平台上(我们的生产环境是阿里云)。
我们的监控系统在选型时,也是纠结了好久。我们的需求来自于多方面的,一方面要对系统服务的日志进行监控(在虚拟机中),如kubernetes、etcd等服务的日志,另一方面要对应用、数据库、redis等其他软件的日志进行监控(在容器中)。
考虑到统一日志源,我们最终决定让所有的日志都输入到系统日志journald中,由journald作为统一对外日志发送来源。UMC系统的日志监控架构如图所示:
跑在容器中的应用、数据库等软件都会把日志落到容器日志(docker日志),然后在docker系统服务上进行配置,将docker容器日志输出到系统日志服务journald中。这样,容器中的日志就统一到了系统日志中。针对于运行在虚拟机上的系统软件,如kubernetes、etcd等,配置成系统服务service,使用systemd管理,自然也就做到了将其日志输入到journald中。
再往上就比较简单了,自实现一个agent,读取journald中的日志,通过tcp协议发送到fluentd中,考虑到现在的日志量并不会太大,所以没有再使用kafka进行缓冲,而是直接经过fluentd的拦截和过滤,将日志发送到Elasticsearch中。
为什么选择Fluentd而不是选择logstash?
-
logstash插件相当丰富,但是fluentd的插件已经能满足要求了
-
Logstash是JRuby语言实现的,依赖jvm运行,内存占用较高,性能也比较差
-
我们的日志主要来源还是docker,Fluentd的方案与Logstash差不多,但是它可以省掉Indexer这层,而且它的核心代码是C++写的,从效率上说会比Logstash高很多。Fluentd是除了Splunk以外唯一一个在Docker官方日志驱动里面的工具。Fluentd则不仅支持Logstash那种文件的方式去搜集日志,还可以通过Docker的Fluentd driver直接定向搜集
-
我们的虚拟机操作系统是coreos,安装fluentd更加方便,不需要再去安装jre。
主要解决的问题:
1、所有的日志都混合在一起了,如果区分哪些是A应用在dev环境下的实例的日志?哪些是某个数据库在测试环境下运行的实例日志?
容器的日志一个记录如图所示
我们的ContainerName是有命名规则的,其中包含了产品名(如mysql-1),环境名(如env-deployment),通过这两个属性来进行模糊查询匹配。找到对应的日志。从而也做到了不需要分析日志内容、也不用区分是应用日志还是数据库日志,达到将日志和其对应的产品实例关联起来的目的。
2、ES中文分词插件,ES默认的分词会把“中国”分解成“中”,“国”,这样在检索“中国”的时候,也会把“美国”搜索出来,我们最终安装了ik中文分词插件elasticsearch-analysis-ik,就可以把“中国”当成一个整体去检索了。
六、如何选择适合自己的日志监控方案?
介绍了整个监控平台架构,也介绍了日志监控的技术栈,那么,如何选择适合自己的日志监控方案呢?我认为应当从如下几个方面来综合考量。
-
工具能力是否满足,像logstash/flume/fluentd都满足我们的要求,虽然fluentd相对于另外两个工具的插件少了不少,但是就我们的需求而言,fluentd足够了。
-
性能对比,既然logstash/flume/fluentd都符合要求,相比之下,fluentd的性能最好。
-
看技术能力是否能cover住,如果有些自己特殊的需求是工具满足不了的,就会需要自行扩展工具,那就要好好考量该工具的实现语言自己的团队是否能cover住,比如一个纯java团队,去用ruby语言扩展logstash的能力,就会有些风险了。
-
监控平台日志量评估,要从可扩展性去设计日志监控的架构,当然,对于整个监控平台而言也是如此。
总之,适合自己的才是最好的。
来源:oschina
链接:https://my.oschina.net/u/2441327/blog/1801465