为了保证可用性,传统的关系型数据库(mysql)通常采用一主多备的方式,当主宕机后,切换到备机。

有多种方式可以做到主备自动失效检测切换,比如传统的HA软件heartbeat,keepalived等等,采取虚拟IP的方式对客户端透明;

这里主备自动切换方案没有采取VIP的方式,而是用zookeeper对数据库集群进行管理,可以做到主备失效检测切换,主库的选举,

比如考虑到mysql对多核利用率不高而一个节点部署多个mysql实例,如果采用VIP的方式是不可行的。

基本做法是,每个mysql实例上部署一个agent节点,agent负责对该mysql实例定时进行ping操作,agent在zookeeper上注册临时节点,

如果agent或者该agent代理的mysql宕掉,注册在zookeeper上的节点就会发生变化,利用zookeeper watch功能实现mysq实例失效后的主库的选举操作,

读节点也通过watch master节点的功能实现指向新的master。

如上图所示,zookeeper上的master节点存储当前主节点名称;

servers下面保存在线的节点,命名规则一般为ip:port_序列号;

nodeid为当前的序列号,每当节点获取一个序列号时,该节点值自就增,以便于分配给下一个节点。

过程如下:

a、初始化阶段,创建servers,master,nodeid节点

b、每个client创建servers子节点,zoo_create("/servers/xxx",EPHEMERAL)

c、zoo_get_child(/servers,NULL)

d、若当前client的序列号id是当前最小的节点,则当前节点是master,设置master节点退出

e、否则,zoo_exsists(lastid before id,watcher)//当前节点watch比当前节点id次小的那个节点的状态

如果id不存在,那么退出

否则等待watch触发,重新选举master

相关伪代码参考示例如下:

try {

ProposoWatcher wc = new ProposoWatcher();

final ZooKeeper zk = new ZooKeeper("10.1.1.24:2181", 60000, wc);

wc.setZk(zk);

if (zk.exists("/master", false) == null) {

zk.create("/master", null, Ids.OPEN_ACL_UNSAFE,

CreateMode.PERSISTENT);

}

zk.create("/servers/" + nodeName, new byte[0], Ids.OPEN_ACL_UNSAFE,

CreateMode.EPHEMERAL);

List list = zk.getChildren("/servers", false);

String[] nodes = list.toArray(new String[list.size()]);

Arrays.sort(nodes);

if (nodeName.equals(nodes[0])) {//初次

System.out.println("this is master" + nodes[0]);

zk.setData("/master", nodeName.getBytes(), -1);

} else {

// 监控比自己次小的Node

String lower = "";

for (int i = 0; i < nodes.length; i++) {

if (nodeName.equals(nodes[i])) {

lower = nodes[i - 1];

break;

}

}

zk.exists("/servers/" + lower, true);

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//watcher

public static class ProposoWatcher implements Watcher {

private ZooKeeper zk;

public ZooKeeper getZk() {

return zk;

}

public void setZk(ZooKeeper zk) {

this.zk = zk;

}

@Override

public void process(WatchedEvent event) {

// TODO Auto-generated method stub

switch (event.getType()) {

case None: {

// connectionEvent(event);

break;

}

case NodeDeleted: {

// servers.remove(event.getPath());

System.out.println("node  removed**" + event.getPath());

String delName = event.getPath().substring(

event.getPath().lastIndexOf("/"));

// final ZooKeeper zk1 = zk;

List children = new ArrayList();

try {

children = zk.getChildren("/servers", false);

} catch (KeeperException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

String[] nodes = children.toArray(new String[children.size()]);

Arrays.sort(nodes);

for (int i = 0; i < nodes.length; i++) {

if (nodes[i].compareTo(delName) > 0) {

// TODO:curr Node become master

System.out.println("this is master" + nodes[i]);

try {

zk.setData("/master", nodes[i].getBytes(), -1);

} catch (KeeperException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

break;

}

}

break;

}

}

}

}

mysql zookeeper 切换_zookeeper在mysql主库选举切换中的应用相关推荐

  1. Linux服务器安装JavaWeb环境(二) Redis,MySql,Zookeeper,Keepalive

    /*****************[安装RedisServer]****************/ 第一步:下载redis安装包 http://download.redis.io/releases/ ...

  2. MySQL 集群(三):MySQL + Mycat 实现读写分离,主备切换集群

    MySQL 集群(三):MySQL + Mycat 实现读写分离,主从切换集群 下载 Mycat Mycat 主要文件 端口 Mycat 命令 配置文件 server.xml schema.xml 配 ...

  3. mysql keepalived低版本_Mysql+keepalived主主切换

    Mysql+keepalived主主切换 一,环境介绍 网络结构: VIP :192.168.1.30 MYSQL A:192.168.1.21 MYSQL B:192.168.1.22 二.mysq ...

  4. mycat mysql 主从切换_Mycat读写分离与主从切换

    环境说明 本文的环境信息: 192.168.1.248: slave节点 192.168.1.250: master节点 数据库服务准备工作 主从配置完成后,Slave_IO_Running和Slav ...

  5. drbd实现mysql地热备_heartheartbeat+drbd+mysql主库热备

    1 环境 主机名 网卡 磁盘 master eth0 桥接模式 eth0(192.168.1.10) 自定义模式(VMnet2)(192.168.2.10)VIP 192.168.1.200/210 ...

  6. mysql 5.7 主从切换_mysql5.7 主从复制的正常切换【转】

    目前环境如下: master server IP:172.17.61.131 slave server IP:172.17.61.132 mysql version: mysql-5.7.21-lin ...

  7. mybatis mysql merge_Spring Boot + Mybatis 整合Mysql ,SQLServer数据源以及整合druid,动态调整数据源切换。...

    pom.xml依赖 org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-bo ...

  8. typechoSQLIte转MySQL_Typecho SQLite与MySQL的数据库切换及解决MySQL连接打开缓慢问题

    (本科水平,写得不好请不吝指点 ) Ⅰ Abstract Typecho开源轻量级博客系统拥有WordPress主题插件二次开发等一系列优点,但相比于WordPress笨重复杂的操作,Typecho赢 ...

  9. Linux企业运维 6.6 -- Redis部署及主从切换、Redis+Mysql读写分离

    目录 Redis简介 redis的编译.安装 1.server1的redis配置 2.server2的redis安装 3.server3配置redis 三.redis主从复制 四.Sentine主从自 ...

最新文章

  1. Python初识面向对象
  2. MemCache在Windows环境下的搭建及启动
  3. 服务器 声音文件 nginx,docker nginx搭建视频音频服务器
  4. c++ 获取时间戳_分布式系统理论基础三-时间、时钟和事件顺序
  5. 兼容IE678的placeholder
  6. wxpython bind自定义_wxPython的 - 如何从自定义对话框WX
  7. 设计模式之结构类模式PK
  8. 页面增加html,为静态页面HTML增加session功能
  9. 基于卷积神经网络的大豆病害识别
  10. python访问注册表_Python 操作注册表
  11. Android 蓝牙配对、连接和通信
  12. 10个谷歌浏览器调试技巧
  13. 基于golang的手机号格式验证和邮箱格式验证(正则表达式)
  14. android连iphone热点超时,苹果手机开热点安卓手机连不了为什么
  15. java2的n次方表达式,某个数是2的N次方
  16. socket网络编程 poll的简单用法
  17. 使用命令行操作Windows防火墙
  18. 创客教育的起源和内涵的基本理念
  19. 解决东方财富数据接口激活后仍显示reactive的问题
  20. 重读DRRN(深度递归残差网络)

热门文章

  1. IPv6的利与弊—Vecloud微云
  2. postgresql关闭自动提交
  3. Linux的目录结构与目录管理
  4. 动态规划(最长递增子序列)---最长递增子序列
  5. 【CF526F】Pudding Monsters
  6. 解决dubbo-admin管控台不能显示服务的问题
  7. iOS GCD中级篇 - dispatch_group的理解及使用
  8. Linux编辑器vi使用方法详细介绍
  9. MinGW问题解决:gcc: installation problem, cannot exec `cc1'
  10. 何时开学?教育部最新回应:满足三个条件可开学