Morse's Site
1062 字
5 分钟
通过 `Gossip协议` 与 `StatefulSet` 构建监控报警模块集群
2020-04-18

用户设置的监控报警规则的是一种可并行执行的任务, 这种规则没有依赖性, 所以当云上的监控任务多了以后, 单实例计算势必有瓶颈, 那么就必须将任务分配给多个节点去并行执行. 怎么实现, 我们需要解决以下问题:

  1. 如何将监控任务打散到多个任务节点并行执行;
  2. 当客户对监控报警规则做增删改查动作后, 如何保证多个任务节点reload;
  3. 任务节点如何快速伸缩, 及节点的高可用;

设计实现#

任务分配#

任务分配的问题很好处理, 最简单的方式哈希取模: hash(n) = n % m.

数一定情况下, 将任务目标取哈希值, 然后根据数取模, 如果模的值等于的编号, 则将这条任务分配给这个. 举例:

-w800

是不是很简单. 不过这里有个问题, 桶的数量增加了, 模就变了, 也就是数据分配的桶就变了. 比如现在把三个桶变为四个桶, 则: 6 这个数原来在桶0中, 现在跑到 6 % 4 = 桶2中了.

这种情况再某些场景中是无法忍受的. 比如: 数据库分库分表, 图片存储. 这种场景下就需要使用一致性Hash来解决了, 不过在监控不存在这种情况, 桶数变了, 可以让计算节点重新reload计算规则. 即: 重新把数据库中的监控规则加载, 再分配给各计算节点(桶), 所以监控选择了最简单暴力的: 哈希取模来分配任务.

任务分配的问题解决了, 那么如何把这些桶(计算节点)组成一个集群, 统一响应外部的请求(规则的增删改查), 并且计算节点需要做到伸缩方便, 同时伸缩时也能重新分配计算任务.

集群设计#

说到集群, 就必须要提分布式计算了. 这个概念太大了, 这里就不具体展开了(因为我也只是略懂皮毛).

对于监控报警模块的集群要求:

  1. 扩缩容方便
  2. 统一响应外部请求

这里我们通过使用Kubernetes的StatefulSet+Gossip协议来完成计算节点的扩缩容设计和对外部请求的响应.

  • Gossip协议

Gossip是分布式系统中被广泛使用的协议,其主要用于实现分布式节点或者进程之间的信息交换。Gossip协议同时满足应用层多播协议所要求的低负载,高可靠和可扩展性的要求。由于其简单而易于实现,当前很多系统(例如Amazon S3,Usenet NNTP等)选择基于Gossip协议以实现应用层多播的功能。

通过Gossip协议, 解决监控报警节点之间的通讯问题. 即: 当新的节点加入, 节点的离开(比如故障宕机), 用户对报警规则做增删改查等事件时, 通过Gossip协议对集群节点做广播. 从而使集群总说有节点能响应.

  • StatefulSet(以下简写: sts)

因为监控本身就依赖Kubernetes中的Deployment+Service做微服务设计. 所以对于监控模块这种有状态的服务, 最佳选择就是StatefulSet.(StatefulSet如何使用, 就不展开了, 大家可以在kubernetes官网文档中阅读)

-w800

从截图中, 我们可以看到, 在sts中启动时, 共启动了3个节点, 其中容器启动时注入参数:

--gossip-member cms-alarm-0.cms-alarm:18080,cms-alarm-1.cms-alarm:18080,cms-alarm-2.cms-alarm:18080

参数是三个实例的访问地址, 端口是应用设置的默认gossip协议端口. 通过这些参数注入, 应用启动时, 就会自动向其他节点同步.

-w800 -w800

总结#

通过引入Gossip协议和使用StatefulSet组件, 完成了监控规则计算模块的集群设计. 我们的设计不一定是最好的, 但一定是最贴合我们团队的技术和现状的. 如果大家有什么意见和建议, 欢迎一起讨论.

Gossip协议简介: http://kaiyuan.me/2015/07/08/Gossip/ StatefulSet简介: https://kubernetes.io/zh/docs/concepts/workloads/controllers/statefulset/

通过 `Gossip协议` 与 `StatefulSet` 构建监控报警模块集群
https://fuwari.vercel.app/posts/cncf/gossip/
作者
Morse Hsiao
发布于
2020-04-18
许可协议
CC BY-NC-SA 4.0