问题导读:
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. 与众不同 windows phone (43) - 8.0 相机和照片: 镜头的可扩展性, 图片的可扩展性, 图片的自动上传扩展

    [源码下载] 与众不同 windows phone (43) - 8.0 相机和照片: 镜头的可扩展性, 图片的可扩展性, 图片的自动上传扩展 作者:webabcd 介绍与众不同 windows ph ...

  2. YII页面跳转

    $criteria = new CDbCriteria; $criteria->select = array('ziduan"); $res = Model::model()-> ...

  3. 功放AUX接口解析

    功放上的AUX输入端口就是音频输入端口,用来连接音频输出设备:PC机上声卡.MP3播放器.CD机等

  4. ASP.NET Web API 特性

    ASP.NET MVC 4 包含了 ASP.NET Web API, 这是一个创建可以连接包括浏览器.移动设备等多种客户端的 Http 服务的新框架, ASP.NET Web API 也是构建 RES ...

  5. mysql max_allowed_packet过小导致的prepare失败

    最近公司一台阿里云上模拟环境突然好好地就出错了额,总提示:"Unknown prepared statement handler (stmt) given to DEALLOCATE PRE ...

  6. dbcp/c3p0连接池设置mysql会话变量

    我们有几个计算风控值的定时任务,几乎每隔5秒会更新所有账户的当前总资产并以此通知风控,每隔一小时就产生一两个G的binlog,几十台服务器折腾..数据库是公用的,代码是通过工具自动生成的,直接修改流程 ...

  7. Visual Studio添加dll程序集引用操作步骤

    Visual Studio 中添加引用的操作: 在“解决方案资源管理器”中,先右击项目图标,在弹出菜单选择“添加引用...” 然后在弹出的窗口中选择所要添加的选项,点击确定就可以了. 原文:http: ...

  8. RHEL7文件权限

    本文介绍Linux下的文件权限 操作系统为RHEL7.2_X86_64 可以从以下三种访问方式限制访问权限: 1 只允许用户自己访问 2 允许一个预先指定的用户组中的用户访问 3 允许系统中的任何用户 ...

  9. 文件无刷新上传(swfUpload与uploadify)

    文件无刷新上传并获取保存到服务器端的路径 遇到上传文件的问题,结合之前用到过的swfUpload,又找了一个无刷新上传文件的jquery插件uploadify,写篇博客记录一下分别介绍这两个插件的实现 ...

  10. CSS3属性(二)

    <html> <head> <title>css2</title> <style type="text/css"> di ...