本文讲述基于zookeeper选主与故障切换的方法。我们的例子使用的是python。

使用的库是kazoo,安装方式

pip install kazoo 

应用场景:

  • 多个实例部署,但不是“去中心化”的部署方式;
  • 有且只有一个节点作为master,履行master的职责,在例子中是注册调度器;
  • 其他实例作为slave,不提供调度功能,但是在master节点挂掉之后,可以重新进行选主调度。

1、注册调度器

我们只给出伪代码,简单的打印调度器注册结果。

# -*- coding:utf-8 -*-# 调度器注册和关闭
# 模拟主节点的职责
class MyScheduler(object):# 注册调度器def init_scheduler(self):print '########## 开启调度器成功 ############'# 关闭调度器def stop_scheduler(self):print '########## 关闭调度器成功 ############'

2、选主与故障切换代码

1)使用add_listener注册监听器,监听zookeeper会话超时,Session Expired,否则在会话超时的场景中会出现锁不一致的问题,可以参看这篇文章。

  • 会话超时之后,我们要重新建立Session,在我们的例子里,会循环直到Session重新建立。
  • 重新注册Watcher,因为Watcher会随着Session失效而失效。在我们的例子里,通过执行get_children重新注册了Watcher。

2)向zookeeper注册自己,使用参数makepath=True级联创建节点;使用参数ephemeral=True, sequence=True参数,也就是创建临时有序节点:

  • 当实例挂掉,session断开,注册的节点会自行消失
  • 有序节点,会节点后添加一个有序编号

3)注册Watcher,观察/dmonitor/master的子节点,当发生以下事件时:

  • Created:新增子节点
  • Deleted:删除子节点
  • Changed:子节点数据变化
  • Child:子节点的下一级节点

进行重新选主。

# -*- coding:utf-8 -*-import socket
import traceback
from kazoo.client import KazooClient
from kazoo.client import KazooState
from MyScheduler import MySchedulerclass HAMaster(object):def __init__(self):self.path = '/dmonitor/master'self.scheduler = MyScheduler()self.zk = KazooClient('10.93.21.21:2181,10.93.18.34:2181,10.93.18.35:2181', timeout=10)self.zk.start()self.zk.add_listener(self.my_listener)self.is_leader = Falsedef create_instance(self):instance = self.path + '/' + socket.gethostbyname(socket.gethostname()) + '-'self.zk.create(path=instance, value="", ephemeral=True, sequence=True, makepath=True)# 选主逻辑: master节点下, 所有ephemeral+sequence类型的节点中, 编号最大的获得领导权.def choose_master(self):print "########## 选主开始 ############"instance_list = self.zk.get_children(path=self.path, watch=self.my_watcher)instance = max(instance_list).split('-')[0]# 本实例获得领导权if instance == socket.gethostbyname(socket.gethostname()):if not self.is_leader:self.scheduler.init_scheduler()self.is_leader = Trueprint "######### 我被选为master, 我以前不是master, 注册调度 ##########"else:print "######### 我被选为master, 我以前是master, 不再注册调度 ##########"# 本实例没有获得领导权else:if self.is_leader:self.scheduler.stop_scheduler()self.is_leader = Falseprint "######### 我被选为slave, 我以前不是slave, 关闭调度 ##########"else:print "######### 我被选为slave, 我以前是slave, 不再关闭调度 ##########"print "########## 选主完成 ############"def my_listener(self, state):if state == KazooState.LOST:print "########## 会话超时:KazooState.LOST ############"while True:try:self.create_instance()self.zk.get_children(path=self.path, watch=self.my_watcher)print "########## 会话超时:重建会话完成! ############"breakexcept Exception, _:traceback.print_exc()elif state == KazooState.SUSPENDED:print "########## 会话超时:KazooState.SUSPENDED ############"elif state == KazooState.CONNECTED:print "########## 会话超时:KazooState.CONNECTED ############"else:print "########## 会话超时:非法状态 ############"def my_watcher(self, event):if event.state == "CONNECTED" and event.type == "CREATED" or event.type == "DELETED" or event.type == "CHANGED" or event.type == "CHILD":print "########## 监听到子节点变化事件 ############"self.choose_master()else:print "########## 监听到未识别的事件 ############"

3、测试一下

测试代码如下

# -*- coding:utf-8 -*-
import time
from HAMaster import HAMasterha = HAMaster()
# 向zk注册自己
ha.create_instance()
# 进行选主
ha.choose_master()while 1:time.sleep(10)

运行这个脚本,模拟如下几个场景:

1)初始选主

顺序在两台机器上启动测试脚本。

client10

[data_monitor@bigdata-arch-client10 zookeeper]$ python run.py 

client11

[data_monitor@bigdata-arch-client11 zookeeper]$ python run.py 

client10输出

[data_monitor@bigdata-arch-client10 zookeeper]$ python run.py
########## 选主开始 ############
########## 开启调度器成功 ############
######### 我被选为master, 我以前不是master, 注册调度 ##########
########## 选主完成 ############
########## 监听到子节点变化事件 ############
########## 选主开始 ############
######### 我被选为master, 我以前是master, 不再注册调度 ##########
########## 选主完成 ############

client11输出

[data_monitor@bigdata-arch-client11 zookeeper]$ python run.py
########## 选主开始 ############
######### 我被选为slave, 我以前是slave, 不再关闭调度 ##########
########## 选主完成 ############

可以看到,client10倍选为主节点并注册调度器,client11作为slave节点。

2)主实例挂掉

我们把client10上的实例kill掉。

client10上不再输出

client11上总体输出如下

[data_monitor@bigdata-arch-client11 zookeeper]$ python run.py
########## 选主开始 ############
######### 我被选为slave, 我以前是slave, 不再关闭调度 ##########
########## 选主完成 ############
########## 监听到子节点变化事件 ############
########## 选主开始 ############
########## 开启调度器成功 ############
######### 我被选为master, 我以前不是master, 注册调度 ##########
########## 选主完成 ############

可以看到监听到节点的变化,并进行了重新选主,client11被选为主节点(只剩他了)并注册了调度器。

tips:观察到节点变化的实效性是通过timeout=10参数控制的,也就是超过10s session不能维持就会认为实例挂了,zookeeper会删除节点。

转载于:https://www.cnblogs.com/kangoroo/p/7667293.html

Kazoo Python Zookeeper 选主相关推荐

  1. Zookeeper选主过程,理论和源码结合,还看不懂给你发红包

    文章目录 前言 1.节点角色 2.选举过程 2.1 胜出的条件 2.2 比较的规则 3.代码逻辑综述 4.源码分析 结语 前言 Zookeeper作为Dubbo生态的默认注册中心,得到了非常的普遍的应 ...

  2. Zookeeper选举算法( FastLeader选主)

    FastLeader选主算法: 看网上关于 zookeeper选主节点fast算法的描述,虽然有几篇写的非常不错,但是总感觉描述的差一些,因此打算写一个我认为的较为详细的版本让大家提点意见.当然如果有 ...

  3. 分布式系统选主怎么玩

    来自:架构之美 分布式系统为了保证其可靠性,一般都会多节点提供服务,各别节点的故障不会影响系统的可用性.对于分布式的存储系统来说,在保证可用性的同时,数据的可靠性(不丢失)也是其要解决的核心问题.目前 ...

  4. Zookeeper,etcd,consul内部机制和分布式锁和选主实现的比较

    我的另外3篇文章分别介绍了Zookeeper,etcd,consul是如何实现分布式锁和选主的.本文想比较一下Zookeeper.etcd.consul内部机制有哪些不同,他们实现锁和选主的方式相同和 ...

  5. CAP原理,分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色

    我们知道,一般在分布式应用都有CAP准则: C Consistency, 一致性,分布式中的各个节点数据保持一致 A availability 可用性,任何时刻,分布式集群总是能够提供服务 P par ...

  6. python系列之:kazoo连接Zookeeper操作Zookeeper

    python系列之:kazoo连接Zookeeper操作Zookeeper 一.连接zookeeper 二.读取zookeeper节点 三.读取zookeeper内容 四.kazoo连接Zookeep ...

  7. ZAB协议选主过程详解

    说明 ZAB 协议是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复的一致性协议.基于该协议,ZooKeeper 实现了一种主从模式的系统架构来保持集群中各个副本之间的数据一致性. ZAB ...

  8. raft协议 MySQL 切换_Raft 协议实战系列(二)—— 选主

    注:本文原创,转载请标明出处. 欢迎转发.关注微信公众号:Q的博客. 不定期发送干货,实践经验.系统总结.源码解读.技术原理. 本文目的 笔者期望通过系列文章帮助读者深入理解Raft协议并能付诸于工程 ...

  9. Raft算法实现 - Sofa-JRaft,选主,数据写入,日志复制

    关于raft算法相关细节,可以全看之前的文章 分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色 ...

最新文章

  1. [转] 如何从多份Java/JEE工作中进行抉择
  2. android之多媒体篇(二)
  3. 洛谷 P3805 manacher算法
  4. 漫游Kafka之过期数据清理
  5. linux shell 变量 管道,linux下shell,变量,管道,重定向等基础知识及技巧
  6. 计算机mips是什么,在计算机术语中,什么叫MIPS
  7. js怎么获取扫码枪条码_生产扫码计件解决方案
  8. UI设计素材|视频类APP图标
  9. coin collector(一道测试题)
  10. cgroup学习(八)——CPUSET子系统
  11. SCDM学习笔记(5)
  12. Python数据分析练习
  13. Ubuntu美化开关机界面 - Linux
  14. android alert
  15. MySQL精简版安装教程
  16. CorelDRAW中如何安装字体
  17. 视频无法播放是怎么回事
  18. C++STL面试详解
  19. 数字藏品交易系统开发 数字藏品开发
  20. 软件协助企业实现协作创新,构建商业价值网络

热门文章

  1. Android游戏开发项目实战
  2. 仿写微博 按照时间顺序发表内容
  3. 陳三甲网络笔记:寻寻觅觅,最后把自己搞丢了!
  4. 从进军空气消毒赛道看格兰仕的改变
  5. BlueMix与商业智能BI(智慧医疗场景)
  6. 英雄联盟怎么解除小窗口_英雄联盟手游艾希怎么出装-英雄联盟手游艾希出装推荐...
  7. Laravel基础二之Migrations和验证
  8. javascript入门_Netlify入门:部署JavaScript应用程序的最简单方法
  9. 教育培训学校公众号版v1.3.4
  10. Hive命令的3种调用方式