问题导读:
1.如何利用zookeeper保证集群Master可用性和唯一性?
2.zookeeper竞选Master包含哪些过程?
3.zookeeper竞选Master机制利用了zk哪些特性?

zookeeper应用场景中提出了对于Master节点管理的问题,如何保证集群中Master可用性和唯一性,下面就利用zookeeper来实现。
在确保zookeeper集群节点安装配置的前提下,假设zk已经对外提供了正常的服务,通过下面的步骤来实现Master竞选

  • Client连接到zk上,判断znode /Roles/workers是否存在,不存在则建立,znode的类型是PERSISTENT类型,保证不会随着C1的session断开而消失。
  • Client在/Roles/workers下面建立一个SEQUENCE|EPHEMERAL类型的znode,前缀可以是worker,由zk保证znode编号是递增而且是暂时的,EPHEMERAL在前文说了,一旦session断开创建的znode也会消失。
  • Client通过getChildren获取所有的/Roles/workers下znode列表,并且设置一个Watcher等待通知,返回值有多少个znode数量就对应Client来竞选。
  • 对于步骤4返回的节点列表进行排序,找到最小的worker编号,如果是和自己创建的一致(步骤2返回值),那么就代表自己的编号是最小的,自己就是Master。如果发现自己的编号不是最小,那么就等待通知,一旦Watcher触发,就在Watcher回到步骤3。

上面的机制主要利用了zk的几个特性

  • 对于N个客户端同时请求create一个znode,zk能保证顺序的一致性,并且保证每个客户端创建的znode节点是递增并且唯一。
  • 因为创建的znode是临时的,一旦session断开,那么znode就会从zk上消失,从而给每个设置Watcher的客户端发送通知,让每个客户端重新竞选Master,编号小的肯定是Master,保证了唯一性。

下图是上面的逻辑图
<ignore_js_op>

下面是实现的代码,默认是连接本地的zk服务,端口是2181,zkclient模块位于zookeeper python接口只需要运行多个下面的脚本就会能实现Master的竞选。

  • 先后在三个终端上面运行下面的脚本,模拟为c1,c2,c3三个client,创建的节点依次是/Roles/workers/worker0000000000,/Roles/workers/worker0000000001,依次是/Roles/workers/worker0000000002
  • 发现c1成功竞选了Master,然后c2和c3都是slave
  • 把c1关了从而导致依次是/Roles/workers/worker0000000000消失,一段时间后c2和c3会重新竞选,c2会成为master,c3是slave
  • 重新启动c1,发现c1立马加入集群,消息里面变更表示创建了新的znode依次是/Roles/workers/worker0000000003,重新竞选,c2还是master

PS:上面步骤3里面一个客户端关闭后经历了一段时间znode才会删除,原因是这段时间内zk的session还没有被清除,因为关闭是通过ctrl+c关闭的。但是加了一个客户端,znode里面创建,就会通知其余注册了watcher的客户端

#!/usr/bin/env python2.7
# -*- coding: UTF-8 -*- import logging
from os.path import basename, join from zkclient import ZKClient, zookeeper, watchmethod logging.basicConfig(
level = logging.DEBUG,
format = "[%(asctime)s] %(levelname)-8s %(message)s"
) log = logging class GJZookeeper(object): ZK_HOST = "localhost:2181"
ROOT = "/Roles"
WORKERS_PATH = join(ROOT, "workers")
MASTERS_NUM = 1
TIMEOUT = 10000 def __init__(self, verbose = True):
self.VERBOSE = verbose
self.masters = []
self.is_master = False
self.path = None self.zk = ZKClient(self.ZK_HOST, timeout = self.TIMEOUT)
self.say("login ok!")
# init
self.__init_zk()
# register
self.register() def __init_zk(self):
"""
create the zookeeper node if not exist
|-Roles
|-workers
"""
nodes = (self.ROOT, self.WORKERS_PATH)
for node in nodes:
if not self.zk.exists(node):
try:
self.zk.create(node, "")
except:
pass @property
def is_slave(self):
return not self.is_master def register(self):
"""
register a node for this worker,znode type : EPHEMERAL | SEQUENCE
|-Roles
|-workers
|-worker000000000x ==>>master
|-worker000000000x+1 ==>>worker
....
"""
self.path = self.zk.create(self.WORKERS_PATH + "/worker", "1", flags=zookeeper.EPHEMERAL | zookeeper.SEQUENCE)
self.path = basename(self.path)
self.say("register ok! I'm %s" % self.path)
# check who is the master
self.get_master() def get_master(self):
"""
get children, and check who is the smallest child
"""
@watchmethod
def watcher(event):
self.say("child changed, try to get master again.")
self.get_master()
try :
children = self.zk.get_children(self.WORKERS_PATH, watcher)
except zookeeper.ConnectionLossException:
print "losing connection with zookeeper..."
return False
except :
return False
children.sort()
self.say("%s's children: %s" % (self.WORKERS_PATH, children)) # check if I'm master
self.masters = children[:self.MASTERS_NUM]
if self.path in self.masters:
self.is_master = True
self.say("I've become master!")
else:
self.say("%s is masters, I'm slave" % self.masters) def say(self, msg):
"""
print messages to screen
"""
if self.VERBOSE:
if self.path:
log.info("[ %s(%s) ] %s" % (self.path, "master" if self.is_master else "slave", msg))
else:
log.info(msg) def main():
gj_zookeeper = GJZookeeper() if __name__ == "__main__":
main()
import time
time.sleep(1000)

  

文章转自:http://www.aboutyun.com/forum.php?mod=viewthread&tid=9277&ctid=16

zookeeper适用场景:如何竞选Master及代码实现的更多相关文章

  1. zookeeper适用场景:zookeeper解决了哪些问题

    问题导读:1.master挂机,传统做法备份必然是以前数据,该如何保证挂机数据与备份数据一致?2.分布式系统如何实现对同一资源的访问,保证数据的强一致性?3.集群中的worker挂了,传统做法是什么? ...

  2. zookeeper适用场景:分布式锁实现

    问题导读:1.zookeeper如何实现分布式锁?2.什么是羊群效应?3.zookeeper如何释放锁? 在zookeeper应用场景有关于分布式集群配置文件同步问题的描述,设想一下如果有100台机器 ...

  3. zookeeper适用场景:配置文件同步

    问题导读:1.本文三个角色之间是什么关系?2.三个角色的作用是什么?3.如何代码实现这三个角色的作用? 在 zookeeper适用场景:zookeeper解决了哪些问题有关于分布式集群配置文件同步问题 ...

  4. 【分布式】Zookeeper应用场景

    一.前言 在上一篇博客已经介绍了Zookeeper开源客户端的简单实用,本篇讲解Zookeeper的应用场景. 二.典型应用场景 Zookeeper是一个高可用的分布式数据管理和协调框架,并且能够很好 ...

  5. Zookeeper应用场景和ZAB协议

    Zookeeper应用场景 数据发布/订阅(配置中心) 我们平常的开发过程中,经常会碰到这样的需求:系统中需要一些通用的配置信息,如一些运行时的开关.前端需要展示的通知信息.数据库配置信息等等.这些需 ...

  6. merge 本地 master 分支代码提示 “Already up-to-date”

    在使用 git 的过程中由于误操作,导致从本地 master 分支 merge 代码到当前分支失败,虽然当前分支和 master 分支代码不同步,但是仍然提示 Already up-to-date. ...

  7. ActiveMQ 基于zookeeper的主从(levelDB Master/Slave)搭建以及Spring-boot下使用

    0:说明 ActiveMQ 5.9.0新推出的主从实现,基于zookeeper来选举出一个master,其他节点自动作为slave实时同步消息.因为有实时同步数据的slave的存在,master不用担 ...

  8. git 如何把master分支代码合并到自己的分支

    master分支的代码领先自己的分支,git 如何把master分支代码合并到自己的分支 1.首先切换到主分支 git checkout master 2.使用git pull 把领先的主分支代码pu ...

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

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

随机推荐

  1. AxWebBrowser与WebBrowserU盾登陆时的使用

    PS:上个月为财务小妹做了个自动上传报表的工具,财务妹子表示调戏我很开心T_T~~.   由于该小程序涉及到登陆,准备用WebBroswer,这一下撞墙上了,无法展示U盾密码框.   我在博问上的问题 ...

  2. FL2440驱动添加(5)ADC驱动学习笔记

    由图可知,模拟ADC分为两部分功能,一部分是触屏功能,另一部分就是普通ADC功能.分别可以产生INT_TC和INT_ADC 两个中断.该ADC模块总共有8个通道可以进行模拟信号的输入,分别是AIN0. ...

  3. asp.net 发送邮件

    asp.net 发送邮件 System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();            msg.To. ...

  4. JS中检测数据类型的几种方式及优缺点

    1.typeof 用来检测数据类型的运算符 typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."string&quo ...

  5. WCF服务部署到IIS7.5

    下面介绍如何把WCF服务部署到IIS: 为WCF服务创建.svc文件 我们知道,每一个ASP.NET Web服务都具有一个.asmx文本文件,客户端通过访问.asmx文件实现对相应Web服务的调用.与 ...

  6. 使用CodeMirror在浏览器中实现编辑器的代码高亮效果

    使用CodeMirror在浏览器中实现编辑器的代码高亮效果 在网站后台管理中希望能够对网站的样式表css与js文件以及模板html进行管理,在编辑的时候只是以普通文本展示又太普通,显得好难看,于是便在 ...

  7. android布局--Android fill_parent、wrap_content和match_parent的区别

    来自:http://www.cnblogs.com/nikyxxx/archive/2012/06/15/2551390.html 三个属性都用来适应视图的水平或垂直大小,一个以视图的内容或尺寸为基础 ...

  8. 转:Web应用程序项目XX已配置为使用IIS

    转:http://www.cnblogs.com/Joetao/articles/2392526.html 今天在看开源项目Umbraco是,出现一个项目加载不了,并报如下错误: Web应用程序项目U ...

  9. C语言原子接口与实现

    原子是一个指向唯一的.不可变的0个或任意多个字节序列的指针,大多数原子都是指向以空字符结束的字符串,但是任何一个指向任意字节序列的指针都可以使原子.任何原子只能出现一次.如果两个原子指向同一个内存单元 ...

  10. 【原】log4cplus使用说明

    网上关于开源日志工具log4cplus的说明有很多,但大多略显复杂,本文主要从实用的角度,介绍一种最简单而且又实用的方法.本文的方法已经足够满足实际工程中的使用需求,而且不需要很复杂的流程,可以实现. ...