集群管理,包括集群监控和集群控制两大块。集群监控侧重对集群运行时状态的收集。集群控制是对集群进行操作和控制。
日常开发和运维需求
如何快速的统计当前生产环境一共有多少台机器
如何快速的获取机器上下线的情况
如何实时监控集群中每台主机的运行时状态
Zookeeper实现集群监控
Zookeeper两大特性
1、客户端如果对Zookeeper的数据节点注册Watcher监听。那么当该数据节点的内容或者是其子节点列表发生变更时,Zookeeper服务器就会像订阅的客户端发送变更请求。 2、对在Zookeeper上创建的临时节点,一旦客户端与服务端之间的会话失效,那么临时节点也会被删除。
实现方案
1、在监控系统建一个持久节点 /clusterServers
,并在该节点上注册一个Watcher监听。
2、只要有进行动态添加机器的操作,那么就在 /clusterServers
节点下创建一个临时节点: /clusterServers/{Hostname}
。这样,监控系统就能够实时监测机器的变动情况。
3、如果机器发生故障宕机,则客户端会话也会随之消失,客户端对应的临时节点也将清除。
分布式日志收集系统
核心工作
架构设计
整个日志系统会把需要手机的日志源机器,分为多个组别,每个组别对应一个收集器机器(后台机器),用于收集日志。
需处理问题
变化的日志源机器
在生产环境中,每个应用的机器几乎每天都在变化(机器硬件问题、扩容、机房迁移、网络问题等)。
也就是说每个组别中的日志源机器通常是在不断变化的。
变化的收集器机器
日志收集系统自身也会有机器的变更或扩容。会出现新的收集器机器加入或者是老的收集器机器退出的情况。
针对日志源机器或者是收集器机器的变更问题,其实就是为了能够快速、合理、动态地为每个收集器分配对应的日志源机器。处理变更问题,保证日志系统的正确稳定运转,就可以使用Zookeeper处理日志系统收集场景下的变更问题。
Zookeeper场景使用步骤
1、注册收集器机器
使用Zookeeper来进行日志系统收集器的注册。
可以在Zookeeper上创建一个节点作为收集器的根节点: /logs/collector
(收集器节点);
每个收集器机器在启动的时候,都会在收集器节点下创建自己的节点: /logs/collector/{HostName}
。
2、任务分发
等到所有的收集器机器都创建好自己对应的节点后,系统会根据收集器节点下的子节点个数,将所有的日志源机器分为对应的若干组。
然后将分组后的机器列表分别写到这些收集器机器节点( /logs/collector/host1
)创建的子节点上去。
这样一来,每个收集器机器能够从自己对应的收集器机器节点上获取日志源机器列表,进而开始日志手机工作。
3、状态汇报
完成收集器机器的注册以及任务分发后,需要考虑收集器机器故障宕机的可能。
针对该问题,需要有一个收集器的状态汇报机制:每个收集器机器在创建完自己的专属节点后,还需要在对应的子节点上创建一个状态子节点( /logs/collector/host1/status
),每个收集器机器都需要定期向该节点写入自己的状态信息。—— 可以将这种策略看作是一种心跳检测机制,通常收集器机器都会在这个节点中写入日志收集进度信息。日志系统根据这个状态子节点的最后更新时间来判断对应的收集器机器是否存活。
4、动态分配
如果收集器机器挂掉或者是扩容了,就需要能够动态地进行收集任务的分配。
在运行过程中,日志系统是始终关注着 /logs/collector
这个节点下所有子节点的变更的,一旦检测到有收集器机器停止汇报或者是有新的收集器机器加入,就要开始进行任务的重新分配。
无论是针对收集器机器停止汇报(也就是机器挂掉)或者是新机器加入的情况,日志系统都需要将之前分配给收集器的所有任务(日志源机器)进行转移。
有以下两种做法:
- 全局动态分配
在出现收集器机器挂掉或扩容的情况,日志系统需要根据最新的收集器机器列表,立即对所有的日志源机器重新进行一次分组,然后将其分配给所有的收集器机器。
做法过于简单粗暴,同时存在问题,一个或部分收集器机器变更就会导致全局任务的分配,影响面和风险较大。
- 局部动态分配
顾名思义,就是在消费为内进行任务的动态分配。
在这种策略上,每个收集器机器在汇报自己的日志手机状态的同时,也会把自己的负载(任务执行的综合评估取得的负载信息)汇报上去。
如果有一个收集器机器挂掉,那日志系统就会把之前分配给这个挂掉机器的日志源机器转移到负载较低的机器。
如果有新的收集器挂掉,那日志系统就会把那些负载高机器上的日志源机器转移到新加入的机器。
5、注意事项
- 节点类型
在 /logs/collector
节点下创建临时节点可以很好判断机器是否存活。但是若机器挂了,那该临时节点就会被删除,记录在该节点下的日志源机器列表也会被清除。
所以需要选择持久节点来标识每台收集器机器,并在节点下分别创建 /logs/collector/{Hostname}/status
节点来标识每个收集器机器的状态。
这样既能实现对所有机器的监控,同时在及其挂掉后,依然能够将分配任务还原。
- 日志系统节点监听
若采用Watcher机制,那么通知的消息量的网络开销会非常大。
需要采用日志系统主动轮询收集器节点的策略,这样可以节省网络流量,但是存在一定的延时。