前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于zookeeper的daemon框架方案——支持容灾和心跳监控

基于zookeeper的daemon框架方案——支持容灾和心跳监控

原创
作者头像
tyriqchen
发布于 2018-08-02 13:23:38
发布于 2018-08-02 13:23:38
1.2K10
代码可运行
举报
文章被收录于专栏:不忘初心不忘初心
运行总次数:0
代码可运行

1 背景

在线上项目中,很多时候需要起一个daemon做守护进程,用于不停地或以一定间隔地执行工作,比如每隔20s把内存中的数据做快照写磁盘。

一些项目中的daemon是以单机仅运行一个实例的方式存在的。这样做的理由主要有:

(1)很多daemon没必要多机同时运行,因为这样会重复做一些工作,意义不大且浪费性能。

(2)有些daemon多机同时运行是会出问题的,比如上报数据,转账等,一旦重复会导致很多竞争和不一致的问题。

但另一方面,单机运行daemon又很容易造成单点故障的问题,无法做到多机容灾。于是在这样的背景下,我们基于zookeeper设计了这个daemon框架,利用分布式锁的概念和心跳监控等措施,保证了多机环境下同一时间有且仅有一个daemon正在运行,同时监控daemon的运行情况,及时告警。

2 整体架构

daemon框架整体架构
daemon框架整体架构

整个daemon框架主要是由业务daemon模块,zookeeper集群和platform_daemon_alive_monitor监控模块三大部分构成。

daemon

一个daemon模块由多个daemon实例构成,每个daemon实例由一个master加一个或多个worker构成。daemon本身是采用主从模型,master初始化和维护一些基础配置数据,并负责和zookeeper集群通信;接着fork出多个worker子进程来执行工作,同时监控子进程的执行:在worker退出时负责回收,并在worker异常退出时告警且重新fork出足够数量的worker继续执行工作。

zookeeper

一个分布式协调服务的zookeeper集群,当中维护了一个“目录树”,并由内部分布式一致性协议保证了集群中各个节点上这棵树的内容是一致的,对zookeeper的操作其实就是对这棵树的操作。同时它也是采用的主从模型,由leader节点对外提供服务,follower节点做容灾备份,保证了其高可用性(存活节点数大于N/2即可正常运行)。

每个daemon启动后需要到这个zookeeper集群的目录树中注册一个有序临时节点,由这个临时节点充当了心跳的角色,只要这个临时节点还存在,则说明对应的daemon的master仍然存活,daemon尚可工作。同时因为各个daemon注册的临时节点是有序的,我们规定只有获得最小序号的那个daemon可以工作,其余的daemon要保持休眠状态,直到上一个daemon因为一些原因停止工作后才由次小序号的daemon接替工作,这样就保证了同一时间点只有一个daemon处于工作状态,并且不会产生惊群现象。如图所示:

daemon锁节点树
daemon锁节点树

platform_daemon_alive_monitor

platform_daemon_alive_monitor模块用于监控zookeeper上这颗目录树,每隔5分钟扫描一次这个目录树,把其中临时节点数少于N的daemon告警出来,我们当前把这个值设置为2,要求所有daemon至少部署2台。platform_daemon_alive_monitor目前是简单地用python脚本+crontab的方式来实现的。实际上,我们把这个脚本部署在了所有zookeeper集群上,让它同时监控了各台机器上zookeeper节点自身的运行情况,以便在zookeeper部分节点挂掉的情况下可以及时告警出来。

3 实现要点

这里截取了daemon框架中master主流程的部分核心代码,当中体现了master去zookeeper上“抢锁”,抢锁失败则停止worker进程,成功则启动worker进程以及监控worker进程执行的整个流程。master在daemon启动后就一直循环执行这个过程直到退出。

其中_zookeeper_lock_switch参数是为了控制daemon是否必须抢锁成功(即自己必须是序号最小的那个daemon)才运行的开关。毕竟并不是所有daemon都需要单机执行,比如rocketmq的消费者daemon一般来说同时运行得越多越好。但无论_zookeeper_lock_switch是开是关,master一开始都需要调用ZK_PROXY_INSTANCE->distributed_lock方法去和zookeeper通信,因为它不仅是为了获取锁,同时也是向zookeeper注册当前daemon实例,证明自己“存活”的不可或缺的步骤。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void CDaemonMaster::RunForever()
{
    while (!g_master_need_quit)
    {
        sleep(1);

        // 无论是否打开锁开关都要加锁,这是为了监控daemon存活与否
        string zk_cur_dis_node;
        int ret = ZK_PROXY_INSTANCE->distributed_lock(_zookeeper_lock_root_path + _process_name + "/",
                zk_cur_dis_node);
        if (ret == EN_ZKPROXY_LOCKED)
        {
            // 加锁成功,可以执行主任务
        }
        else if (ret == EN_ZKPROXY_LOCK_RETRY)
        {
            // 如果必须加锁成功才能执行,则未加锁成功关闭所有子进程
            if (_zookeeper_lock_switch)
            {
                StopWorkers();
                continue;
            }
            // 如果不要求加锁成功,则可以执行主任务
        }
        else
        {
            ERROR_LOG("distributed_lock failed, ret:%d, msg:%s",
                    ret, ZK_PROXY_INSTANCE->get_err_msg());
            if (!_keep_working_when_zk_error)
            {
                // zk发生错误,杀掉所有子进程,继续下一轮
                StopWorkers();
                continue;
            }
            else
            {
                // zk出错仍然工作
                ret = 0;
            }
        }

        // fork进程,开始工作
        if(_worker_pids.size() < _worker_num)
        {
            StartWorkers();
        }

        while(true)
        {
            int status = 0;
            pid_t pid = waitpid(-1, &status, WNOHANG);
            if(pid < 0)
            {
                if(errno != ECHILD)
                {
                    ERROR_LOG("waitpid error, msg=%s", strerror(errno));
                }
                break;
            }
            else if(pid == 0)
            {
                //DEBUG_LOG("no process exit");
                break;
            }
            else
            {
                Alarm("[%s] child process dead", _process_name.c_str());
                ERROR_LOG("child pid=%d exit unexpected! status=%d, WIFEXITED(status)=%d, WEXITSTATUS(status)=%d, WIFSIGNALED(status)=%d, WTERMSIG(status)=%d",
                        pid,
                        status,
                        WIFEXITED(status),
                        WEXITSTATUS(status),
                        WIFSIGNALED(status),
                        WTERMSIG(status));

                _worker_pids.erase(pid);
            }
        }
    }

    // 停止工作
    StopWorkers();

    // 释放锁
    ZK_PROXY_INSTANCE->distributed_lock_clean();

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
请问有java版的实现吗
请问有java版的实现吗
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
zookeeper学习系列:一、入门
基本是 http://zookeeper.apache.org/doc/trunk/zookeeperOver.html 的翻译,应用场景摘抄:http://www.wuzesheng.com/?p=
架构师刀哥
2018/03/20
1.1K0
zookeeper知识结构3-分布式锁
zk相关文章已经有了三篇《zookeeper-paxos》、《zookeeper知识结构》、《zookeeper知识结构2-zab协议》
码农戏码
2021/03/23
3340
一一例举ZooKeeper 的实战应用场景
ZooKeeper 是一个高可用的分布式数据管理与系统协调框架。基于对 Paxos 算法的实现,使该框架保证了分布式环境中数据的强一致性,也正是基于这样的特性,使得 ZooKeeper 解决很多分布式问题。网上对 ZK 的应用场景也有丌少介绍,本文将结合作者身边的项目例子,系统地对ZK 的应用场景进行一个分门归类的介绍。
lyb-geek
2019/10/22
1.1K0
5分钟让你了解 ZooKeeper 的功能和原理
ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现。
Java周某人
2019/08/13
1.2K0
进阶分布式系统架构系列(十三):Zookeeper 分布式锁原理与实现
前面介绍了 Zookeeper 集群 ZAB 协议、配置中心、注册中心、数据与存储、会话与事务管理等相关的知识点,今天我将详细的为大家介绍 zookeeper 分布式锁相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!!
民工哥
2023/09/09
2.1K0
进阶分布式系统架构系列(十三):Zookeeper 分布式锁原理与实现
zookeeper监控告警
一、ZooKeeper简介 ZooKeeper作为分布式系统中重要的组件,目前在业界使用越来越广泛,ZooKeeper的使用场景非常多,以下是几种典型的应用场景: l 数据发布与订阅(配置中心) l 负载均衡 l 命名服务(Naming Service) l 分布式通知/协调 l 集群管理与Master选举 l 分布式锁 zk环境搭建 这里不详细说明,提供详细blog说明。 Zookeeper集群搭建:https://cloud.tencent.com/developer/article/1021111 Z
三丰SanFeng
2018/01/16
3.3K1
zookeeper监控告警
[源码解析] PyTorch 分布式之弹性训练(6)---监控/容错
关于PyTorch弹性训练,迄今为止我们已经分别介绍了 Agent 和 rendezous,但是有些部分并没有深入,比如监控,本文就把它们统一起来,对弹性训练做一个整体逻辑上的梳理。
罗西的思考
2022/05/09
1.2K0
[源码解析] PyTorch 分布式之弹性训练(6)---监控/容错
ZooKeeper 的应用场景
ZooKeepr 提供基于类似于文件系统的目录节点树方式的数据存储,这是一个共享的内存中的树型结构。有几个概念需要关注一下。
runzhliu
2020/08/06
1.7K0
ZooKeeper 的应用场景
node服务的监控预警系统架构
需求背景 目前node端的服务逐渐成熟,在不少公司内部也开始承担业务处理或者视图渲染工作。不同于个人开发的简单服务器,企业级的node服务要求更为苛刻: 高稳定性、高可靠性、鲁棒性以及直观的监控和报警 想象下一个存在安全隐患且没有监控预警系统的node服务在生产环境下运行的场景,当某个node实例挂掉的情况下,运维人员或者对应开发维护人员无法立即知晓,直到客户或者测试人员报告bugs才开始解决问题。在这段无人处理的时间内,损失的订单数和用户的忠诚度和信任度将是以后无法弥补的,因此对于node程序的业务开发者
欲休
2018/03/15
1.4K0
node服务的监控预警系统架构
ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据
本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法、Zab协议、通信协议等相关知 识,理解起来比较抽象所以还需要借助一些应用场景,来帮我们理解。由于内容比较多,一口气吃不成胖子,得慢慢来一步一个脚印,因此我对后期 ZooKeeper的学习规划如下:
用户5640963
2019/07/26
3840
ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据
ZooKeeper 核心通识
作者:mosun,腾讯 PCG 后台开发工程师 文章分三部分展开陈述:ZooKeeper 核心知识、ZooKeeper 的典型应用实现原理、ZooKeeper 在中间件的落地案例。 为了应对大流量,现代应用/中间件通常采用分布式部署,此时不得不考虑 CAP 问题。ZooKeeper(后文简称 ZK)是面向 CP 设计的一个开源的分布式协调框架,将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用,分布式应用程序可以基于它实现诸如 数据发布/订阅、负
腾讯技术工程官方号
2022/11/30
8770
ZooKeeper 核心通识
Zookeeper初识
•Zookeeper 是 Apache Hadoop 项目下的一个子项目,是一个树形目录服务。
小炜同学
2022/09/23
3650
少年:ZooKeeper学一下
很多中间件,比如Kafka、Hadoop、HBase,都用到了 Zookeeper,于是很多人就会去了解这个 Zookeeper 到底是什么,为什么它在分布式系统里有着如此无可替代的地位。
sowhat1412
2020/11/05
5660
少年:ZooKeeper学一下
ZooKeeper(二)
即所谓的配置中心,就是发布者经数据发布到ZooKeeper的一个或一系列节点上,供订阅者进行数据订阅,进而达到动态的获取数据的目的,实现配置信息的集中式管理和数据的动态更新
小土豆Yuki
2021/07/16
3830
ZooKeeper(二)
Zookeeper 原理与实践
1、Zookeeper 的由来 在Hadoop生态系统中,许多项目的Logo都采用了动物,比如 Hadoop 和 Hive 采用了大象的形象,HBase 采用了海豚的形象,而从字面上来看 ZooKeeper 表示动物园管理员,所以大家可以理解为 ZooKeeper就是对这些动物(项目组件)进行一些管理工作的。 对于单机环境多线程的竞态资源协调方法,我们一般通过线程锁来协调对共享数据的访问以保证状态的一致性。 但是分布式环境如何进行协调呢?于是,Google创造了Chubby,而ZooKeeper则是对于Ch
用户1177713
2018/02/24
2.5K0
Zookeeper 原理与实践
JAVAEE分布式技术之Zookeeper的第一次课
1,课程回顾 2,本章重点 zk的简介和使用场景 zk 的集群搭建 zk 的选举原理
张哥编程
2024/12/13
870
JAVAEE分布式技术之Zookeeper的第一次课
Zookeeper应用场景汇总(超详细)
注意:在上面提到的应用场景中,有个默认前提是:数据量很小,但是数据更新可能会比较快的场景。
编程大道
2022/03/31
1.8K0
不懂 ZooKeeper?这给你讲的明明白白
面试常常被要求「熟悉分布式技术」,当年搞 “XXX管理系统” 的时候,我都不知道分布式系统是个啥。分布式系统是一个硬件或软件组件分布在不同的网络计算机中上,彼此之间仅仅通过消息传递进行通信和协调的系统。
程序员小猿
2021/01/19
5720
不懂 ZooKeeper?这给你讲的明明白白
zookeeper学习系列:三、利用zookeeper做选举和锁
之前只理解zk可以做命名,配置服务,现在学习下他怎么用作选举和锁,进一步还可构建master-slave模式的分布式系统。 为什么叫Zoo?“因为要协调的分布式系统是一个动物园”。 ZooKeeper是一个中性化的Service,用于管理配置信息、命名、提供分布式同步,还能组合Service。所有这些种类的Service都会在分布式应用程序中使用到。每次编写这些Service都会涉及大量的修bug和竞争情况。正因为这种编写这些Service有一定难度,所以通常都会忽视它们,这就使得在应用程序有变化时变得难以
架构师刀哥
2018/03/20
7450
调度系统Apache DolphinScheduler介绍和设计原理
大数据任务调度作为大数据建设中的核心基础设施。Apache DolphinScheduler是一个分布式、去中心化、易扩展的可视化DAG工作流任务调度系统,其致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用。
大数据真好玩
2021/09/18
10.7K0
调度系统Apache DolphinScheduler介绍和设计原理
相关推荐
zookeeper学习系列:一、入门
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验