采集自动组合( 小米运维研发技术负责人,互联网公司监控解决方案主程 )

优采云 发布时间: 2021-09-02 07:12

  采集自动组合(

小米运维研发技术负责人,互联网公司监控解决方案主程

)

  

  秦晓辉,小米运维研发技术负责人,互联网公司监控解决方案OpenFalcon主程序,国内首个开源PaaS平台DINP主程序,企业级业务监控Minos作者,Gopher,现负责小米建设运维平台。关注运维自动化和PaaS领域。

  今天给大家简单介绍一下OpenFalcon处理高并发的方法。 OpenFalcon 是小米运维团队的监控系统。 OpenFalcon 主要面向运维架构师、DevOPs、关注高并发的开发者。小米在使用OpenFalcon的过程中,每个周期(5分钟)上报数据约1亿条。

  下面先简单介绍一下OpenFalcon,然后再介绍小米处理高并发场景的7种方法,包括数据采集怎么做,转发,分片,告警等。

  

  (OpenFalcon架构,点击图片可全屏放大)

  OpenFalcon 简介

  

  监控系统是整个运维环节,乃至整个产品生命周期中最重要的环节。

  公司刚起步,业务还小,运维团队刚刚成立初期,选择开源监控系统是省时、省力、效率最高的方案.

  之后,随着业务规模的不断快速增长,监控的对象越来越多,也越来越复杂。监控系统使用的对象也从最初的几个SRE扩展到了更多的DEVS和SRE。 此时,监控系统的容量和用户的“使用效率”成为最突出的问题。

  OpenFalcon 来自小米运维团队。 2014年初开发,大约半年后,第一个版本上线。此后,它一直稳定地在线运行。后来,我们建立了 OpenFalcon 社区。

  *敏*感*词*山云、京东金融、赶集、易信、快网等

  像BAT这样的大公司还不知道要不要用OpenFalcon,大部分都是自研系统。

  OpenFalcon的官网是,文档地址是,感兴趣的同学可以访问了解一下。

  OpenFalcon 就是在这种情况下产生的。当时小米拥有三套Zabbix,每套可支持约2000台机器。当时有6000台机器,所以造了3套Zabbix。此外,还有一个内部业务监控系统,内部称为PerfCounter,负责监控业务绩效指标。

  因为4套监控系统的维护比较麻烦,所以就有了开发这样一个统一的解决方案的想法,那就是OpenFalcon。

  (高可用编辑器:看来伟人都是懒惰的,永远是强大系统的源头)

  OpenFalcon 的其他功能包括:

  横向扩展能力:支持每周期数亿条数据采集、告警判断、历史数据存储和查询

  高可用:整个系统无核心单点,易运维,易部署,可横向扩展

  开发语言:整个系统后端使用golang编写,门户和仪表盘使用Python编写

  OpenFalcon在高并发场景下的7个对策

  

  1.数据采集推拉选择

  对于监控系统,它包括几个核心功能:data采集、历史数据存储、报警,最后是图形显示和数据挖掘。

  数据采集

  我们希望为这块做一个统一的东西,所以需要采集很多监控指标,比如Linux本身的监控指标,比如CPU、内存、网卡、IO等,一些硬件指标,如风扇转速、温度等,外加一些开源软件如MySQL、Nginx、OpenStack、HBase等监控指标。

  公司有很多产品线。我们希望采集 可用于每个服务运行状态。比如中间层服务开放了一些RPC端口。服务过程中每个RPC端口的延迟和QPS是多少?我想知道。

  因此,需要覆盖很多监测指标。监控组一开始只有两个人。不可能采集所有监控指标——人手不够,技术水平不达标。

  所以我们需要一起建立监控数据,让专业的人做专业的事。

  DBA 学生对 MySQL 比较熟悉。然后去采集MySQL相关指标,分布式组同学去采集HBase或Hadoop等指标,网络组同学去采集交换机路由器指标。

  监控团队要做的是制定规范。开发数据进来的机制,然后公司开发人员和运维人员按照规范推送数据。

  数据采集没有使用pull方式,因为数据源太多,作为Client去连接源,采集data,然后关闭连接,会产生很多time_wait状态的连接,吞吐量肯定会很低,所以让自己成为服务器端。现在每个周期有1亿多条数据。

  此循环的简要说明。监测数据是一个连续的报告。比如Linux的一些基本监控项在采集后一分钟上报一次,下一分钟再采集。有些事情(例如业务监控)有 3 分钟和 5 分钟。

  所以周期是指数据量在5分钟以内,有数据上报动作。

  2.中间节点快速转发和容错

  

  有很多数据需要推送到服务器端。服务器端的前端组件是Transfer。 Transfer接收到数据后,转发给接下来的两个组件,一个是Graph(用于绘图),另一个是Judge(用于做报警判断)。

  先为每个后端实例创建一个Queue,比如20个Graph实例,60个Judge实例,每个实例创建一个Queue,每个Transfer内存有80个Queues,

  当有一条监控数据进来时,需要判断数据发送到哪个实例,然后放到这个实例对应的Queue中。 Transfer接收数据的RPC逻辑非常简单。接收到数据后,放入Queue,立即返回。

  代理转,转判断,判断到Redis,Redis报警,报警链接比较长,如果想尽快触发报警,需要快速处理链接的每个链接,使用Queue方式,传输吞吐量特别大,不会拖慢整个链路。

  放入队列的数据有问题。如果没有及时转发,比如后端负载比较高或者挂了,Queue数据就会堆积,超过内存就会崩溃。所以采取了一个简单的保护措施来设置 Queue 如果长度是固定的,如果超过 Queue 的长度,则数据无法放入。

  数据推送到Queue后,有一个worker专门把它读入Queue,读完后再转发。转发动作是由一堆写worker完成的,worker指的是goroutine,所以一堆goroutine协同工作,提高转发性能。

  3. 一致性哈希分片提高吞吐能力

  

  一致性哈希分片

  这么多数据,一台机器处理不了,所以做了数据切分,即一台机器只处理部分数据。报警数据采用 Judge 分段,绘图数据采用 Graph 分段。全部使用一致哈希。

  一致性哈希分片的一个问题是扩展和收缩很麻烦。数据命中某个判断后,会继续命中该判断。

  当列表发生变化时,由于一致性哈希算法,原本被一个judge实例命中的数据会被另一个judge实例命中,因此Judge必须保证没有状态,以便于扩容和缩容。

  状态标签

  其实说没有地位也不合适。法官记忆中也有几点。比如某台机器的cpu.idle数据上来后,连续3到5次达到特定阈值就会报警,而不是达到阈值就立即报警。和CPU一样,闹钟总是忙碌的。 Judge 判断时,判断多个点。

  报警产生后,还有一些后续的处理,比如对报警事件做出判断,上次事件的状态是什么,已经报警了多少次,是不是最大次数无法再次报告的警报?避免重复报警对加工人员造成干扰。一般来说,每个人都会设置闹钟3次。

  所以报警事件需要记录一个状态,标记是否健康,如果有问题,记录当前次数。法官状态存储在数据库中。虽然上来1亿条数据,但实际上报警数据并不多,可能只有10万条数据级,所以可以存入数据库,所以Judge去掉报警事件状态。

  Judge的记忆中虽然还有上面提到的一些数据状态,但问题不大。因为监控数据不断上来,即使丢失了一些状态,新的Judge实例很快就会被数据填满。

  扩展

  一致性散列对扩展不是很友好。比如20台Graph机器变成40台机器,老Graph实例的部分数据必然会转移到新Graph上,所以我们做了自动数据迁移。

  这种自动迁移是一致性哈希引起的问题。如果使用映射表进行分片,数据和图实例的对应关系在映射表中统一维护,扩展简单很多。

  4. 快速匹配数据和策略

  

  当数据上来时,需要判断数据是否触发了报警策略。有很多策略。例如,我们的系统中有数以万计的项目。

  上传一条数据后,需要先判断该数据与哪种策略相关,然后再判断阈值和是否触发告警。

  我们选择将所有报警策略列表同步到数据库中,因为整个公司不会有太多的策略列表。虽然数据量很大,但没有太多的策略,比如只有几千或几万。

  在策略库中做了一个简单的索引,方便数据上来后快速定位策略,然后根据阈值看是否需要报警。

  为了加快策略的决策,需要了解一些近期的历史数据。历史记录存储在Judge内存中,因此获取速度相对较快。

  测试第一个版本时,没有放入内存。当时使用了56个Redis实例,每个实例的QPS在3000左右。当时量并不大,还达到了这么高的QPS。由于并发性高,把数据放在Redis中不是很好的解决方案,后来放到Judge内存中。这样处理起来要快得多。

  判断内存和数据库中也存在报警状态。每次报警判断都需要访问DB,所以加载到Judge内存中,相当于缓存机制,内存不去DB加载。当Judge 重新启动时,内存中没有数据。此时需要将报警状态的判断加载到DB中,然后再读入内存。

  5.延迟数据写入,减少RRD文件打开次数

  

  时间序列数据自动归档

  报警数据存储使用比较有名的RRD。大量开源监控软件使用RRD来存储时间序列数据。

  RRD 的最大优势是自动归档。有监测数据的特点。无需关心历史监控数据的具体数值,只需要知道当前的趋势即可。

  可能需要查看最近 6 小时的原创值。但是,最近 3 天和 1 个月对原创值的需求非常小。而且积分这么多,一分钟一分,一天1440分。加载1个月后浏览器没有崩溃就奇怪了。

  只要可以看到历史点的趋势。因此,监控数据尤其需要归档功能。例如,一个小时的数据归档是一个点,RRD可以帮助我们做到这一点。

  RRD 优化:延迟合并写入

  RRD默认操作性能比较差,它的逻辑是打开RRD文件,然后seek、write、seek、write,最后关闭文件句柄。一个监控指标对应一个RRD文件。比如这台机器处理大约200万个监控指标时,实际上有200万个RRD文件。

  每次写数据时,打开RRD文件,读取头信息,包括一些元信息,记录归档策略和数据类型等数据,然后进行写操作。

  如果在每条数据上来之后执行这个操作,RRD读写会造成极大的IO。虽然现在硬盘都是SSD,但由于IO高,做了延迟写入的优化。

  目前每1分钟上报一次数据,部分数据可能每10秒或30秒上报一次。不是上报并立即打开RRD文件写入,而是等待10分钟或30分钟,在内存中缓存一段时间,缓存30或60个点,打开文件一次,写入一次,然后关闭它可以减少RRD文件打开次数,减少IO。

  我们使用缓存时间,比如缓存半个小时,然后按照半个小时的长度来断数据。例如,半小时是 1,800 秒。例如,1,800 秒被制成 1,800 个槽。每个数据上来后,均匀分布在 1800 个槽中。写的时候,慢慢写。这是一个分手操作,以避免出现一些 IO 高峰。

  6. 报警事件按优先级排队缓冲

  

  报警事件量通常不是特别大,但有时会比较大——当触发一些大面积的报警时,比如核心交换机挂了,就会产生特别大的报警。

  比如服务依赖几个上游服务,上游服务宕机,下游所有服务都报警。如果核心交换机宕机,很多核心业务都会受到影响。核心业务受到影响后,很多下游业务都会产生告警,从而产生大面积告警。但正常情况下,报警音量是一个非常稳定的音量。

  当发生大面积报警时,我们仍然应用Queue机制,使用Queue平滑峰值。

  告警分类处理

  我们将告警从 P0、P1 分类到 P5,其中 P0 最高。

  基于优先级的分级策略

  我们对告警事件进行分类,每一级对应Redis中的一个Queue。使用Redis BRPOP简单的按照优先级处理告警事件,即先处理P0,然后依次处理P1、P2。

  7.通过限制worker数量来限制发送接口的流量

  

  系统本身可能有比较长的链接,每个链接都希望能够处理高并发。事实上,在系统开发过程中,我们依赖其他基础设施,例如内部SMTP服务器来发送电子邮件和短信通道。发送短信,但是这些接口不能处理大并发。

  当系统依赖调用多个并发性较差的接口时,最好设置一个限流。

  有一个特殊的模块*敏*感*词*可以发送警报电子邮件或警报消息。当它发送时,它可以配置多个Worker。可以理解为最多有多少个线程可以调用发送接口。这样可以保护后端发送接口,不会被破坏。

  总结

  

  回到今天的话题“百万并发”,总结一下我们在OpenFalcon的设计中用到的技术。

  1.分片:如果一台机器无法抵抗,就会分成多台机器。数人云是一个PaaS平台。 PaaS 平台易于扩展。原来的三百个实例现在是三千个,在页面上按下按钮,3000个实例可以在10秒内制作3000个切片。

  2. 队列:有时候会有一些高峰,我们不想被高峰淹没,所以我们使用队列作为缓冲区。该系统在许多地方使用队列。例如,在传输存储器中内置多个队列并被警报事件使用。 Redis 做队列服务。

  3.索引:索引可以加快查询速度。

  4.限流:当后端接口不能承受压力时,会限流。

  这些只是一些简单而通用的方法。他们没有炫耀那些高科技、难懂、难学的东西。希望能为大家在处理高并发时提供一些参考。谢谢你。 !

  相关精彩文章

  

  想关注更多高并发技术,请订阅公众号了解更多文章。请注明来自高可用框架“ArchNotes”微信公众号,并附上以下二维码。

  高可用性架构

  改变互联网的构建方式

  

  长按二维码订阅“高可用框架”公众号

  

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线