天机镜——优土大数据平台应用级别监控利器
上古十大神器之一天机镜:天机镜又名昆仑镜。昆仑山西王母所有,能洞察天机,知晓古今!
1. 动机
在业务系统开发的前期,我们往往只专注到业务逻辑,而忽略了对系统本身的监控。 对硬件资源的监控运维同学提供的ganglia以及ZENOSS 能很好的满足我们的需求,监控机器的磁盘、cpu负载,内存,load,连接数等等。但是介于核心功能以及硬件指标之间的一部分监控数据目前是空白的,比如服务本身的负载,jvm使用,qps,tps,队列大小,等等。这些数据本不属于业务功能,但是对后续服务扩容,定位问题能够提供良好的依据。
天机镜的诞生就是为了解决这部分需求,我们提供一个轻量级的数据采集接口,采集业务系统的各种指标,并将这些指标以图表的形式展示出来, 能够直观清晰的显示各个指标信息。我们也提供了对用户所关注的指标的实时监控和报警的功能,同时还可以为用户提供定制报表的服务。
目前,天机镜为大数据应用的上百个监控场景提供了服务,每天收集5亿条监控数据,持久存储可达30天。然而目前仅使用四个节点作为存储,集群依然可以再增加三倍的业务量。
2. 功能设计
天机镜提供了图形化的查询界面,以曲线的形式呈现数据,下面是若干用例:
图1 Kafka集群全局负载均衡对比图(上面显示了不同ip的字节流量)
图2. storm应用内存泄露案例(曲线名称为ip::pid,可以看出106的进程稳定,而107的进程内存到一定值后OOM,然后重启,进程号改变)
图3. 某方法调用耗时监控(上图的点的意义是最近样本池中99.9%的调用都在0.19s以下,当然可以看平均值、p50、p75、p98、p99等等)
看完是否有些感觉?这就是我们日常工作中可能会关注的一些指标。在这里,我们给这些指标取个专业点儿的名字:“维度”,也就是观测应用的某一个角度。一个应用存在多个被关注的指标,那么我们就从多个维度出发,去对它进行监控。天机镜利用了java Metrics(一个开源的度量包https://dropwizard.github.io/metrics/3.1.0/)对监控行为做了几个分类:a. 绝对值;b.计数;c.速率;d.时间分布;e.数值结果分布;基本上任何不同类型的度量需求都会被这五种度量类型满足。下面可以简单的列举一些例子:
绝对值:队列大小,Buff使用(基本上是一些size类的)
计数:GC次数、累计时间,出现403次数,返回错误error1的次数
速率:tps,qps,function1的每秒调用次数
时间分布:function1调用时间50%(75%,98%,99%,99.9%)都在多少秒以下,最大耗时,平均耗时
数值结果分布:function1的返回值50%(75%,98%,99%,99.9%)都在多少以下。
上面的这些实例性的描述,基本可以涵盖80%的需求。实际上,我们在设计采集客户端时,就是为了满足这80%的需求。再这个前提下,保证常用api的default设定能够在大部分情况下适用。
数据模型与查询接口
数据模型的设计需要考虑功能与相应的存取效率,而查询接口就要巧妙利用模型中的数据直观多元的呈现给用户。我们在考虑设计监控数据结构时参考了现实世界的破案现场,因为最初的设计动机就是为了快速定位系统出现的问题,实际上我们需要的就是:(人物,时间,地点,事件),再直白一点就是:(应用,时间戳,进程唯一标识符,维度及维度大小)。你可以回过头去看上面OOM的例子。在视觉影像完全靠脑补的日子里,我们只能从黑白控制台中利用丑陋的命令行去查看系统日志。天机镜出现以后,我们简单的在界面上点击几下,他就会将当时的现场回放出来。下面是存储表结构的细节:
1
2
3
4
5
6
|
appID: 应用的唯一标识
sceneID:场景ID,应用下面的唯一标识
timestamp:时间戳
location:汇报该指标所在的位置,可以是一个ip,也可以是一个ip+端口,也可以是用户自定义的一种特定标识
dimValue:具体指标名称,比如在负载场景下,具体指标就有:QPS,刷磁盘速率,Buffer大小等等
kpiValue:对应指标的值,可以是速率类型的,也可以是百分比类型的,也可以是个绝对值大小
|
查询接口非常简单,我们需要设定一个条件:时间区间,哪些维度,哪些进程(ip or ip+pid)。另外我们提供了多种展示方式,可以将相同的维度的不同曲线放在一张图表(例如:负载均衡比较),也可以将一组ip的不同维度放在一张图(消息系统流入流出的流量比较,命中与未命中数量的比较)。
采集客户端设计
采集客户端的设计决定了监控平台的易用性,使用者往往是业务开发人员,要用最小的成本换来最大的收益。所以在设计客户端时我们从不同的角度考虑了其易用性:
1. 轻量化的客户端:对于完成api层面的监控,我们首先要将采集客户端植入应用之中,这里我们选择在client端做轻量化的统计计算,并且开启一个静默线程每一分钟把当前的计算结果发送到后端存储,在网络不通畅的情况下,客户端感知不到异常的存在。同步监控统计结果太频繁不仅会导致后端存储压力过大,也会影响用户应用的性能,更重要的是,实时需求1分钟足以。
2. 超简单的API:用户最希望的是写一行代码就完成了监控工作,而现实中我们也的确是这么做的。之所以能做到这一点,也正是因为我们梳理出80%的需求,而另外20%个性需求才需要调用较为复杂的API,并且有些通用监控室无需设置的,比如JVM相关的各种监控。
所以对于监控数据的收集,我们的定位是:归档时间长,允许丢失,近实时,统计量丰富。可能用一个词汇描述监控数据比较合适:“可视化应用日志”。
服务端设计
对于简单表结构存储大量数据的场景,Hbase是我们的绝佳选择。为了满足天机镜的查询需求,我们在Hbase集群上安装了Phoenix插件。Phoenix支持了类SQL语言,很容易与前端界面集成在一起,另外对于接收服务器,我们简单的使用nginx+webserver的方式。对于更大的并发量,可以在接收服务器做一些batch以及throttle。接收服务器的好处还有一个就是解耦了采集端与存储层,天机镜除了支持Hbase存储之外,还支持了mysql存储。另外对于不同的数据源,接收服务器还可以支持采集jmx监控数据。
图3 天机镜整体架构图
岂止于监控,数据总是有用的。目前我们对数据平台的基础服务层做了一定的封装,内置了很多通用指标的监控,这样我们可以对所有平台的使用者的应用做出大致的资源占用量监控,比如消息系统的流量贡献、消费与生产消息量的核对、请求量统计、缓存命中率、数据扫描量等等。天机镜开放了数据访问接口,用户可以定制报表,平台管理员可以生成消费资源报表。另外,利用其近实时(一分钟内)的特性做短信和邮件的报警等等。
3. 一些结论与建议
总体而言,天机镜的工作是把应用的运行日志图形化展现,并且可以根据任何时间以多元方式对比呈现,大大化简了排查问题的难度,同时通过报表也能让我们更直观的了解程序,预警功能避免一些问题的发生。天机镜像是一种刻画数据平台生态链各环节状态的数据引擎,当然,这需要精心设计出一个更好的交互式UI或者报表。
客户端
需求的梳理,最简单的api满足最大众的需求,如果想兼顾,那么必然会让api更加复杂难用;
不需要刻意追求数据的高实时性,增大80%的成本却提高了1%的收益这是得不偿失的;
既然是“可视化日志”,那么就允许丢失,同上;
静默,不要因为监控影响了自己的应用运行;
服务端
做好解耦,这样无论你因为量级升级系统,还是因为功能升级系统都有很大的好处;
中间件的数据处理策略会让你的基础服务更加稳定、高效;
存储端
我们在使用Hbase时遇到的最大问题在于删除数据后会导致一些IO风暴,另外在Phoenix0.4.0存在了跑死cpu的情况(0.4.2已经解决)。对于这些情况我们的解决方案是,让表在时间上分表。换而言之就是让table像日志文件一样按照时间rolling,这样的好处是删除老数据永远都不会出现IO风暴,因为直接drop的表更当前写入的表无关。单表的数据量也会因此大大减少,查询会非常高效。但缺点就是查询时需要做一些简要的时间区间判断,在跨表查询时会十分繁琐,需要做两个sql的结果进行合并。