ZooKeeper 集群的详细部署

ZooKeeper 集群部署

  • [一、ZooKeeper 简介](#一、ZooKeeper 简介)
    • [1.1 什么是 ZooKeeper](#1.1 什么是 ZooKeeper)
    • [1.2 ZooKeeper 特点](#1.2 ZooKeeper 特点)
  • [二 ZooKeeper 的架构和设计](#二 ZooKeeper 的架构和设计)
    • [4.1 ZooKeeper 数据模型](#4.1 ZooKeeper 数据模型)
      • [4.1.1 Znode 节点特性](#4.1.1 Znode 节点特性)
  • [三、ZooKeeper 的集群安装前准备工作](#三、ZooKeeper 的集群安装前准备工作)
    • [3.1 需要的准备工作](#3.1 需要的准备工作)
    • [3.2 Linux 系统 3 个节点准备](#3.2 Linux 系统 3 个节点准备)
    • [3.2.1 克隆](#3.2.1 克隆)
      • [3.2.2 配置另外两台服务器的静态IP](#3.2.2 配置另外两台服务器的静态IP)
      • [3.2.3 修改主机名](#3.2.3 修改主机名)
    • [3.3 配置主机名与IP地址映射](#3.3 配置主机名与IP地址映射)
    • [3.4 配置时钟同步](#3.4 配置时钟同步)
    • [3.5 集群 SSH 免密登录](#3.5 集群 SSH 免密登录)
      • [3.5.1 为什么需要 SSH 免密登录](#3.5.1 为什么需要 SSH 免密登录)
      • [3.5.2 配置 节点免密登录](#3.5.2 配置 节点免密登录)
      • [3.5.3 配置集群 SSH 免密登录](#3.5.3 配置集群 SSH 免密登录)
  • [四、ZooKeeper 的集群安装](#四、ZooKeeper 的集群安装)
    • [4.1 集群脚本开发](#4.1 集群脚本开发)
    • [4.2 集群脚本配置](#4.2 集群脚本配置)
    • [4.3 ZooKeeper 集群配置](#4.3 ZooKeeper 集群配置)
      • [4.3.1 ZooKeeper 下载](#4.3.1 ZooKeeper 下载)
      • [4.3.2 上传解压](#4.3.2 上传解压)
      • [4.3.3 配置 zookeeper 配置文件 zoo.cfg](#4.3.3 配置 zookeeper 配置文件 zoo.cfg)
      • [4.3.4 创建各节点服务编号](#4.3.4 创建各节点服务编号)
    • [4.4 启动 ZooKeeper 集群服务](#4.4 启动 ZooKeeper 集群服务)
  • 五、在配置过程的一些问题总结
    • [5.1 启动单个节点zookeeper正常,启动集群失败,并提示如下:](#5.1 启动单个节点zookeeper正常,启动集群失败,并提示如下:)

一、ZooKeeper 简介

1.1 什么是 ZooKeeper

  • 定义:zookeeper一个分布式的开源的协调服务框架,服务于分布式应用。
    • 它暴露了一系列的原语操作服务,因此分布式应用能够基于这些服务,构建出更高级别的服务,比如同步,配置管理,分组和命名服务。

    • zookeeper设计上易于编码,数据模型构建在我们熟悉的树形结构目录风格的文件系统中,

    • zookeeper运行在Java中,同时支持Java和C 语言

1.2 ZooKeeper 特点

  • 最终一致性
    • 客尸端末论连接到哪个 Server,展示给它的都是同一个视图,这是Zookeeper最重要的特点。
  • 可靠性
    • Zookeeper 具有简单、健壮、良好的性能。如果一条消息被一台服务器接收,那么它将被所有的服务器接收。
  • 实时性
    • Zookeeper 保证客户端将在一个时间间隔范围内,获得服务器的更新信息或者服务器失效的信息。但由于网络延时等原因
    • zookeeper 不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
  • 等待无关(wait-free)
    • 慢的或者失效的客户端不得干预快速的客户端的请求,这就使得每个客户端都能有效地等待。
  • 原子性
    • 对zookeeper的更新操作要么成功,要么失败,没有中间状态。
  • 顺序性
    • 它包括全局有序和偏序两种
      • 全局有序是针对服务器端,例如,在一台服务器上,消息A在消息B前发布,那么所有服务器上的消息A都将在消息B前被发布。
      • 偏序是针对客户端,例如,在同一个客户端中,消息B在消息A后发布,那么执行的顺序必将是先执行消息A然后在是消息B。所有的更新操作都有严格的偏序关系,更新操作都是串行执行的,这一点是保证ZooKeeper功能正确性的关键。

二 ZooKeeper 的架构和设计

Zookeeper 服务自身组成一个集群(2n+1个服务节点最多允许n个失效)。Zookeeper 服务有两个角色:一个是主节点(Leader),负责投票的发起和决议,更新系统状态;另一种是从节点(Follower),用于接收客户端请求并向客户端返回结果,在选主过程(即选择主节点的过程)中参与投票。主节点失效后,会在从节点中重新选举新的主节点。

4.1 ZooKeeper 数据模型

zookeeper的数据结构与linux文件系统很类似,与Linux中的文件系统路径不同,Zookeeper中的路径必须是绝对路径,而且每条路径只有唯一的一种表示方式(/app1/p_3)。

4.1.1 Znode 节点特性

  • 临时节点

    znode节点有两种:临时节点和持久节点。znode的类型在创建时就确定,之后不能修改当创建临时节点的客户端会话结束时,2ookeeper 会将该临时节点删除。而持久节点不依赖与客户端会话,只有当客户端明确要删除该持久节点时才会被真正删除。临时节点不可以有子节点,即使是短暂的子节点。

  • 顺序节点

    顺序节点是指名称中包含Zookeeper指定顺序号的znode。如果在创建znode的时候设置了顺序标识,那么该znode名称之后就会附加一个值,这个值是由一个单调递增的计数器所添加的,由父节点维护。

  • 观察机制

    客户端可以在znode上设置watcher,当节点状态发生改变时将会触发watcher所对应的操作当watcher被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watcher只能被触发一次,这样可以减少网络流量。为了能够多次收到通知,客户端需要重新注册所需的watcher

三、ZooKeeper 的集群安装前准备工作

3.1 需要的准备工作

  • Linux 系统3 个节点准备
  • 配置主机名与IP地址映射
  • 配置时钟同步
  • 集群SSH密码登录
  • JDK安装

目标配置如下三台服务器:

服务器序号 IP 主机名称
1 192.168.220.151 hadoop1
2 192.168.220.152 hadoop2
2 192.168.220.153 hadoop3

3.2 Linux 系统 3 个节点准备

3.2.1 克隆

使用MVware 的克隆功能,克隆出另外两台 Hadoop 服务器

选择克隆完整版

3.2.2 配置另外两台服务器的静态IP

登录服务后,修改服务器网络配置:

bash 复制代码
[root@hadoop1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33

修改 IP 地址即可,其他不变

3.2.3 修改主机名

bash 复制代码
[root@hadoop1 ~]# vim /etc/hostname

第二台服务器主机名:hadoop2 ,第三台服务器主机名:hadoop3

3.3 配置主机名与IP地址映射

三台服务器都需要配置主机名与IP地址映射

bash 复制代码
[root@hadoop1 ~]# vim /etc/hosts

添加如下内容:

bash 复制代码
192.168.220.151 hadoop1
192.168.220.152 hadoop2
192.168.220.153 hadoop3

三台服务器可以通过主机名相互访问

3.4 配置时钟同步

Hadoop 集群对节点的时间同步要求比较高,要求各个节点的系统时间不能相差太多,否则会造成很多问题,比如,最常见的连接超时问题。所以需要集群节点的系统时间与互联网的时间保持同步,但是在实际生产环境中,集群中大部分节点是不能连接外网的,这时候可以在内网搭建一个自己的时钟服务器(比如 NTP 服务器),然后让 Hadoop 集群的各个节点与这时钟服务器的时间保持同步

此处我选择 hadoop1 作为时钟服务器(大家随意)

  • 查看时间类型
bash 复制代码
[root@hadoop1 ~]# date

CST 为上海时间,如果是 HKT,表示香港时间,可以通过如下操作进行调整

bash 复制代码
[root@hadoop1 ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 

注意:检测所有服务器的时间类型,保证都是上海时间

  • 配置 NTP 服务器

  • 检测 NTP 服务是否安装

bash 复制代码
# 检测是否安装 ntp
[root@hadoop1 ~]# rpm -qa | grep ntp

# 如果没有安装,进行安装
[root@hadoop1 ~]# yum install -y ntp

安装成功

  • 修改配置文件 ntp.conf
bash 复制代码
[root@hadoop1 ~]# vim /etc/ntp.conf 

#启用 restrict 限定该机器网段,192.168.220.151为当前节点的IP地址

restrict 192.168.220.151 mask 255.255.255.0 nomodify notrap

#注释掉 server 域名配置

#server 0.centos.pool.ntp.org iburst

#server 1.centos.pool.ntp org iburst

#server 2.centos.pool.ntp,org iburst

#server 3.centos.pool.ntp.org iburst

#添加如下两行配置,让本机和本地硬件时间同步

server 127.127.1.0

fudge 127.127.1.0 stratum 10

  • 启动 ntp 服务器
    执行 chkconfi&npdon 命令,可以保证每次机器启动时,NTP 服务都会自动启动,具体操作
    如下所示。
bash 复制代码
[root@hadoop1 ~]# chkconfig ntpd on

查看ntpd 服务状态

bash 复制代码
# 查看ntpd 服务状态
[root@hadoop1 ~]# sudo systemctl status ntpd

# 如果ntpd 服务没有启动执行如下脚本
[root@hadoop1 ~]# sudo systemctl start ntpd
  • 配置其他节点定时同步时间

hadoop2和 hadoop3 节点通过 Linux crontab 命令,可以定时同步 hadoop1 节点的系统时

间,具体操作如下所示。

bash 复制代码
[root@hadoop1 ~]# crontab -e

添加如下内容:

bash 复制代码
# 表示每过10分钟进行一次时钟同步
0-59/10 * * * * /usr/sbin/ntpdate hadoop1

查看 ntp 服务是否启用成功

bash 复制代码
[root@hadoop2 hadoop]# timedatectl

**备注**:hadoop02 和 hadoop03 节点也需要使用 yum install -yn,命令安装 NTP 服务,才能使用 npdate 时间同步命令。

3.5 集群 SSH 免密登录

3.5.1 为什么需要 SSH 免密登录

SSH(Secure shell)是可以在应用程序中提供安全通信的一个协议,通过 SSH 可以安全地进行网络数据传输,它的主要原理就是利用非对称加密体系,对所有待传输的数据进行加密,保证数据在传输时不被恶意破坏、泄露或者篡改。

但是 Hadoop集群使用 SSH不是用来进行数据传输的,而是在 Hadoop集群启动和停止的时候,主节点需要通过 SSH 协议启动或停止从节点上面的进程。如果不配置SSH 免密登录,对 Hadoop 集群的正常使用没有任何影响,但是在启动和停止 Hadoop 集群的时候,需要输入每个从节点的密码。可以想象一下,当集群规模比较大的时候,比如达到成百上千节点的规模,如果每次都要分别输入集群节点的密码,这种方法肯定是不可职的,所以要对 Hadoop集群进行 sSH 免密登录的配置。

3.5.2 配置 节点免密登录

SSH 免密登录的功能跟用户密切相关,为哪个用户配置了SSH,那个用户就具有 SSH免密登录的功能,没有配置的用户则不具备该功能,这里选择为 hadegp用户配置 SSH免密登录。首先在控制台,使用su命令切换到 root用户的根目录,然后使用ssh-keygen -t rsa 命令(ssh.keysen是秘钥生成器,-t是一个参数,rsa 是一种加密算法)生成秘钥对(即公钥文件id .rsa.pub 和私钥文件 id.rsa)。

先配置 hadoop1 节点免密登录,然后其他两个节点按照相同的方法处理

bash 复制代码
# 删除.ssh文件 
[root@hadoop1 ~]# rm -rf .ssh/*

# 生成密钥
[root@hadoop1 ~]# ssh-keygen -t rsa

# 拷贝公钥 id_rsa.pub 到 authrized_keys
[root@hadoop1 ~]# cp .ssh/id_rsa.pub .ssh/authorized_keys

# 给 .ssh/ 授权
[root@hadoop1 ~]# chmod 700 .ssh
[root@hadoop1 ~]# chmod 600 .ssh/*

`备注`:给 hadoop2 和 hadoop3 也按照上面的处理


3.5.3 配置集群 SSH 免密登录

  • 为了实现集群节点之间SSH免密登录,我们还需要将hadoop2和 hadoop3的公钥id_ras.pub复制到 hadoop1中的 authorized keys 文件中,具体操作命令如下所示:
bash 复制代码
# 在 hadoop2 中将 id_ras.pub 内容拷贝到 hadoop1 的 authorized_keys
[root@hadoop2 ~]# cat ~/.ssh/id_rsa.pub | ssh root@hadoop1 'cat >> ~/.ssh/authorized_keys'

# 在 hadoop3 中将 id_ras.pub 内容拷贝到 hadoop1 的 authorized_keys
[root@hadoop3 ~]# cat ~/.ssh/id_rsa.pub | ssh root@hadoop1 'cat >> ~/.ssh/authorized_keys'

查看 hadoop1 的 authorized_keys

  • 然后将hadoop1中的authorized keys文件分发到hadoop2和hadoop3节点,具体操作如下所示:
bash 复制代码
# hadoop1中的authorized_keys文件分发到hadoop2
[root@hadoop1 ~]# scp -r /root/.ssh/authorized_keys root@hadoop2:/root/.ssh/

# hadoop1中的authorized keys文件分发到hadoop3
[root@hadoop1 ~]# scp -r /root/.ssh/authorized_keys root@hadoop3:/root/.ssh/

查看 hadoop2或hadoop3 的 authorized_keys

四、ZooKeeper 的集群安装

4.1 集群脚本开发

集群脚本用于提升效率,一个脚本可以管理全部集群服务器,从而避免到每一台服务器上去执行脚本

一共涉及3个脚本:deploy.conf、deploy.shrunRemoteCmd.sh

deploy.conf:配置文档,用于规划集群,集群信息添加到此文件,统一进行管理

deploy.sh:分发脚本,用于在集群中 批量拷贝或推送文件

runRemoteCmd.sh:分发命令脚本,用于在集群中 批量执行命令

脚本内容分别如下

  • deploy.conf
bash 复制代码
#规划集群角色
hadoop1,master,all,
hadoop2,slave,all,
hadoop3,slave,all,
bash 复制代码
#!/bin/bash
if [ $# -lt 3 ]
then
  echo "Usage: ./deploy.sh srcFile(or Dir) descFile(or Dir) MachineTag"
  echo "Usage: ./deploy.sh srcFile(or Dir) descFile(or Dir) MachineTag confFile"
  exit
fi

src=$1
dest=$2
tag=$3

if [ 'a'$4'a' == 'aa' ]
then
  # 此处写自己存放 deploy.conf 位置
  confFile=/root/tools/deploy.conf
else
  confFile=$4
fi

if [ -f $confFile ]
then
  if [ -f $src ]
  then
    for server in `cat $confFile | grep -v '^#'|grep ','$tag','|awk -F',' '{print $1}'`
    do
      scp $src $server":"${dest} 
    done
  elif [ -d $src ]
  then
    for server in `cat $confFile | grep -v '^#'|grep ','$tag','|awk -F',' '{print $1}'`
    do
      scp -r  $src $server":"${dest} 
    done
  else
    echo "Error: No source file exist"
  fi
else
  echo "Error: Please assign config file or run deploy.sh command with deploy.conf in same directory"
fi
bash 复制代码
#!/bin/bash

if [ $# -lt 2 ]
then
  echo "Usage: ./runRemoteCmd.sh Command MachineTag"
  echo "Usage: ./runRemoteCmd.sh Command MachineTag confFile"
  exit
fi


cmd=$1
tag=$2
if [ 'a'$3'a' == 'aa' ]
then
  # 此处写自己存放 deploy.conf 位置
  confFile=/root/tools/deploy.conf
else
  confFile=$3
fi

if [ -f $confFile ]
then 
  for server in `cat $confFile | grep -v '^#'|grep ','$tag','|awk -F',' '{print $1}'`
  do 
    echo "*******************$server***********************"
    ssh $server "source /etc/profile; $cmd"
  done
else
  echo "Error: Please assign config file or run deploy.sh command with deploy.conf in same directory"
fi

注意:confFile按照你存放 deploy.conf 文件路径配置,其他基本可以不用调整

4.2 集群脚本配置

这里,我将以上脚本放到 hadoop1服务器,位置如下:

bash 复制代码
[root@hadoop1 tools]# chmod u+x deploy.sh runRemoteCmd.sh 
  • 将脚本配置到环境变量中,方便在任意路径可以使用
bash 复制代码
[root@hadoop1 tools]# vim /etc/profile

最下面添加如下内容:

bash 复制代码
# 添加hadoop集群管理 tools 脚本变量
PATH=/root/tools/:$PATH
  • 记得更新缓存
bash 复制代码
[root@hadoop1 tools]# source /etc/profile
  • 集群脚本测试

a. 先测试文件分发

bash 复制代码
# 随便创建一个 words.log 文本
[root@hadoop1 ~]# vim words.log
# 使用 deploy.sh 脚本分发 到 规划集群角色 为slave的节点中(我这也就是 hadoop2 hadoop3)
[root@hadoop1 ~]# deploy.sh words.log /root/ slave

查看 hadoop2 或 hadoop3 的 是否有words.log文件

b. 测试批量脚本执行

bash 复制代码
# 批量查看 hadoop1 hadoop2 hadoop3 运行的 java 进程
[root@hadoop1 hadoop]# runRemoteCmd.sh "jps" all

至此,是不是很方便

4.3 ZooKeeper 集群配置

4.3.1 ZooKeeper 下载

ZooKeeper下载地址https://archive.apache.org/dist/zookeeper/

这里我使用的是 3.8.4

4.3.2 上传解压

使用xshell 上传到 /root 目录,解压到

bash 复制代码
# 解压到/root
[root@hadoop1 ~]# tar -zxvf /root/apache-zookeeper-3.8.4-bin.tar.gz

# 移动到 /usr/local 目录
[root@hadoop1 ~]# mv apache-zookeeper-3.8.4-bin /usr/local/zookeeper-3.8.4

# 给 zookeeper-3.8.4 创建软连接
[root@hadoop1 local]# ln -s zookeeper-3.8.4/ zookeeper

4.3.3 配置 zookeeper 配置文件 zoo.cfg

  • 拷贝
bash 复制代码
#  进入配置文件目录
[root@hadoop1 conf ] cd /usr/local/zookeeper/conf

# 拷贝 模板 zoo_sample.cfg 为 zoo.cfg
[root@hadoop1 conf]# cp zoo_sample.cfg zoo.cfg

# 进入修改配置文件
[root@hadoop1 conf]# vim zoo.cfg
  • 需要修改内容:
    • 数据目录调整,需要提取创建
      dataDir=/usr/local/data/zookeeper/zkdata
    • 日志目录调整,需要提取创建
      dataLogDir=/usr/local/data/zookeeper/zkdatalog
    • 访问端口号
      clientPort=2181
    • server. 每个节点服务编号=服务器ip地址(或主机名):集群通信端口:选举端口
      server.1=hadoop1:2888.3888
      server.2=hadoop2:2888.3888
      server.3=hadoop3:2888.3888

备注:如果有四台zookeeper的话,由于非observer节点数必须为奇数个

  • 所以如果有第四台的话,可以使用如下添加方式:
  • server.4=xx.xx.xx.xx:2888:3888:observer
  • id是自己定义的,0~255间,不必一次递增,自己定即可,id表示该节点所持有的投票编号id,必需保证全局唯一
  • 不要在配置后面加注释#,这会导致cfg文件解析失败!从而导致zookeeper无法正常启动!
  • 将 /usr/local/zookeeper-3.8.4 修改后的文件批量分发给 hadoop2 和 hadoop3
bash 复制代码
[root@hadoop1 local]# deploy.sh zookeeper-3.8.4 /usr/local/ slave

4.3.4 创建各节点服务编号

分别在 Zookeeper 集群各个节点,进入/usr/local/zookeeper/data/zkdata目录,创建文件 myid,然后分别输入服务编号,具体操作如下所示:

bash 复制代码
# hadoop1 节点
[root@hadoop1 zkdata]# touch /usr/local/zookeeper/data/zkdata/myid
[root@hadoop1 zkdata]# echo 1 > myid

# hadoop2 节点
[root@hadoop1 zkdata]# touch /usr/local/zookeeper/data/zkdata/myid
[root@hadoop1 zkdata]# echo 2 > myid

# hadoop3 节点
[root@hadoop1 zkdata]# touch /usr/local/zookeeper/data/zkdata/myid
[root@hadoop1 zkdata]# echo 3 > myid

4.4 启动 ZooKeeper 集群服务

在集群各个节点分别进入zookeeper安装目录,然后使用如下命令启动 Zookeeper 服务。

bash 复制代码
# 批量启动 ZooKeeper 集群服务
[root@hadoop1 zkdata]# runRemoteCmd.sh "/usr/local/zookeeper/bin/zkServer.sh start" all

# 批量查看 ZooKeeper 集群服务状态
[root@hadoop1 zookeeper]# runRemoteCmd.sh "/usr/local/zookeeper/bin/zkServer.sh status" all

五、在配置过程的一些问题总结

5.1 启动单个节点zookeeper正常,启动集群失败,并提示如下:

此报错提示,我也被卡住很久,网上找了各种办法都不行,后面发现把配置文件 zoo.cfg的 三个主机名分别更换位相应的IP地址,集群启动正常

然后就验证了配置没有问题,就是三台服务器之间的相互访问问题,然后使用命令 ssh hadpoopX (X 代表另外两条服务器编号) 分别到三台服务器相互访问,当出现提示,全部输入 yes ,让后再把 配置文件 zoo.cfg 改为对应主机名称就正常了

也就是刚配置好的服务器,要让他们之间互相允许访问

相关推荐
code在飞18 小时前
windows 部署 Kafka3.x KRaft 模式 不依赖 ZooKeeper
windows·分布式·zookeeper·kafka
不会飞的鲨鱼19 小时前
Windows系统下使用Kafka和Zookeeper,Python运行kafka(二)
windows·zookeeper·kafka
搞不懂语言的程序员1 天前
Kafka Controller的作用是什么?故障时如何恢复? (管理分区和副本状态;通过ZooKeeper选举新Controller)
分布式·zookeeper·kafka
giser@20112 天前
Zookeeper单机版安装部署
分布式·zookeeper·安装教程·单机部署
giser@20113 天前
ZooKeeper工作机制与应用场景
分布式·zookeeper·云原生
搞不懂语言的程序员4 天前
Kafka的核心组件有哪些?简要说明其作用。 (Producer、Consumer、Broker、Topic、Partition、ZooKeeper)
分布式·zookeeper·kafka
程序员buddha5 天前
SpringBoot+Dubbo+Zookeeper实现分布式系统步骤
分布式·zookeeper·dubbo·springboot
佳腾_12 天前
【分布式系统中的“瑞士军刀”_ Zookeeper】二、Zookeeper 核心功能深度剖析与技术实现细节
分布式·zookeeper·云原生·集群管理·命名服务
佳腾_13 天前
【分布式系统中的“瑞士军刀”_ Zookeeper】三、Zookeeper 在实际项目中的应用场景与案例分析
分布式·zookeeper·云原生
慧一居士15 天前
Zookeeper HA集群搭建
分布式·zookeeper