网站运维技术与实践之数据分析与报警

对于日益积累的监控数据,显然需要有规划地进行存储和分析,做到“故障没来时有预防,故障来临时有提示,故障到来时有解决方案”。

一、时间序列存储

对于大多数监控数据,都有一个天然的类似数据库主键的属性,那就是时间。所以,通常情况下,各类监控系统的后台数据库都可以认为是时间序列的数据存储,并由此诞生了一批针对监控数据存储开发的数据库,其中最有代表性是RRDtool和Graphite。

1.RRDtool(Round-Robin DataBase Tool)

Round-Robin(循环)在运维人员眼里是一个很熟悉的词汇。负载均衡中最基础的算法就是Round-Robin,意即逐一循环。这个词很形象地描绘了RRD数据库的内部结构。

RRD数据库是一个固定空间大小的文件,其内部可以看做一个固定刻度的圆形表盘,每个刻度存储一个时间点的数据。表上有一个指针,永远指向最新写入数据的位置。指针随着数据写入转动,转完一圈后,就覆盖掉之前的数据从头继续。

上面这段描述中,有一点需要单独拿出来支出,即”指针岁随数据写入转动”。这个数据写入,并不等同于运维人员调用rrdtool命令插入数据。这也是RRD数据库和普通数据库一个明显的不同-在指定的时间间隔后,如果RRD每个收到明确的数据插入请求,它依然会自行发起一次“空”数据写入,占据这个刻度空间。这也是我们一般用钟表比喻RRD的原因,指针实际是定时转动的。

 

2.Graphite

相对1999年诞生的RRD,2006年才出生的Graphite通过与Statsd实时监控系统的结合,在最近几年大数据的浪潮中得到迅速普及和发展。

Graphite项目包括三部分:展示图形的graphite-web,接收和写入数据的carbon,数据存储引擎whisper。这里我们先不谈论graphite-web而专注于数据部分。

Graphite与RRD一脉相承,事实上,最开始的Graphite就是打算通过额外的Python脚本存取分布式的RRD文件(看起来更类似于Cacti的角色)。

但最终Graphite没有选择RRD而是自己用Python实现存储引擎whisper,主要原因如下:

(1)Graphite的设计更倾向于展示数据而不是各种算法

在实际运用中,类似”网站访问500错误数统计”是Graphite常见的典型需求之一。而在网站一切正常的情况下,500错误肯定是具有偶发性质的。这与RRD数据结构设想的“有规律的定时记录数据”是相互冲突的。

(2)性能问题

在Graphite项目开始的时候,RRD在同一时刻,只允许往一个数据库里写入一个数值,而whisper可以合并多个数值批量写入。这样在高负载情况下,同时操作大量文件时,Graphite就不会被“磁盘IOPS“的瓶颈限制住。不过RRDtool现在已经解决了性能问题。但是在在第一点没有解决之前,虽然Python写的whisper性能比C写的rrdtool慢2~5倍,Graphite也会继续使用自己的whisper引擎。

 

3.OpenTSDB

时间序列数据库家族里还有一个新加入的成员:HBase社区的OpenTSDB。OpenTSDB只存储最基本的<timestamp,value>键值对,其余功能都依赖于HBase集群完成。有兴趣的读者可以参阅其官网,地址:http://opentsdb.net。

总的来说,从RRDtool到Graphite再到OpenTSDB,数据库中内置的数据类型和聚合算法越来越少,数据存储的可靠性和可扩展性越来越强。具体如何选择,就取决于数据量大小和运维团队二次开发能力。

 

二、全文搜索引擎ElasticSearch

前面说到的RRD、Graphite、OpenTSDB等,都只能存储数值型数据,这需要我们提前先整理好数据,因此不足以应对突发性的需求。比如,网站新出现的热门话题,我们需要关注这个话题的相关监控数据,这时候再动手创建数据库,然后写脚本过滤日志,最后导入库中绘图,不过等到这个过程完了,恐怕就晚了。

或许大家在应对这个问题的时候,都通过搜索引擎知道了Spluck这个工具,可惜的是这不是一个开源软件,它只提供每天索引500MB的免费试用版本。有些运维人员只好先行裁剪数据,只导入所需的部分来进行查询,倒可以算是一种临时抱佛脚的解决办法。

1.简介

ElasticSearch是一个分布式的Lucene全文搜索引擎,提供RestFul的API接口,也是最近相当流行的日志存储分析平台。它提供更加强大的搜索和统计功能。

关于全文搜索的基础原理,不了解的读者可以参考《大规模Web服务开发技术》中的》第九章挑战全文搜索技术 电子书的下载地址为:http://vdisk.weibo.com/s/zmzzSciGaVonL(感恩互联网时代为我们学习提供很多渠道)

目前ElasticSearch几个著名的客户如下:

(1)Mozilla,自动构建和测试集群,通过Flume发送ES。

(2)Sony,采用ES进行娱乐项目的使用数、用户评分、标题和说明等的存储和搜索。

(3)StumbleUpon,著名社交内容推荐引擎公司,用ES索引HBase数据方便不熟悉Hadoop编程的开发人员完成搜索功能,称上手快,1小时内搞定。

(4)Infochimps,著名大数据分析服务公司,通过ES索引超过2.5亿个对象,4TB以上的Hadoop数据。

(5)Ataxo Social Inside,捷克斯洛伐克的一家社交舆情监控分析公司,从网页数据库到后台分析都用ES。

(6)MetaCPAN和Github,都是代码托管网站,用ES做开源项目代码搜索。

ElasticSearch中文社区:https://elasticsearch.cn/

ElasticSearch权威指南下载:http://www.java1234.com/a/javaziliao/shuji/2016/0104/5478.html

 

2.安装

ElaticSearch官网提供了各个版本的deb安装包。因为ES是一个Java项目,没有什么动态库依赖,所以我们可以很容易地根据deb生成rpm安装包。

ES源代码托管:https://github.com/elastic/elasticsearch/

也可以选择直接下载代码后运行./bin/elasticsearch即可

Linux安装教程:https://blog.csdn.net/sinat_28224453/article/details/51134978

Windows安装教程:https://www.cnblogs.com/zhangchenliang/p/4214408.html

 

3.集群

ES集群的部署可谓是“傻瓜式”的,唯一需要自定义的地方就是/etc/elasticsearch/elasticsearch.yml里的cluster.name。然后,在Discovery可达的范围内,所有的elasticsearch node会自动寻找和自己有相同cluster.name的兄弟,然后按照最朴素的先来后到的规则确定master。到此,集群就完成了。

在ES集群中,存在多种角色,如下:

(1)master node:有资格被选举成为master的node。但是和MySQL的master-slave结构不同,ES中master的作用只是负责维护整个cluster的state,也就是nodes和shards的列表,然后通知其他所有的API,也就是常说的CRUD,都是可以直接发给集群里任何一个master node的,这个node会自动根据请求来操作整个集群。

(2)data node:存储数据的node。ES中,data node上有index和shard两级实际存在的目录。但逻辑上,index一旦创建,其shards数就不能再变更,因为ES的shard方法就是简单的取余;而replica数是可以随时通过API调整的。

(3)client node:如果一个node 不存储数据,那么它在接收到请求的时候,只能从master上获取shards列表,然后把请求转发给相应的data node,最后再把结果转发回去。但本质上,client node也是cluster的一部分。在这种配置时,通常是cluster内部采用9300端口的transport通信,只留几个client node开放9200端口的HTTP接口对外接收RestFul请求。

关于ES的基础操作在此就不列举了,感兴趣的可以参照前面的ES权威指南下载地址,下载下来仔细研究,毕竟我这里只是普及和稍微讲讲理论知识和对应的应用场景罢了。

另外关于数据可视化分析工具,在此说两个,一个是Gnuplot,另外一个是AmCharts。另外声明一下,可视化工具绝非这两个,还有很多,大家可以根据自己的需求百度或Google搜索找找。

 

三、报警

对于运维工作来说,还剩下一个更需要实时性的功能-报警。报警的方式有很多种,最常见的就是电子邮件、短信等。随着通信的发达,很多工具支持像微信告警等手段,比如我上家公司就通过Zabbix加微信联合报警。

1.SendMail

邮件发送是产品运维乃至运营工作中的很重要部分。sendEmail和postFix的配置部署也是Linux运维人员的必备技能之一。不过在监控系统中,我们可以用更简洁易用的命令来快速完成工作。

sendEmail就是这样一个工具。下载地址:http://caspian.dotconf.net

 

2.WebSocket

在工作时间段,运维人员更经常停留在浏览器界面而不是邮件客户端界面,至于手机等设备,离视线更加遥远,所以在这种情况下,我们可以通过浏览器的帮助,使用成本极低的网页报警,同样可以获得很好的效果。

网页实时刷新,是近年来最流行的技术话题之一。从运维的实际需求出发,我们不用考虑太多并发的性能问题,更需要考虑的是快捷开发,简单上手。就此,这里推荐开发社区的小软件:Juggernaut。下载地址:https://github.com/maccman/juggernaut

 

3.手机推送

运维人员下班之后,尤其是在下班路上,除了传统的短信报警,在移动互联网时代,也有了更加“时髦”的处理方式,那就是:用手机APP来收报警。

手机推送消息,是很多APP都有的基础功能。我们不需要自己从头研究推送原理,然后实现全套系统,直接使用JPush极光推送,可以极简单地实现这个报警功能。极光推送APP的示例:

注册账户->新建应用(纯页面操作,填写应用名称,获取对应的Key和master secret)->下载Example包->用adt eclipse打开eclipse项目并生成APK文件

 

4.分级和归并

前面三种工具,以及其他还没有提到的各种信息传送渠道,都只解决了一个问题:把信息传递到运维人员身边。但这个信息是否能有效让运维人员对故障作出判断并解决问题呢?

实际的工作中,并不缺乏这样的情况:半夜被报警叫醒,只是一个磁盘85%的小问题,支持到明早上上班再解决肯定没问题,于是继续睡觉。结果早上一看,在昨晚半小时重复一次磁盘报警,还夹着一条宕机。

这就是告警设计的另一个重要方向:如何提高信息的有效传递。归纳起来,就是要”有多又少”-不同意义的信息要多,一点不能遗漏;相同的信息要少,每条都可以引起运维人员的快速响应。

一般来说,做到这点有两个办法:分级和归并。

其实分级告警和归并过滤在Nagios报警设计中都有所体现,比如WARNING、CRITICAL和RECOVERY状态的区别,主机和服务的dependency关系,报警的escalations变更等。只要用好Nagios的细节控制,就可以减少很多无谓的报警。

对于非Nagios体系的监测告警,我们则需要自己动手完成。设计思路上,完全可以参考Nagios项目。实现办法上则可以完全从告警出口处控制。一般我们使用的短信网关,都会采用MySQL作为短信存储。我们可以限制MySQL数据库的权限,自己编写一个简单的HTTP服务作为短信告警的统一接收入口。这样,在HTTP服务接收到信息之后,可以先对MySQL中的近期数据进行查询统计,一旦经过逻辑计算认为应该被归并过滤掉,那么在最后信息入库的时候,直接将SQL中是否发生的列标记为已发送,或者自定义代表被过滤的其他数字-请注意,虽然信息最后被过滤,但千万不能直接丢弃掉。“被过滤”也是一种记录,也有价值。