小米开源监控系统OpenFalcon应对高并发7种手段
2019独角兽企业重金招聘Python工程师标准>>>
小米开源监控系统OpenFalcon应对高并发7种手段
原创 2016-04-01 秦晓辉 高可用架构 编者按:本文是秦晓辉在 3 月 27 日数人云“百万并发”活动的演讲,授权「高可用架构」首发。转载请注明来自高可用架构公众号「ArchNotes」。
秦晓辉,小米运维研发技术负责人,互联网公司监控解决方案 OpenFalcon 主程,国内第一套开源 PaaS 平台 DINP 主程,企业级业务监控 Minos 作者,Gopher,现负责小米运维平台的搭建。关注运维自动化、PaaS 领域。
今天给大家简单介绍一下 OpenFalcon 应对高并发的一些手段。OpenFalcon 是一个监控系统,来自于小米的运维团队,OpenFalcon 主要针对运维架构师、DevOP 及关注高并发的研发人员。小米在使用 OpenFalcon 的过程当中,每个周期(5 分钟)大约有 1 亿条数据汇报上来。
下面我首先会对 OpenFalcon 做一个简单介绍,然后再介绍小米在高并发场景 7 种应对的手段,包括怎么做数据采集、转发、分片、报警等内容。
(OpenFalcon 架构,点击图片可全屏缩放)
OpenFalcon 简介
监控系统是整个运维环节,乃至整个产品生命周期中最重要的一环。
当公司刚刚起步,业务规模较小,运维团队也刚刚建立的初期,选择一款开源的监控系统,是一个省时省力,效率最高的方案。
之后,随着业务规模的持续快速增长,监控的对象也越来越多,越来越复杂,监控系统的使用对象也从最初少数的几个 SRE,扩大为更多的 DEVS,SRE。这时候,监控系统的容量和用户的“使用效率”成了最为突出的问题。
OpenFalcon 来自于小米的运维团队,在 2014 年初开发,大约开发了半年左右第一个版本上线,之后一直在线上稳定运行,后来我们成立了 OpenFalcon 社区。
现在有很多公司正在使用 OpenFalcon,像美团、金山云、京东金融、赶集、宜信、快网等。
BAT 这种大公司目前还没了解到是否使用 OpenFalcon,他们大多使用自研系统。
OpenFalcon 官网是 http://open-falcon.org/ ,文档地址是 http://book.open-falcon.org/ ,感兴趣的同学的可以进一步访问了解。
OpenFalcon 是在这样一个场景下产生,当时小米有三套 Zabbix,每套大约可以支撑 2,000 台机器左右。当时有 6,000 台机器,所以搭建了 3 套 Zabbix。另外内部还有 1 套业务监控系统,内部叫 PerfCounter,负责业务性能指标监控。
由于 4 套监控系统维护起来比较麻烦,于是就有了开发这么一个大一统的解决方案,也就是 OpenFalcon 的想法。
(高可用小编:看来牛人偷懒,永远是强大系统产生的源动力)
OpenFalcon 其他部分特性还包括:
水平扩展能力:支持每个周期上亿次的数据采集、告警判定、历史数据存储和查询
高可用:整个系统无核心单点,易运维,易部署,可水平扩展
开发语言: 整个系统的后端全部 golang 编写,portal 和 dashboard 使用Python 编写
OpenFalcon 在高并发场景的 7 种应对手段
- 数据采集推拉抉择
对于监控系统来说,包含几个核心功能:数据采集、历史数据存储、报警,最后是绘图展示及数据挖掘。
数据采集
这一块我们希望做一个大一统的东西,因此要采集很多监控指标,比如 Linux 本身的监控指标,像 CPU、内存、网卡、IO 等,一些硬件指标,比如风扇的转速、温度等等,再加上一些开源软件如 MySQL,Nginx,OpenStack,HBase 等监控指标。
公司内部有很多产品线,每一个服务运行状况都希望采集到,比如中间层服务开了一些 RPC 端口,每一个 RPC 端口在服务过程中,latency 是多少,QPS 是多少,我们都希望了解到。
所以需要覆盖很多监控指标,监控团队刚开始只有两个人,不可能把所有监控指标都采集到——人力不行、技术水平也达不到。
所以我们需要共建监控数据,让专业的人干专业的事。
DBA 同学对 MySQL 比较熟,那他们去采集 MySQL 相关指标,分布式团队同学去采集 HBase 或 Hadoop 等指标,网络组同学去采集交换机路由器指标。
而作为监控团队要做的,就是制订一个规范。制定一个数据进来的机制,然后公司开发人员和运维人员按照规范去推送数据。
数据收集没有采用拉的方式,因为太多数据源,作为一个 Client 去连接源端,采集数据,再关闭连接,会产生很多 time_wait 状态连接,其吞吐必然是不高,所以要把自己做成 Server 端。现在每个周期有 1 亿多条数据。
这个周期简单解释一下,监控数据是一个持续上报,比如 Linux 一些基本监控项一分钟一次采集之后上报,下一分钟再采集再上报。一些像业务监控有 3 分钟的,有 5 分钟的。
因此周期是指数据量是 5 分钟以内,有上报动作的数据。
- 中间节点快速转发与容错
数据有很多要 Push 到 Server 端,Server 端最前端组件是 Transfer,Transfer 接收到数据后要把它转发给后面两个组件,一个是 Graph(用来做绘图),一个是 Judge(用来做报警判断)。
首先对每一个后端实例创建一个 Queue 出来,比如 20 个 Graph 实例,60 个 Judge 实例,为每个实例创建一个 Queue,每个 Transfer 内存中有 80 个 Queue,
当一条监控数据过来之后,需要判断数据发到哪一个实例,然后放到这个实例对应 Queue。Transfer 接收数据 RPC 逻辑非常简单,数据拿到后放到 Queue 就立马返回。
Agent 到 transfer,transfer 到 judge,judge 到 Redis,Redis 到 alarm,报警链路比较长,如果希望尽快触发报警,链路每一个环节都希望比较快速处理,用 Queue 方式,Transfer 吞吐特别大,不会拖慢整个链路。
数据放在 Queue 中有一个问题,如果不及时转发,比如后端 load 比较高或者挂了,Queue 数据就会堆积,超过内存就会 crash,所以做了一个简单保护措施,将 Queue 设成定长,超过 Queue 长度,数据就放不进来。
数据 Push 到 Queue 后,有一个专门对 Queue 读入 worker,读到了之后转发。转发这个动作由一堆写 worker 完成,这里 worker 是指 goroutine,如此这般,一堆 goroutine 协同工作,来提高转发性能。
- 一致性哈希分片提高吞吐容量
一致性哈希分片
这么多数据上来不可能由一台机器处理,因此做了一个数据分片,即一个机器只处理一部分数据,报警数据是由 Judge 做分片,绘图数据由 Graph 做分片,这两个都是使用一致性哈希。
一致性哈希分片有一个问题,就是扩缩容比较麻烦,数据打到某个 judge 之后,就会一直打到这个 judge。
当列表发生变化时候,由于一致性哈希算法,原来打到一台 judge 实例的数据就会打到另外一个 Judge 实例,所以 Judge 一定要保证没有状态,这样才能方便扩缩容。
状态标记
其实说它没有状态也不太合适,judge 内存里也存了几个点。比如某一台机器 cpu.idle 数据上来之后,连续 3 ~ 5 次达到一个特定阀值才去报警,而不是达到阀值立马报警。像 CPU,是一直都忙碌状态才去报警,Judge 判断的时候它是判断多个点。
产生报警之后,还有一些后续处理,比如对这个报警事件做一个判断,上次产生事件是什么状态,他是第几次报警,是不是达到了最大报警次数不能再报了,避免重复报警给处理人员造成干扰。一般大家都设置报警 3 次。
因此报警事件需要记录一个状态,标记是否健康,如果有问题,记录当前是第几次。Judge 状态存在数据库,虽然 1 亿条数据上来,实际上报警数据不多,可能只有 10 万条数据级别,因此可以存入数据库,这样 Judge 就剥离了报警事件状态。
虽然 Judge 内存当中还存一些前面所说数据状态,但也不是一个大问题。因为监控数据是源源不断上来,即使丢掉一些状态,新的 Judge 实例很快就会又填充数据。
扩容
一致性哈希对扩容不是很友好,比如 20 台 Graph 的机器如果变成 40 台,势必有老的 Graph 实例的一部分数据打到新的 Graph 上,因此我们做了一个自动数据迁移。
这个自动迁移是由于一致性哈希造成的问题,如果用映射表做分片,在映射表这统一维护数据和 graph 实例对应关系,扩容就简单很多。
- 数据与策略快速匹配
当数据上来后,要判断这个数据是不是触发了报警策略,策略有很多种,比如我们现在系统中有几千上万条。
上来一条数据之后,要判断这个数据跟哪一条策略相关,然后再判断阀值是多少,是不是要触发报警。
我们选择去数据库同步所有报警策略列表,因为策略列表整个公司不会特别多,虽然数据量多,但是策略不是特别多,比如只有几千条或者几万条。
在策略数据库做了一个简单索引,方便数据上来之后快速定位策略,然后根据阀值看是否要需要报警处理。
为了加快策略判定,需要知道近期一些历史数据,历史存在 Judge 内存中,这样获取速度相对来说快一些。
第一个版本做测试时没有放到内存中,当时用了 56 个 Redis 实例,每个实例大概有 3,000 QPS,那时上的量不大,仍然达到了一个这么高的 QPS。由于并发高,把数据放到 Redis 中并不是一个很好的解决办法,后来就把它放到了Judge 内存里。这样处理起来就快很多。
报警状态也存在 Judge 内存及 DB。如果每个报警判断都去访问 DB 比较耗时,所以就加载到 Judge 内存,相当与缓存的机制,内存没有再去 DB 加载。在 Judge 重启的时候,内存没有数据,这时报警状态的判断需要去 DB 加载,然后再读到内存里。
- 数据延迟写入,减少 RRD 文件打开次数
时间序列数据自动归档
报警数据存储采用 RRD,RRD 比较有名。大量开源监控软件存储时间序列数据都选用 RRD。
RRD 最大的优点是自动归档。监控数据有一个特点,不需要关心历史监控数据具体的值,只需知道当时的趋势即可。
最新 6 个小时可能有看原始值需求。但是最近 3 天 及 1 个月原始值的需求就很小。而且那个点特别多,一分钟 1 个点,一天有 1440 个点。如果加载 1 个月浏览器不崩才怪。
由于对历史点只要能看到趋势就行。因此监控数据特别需要归档功能。比如一个小时的数据归档为一个点,RRD 可以帮我们做这个事情。
RRD 优化:延迟合并写入
RRD 默认操作性能比较差,它的逻辑是打开 RRD 文件,然后去 seek,write,seek,write,最后 close 文件句柄。一个监控指标对应一个 RRD 文件,比如这个机器上面处理了大约 200 万个监控指标,实际上就有 200 万个 RRD 的文件。
每次写入数据的时候,打开这个 RRD 文件,读头部信息,包含一些 meta 信息,记录了归档策略、数据类型之类数据,然后去做写入操作。
如果每一个数据上来之后都做这个操作,RRD 读写会造成特别大的 IO。虽然现在磁盘都是 SSD,但由于 IO 居高不下,于是做了一个延迟写入的优化。
现在数据都是 1 分钟上报一次,可能有的数据 10 秒或 30 秒上报一次。并不是上报上来立马打开 RRD 文件写入,而是等 10 分钟或者 30 分钟,在内存中缓存一段时间,缓存 30 个点或者 60 个点,一次性把文件打开,一次性写入再关闭,这样可以减少 RRD 文件打开的次数,让 IO 降低一些。
我们根据缓存的时间,比如缓存半个小时,再按照半个小时时间长度来做数据打散,比如现在半个小时是 1,800 秒,举个例子,1,800 秒把它做成 1,800 个槽位,每个数据上来之后平均分散到 1,800 个槽位当中,写的时候慢慢地写,这样做了一个打散操作,避免让 IO 出现一些峰值。
- 报警事件按优先级入队列缓冲
报警事件量通常不是特别大,但个别时候会比较大——触发一些大面积报警的时候,比如某一个核心交换机挂掉了,会产生特别大的报警。
比如服务依赖于上游某几个服务,上游服务挂了,所有下游服务都报警。如果核心交换机挂了,很多核心服务都受影响,核心服务受影响之后,下游很多服务就产生报警,这样产生一个大面积报警。但通常情况下,报警量都是一个很平稳的一个量。
当大面积报警出现时,我们仍然是应用 Queue 机制,用 Queue 来抹平峰值。
报警的分级处理
我们将报警进行分级,从 P0、P1 一直到 P5,P0 最高。
基于优先级的分级策略
P0、P1 发短信发邮件,并且是收到报警立即发; P2 这个级别发短信不是立即发,而是做一个报警合并; P3、P4 那些低级别就做报警合并,同时不发短信,只发邮件。
我们对报警事件做一个分级,每一个级别就对应 Redis 里面一个Queue。利用 Redis BRPOP 简单实现按照优先级处理报警事件,即先处理 P0,再处理 P1、P2 顺序。
- 通过限制 Worker 数目发送接口限流
系统本身可能链路比较长,每个链路都希望能够扛住高并发,实际上在系统开发过程当中,我们依赖于其他基础设施,比如内部有 SMTP 服务器来发送邮件,有短信通道来发送短信,但是这些接口扛不住很大的并发。
当要系统依赖调用几个并发能力较差的接口,最好做一个限流。
有一个专门的模块 Sender 发送报警邮件或者报警短信,它发送时候可以给它配置一个 Worker 数量,大家可以理解成最多有多少个线程来调用发送接口。这样就可以保护后端发送接口,不至于把它打挂。
总结
回到今天的议题“百万并发”,总结我们在设计 OpenFalcon 用到的技术。
分片:一台机器抗不住就分成多台机器,数人云是一个 PaaS 平台,PaaS 平台很容易做扩容,原来三百台实例现在做三千台,在页面上按键按一下,10 秒就可以让 3000 台实例起来,做 3000 个分片。
队列:有时候产生一些峰值,我们不希望被峰值打垮,于是用队列做缓冲,这个系统有多个地方用到队列,比如 transfer 内存中构建了多条队列,报警事件使用 Redis 做队列服务。
索引:索引可以加快查询速度。
限流:后端的接口抗不住压力的时候会做限流。
这只是几个简单的、很普适的手段,没有炫耀那些高精尖、大家不太能理解及很难借鉴的东西,希望能给大家在应对高并发时候提供一些参考,谢谢大家!
相关精彩文章
基于 Locust、Tsung 的百万并发秒杀压测案例 5 人技术团队开发 Go Web 项目的 9 条教训 小米抢购限流峰值系统「大秒」架构解密
想关注更多高并发技术,请订阅公众号获取更多文章。转载请注明来自高可用架构「ArchNotes」微信公众号及包含以下二维码。
高可用架构 改变互联网的构建方式
转载于:https://my.oschina.net/tantexian/blog/713846
小米开源监控系统OpenFalcon应对高并发7种手段相关推荐
- 小米开源监控系统Open-falcon部署笔记(上)
一.环境准备 操作系统:centos7.4 1.1 更换yum源 1.1.1 备份默认的yum文件 mv /etc/yum.repos.d /etc/yum.repos.d.bak 1.1.2 新建y ...
- 小米的开源监控系统open-falcon架构设计,看完明白如何设计一个好的系统
小米的开源监控系统open-falcon架构设计,看完明白如何设计一个好的系统 小米的http://book.open-falcon.org/zh/intro/ 早期,一直在用zabbix,不过随着业 ...
- Open-Falcon 小米开源监控系统Dashboard使用操作与告警通知
前言 上一章节我们已经完成了Open-Falcon的单机部署,这一章节主要介绍Open-Falcon的用户注册.功能使用和监控客户端配置. Open-Falcon 部署参考:CentOS-7 单机部署 ...
- 小米开源监控系统监控mysql_二、小米开源监控平台open-falcon安装与使用
小米开源企业级监控平台open-falcon安装与部署 由于实验机器不多,并不是生产环境,只是作为学习使用,故采用 ALL In One 的模式,即一个中心主机,其他主机都往这一个中心主机推送数据.中 ...
- 账户系统如何应对高并发、热点账户等问题
互联网金融系统的核心是支付结算,而支付结算的基础又是账户系统.互金账户系统的特点是并发量大.响应快.交易金额大,热点账户问题突出.一个合格的账户系统既要解决上述问题,又必须绝对保证资金安全.作为这家互 ...
- 小米开源监控系统监控mysql_小米开源监控 Open-Falcon 3.0 部署
一.系统环境准备 目前我这里使用单机版进行部署,也可以前后端进行分离,前端,后端,数据库分别在不同的服务器上进行部署搭建 1.更改主机名 [root@localhost ~]# hostnamectl ...
- 视频直播系统开发:如何应对高并发访问?
视频直播开发的挑战 随着移动互联网的快速普及,视频直播已经成为了新的社交媒体形式,也成为了一种新的商业模式.现在,越来越多的人开始使用视频直播来展示自己的生活和工作,同时,越来越多的企业开始将视频直播 ...
- 小米开源监控open-falcon安装
https://www.cnblogs.com/liangqihui/p/6618127.html 前言 近期爆出Zabbix有严重bug,加上一直对zabbix的性能.UI不满.所以这次想钻研一下最 ...
- 程序员过关斩将--应对高并发系统有没有通用的解决方案呢?
" 灵魂拷问: 应对高并发系统有没有一些通用的解决方案呢? 这些方案解决了什么问题呢? 这些方案有那些优势和劣势呢? 对性能孜孜不倦的追求是互联网技术不断发展的根本驱动力,从最初的大型机到现 ...
最新文章
- 中科院微生物所高程组招聘助研3名(正式编制)
- 骚年快答 | 微服务架构中的BFF到底是啥?
- 苏嵌第一天,shell中一些基础知识
- 信息学奥赛一本通 1925:【03NOIP普及组】麦森数 | OpenJudge NOI 4.4 1708:麦森数 | 洛谷 P1045 [NOIP2003 普及组] 麦森数
- 将远程数据库中的某表数据复制到本数据库(ORACLE)
- pycharm不能输入代码
- 集成学习——机器学习(周志华)
- 易语言之编译后图标模糊的处理方案
- Visual Studio Code快捷指令
- Android10闪退无日志,【报Bug】Android10手机白屏闪退
- xshell .swp文件
- 【Python自然语言处理】读书笔记:第七章:从文本提取信息
- Java poi api插入文字水印到docx文件
- 一文彻底看懂LightGBM
- 咖啡豆是怎么生产出来的
- ibm服务器日志文件提取,IBM服务器日志搜集方法
- SE:17.网络编程
- Class文件结构分析
- 同比增速创上市以来新低,云米科技何时能够走出小米的舒适圈?
- 很多工程项目没有意识到Oracle P6软件的重要性