使用zookeeper实现分布式master选举(c 接口版本)

zookeeper,已经被很多人所熟知,主要应用场景有(数据订阅/发布 ,负载均衡, 命名服务, 分布式协调/通知,集群管理,Master选举,分布式锁,分布式队列)。

C接口的描述  主要参考 Haippy 的文章 :Zookeeper C API 指南 (感谢大神)

但是网上的C++版 示例代码少之又少,作为一个小白,自己摸索,给大家参考。

Master选举的需求主要如下:

1.多台机器同时进行选举,产生唯一的一台机器作为Master,其它的机器作为slave。

2.当Master宕机后,需要在所有存活的slave中再次选举一个成为新的Master。

3.当新的master宕机后,继续选举,如此反复。

这样保证了在大多数分布式系统中Master不会宕机。在这里我们默认zookeeper是高可用的。(即不考虑zookeeper失效。)

思路主要如下:

1.每个进程都会去创建一个临时文件(名为master,该文件里面的值为master的ip地址),zookeeper将会保证那么多的进程只有一个进程能够创建成功。收到ZOK,其它的都会收到ZNODEEXISTS(已存在)。

2.没有创建成功的节点slave节点将会去监视这个已经创建成功的“文件”(master) ,当该文件发生变化时,slave将会触发相对应的函数。

临时文件:为ZOO_EPHEMERAL类型,正如 EPHEMERAL(短暂的)本意,当创建这个文件的进程挂了,zookeeper会自动检测到(正是利用这个特性)。

变化: 这个变化有很多种可能,如该文件的内容变了,该文件下的子文件增加或减少了,(在zookeeper中文件既是文件又是一个文件夹),也可能是该文件被删除了。

值的一提的是,如Haippy所述,zookeeper watch函数是 “一次性”的,简单的说  小明 调用了watch观察 自己家的门。 此时,小红打开了门,watch函数立刻告诉了小明,小明就过去把门关了。这个时候如果小明没有再次调用watch函数,小红再偷偷的开门,小明是不知道的,讲了那么啰嗦其实就是一句话“每次触发watch函数后,请别忘记再次调用watch函数”(当然还是要看具体的场景)。

下面贴上代码(所有的解释都写在代码注释中): 编译命令为   g++ election.cpp -o election -lzookeeper_mt -std=c++11  (不是-lzookeeper_st 否则一点反应都没)

  1 /*
  2  * =============================================================================
  3  *
  4  *       Filename:  election.cpp
  5  *
  6  *    Description:  elect master test by zookeeper
  7  *
  8  *        Created:  02/15/2013 08:48:49 PM
  9  *
 10  *         Author:  zhejiangxiaomai, [email protected]
 11  *        Company:  ECNU
 12  *
 13  * =============================================================================
 14  */
 15 #include <unistd.h>
 16 #include <stdio.h>
 17 #include <stdlib.h>
 18 #include <string.h>
 19 #include <zookeeper/zookeeper.h>
 20 #include <zookeeper/zookeeper_log.h>
 21 #include <iostream>
 22 using namespace std;
 23
 24 int status = -1;
 25 // 1 : master 0 :slave
 26 zhandle_t* init(const char* host, int timeout);
 27 void init_1(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx);
 28 void getResult(int rc, const char *name, const void *data);
 29 void go_to_election(zhandle_t* zh, int type, int state, const char* path, void* ip);
 30 void get_master(int rc, const char *value, int value_len, const struct Stat *stat, const void *data);
 31 void watch_master(zhandle_t* zh, const char* ip);
 32
 33 int main(int argc, const char *argv[])
 34 {
 35     const char* host = "127.0.0.1:2181";
 36     int timeout = 30000;
 37     zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
 38     const char* ip = argv[1];
 39     //初始化连接句柄
 40     zhandle_t* zh = init(host, timeout);
 41     //参加选举
 42     go_to_election(zh,0,0,"/master",(void *) ip);
 43     //按下空格即可清除句柄,退出程序
 44     getchar();
 45     zookeeper_close(zh);
 46     return 0;
 47 }
 48 //创建连接zookeeper的句柄
 49 zhandle_t* init(const char* host, int timeout){
 50     zhandle_t* zkhandle = zookeeper_init(host,init_1,timeout, 0, NULL, 0);
 51     if (zkhandle == NULL) {
 52         fprintf(stderr, "Error when connecting to zookeeper servers...\n");
 53         exit(EXIT_FAILURE);
 54     }
 55     return zkhandle;
 56 }
 57 //做为创建句柄的watch函数(一般输出句柄的信息,但是我没有处理)
 58 void init_1(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx)
 59 {
 60     std::cout<<"init handler"<<endl;
 61 }
 62 //参选函数
 63 void go_to_election(zhandle_t* zh, int type, int state, const char* path, void* ip)
 64 {
 65     //创建一个/master文件,值为char* 类型的IP,长度为15,
 66     //该文件为类型为ZOO_EPHEMERAL,当创建完成后会调用getResult函数
 67     int ret = zoo_acreate(zh, "/master", (char*)ip, 15,
 68            &ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL,
 69            getResult, "election");
 70     if (ret) {
 71         fprintf(stderr, "Error %d for %s\n", ret, "election");
 72         exit(EXIT_FAILURE);
 73     }
 74     //此处sleep一秒,没有这个步骤程序就没有效果,
 75     //我认为是create没有那么快,没有创建完成的watch就没有意义。
 76     sleep(1);
 77     if(status == 0)
 78     {
 79     //如果是slave就观察master
 80         watch_master(zh, (const char*)ip);
 81     }
 82 }
 83 //判断创建结果,结果保存在rc中,并改变状态。
 84 //在此看起来其他参数没有用到,但是这是七种回调函数的一种格式,需要遵守。
 85 void getResult(int rc, const char *name, const void *data)
 86 {
 87     switch(rc){
 88         case ZOK:
 89             std::cout<<"Become master"<<endl;
 90             status = 1;
 91             break;
 92         case ZNODEEXISTS:
 93             std::cout<<"Become slave, keep watch"<<endl;
 94             status = 0;
 95             break;
 96     }
 97 }
 98 //在此仅仅是将master文件的值输出.
 99 void get_master(int rc, const char *value, int value_len,
100     const struct Stat *stat, const void *data){
101     std::cout<<(char *)data<<(char*)value<<endl;
102 }
103
104 void watch_master(zhandle_t* zh, const char* ip){
105    //获取/master文件的值 通过回调函数 get_master. 当该文件发生改变时带着自己的ip地址重新去注册
106    int ret = zoo_awget(zh, "/master",go_to_election,(void *)ip ,
107                    get_master,"get master ip :");
108    if (ret) {
109             fprintf(stderr, "Error %d for %s\n", ret, "re");
110             exit(EXIT_FAILURE);
111         }
112 }

实现结果图:(master从0.1 变为了0.2 变为了0.3)

时间: 2024-10-07 01:11:47

使用zookeeper实现分布式master选举(c 接口版本)的相关文章

ZooKeeper场景实践:(6)集群监控和Master选举

1. 集群机器监控 这通常用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应.这样的场景中,往往有一个监控系统,实时检测集群机器是否存活. 利用ZooKeeper有两个特性(读可监控,临时节点),就可以实现一种集群机器存活性监控系统: 1. 客户端在节点 x 上注册一个Watcher,那么如果x的子节点变化了,会通知该客户端 2. 创建EPHEMERAL类型的节点,一旦客户端和服务器的会话结束或过期,那么该节点就会消失 利用这两个特性,可以分别实现对客服端的状

zookeeper典型应用场景之一:master选举

对于zookeeper这种东西,仅仅知道怎么安装是远远不够的,至少要对其几个典型的应用场景进行了解,才能比较全面的知道zk究竟能干啥,怎么玩儿,以后的日子里才能知道这货如何能为我所用.于是,有了如下的学习: 我们知道zookeeper可以用于搭建高可用服务框架,主要先看以下几个应用场景:1. master的选举基本思路和编码实现2. 数据的发布和订阅3. 软负载均衡4. 分布式队列5. 分布式锁6. 命名服务 目前zookeeper常用的开发包有zkclient跟curator,后者更为方便,日

Zookeeper系列五:Master选举、ZK高级特性:基本模型

一.Master选举 1. master选举原理: 有多个master,每次只能有一个master负责主要的工作,其他的master作为备份,同时对负责工作的master进行监听,一旦负责工作的master挂掉了,其他的master就会收到监听的事件,从而去挣脱负责工作的权利,其他没有争夺到负责主要工作的master转而去监听负责工作的新master. 本质其实是利用zookeeper的临时节点的特性:临时节点随着会话的消亡二消亡,同一个临时节点只能创建一个,创建失败的节点(从master)对创

(原)3.1 Zookeeper应用 - Master选举

本文为原创文章,转载请注明出处,谢谢 Master 选举 1.原理 服务器争抢创建标志为Master的临时节点 服务器监听标志为Master的临时节点,当监测到节点删除事件后展开新的一轮争抢 某个服务器成功创建则为Master 2.架构图 Master:服务器争抢节点 Servers:服务器列表节点 work Server:服务器节点 3.流程图 4.核心代码 workServer监听 public WorkServer(final ServerData serverData) { this.s

ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据

转:http://www.cnblogs.com/sunddenly/p/4092654.html 引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法.Zab协议.通信协议等相关知识,理解起来比较抽象所以还需要借助一些应用场景,来帮我们理解.由于内容比较多,一口气吃不成胖子,得慢慢来一步一个脚印,因此我对后期ZooKeeper的学习规划如下: 第一阶段: |---理解ZooKeeper的应用 |---ZooKeeper是什么 |--

基于ZooKeeper的分布式Session实现(转)

1.   认识ZooKeeper ZooKeeper—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动 物所观赏.为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才 能更加放心安全的观赏动物.回到我们企业级应用系统中,随着信息化水平的不断提高,我们的企业级系统变得越来越庞大臃肿,性能急剧下降,客户抱怨频频.拆 分系

zookeeper实现分布式的思路

Hadoop生态系统为开源届提供很多优秀软件,zookeeper便是其中一员. 前段时间项目中用到了zookeeper,主要是用作服务的注册和发现使用方式类似阿里的dubbo.实际上zookeeper的功能不仅仅只有这些内容,它提供了一系列非常方便使用的功能,后面会提到.这篇文章仅仅是我个人的一点儿理解,如有错误烦请指正,以免给别人误导. 1.zookeeper是什么 zookeeper的名字很有趣被称为动物管理员,这是因为Hadoop生态系统中很多软件的名字都是动物,hadoop本身就是小象的

基于Solr和Zookeeper的分布式搜索方案的配置

1.1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使用SolrCloud来满足这些需求. SolrCloud是基于Solr和Zookeeper的分布式搜索方案,它的主要思想是使用Zookeeper作为集群的配置信息中心. 它有几个特色功能: 1)集中式的配置信息 2)自动容错

基于ZooKeeper的分布式Session实现

基于ZooKeeper的分布式Session实现 1.   认识ZooKeeper ZooKeeper—— “动物园管理员”.动物园里当然有好多的动物,游客可以根据动物园提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动 物所观赏.为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才 能更加放心安全的观赏动物.回到我们企业级应用系统中,随着信息化水平的不断提高,我们的企业级系统变得越