Zookeeper 集群部署的那些事儿
简介

额。。。。, &*$% 淘气!
ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效、高可用的分布式协调服务。
ZooKeeper本质上是一个分布式的小文件存储系统。提供类似于文件系统目录树方式的数据存储,并且可以对书中的节点进行有效管理。从而用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,实现基于数据的集群管理。
运行模式
ZooKeeper 运行模式有三种:单机模式、伪集群模式、集群模式

单机模式: ZooKeeper 只运行一台服务器上面,这种模式一般用于开发测试环境,用于节省机器数量,加上开发调试不需要特别好的稳定性
伪集群模式: 这是一种特殊的集群模式,即一台服务器上面部署多个ZooKeeper实例,当然这个时候就需要你这台服务器性能比较好。在这种情况下,我们需要通过不同的端口来启动ZooKeeper实例,以此来通过集群的方式对外提供服务。
这种模式下,我们只需要修改zoo.cfg下的同一个服务器不同端口连接地址即可
server.1=ip1:2888:3888
server.2=ip1:2889:3889
server.3=ip1:2890:3890
集群模式: Zookeeper集群 运行在一组机器上,一般三台以上的机器就可以组成集群了,组成ZooKeeper集群的每一台机器都会在内存中维护当前服务的状态,机器之间也会互相保持通信。
只要集群中过半的服务存活,就能正常对外提供服务,如果说当我们的leader挂掉了,在选举过程中是无法提供服务的,直到leader选举完成!
这种模式下,我们只需要修改zoo.cfg下的不同服务器的连接地址即可
server.1=ip1:2888:3888
server.2=ip2:2888:3888
server.3=ip3:2888:3888
Zookeeper集群有什么用
ZooKeeper 实现了高性能,高可靠性和有序的访问。高性能保证了ZooKeeper能应用在大型的分布式系统上,高可靠性保证它不会由于单一节点的故障而造成任何问题。有序的访问能保证客户端可以实现较为复杂的同步操作。
负载均衡
这里说的负载均衡是指软负载均衡。在分布式环境中,为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,来达到高可用。
命名服务
在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或者服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址、远程对象等这些我们可以统称为Name,其中比较常见的就是一些分布式服务框架中的服务地址列表。通过调用ZooKeeper提供创建节点的API,能够很容易创建一个全局唯一的Path,这个Path可以作为一个名称。
阿里巴巴集团开源的分布式服务框架Dubbo中使用ZooKeeper来作为其命名服务,维护全局的服务地址列表,点击这里查看Dubbo开源项目。
分布式协调
ZooKeeper中特有的Watcher注册与异步通知机制,能够实现分布式环境下不同系统之间的通知与协调,实现对数据变更的及时处理,使用方法通常是不同系统都对ZooKeeper同一个Znode进行注册,监听Znode的变化。
如果其中一个系统更新了Znode,那么另外系统也能够收到通知,并做出相应的处理。
集群管理
集群管理主要是包含其中两点:服务状态监听(退出和加入)、master选举。
服务状态监听: 所有机器在父目录下创建临时目录节点,监听父目录节点的子节点变化消息,如果有机器挂掉,这个机器与ZooKeeper的连接断开,这个创建的临时目录节点就会被删除,其他机器收到消息,某个服务下的节点目录被删除,就知道这个某个节点宕机。
如果有新的机器或者服务加入,会在该父目录节点下创建一个临时子节点,所有服务就会收到通知,有新的目录产生。
master选举: master选举是ZooKeeper中最为经典的应用场景了,在分布式环境中,相同的业务应用分布在不同的机器上,有的业务逻辑,通常只需要其中一台服务完成,然后其他服务共享,这样可以大幅度减少重复劳动,提高服务性能,比如 HDFS 中 Active NameNode 的选举。
通常情况下,我们可以选择常见的关系型数据库中的主键特性来实现,在成为Master的机器都想数据库中插入一条相同主键ID的记录,数据库会帮我们进行主键冲突检查,也就是说,只有一台机器能够插入成功,那么我们就认为向数据库中插入数据的机器就是Master
但是当我们的Master机器挂掉了,那么谁能够告诉我们Master挂掉了,关系型数据库是无法通知我们这个事情的,但是ZooKeeper可以做到。
ZooKeeper能够保证在分布式高并发情况下节点的创建一定能够保证全局唯一性,ZooKeeper将会保证客户端无法创建一个已经存在的数据单元节点。也就是说,如果同时有多个客户端请求创建同一个临时节点,那么最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很容易的在分布式环境中进行Master选举了,成功创建该节点的客户端所在的机器就成为了Master,同时企业没有成功创建该节点的客户端,都会在该节点上注册一个子节点变更的Watcher,用于监控当前的Master机器是否存活,一旦发现当前的Master挂了,那么其他客户端将会重新进行Master选举,这样就实现了Master的动态选举。

ZooKeeper集群必须是奇数?
一个ZooKeeper集群通常由一组机器组成,一般是3台以上就可以组成一个可用的ZooKeeper集群了。只要集群中存在超过一半的机器能够正常工作,那么ZooKeeper集群就能正常对外提供服务。

在这里,有一个误区,就是为了让 ZooKeeper 群能够正确的选举出 leader 我们必须要把 ZooKeeper 集群服务器的数量设置为奇数,其实任意台的ZooKeeper都可以正常选举出Leader和运行。
关于集群服务数量中,ZooKeeper官方也给出了奇数的建议,而且基于ZooKeeper 过半以上存活服务可用 的特性,如果ZooKeeper需要对外提供服务,那么至少要保证有过半存活的机器能够正常工作,如果我们想要搭建一台允许挂点一定数量(N)的集群机器,那我们至少要部署 2*N+1台服务器来搭建ZooKeeper集群。
容错率
从容错率来讲,我们要保证 过半以上存活的特性
如果我们允许挂掉1台服务,那我们至少要搭建(2*1+1)台服务器,也是就3台服务器(3的半数为1.5,默认向下取整为1,半数以上那就是2)
如果我们允许挂掉2台服务,那我们至少要搭建(2*1+1)台服务器,也是就5台服务器(5的半数为2.5,默认向下取整为2,半数以上那就是3)
同样我们部署六台机器,那么我们遵循过半以上存活服务可用的特性,同样也只能挂掉2台服务器,因为如果挂掉3台,无法遵循服务过半的特性
因此,我们可以从上面条件中看到,对于一个由6台服务器构成的ZooKeeper集群来说,和一个用5台服务器构成的ZooKeeper集群,在容灾能力上没有任何的显著优势,所以ZooKeeper集群 通常会设置成奇数台服务器即可
下载
下载地址:https://zookeeper.apache.org/releases.html
安装
ZooKeeper安装首先需要安装JDK,ZooKeeper的安装步骤在上一篇文章中介绍过,大家感兴趣的可以看一下:https://muxiaonong.blog.csdn.net/article/details/120543298
修改配置
当我们将conf下的 zoo_sample.cfg 文件复制并重命名为 zoo.cfg 文件后,通过 vim zoo.cfg命令对这个文件进行修改:

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
server.1=192.168.5.129:2888:3888
server.2=192.168.5.130:2888:3888
server.3=192.168.5.131:2888:3888
tickTime: 客户端与服务端或者服务端和服务端之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳,通过心跳不仅能够用来监听机器的工作状态,还可以通过心跳来控制follower和Leader的通信时间,默认情况下FL(Follower和Leader)的会话通常是心跳间隔的两倍,单位为毫秒。
initLimit: 集群中的follower服务器与Leader服务器之间的初始连接时能容忍的最多心跳数量
syncLimit: 急群众的follower服务器与leader服务器之间的请求和回答最多能容忍的心跳数量
dataDir: 目录地址,用来存放myid信息和一些版本、日志、服务器唯一ID等信息
clientPort: 监听客户端连接的端口
server.n=127.0.0.1:2888:3888
n:代表的是一个数字,表示这个服务器的标号
127.0.0.1:IP服务器地址
2888:ZooKeeper服务器之间的通信端口
3888:Leader选举的端口
两个需要修改的点:
- 修改的是目录结构(dataDir),不要用它默认的
- 添加server.1 集群服务器配置信息
官方参考文档:https://zookeeper.apache.org/doc/r3.5.8/zookeeperStarted.html
创建服务器ID
在这里我们需要创建一个 myid 的文件,我们需要在 dataDir 指定的目录下,手动创建这个目录。
创建命令:mkdir -p /tmp/zookeeper
然后在myid 文件里面添加对应的server.1中的 “1” 这个数字,如下所示
[root@VM-0-7-centos zookeeper]# more myid
1
后面的机器,依次在 dataDir 指定的目录下(/tmp/zookeeper),创建 myid 文件,写上相应配置的数字,比如我们在zoo.cfg后面写的是server.1,那么当前myid的文件就写一个数字1就可以了
server.1=192.168.5.129:2888:3888
server.2=192.168.5.130:2888:3888
server.3=192.168.5.131:2888:3888
配置环境变量
为了方便我们可以在全局使用ZooKeeper命令,我们需要配置ZooKeeper的环境变量。
通过命令:vi /etc/profile
添加ZooKeeper的环境变量。
export JAVA_HOME=/usr/local/java/jdk1.8.0_261
export ZK_HOME=/usr/local/java/apache-zookeeper-3.7.0-bin/
export PATH=$PATH:$JAVA_HOME/bin:$ZK_HOME/bin
变量生效:source /etc/profile
关闭防火墙
在这里大家记得,如果是生产或者正式的,需要开放对应的端口进行通信。
如果是我们测试用的服务器,需要关闭防火墙,不然会有拦截,无法进行服务之间的通信,在这里我们是测试,关闭防火墙即可。
这里我使用的服务是CentOS 7.0,默认使用的是firewall作为防火墙。
防火墙设置
查看防火墙状态:firewall-cmd --state
立即关闭防火墙,重启失效:systemctl stop firewalld.service
禁止开机启动防火墙:systemctl disable firewalld.service
端口设置
开放2888端口:firewall-cmd --zone=public --add-port=2888/tcp --permanent
关闭2888端口:firewall-cmd --zone=public --remove-port=2888/tcp --permanent
启动服务
查看日志启动命令:zkServer.sh start-foreground
后台启动命令:zkServer.sh start
停止命令:zkServer.sh stop
查看状态命令:zkServer.sh status
我们分别用 zkServer.sh status命令查看节点状态,三台机器中,有两台成为了 follower,一台成为了Leader节点。



使用命名查看ZooKeeper端口情况:netstat -natp | egrep '(2888|3888)'



端口说明
3888:是选举用的
2888:是leader接受write请求
因此我们可以看到130这一台机器出了有 130:2888以外还有130:3888 端口对自身进行监听,这个是保证leader可以进行write操作的命令,具体通信如下所示:

注意事项
如果搭建中出现问题,首先我们需要排查的问题,包含以下几点
- 防火墙有没有关闭
- zoo.cfg 下的文件路径 dataDir 的目录有没有创建,不是自动创建的,需要我们进行手动创建,创建命令
mkdir -p /tmp/zookeeper - 我们可以通过
zkServer.sh start-foreground启动过程的报错信息
总结
到这里,关于ZooKeeper的集群就讲解完毕了,主要介绍了ZooKeepe集群的作用和安装部署,以及原理,今天的ZooKeeper集群到这里就讲完了,下期精彩持续更新中。
码字不易,感兴趣的小伙伴记得点赞关注~
我是牧小农,怕什么真理无穷,进一步有进一步的欢喜,大家加油!
Zookeeper 集群部署的那些事儿的更多相关文章
- Centos6下zookeeper集群部署记录
ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等. Zookeeper设计目的 最终一致性:client不论 ...
- 分布式协调服务之Zookeeper集群部署
一.分布式系统概念 在聊Zookeeper之前,我们先来聊聊什么是分布式系统:所谓分布式系统就是一个系统的软件或硬件组件分布在网络中的不同计算机之上,彼此间通过消息传递进行通信和协作的系统:简单讲就是 ...
- HBase集成Zookeeper集群部署
大数据集群为了保证故障转移,一般通过zookeeper来整体协调管理,当节点数大于等于6个时推荐使用,接下来描述一下Hbase集群部署在zookeeper上的过程: 安装Hbase之前首先系统应该做通 ...
- Zookeeper集群部署
一. 部署前的准备工作 保证各个主机之间能够正常通信,最好是在同一网段. 修改host文件,加入IP和主机名的映射.方法为修改/etc/hosts和etc/hostname文件,不同的Linux发行版 ...
- 消息中间件kafka+zookeeper集群部署、测试与应用
业务系统中,通常会遇到这些场景:A系统向B系统主动推送一个处理请求:A系统向B系统发送一个业务处理请求,因为某些原因(断电.宕机..),B业务系统挂机了,A系统发起的请求处理失败:前端应用并发量过大, ...
- docker环境下solrcloud+zookeeper集群部署教程
前言:两个月前的16年11月份完成的配置,使用的solr6.1和zookeeper3.4,刚刚写成blog,目前版本可能有小版本的变化. 本例完成结果为:在docker环境下部署solrcloud集群 ...
- Zookeeper集群部署与配置(三)
在上一篇博客中我们讲解了<Zookeeper的单机配置>,此篇博客将继续介绍Zookeeper的集群部署与配置. 环境 集群配置的环境与单机配置的环境相同,唯一不同的就是集群是在多台服务器 ...
- Zookeeper集群部署及报错分析
安装 下载压缩包 解压 修改zoo.cfg文件 创建myid文件 启动 自启动配置 有时间再补hhh 报错处理 很荣幸的遇到了大部分报错,日志再zookeeper目录的bin下的zookeeper.o ...
- zookeeper集群部署问题排查记录
今天在三台虚拟机搭建zookeeper集群,一直连不通,然后进行了几个小时的斗争,做个记录. 具体部署方式网上有很多, 不在赘述.产生连接不同的问题主要有以下几个方面: 1.仔细检查配置文件. 是否有 ...
随机推荐
- Promise.race()
Promise.race([ ])---race竞赛,只要有一个决议了,就返回一个promise实例(对应resolve()或reject( )中参数值: 1.与Promise.all()对应的,还有 ...
- 微信小程序--聊天室小程序(云开发)
微信小程序 -- 聊天室小程序(云开发) 从微信小程序开发社区更新watch接口之后,一直在构思这个项目.项目已经完成很久,但是一直都没有空写一篇博客记录展示一下. 开源地址 wx-cloud-im: ...
- C语言编译步骤
C语言编译步骤: 1.预处理(hello.i ):宏定义展开.条件编译等,同是将代码中的注释删除,这里并不会检查语法 2.编译(hello.s):检查语法,将预处理后文件编译生成汇编文件. 3.汇 ...
- webservice学习总结(一)-- WebService相关概念介绍
一.WebService是什么? 基于Web的服务:服务器端整出一些资源让客户端应用访问(获取数据) 一个跨语言.跨平台的规范(抽象) 多个跨平台.跨语言的应用间通信整合的方案(实际) 二.为什么要用 ...
- CSP-J&S 2020挂分记
应该是退役记 OI 是一门玄学--考后有感 Day -inf 找各科老师请假备考,看着我倒一倒二的好成绩分纷劝我放弃竞赛,成功请到了假. Day -1 怎么莫名其妙大家都在学些奇怪的东西? 跟风写了一 ...
- Python - 通过PyYaml库操作YAML文件
PyYaml简单介绍 Python的PyYAML模块是Python的YAML解析器和生成器 它有个版本分水岭,就是5.1 读取YAML5.1之前的读取方法 def read_yaml(self, pa ...
- MongoDB索引的简单理解
目录 MongoDB索引 1.语法准备 2.数据准备: 3.索引 3.1 唯一索引 3.2 单键索引 3.3 多键索引 3.4 复合索引 3.5 交叉索引 3.6 部分索引 3.7覆盖索引 3.8 全 ...
- 第24篇-虚拟机对象操作指令之getfield
getfield指令表示获取指定类的实例域,并将其值压入栈顶.其格式如下: getstatic indexbyte1 indexbyte2 无符号数indexbyte1和indexbyte2构建为(i ...
- grep、cut、awk、sed的使用
grep.cut.awk.sed 常常应用在查找日志.数据.输出结果等等,并对我们想要的数据进行提取.通常grep,sed命令是对行进行提取,cut跟awk是对列进行提取 处理海量数据之grep命令 ...
- 快乐中秋,SQL小白入门指南
目录 创建表 最基本的创建 怎么查看一个已经建好的表的信息呢 修改字段 插入数据 修改和删除数据 修改 删除 第一个查询 条件语句 使用age的大小比较,查看大于16岁的学生: 使用多个条件并联,大于 ...