写在前面
之前文章中讲到笔者想要实现一个新的监控系统,原文地址。细思之,重做一遍Open-Falcon并没有意义。所以新的系统会从Open-Falcon借鉴很多东西,但是理念不会相同,我称之为下一代监控系统,那也是有点标题党了,未来的服务很可能会全部container化,这里所谓的下一代监控系统,就会着眼于container化的服务监控。
以前做部署做PaaS,搞了个DINP算是一个总结,这次做监控,也手写一套出来,算是个总结。
叫个什么名字呢?其实特别想叫Minos,Minos是希腊神话中的判官,跟监控系统有点贴切,但是github上没法注册这个organization了,只能加个open的前缀叫做Open-Minos,凑合着用吧,代码还没开始写,你有好名字么?给笔者参考参考呗~
重大改变
下面先阐述一些与Open-Falcon不同的地方,这些改变都有一些考量,要么是为了简化系统,要么是为了去除单点,要么是为了便于运维,要么,是因为我个人的偏执,哈哈
干掉HostGroup
阉割掉了机器分组和策略模板!听起来可真不是个好消息,重大改变,反而是做了阉割。
*我的脑洞历程是这样的
策略表达式在Open-Falcon中只能配置一条规则,太弱了,加强之。可以支持配置多条规则,相同metric,tags长的覆盖tags短的。这样用起来就比较爽了,普通dev再也不用去关心机器分组,不用去关心策略模板,不用去关心复杂的继承关系。
策略表达式做强大了之后,机器是否也可以用策略表达式来监控呢?
其实是可以的,机器监控数据汇报的时候带上业务tags即可。比如minos这个项目用到了20台机器,每个机器采集了监控指标之后,都额外带上这么一个tag:project=minos,host=xx
,这样就可以在web端做如下配置来监控所有机器的cpu.idle:
metric=cpu.idle project=minos all(#2) < 5
这种做法特别适合那些使用container来部署服务的公司,因为每个container都是唯一服务于一个业务,方便打上业务的tags。据说美团的虚机做得特别好,业务没有混部,基本也是一台虚机只属于一个业务,这种场景也比较容易打上业务tags。比较麻烦的情况是一个机器部署了多个服务,不同的团队收同一批机器的报警,这个大家有好办法解决么?这里先卖个关子,我的办法先不透露,防止限制了你的思路。
变更Data Model
endpoint不再单独一个字段,如果需要endpoint,放到tags中,这样做简化了系统,与OpenTSDB的做法一致。endpoint其实也是一种筛选数据的手段,放到tags中,处理起来就变得一致了。
数据存储放弃RRD
RRD是文件系统,处理起来速度比较快,但是不易运维,现在的每个Graph实例都是单点真的是让我如鲠在喉。以前用的zabbix是采用数据库存放历史数据的,history表和trends表其实还不是瓶颈,瓶颈会先出在存放last数据的表。
那么如果我们做一些分库分表的手段,MySQL也可以抗非常大的量,而业界MySQL的运维,已经是非常成熟,这是一个极大的优点。
使用Team贯穿整个系统的权限
用户注册登录进来之后,可以创建Team,这个跟以前的UIC差不多。然后,所有的东西都是与Team挂钩的,比如报警策略,隶属于某个Team;上传的数据,隶属于某个Team;报警事件,也是某个Team来处理。
组件瘦身
所有组件采用Go编写,编译完成之后一个二进制,扔到任何一台机器上都可以跑,组件该合并的合并。
Frontend
首先肯定是需要有个web端,提供用户登录、注册功能,团队维护,报警策略维护,未恢复的报警查看,历史趋势图表查看等等。也就是把以前的多个web端合并在一起了。
数据也push给Frontend,通过http的方式。每个Team有个token,数据push的时候要带上这个token,用来做安全防护,另外就是数据就和某个Team关联起来了。
Frontend可以水平扩展,无状态。
Backend
Frontend拿到数据之后,通过一致性哈希打到后端多个Backend组件,这样就可以做到,某个Backend只处理整个集群的一小部分数据,可以在内存中有针对性的做一些缓存之类的。
Backend要去判断报警,写索引库,写历史数据,做归档。重要的活计都是交给Backend来做了,那某Backend实例挂了怎么办?Frontend会感知到,然后踢掉挂了的Backend实例,重做hash环即可。
Backend可以很轻易的扩容,Frontend也可以很快感知,两个组件之间有心跳机制。这样一来,Backend也没有单点风险。
MySQL
Open-Minos严重依赖MySQL,首先会从业务上分库,用来给Frontend组件存放基础信息的frontend库,用来存放索引的indexes库,用来存放报警历史事件的events库,用来存放心跳信息的naming库,最后是存放历史数据的history库。我们的数据上来之后会写索引库,产生一个自增ID,根据自增ID去分库分表即可。
Redis
报警事件仍然采用Redis存储,Redis的高可用,笔者思考准备在前面架设一个四层负载均衡,两个Redis一主一备,备是冷备,外加一个keepalive脚本放在备机,不断去探测主是不是挂了,主挂了,启动备。
Redis的作用类似一个队列,此处的报警事件需要有个alarm组件来处理,但是我们也可以轻松引入其他consumer,通过redis做多个队列,代码中实现多播即可。
为什么没有引入专门的MQ呢?为了简化系统。
Alarm
处理报警事件,发送报警,可以水平扩展,因为阉割了报警合并功能。
Housekeeper
最后一个组件,家庭主妇,负责清理老旧数据。单点,但是挂个几天无所谓。记得再把她起来即可。
嗯,看起来应该是可以走通,也能处理比较大的数据量。如果你们公司监控数据实在太大,每个周期几十亿条,可以考虑部署多套Open-Minos,只有这几个组件的话,应该不用10分钟就可以搭建起来一套吧,O(∩_∩)O~
*更新
我现在觉得部署多套其实是个挺好的方案,比如miui这个部门的sre部署一套,给miui的dev使用;duokan这个部门的sre部署一套给duokan的dev使用;这些dev相互之间根本没有交集,不同的部门单独一套,还可以有针对性的做一些二次开发。
那这样一来维护成本是不是就高了?那要看Open-Minos做得是不是易于维护了,呵呵。