ZooKeeper 01 - 什么是ZooKeeper + 部署ZooKeeper集群

1.什么是ZooKeeper

ZooKeeper直译就是动物园管理员, 它是用来管Hadoop(大象)、Hive(蜜蜂)、Pig(小猪)等的管理员(这些都是Apache软件基金组织旗下大数据方面的技术框架), Apache Hbase和Apache Solr的分布式集群都用到了ZooKeeper.

(1) 百度百科中的说明:

  • ZooKeeper是一个高可用、分布式的程序协调服务, 是Google的Chubby一个开源的实现, 是Hadoop和Hbase的重要组件.

  • 它是一个为分布式应用提供一致性服务的软件, 提供的功能包括: 配置维护、域名服务、分布式同步、组服务等.

  • ZooKeeper的目标就是封装好复杂易出错的关键服务, 将简单易用的接口和性能高效、功能稳定的系统提供给用户.

(2) ZooKeeper的基本运转流程:

① 选举Leader;
② 同步数据;
③ 选举Leader过程中算法有很多, 但要达到的选举标准是一致的;
④ Leader要具有最高的执行ID, 类似root权限;
⑤ 集群中大多数的机器得到响应并接受选出的Leader.

2.ZooKeeper的功能

2.1 配置管理

项目开发中大多会涉及到各种配置信息, 比如JDBC的连接信息等. 一般将这些信息配置到特定的文件中, 在代码中引入相关配置文件即可.

—— 这是单服务器应用中常用的做法. 当应用很大、配置文件很多, 尤其是在分布式项目中, 多台服务器的配置需要保持一致,
而如果配置信息会被频繁地修改, 这个时候还使用配置文件就不是个好主意了.

扫描二维码关注公众号,回复: 9465048 查看本文章

—— 你总不能手动逐个修改吧? 不仅重复性劳动太多, 而且出错的可能性更大, 后期维护成本太大.

这种情况下往往需要寻找一种集中管理配置的方法 —— 在这个集中的地方修改了配置, 所有对该配置有依赖的服务都可以获得变更.

需要考虑的是, 由于多台服务器上的项目都依赖了这个配置, 为了应用的可靠运行, 需要这个集中提供配置服务的应用具备非常高的可靠性.

基于上述分析, 我们可以通过集群来提供配置服务, 保证系统的可靠性. 此时遗留的问题是, 如何保证配置在集群中的一致性呢?

为了提供这种一致性, 前辈们提出了一致性协议, 实现此协议的服务就有ZooKeeper —— 它使用Zab这种一致性协议来保证一致性.

应用场景:

○ HBase中, 客户端就是连接一个ZooKeeper, 它获得HBase集群的必要配置信息, 然后才可以进一步操作.
○ 开源消息队列Kafka中, 使用ZooKeeper来维护broker的信息.
○ Alibaba开源的SOA框架Dubbo中广泛使用ZooKeeper管理配置信息, 实现服务治理.

2.2 命名服务

场景: 为了通过网络访问一个系统, 我们需要知道对方的IP地址, 但由于IP地址是一串数字, 难以记忆, 对用户并不友好. 这时人们想出通过域名来访问指定的IP地址.

但计算机并不能识别域名. 为了解决这一问题, 设计者们提出了在每台电脑中都存储一份"域名到IP地址的映射"的方案. 问题又来了, 如果域名对应的IP地址发生了变化, 又该如何映射呢?

前辈们又设计了DNS(Domain Name System, 域名系统). 我们只需要先访问一个所有机器都知道的(known)的节点, DNS通过该节点告诉我们当前访问的域名对应的IP地址是什么. 也就是DNS提供统一的访问接口.

在应用开发中也会存在这类问题, 特别是应用中存在大量服务时, 如果我们将服务的地址保存在本地, 其他用户是不好获取这些地址并访问的. 但是如果我们为用户提供统一的入口, 在本地对各种用户请求作相应的映射处理, 就可以解决此类问题.

2.3 分布式锁

ZooKeeper是一个分布式协调服务, 我们可以利用ZooKeeper来协调多个分布式进程之间的活动.

比如在一个分布式环境中, 为提高系统的可靠性, 集群中的每台服务器都部署了相同的服务.

这些相同的服务都要执行相同的任务, 为了保证数据的一致性, 集群之间就要互相协调, 常规的编程方案解决协调问题是非常复杂繁琐的.

通常的做法是: 使用分布式锁, 在某个时刻只有一个服务在工作, 当这台服务出了问题锁就立即释放, 并 fail over 到其他服务. 这种设计被称作叫Leader Election (leader选举). 比如HBase的Master就采用了这种机制.

注意: 分布式锁与进程锁是有区别的, 使用时要更加谨慎.

2.4 集群管理

在分布式集群应用中, 存在诸如软硬件故障、断电、网络等问题, 存在节点出入现象, 即新节点加入集群, 老节点退出集群. 出现这些情况时, 集群中其他节点要能感知到这种变化, 然后根据这种变化做出对应的决策.

应用场景:

○ 在分布式存储系统中, 有一个中央控制节点负责存储的分配, 有新的存储节点加入进来时, 需要根据集群状态来动态分配存储节点,这需要实时感知集群的状态.
○ 在分布式SOA架构中, 服务由某一集群提供, 当消费者访问某个服务时,需要采用某种机制发现集群中有哪些节点可以提供该服务(这也称之为服务发现,比如Alibaba开源的SOA框架Dubbo就采用了ZooKeeper作为服务发现的底层机制).
○ 开源的消息队列Kafka中,通过ZooKeeper对Consumer的上下线进行管理.

3 部署ZooKeeper集群

3.1 下载并解压安装包

ZooKeeper下载地址: http://hadoop.apache.org/zookeeper/releases.html.

#下载后, 上传至特定目录, 这里上传至/data/zookeeper下: 
mkdir -p /data/zookeeper && cd /data/zookeeper
#解压ZooKeeper安装包: 
tar -zxf zookeeper-3.4.10.tar.gz

3.2 创建data和datalog目录

#进入ZooKeeper安装目录
cd zookeeper-3.4.10

#data为ZooKeeper数据存放目录, datalog为ZooKeeper日志存放目录
#若不指定datalog, 默认与数据存放目录一致
mkdir data datalog

#赋予当前用户写权限
chmod 644 data datalog 

3.3 创建myid文件

在data目录下创建myid文件, 文件中只包含一行内容: 该节点对应的server.id的id编号. 如server.1节点中myid文件的内容为1.

#将编号写入到myid文件中
echo 1 > /data/zookeeper/data/myid

#查看写入是否成功
cat /data/zookeeper/data/myid

3.4 修改配置文件zoo.cfg

(1) 修改过程如下:

cd /data/zookeeper/zookeeper-3.4.10/conf

#拷贝文件, 重命名为zoo.cfg
cp zoo_sample.cfg zoo.cfg

#修改zoo.cfg文件: 
vim zoo.cfg

#添加如下内容: 
dataDir=/data/zookeeper/data
dataLogDir=/data/zookeeper/datalog
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

(2) 配置完成的zoo.cfg文件如下:

  # 基本事件单元(毫秒), 用来控制心跳和超时. 
  tickTime=2000 
  
  # 集群中有多台Server, 其中一台为Leader, 其余Server为Follower. initLimit参数指定Follower连接并同步到Leader的初始化心跳时间(即最长通信时间), 以tickTime的倍数表示, 超过该时间则连接失败.
  initLimit=5
  
  # Leader与Follower之间发送消息时, 请求和应答的最大时间, 是tickTime的倍数. 如果Follower在设置的时间内不能与Leader建立通信, 此Follower将被丢弃. 
  syncLimit=2
  
  # 存放ZooKeeper运行时数据的目录, 需要提前建立. 
  dataDir=/data/zookeeper/data
  
  # log目录, 如果没有设置该参数, 默认使用dataDir的目录, 需要提前建立. 
  # 应当谨慎选择日志目录, 使用专用的日志存储设备能很大程度提高系统的性能. 
  dataLogDir=/data/zookeeper/datalog
  
  # 监听client连接的端口号. 
  clientPort=2181
  
  # 设置连接到ZooKeeper的客户端的最大数量(限制并发连接的数量, 它通过IP来区分不同的客户端). 此配置选项可以用来阻止某些类别的Dos攻击, 将它设置为0或不设置将会取消对并发连接的限制. 
  maxClientCnxns=0
  
  # 最小的会话超时时间, 默认为 2 * tickTme 时间
  minSessionTimeout=4000
  
  # 最大的会话超时时间默认情况下为 20 倍的会话超时时间
  maxSessionTimeout=10000
  
  # 集群中各个节点的信息(server.id=ip:port1:port2)
  server.1=zoo1:2888:3888 
  server.2=zoo2:2888:3888 
  server.3=zoo3:2888:3888

(3) 关于 server.id=host:port1:port2 的说明:

id 是每个ZooKeeper节点的编号, 保存在dataDir目录下的myid文件中;

zoo1~zoo3表示各个ZooKeeper节点的hostname或IP地址, 映射关系在系统文件 /etc/hosts 中设置;

port1指定该Server与集群中的Leader通信所使用的端口;

port2指定集群选举Leader时所用的端口.

(4) 常见错误说明:

○ clientPort 不能与port1、port2相同, 否则集群将启动不了.
○ 若采用伪分布式配置方式(即在一台服务器上模拟配置集群), 则各个Server的port1与port2不能相同.
○ 如果采用伪分布式配置方式, dataDir与dataLogDir也需要作不同的配置.

3.5 部署其他节点上的服务

#拷贝ZooKeeper文件夹到其他服务器(zoo2和zoo3) --- 需要确保相应的路径/data/zookeeper存在: 
scp -r /data/zookeeper zoo2:/data/
scp -r /data/zookeeper zoo2:/data/

#分别在zoo2和zoo3服务器上修改ZooKeeper的myid: 
echo 2 > /data/zookeeper/zookeeper-3.4.10/data/myid
echo 3 > /data/zookeeper/zookeeper-3.4.10/data/myid

4 启动ZooKeeper集群

4.1 关闭防火墙

ZooKeeper客户端使用2181端口号, 为了能对外正常使用Zookeeper, 需要开放2181端口号, 或者关闭防火墙:

(1) CentOS 7之前系统的命令:

#查看防火墙状态: 
service iptable status

#临时关闭防火墙: 
service iptables stop

#永久关闭防火墙(禁止开机启动): 
chkconfig iptables off

(2) CentOS 7开始使用systemctl来管理服务和程序, 包括service和chkconfig:

#查看防火墙状态: 
systemctl status firewalld.service

#临时关闭防火墙: 
systemctl stop firewalld.service

#永久关闭防火墙(禁止开机启动): 
systemctl disable firewalld.service 

4.2 启动ZooKeeper集群

(1) 启动步骤:

#依次进入三台服务器, 执行下述命令: 
cd /usr/local/zookeeper-3.4.10/bin
./zkServer.sh start

#查看ZooKeeper运行状态: 
./zkServer.sh status

(2) 常见错误: 在查看ZooKeeper的状态时, 可能会发现控制台抛出错误:

[root@localhost bin]# ./zkServer.sh status 
JMX enabled by default 
Using config: /data/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg 
Error contacting service. It is probably not running 

错误原因: 这里部署的是集群, 其他服务器尚未启动, 当前节点在根据zoo.cfg中配置的服务列表发起选举Leader的请求, 由于无法与集群中的其他节点进行通信, 所以抛出错误.

错误解决: 在启动第二台ZooKeeper服务后, Leader将被选出, 错误就会消失. 因为在ZooKeeper集群中, 如果有2n+1台服务器, 它允许n台服务挂掉而不影响服务.

4.3 ZooKeeper的常用命令

#启动服务: 
sh zkServer.sh start 

#查看服务状态: 
sh zkServer.sh status 

#停止服务: 
sh zkServer.sh stop 

#重启服务: 
sh zkServer.sh restart  
发布了46 篇原创文章 · 获赞 27 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/shichen2010/article/details/104550403