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 否则一点反应都没)

 /*
* =============================================================================
*
* Filename: election.cpp
*
* Description: elect master test by zookeeper
*
* Created: 02/15/2013 08:48:49 PM
*
* Author: zhejiangxiaomai, 358088534@qq.com
* Company: ECNU
*
* =============================================================================
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zookeeper/zookeeper.h>
#include <zookeeper/zookeeper_log.h>
#include <iostream>
using namespace std; int status = -;
// 1 : master 0 :slave
zhandle_t* init(const char* host, int timeout);
void init_1(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx);
void getResult(int rc, const char *name, const void *data);
void go_to_election(zhandle_t* zh, int type, int state, const char* path, void* ip);
void get_master(int rc, const char *value, int value_len, const struct Stat *stat, const void *data);
void watch_master(zhandle_t* zh, const char* ip); int main(int argc, const char *argv[])
{
const char* host = "127.0.0.1:2181";
int timeout = ;
zoo_set_debug_level(ZOO_LOG_LEVEL_WARN);
const char* ip = argv[];
//初始化连接句柄
zhandle_t* zh = init(host, timeout);
//参加选举
go_to_election(zh,,,"/master",(void *) ip);
//按下空格即可清除句柄,退出程序
getchar();
zookeeper_close(zh);
return ;
}
//创建连接zookeeper的句柄
zhandle_t* init(const char* host, int timeout){
zhandle_t* zkhandle = zookeeper_init(host,init_1,timeout, , NULL, );
if (zkhandle == NULL) {
fprintf(stderr, "Error when connecting to zookeeper servers...\n");
exit(EXIT_FAILURE);
}
return zkhandle;
}
//做为创建句柄的watch函数(一般输出句柄的信息,但是我没有处理)
void init_1(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx)
{
std::cout<<"init handler"<<endl;
}
//参选函数
void go_to_election(zhandle_t* zh, int type, int state, const char* path, void* ip)
{
//创建一个/master文件,值为char* 类型的IP,长度为15,
//该文件为类型为ZOO_EPHEMERAL,当创建完成后会调用getResult函数
int ret = zoo_acreate(zh, "/master", (char*)ip, ,
&ZOO_OPEN_ACL_UNSAFE, ZOO_EPHEMERAL,
getResult, "election");
if (ret) {
fprintf(stderr, "Error %d for %s\n", ret, "election");
exit(EXIT_FAILURE);
}
//此处sleep一秒,没有这个步骤程序就没有效果,
//我认为是create没有那么快,没有创建完成的watch就没有意义。
sleep();
if(status == )
{
//如果是slave就观察master
watch_master(zh, (const char*)ip);
}
}
//判断创建结果,结果保存在rc中,并改变状态。
//在此看起来其他参数没有用到,但是这是七种回调函数的一种格式,需要遵守。
void getResult(int rc, const char *name, const void *data)
{
switch(rc){
case ZOK:
std::cout<<"Become master"<<endl;
status = ;
break;
case ZNODEEXISTS:
std::cout<<"Become slave, keep watch"<<endl;
status = ;
break;
}
}
//在此仅仅是将master文件的值输出.
void get_master(int rc, const char *value, int value_len,
const struct Stat *stat, const void *data){
std::cout<<(char *)data<<(char*)value<<endl;
} void watch_master(zhandle_t* zh, const char* ip){
//获取/master文件的值 通过回调函数 get_master. 当该文件发生改变时带着自己的ip地址重新去注册
int ret = zoo_awget(zh, "/master",go_to_election,(void *)ip ,
get_master,"get master ip :");
if (ret) {
fprintf(stderr, "Error %d for %s\n", ret, "re");
exit(EXIT_FAILURE);
}
}

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

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

  1. Zookeeper实现Master选举(哨兵机制)

    master选举使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从模式, ...

  2. zookeeper java代码实现master 选举

    1,master选举使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从模 ...

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

    对于zookeeper这种东西,仅仅知道怎么安装是远远不够的,至少要对其几个典型的应用场景进行了解,才能比较全面的知道zk究竟能干啥,怎么玩儿,以后的日子里才能知道这货如何能为我所用.于是,有了如下的 ...

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

    1. 集群机器监控 这通经常使用于那种对集群中机器状态,机器在线率有较高要求的场景,可以高速对集群中机器变化作出响应.这种场景中,往往有一个监控系统,实时检測集群机器是否存活. 利用ZooKeeper ...

  5. org.apache.curator:master选举和分布式锁

    1. master选举(LeaderSelector) 1)LeaderSelector构造函数 在leaderPath上建立分布式锁:mutex = new InterProcessMutex(cl ...

  6. Zookeeper实现master选举

    使用场景         有一个向外提供的服务,服务必须7*24小时提供服务,不能有单点故障.所以采用集群的方式,采用master.slave的结构.一台主机多台备机.主机向外提供服务,备机负责监听主 ...

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

    一.Master选举 1. master选举原理: 有多个master,每次只能有一个master负责主要的工作,其他的master作为备份,同时对负责工作的master进行监听,一旦负责工作的mas ...

  8. zookeeper【4】master选举

    考虑7*24小时向外提供服务的系统,不能有单点故障,于是我们使用集群,采用的是Master+Slave.集群中有一台主机和多台备机,由主机向外提 供服务,备机监听主机状态,一旦主机宕机,备机必需迅速接 ...

  9. ZooKeeper 典型应用场景-Master选举

    master选举 1.使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从 ...

随机推荐

  1. JS比较两个数值大小的正确方法

    转自:http://www.zzsky.cn/build/content/1832.htm 一般情况下: <script type="text/javsscript"> ...

  2. careercup-高等难度 18.2

    18.2 编写一个方法,洗一副牌.要求做到完美洗牌,换言之,这幅牌52!种排列组合出现的概率相同.假设给定一个完美的随机发生器. 解法:假定有个数组,含有n个元素,类似如下: [1][2][3][4] ...

  3. The Socket API, Part 4: Datagrams

    转:http://www.linuxforu.com/2011/11/socket-api-part-4-datagrams/ By Pankaj Tanwar on November 1, 2011 ...

  4. eclipse的scala环境搭建

    两种方法使eclipse安装scala环境(eclipse luna) 1.下载eclipse for scala IDE http://scala-ide.org/download/sdk.html ...

  5. C#面向对象(四)虚方法实现多态

    一.虚方法实现多态 1,创建一个people基类 using System; using System.Collections.Generic; using System.Linq; using Sy ...

  6. myecplise 打开报错 Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project 'myf'. Java.lang.NullPointerException

    Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project 'myf'.Java.l ...

  7. 1.6 Indexing and Basic Data Operations--目录

    1.6.1 什么是 Indexing 1.6.2 Uploading Data with Index Handlers 1.6.3 Uploading Data with Solr Cell usin ...

  8. 1.6.2 Uploading Data with Index Handlers

    1.Uploading Data with Index Handlers 索引处理器就是Request Handlers,用于添加,更新,删除索引中的文档.另外,使用Tika抽取富文档数据,使用Dat ...

  9. cocos2d-x lua 使用ListView

    cocos2d-x lua 使用ListView version: cocos2d-x 3.6 本文主要讲述:使用Cocos Studio创建ListView,和列表项的模板,代码中通过模板创建列表的 ...

  10. 【Android 界面效果18】Android软件开发之常用系统控件界面整理

    [java] view plaincopyprint?   <span style="font-size:18px">1.文本框TextView TextView的作用 ...