阿里万亿交易量级下的秒级监控

先介绍一下监控系统 Sunfire , 它是阿里集团的业务监控系统 , 前身是蚂蚁的 xflush, 支持应用标准化监控 , 如操作系统 , JVM , 中间件等 。除此之外还有更强大的日志监控能力 , 大多数业务的监控指标都从应用的日志中抽取 。目前覆盖了集团几乎所有 BU 和绝大多数业务 , 每分钟处理 TB 级日志 。
下面将从以下四个方面进行讲解:
1.架构
2.规模与挑战
3.技术选择
4.方向
一、架构
每分钟处理这么大的TB级日志量 , 我们是怎么设计架构去实现它的呢?
1.1、传统日志监控

阿里万亿交易量级下的秒级监控

文章插图
 
上图是传统的日志监控 , 现在大多数监控平台采用的一个方案 。Agnet 检测日志变化增量推送 , 经过消息中间件如 kafka , 流式计算引擎如 Jstorm/flink 去消费 kafka 产生出来的数据 , 中间的流式计算可能有多步的处理 , 最后流向 DB , 很传统的架构 。
这种架构会有一个问题就是:某一分钟的数据 , 何时可以发报警?
1.2、流式计算的问题
Process Time 超过 Event Time Window
我们最早尝试了上面传统的架构 , 但是 , 会有一个问题 , 我到底什么时候这个数据才能发报警呢?因为这个架构最麻烦的是我不知道什么时候数据已经全部到齐了 。如果机器很多 , agent 返回数据的时间并不确定, 要保证所有机器日志采齐了数据才准确 , 这在流式计算里很难处理 。
这是个经典的问题, 有两篇文章很详细的讲解了流式计算中如何解决这种问题:
https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-101
https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-102
【阿里万亿交易量级下的秒级监控】但是数据丢了就是丢了, 无论怎么样就是不准了 , 也很难拍出一个 delay 的时间确保数据可以用来发报警, 那么当数据不准时, 我们能不能知道不准了呢? 为了解决这个问题我们走了另一条路线: 让主动权留在服务端 。
1.3、Sunfire 功能结构
阿里万亿交易量级下的秒级监控

文章插图
 
这是 Sunfire 的功能结构 , 比较重要是 Sunfire-lika 模块 , 它用来支撑整个计算框架的 , 就是线程模型、消息调度处理、故障自愈恢复都是通过这个模块实现的 。
1.4、Sunfire 架构
阿里万亿交易量级下的秒级监控

文章插图
 
这是 Sunfire 架构图 。这个架构图是怎么工作的呢?首先有三个角色 Brain、Reduce 和 Map 。这三个角色我们统称为计算模块 。
ConfigDB 里面配置了监控项 。监控项会定义配置需要从哪个应用、哪个路径采集日志、采集回来的日志应该做哪些的处理、根据什么样的规则进行计算 。
Brain 会按照周期从 ConflgDB 里读取配置 , 生成拓扑 。然后安装到 Reduce 上面 , Reduce 把拓扑再分解成它的子任务 , 再安装到 Map 上面 , 最后 map 去拉日志 。
这里画了两个租户 , 租户 A 和共享租户 , 其实就是资源是独享的还是共用的 。因为我们有一些核心的交易监控 , 也有一些不太重要的 , 还有很多边缘业务 。如果是很重要的用户 , 比如说交易 , 我们就单独给它一个租户 , 它的所有计算资源都是它自己独享的 。对于一些边缘的业务是可以共用服务器的 。我们现在有80多个租户 , 基本上一个租户对应一个大的业务 。
1.5、时序图
阿里万亿交易量级下的秒级监控

文章插图
 
用时序图的视角看一下上面的任务 。这个拓扑包括了配置 , 也包括这个拓扑任务从多少个服务器 , 到底从哪些服务器上去采集日志 , 都是在这个拓扑里面完成的 。有了这个拓扑 , 才有了节点故障时候 , 恢复它的前提条件 。因为拓扑里面包含了所有信息 , 无论是哪个节点挂掉了 , 上游都能用它来恢复下游节点 。
把这个拓扑安装到一台 Reduce 上面去 , 然后 Reduce 会把它分解掉 。假如我有1台 Reduce , 有100个 map , Reduce 会把这个任务分节成100个 Map 。如果这时候有1000个 Agent , 有可能每个 Map 会采集10个 Agent 的日志 , 最终 Map 去 Agent 拉取日志 , 然后再一步步往回走 , Map 做初步的计算, Reduce 再做进一步的聚合存入到 HBase , 然后最终返回给 Brain , 告诉它这个任务完成了 。


推荐阅读