kafka+zookeeper高可用集群搭建shell脚本使用教程

Source

kafka+zookeeper高可用集群搭建shell脚本使用教程

前言

Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎,web/nginx日志、访问日志,消息服务等等,用scala语言编写,Linkedin于2010年贡献给了Apache基金会并成为顶级开源 项目。

一、准备工作

1、环境准备

kafka-zookeeper-1虚拟机 :192.168.25.81

kafka-zookeeper-2虚拟机 :192.168.25.82

kafka-zookeeper-3虚拟机 :192.168.25.83

2、安装3个CentOS7

3、配置服务器以上的ip地址

// 修改network文件,不同机器的文件名不一样,但都是ifcfg-开头
vi /etc/sysconfig/network-scripts/ifcfg-xxxxx

// 修改一下参数
BOOTPROTO=static
IPADDR=xxxxxxx // 如kafka-zookeeper-1虚拟机 IPADDR="192.168.25.81"
GATEWAY=xxxxxx // 网关         GATEWAY="192.168.25.2"
NETMASK="255.255.255.0"
DNS1="114.114.114.114"
ZONE=public
ONBOOT=yes

保存退出
重启网络
systemctl restart network

二、运行脚本

1、3个节点zookeeper服务器启动

一、zookeeper_1.sh

#!/bin/bash
#linux基本软件和jdk1.8+zookeeper_1高可用集群安装脚本

echo "开始安装vim"
rpm -qa|grep vim
yum -y install vim*
echo "vim安装完毕"

echo "安装telnet和xinetd和设置开机启动"
rpm -qa telnet-server
rpm -qa xinetd
yum list |grep telnet
yum -y install telnet-server.x86_64
yum -y install telnet.x86_64
yum list |grep xinetd
yum -y install xinetd.x86_64
systemctl enable xinetd.service
systemctl enable telnet.socket
echo "telnet和xinetd和设置开机启动安装完毕"

echo "开启telnet和xinetd的service"
systemctl start telnet.socket
systemctl start xinetd
echo "开启telnet和xinetd的service完毕"

echo "开启防火墙端口"
firewall-cmd --zone=public --add-port=23/tcp --permanent
firewall-cmd --reload
echo "开启防火墙端口完毕"

echo "安装net工具包"
x=`rpm -qa | grep net-tools`
if [ `rpm -qa | grep net-tools |wc -l` -ne 0 ];then
echo "net-tools已存在"
else
yum install -y net-tools
fi
echo "安装net工具包完毕"

echo "安装wget"
x=`rpm -qa | grep wget`
if [ `rpm -qa | grep wget |wc -l` -ne 0 ];then
echo "wget已存在"
else
yum -y install wget
fi
x=`rpm -qa | grep setup`
if [ `rpm -qa | grep setup |wc -l` -ne 0 ];then
echo "setup已存在"
else
yum -y install setup
fi
x=`rpm -qa | grep perl`
if [ `rpm -qa | grep perl |wc -l` -ne 0 ];then
echo "perl已存在"
else
yum -y install perl
fi
echo "安装wget成功"

echo "安装ntp时间同步"
rpm -qa|grep ntp
yum install -y ntp
echo "安装ntp时间同步完毕"
echo "设开机启动ntp时间同步"
systemctl start ntpd.service
systemctl enable ntpd.service
echo "设开机启动ntp时间同步完毕"

echo "开始安装jdk1.8"
echo "下载jdk"
x=`rpm -qa | grep jdk`
if [ `rpm -qa | grep jdk |wc -l` -ne 0 ];then
echo "jdk1.8已存在"
else
yum install java-1.8.0-openjdk* -y
fi
echo "
# /usr/share/doc/setup-*/uidgid file
if [ \$UID -gt 199 ] && [ \"\`/usr/bin/id -gn\`\" = \"\`/usr/bin/id -un\`\" ]; then
    umask 002
else
    umask 022
fi          

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r \"\$i\" ]; then      
        if [ \"\${-#*i}\" != \"\$-\" ]; then
            . \"\$i\"
        else  
            . \"\$i\" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64
export JRE_HOME=\${JAVA_HOME}/jre
export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib
export PATH=\${JAVA_HOME}/bin:\$PATH 
" > /etc/profile
echo "安装jdk1.8完毕"


echo "开始安装Zookeeper集群搭建"
cd /opt
wget https://archive.apache.org/dist/zookeeper/stable/zookeeper-3.4.10.tar.gz
tar zxvf zookeeper-3.4.10.tar.gz

echo "创建/opt/zookeeper-3.4.10/conf/zoo.cfg"
echo "开始编辑/opt/zookeeper-3.4.10/conf/zoo.cfg"
echo "
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/root/zookeeper/data
    dataLogDir=/root/zookeeper/logs
    clientPort=2181
    server.1=$1:2888:3888
    server.2=$2:2888:3888
    server.3=$3:2888:3888
" > /opt/zookeeper-3.4.10/conf/zoo.cfg
echo "编辑/opt/zookeeper-3.4.10/conf/zoo.cfg完毕"

echo "创建/root/zookeeper/data/myid"
cd /root
mkdir zookeeper
cd zookeeper
mkdir data
echo "1" > /root/zookeeper/data/myid
echo "创建/root/zookeeper/data/myid完毕"

echo "开启防火墙端口"
firewall-cmd --zone=public --add-port=2181/tcp --permanent
firewall-cmd --zone=public --add-port=2888/tcp --permanent
firewall-cmd --zone=public --add-port=3888/tcp --permanent
firewall-cmd --zone=public --add-port=9092/tcp --permanent
firewall-cmd --reload
echo "开启防火墙端口成功"

echo "启动zookeeper"
cd /opt/zookeeper-3.4.10/bin/
./zkServer.sh start
echo "zookeeper启动成功"

说明:

1、dataDir 和 dataLogDir 需要在启动前创建完成

2、clientPort 为 zookeeper的服务端口

3、server.0、server.1、server.2 为 zk 集群中三个 node 的信息,定义格式hostname:port1:port2,其中 port1 是 node 间通信使用的端口,port2 是node 选举使用的端口,需确保三台主机的这两个端口都是互通的

4、在第一台节点1主机上建立的 myid 文件内容是 1,第二台节点2主机上建立的myid文件内容是 2,第三台节点3主机上建立的myid文件内容是 3。myid文件内容需要与/opt/zookeeper-3.4.10/conf/zoo.cfg中的配置的server.id的编号对应。
  • 把zookeeper_1.sh上传到节点1虚拟机/home目录下,用以下命令执行脚本权限

    • cd /home
    • chmod 777 ./*.sh
  • 执行脚本命令

    • ./zookeeper_1.sh 节点1虚拟机ip地址 节点2虚拟机ip地址 节点3虚拟机ip地址
    • ./zookeeper_1.sh 192.168.25.81 192.168.25.82 192.168.25.83

    参数说明 :

      ip地址 :zookeeper集群3个节点的ip地址
    

打开cd /opt/zookeeper-3.4.10/conf/zoo.cfg 检查

输入jpa命令,zookeeper启动成功

二、zookeeper_2.sh

#!/bin/bash
#linux基本软件和jdk1.8+zookeeper_2高可用集群安装脚本

echo "开始安装vim"
rpm -qa|grep vim
yum -y install vim*
echo "vim安装完毕"

echo "安装telnet和xinetd和设置开机启动"
rpm -qa telnet-server
rpm -qa xinetd
yum list |grep telnet
yum -y install telnet-server.x86_64
yum -y install telnet.x86_64
yum list |grep xinetd
yum -y install xinetd.x86_64
systemctl enable xinetd.service
systemctl enable telnet.socket
echo "telnet和xinetd和设置开机启动安装完毕"

echo "开启telnet和xinetd的service"
systemctl start telnet.socket
systemctl start xinetd
echo "开启telnet和xinetd的service完毕"

echo "开启防火墙端口"
firewall-cmd --zone=public --add-port=23/tcp --permanent
firewall-cmd --reload
echo "开启防火墙端口完毕"

echo "安装net工具包"
x=`rpm -qa | grep net-tools`
if [ `rpm -qa | grep net-tools |wc -l` -ne 0 ];then
echo "net-tools已存在"
else
yum install -y net-tools
fi
echo "安装net工具包完毕"

echo "安装wget"
x=`rpm -qa | grep wget`
if [ `rpm -qa | grep wget |wc -l` -ne 0 ];then
echo "wget已存在"
else
yum -y install wget
fi
x=`rpm -qa | grep setup`
if [ `rpm -qa | grep setup |wc -l` -ne 0 ];then
echo "setup已存在"
else
yum -y install setup
fi
x=`rpm -qa | grep perl`
if [ `rpm -qa | grep perl |wc -l` -ne 0 ];then
echo "perl已存在"
else
yum -y install perl
fi
echo "安装wget成功"

echo "安装ntp时间同步"
rpm -qa|grep ntp
yum install -y ntp
echo "安装ntp时间同步完毕"
echo "设开机启动ntp时间同步"
systemctl start ntpd.service
systemctl enable ntpd.service
echo "设开机启动ntp时间同步完毕"

echo "开始安装jdk1.8"
echo "下载jdk"
x=`rpm -qa | grep jdk`
if [ `rpm -qa | grep jdk |wc -l` -ne 0 ];then
echo "jdk1.8已存在"
else
yum install java-1.8.0-openjdk* -y
fi
echo "
# /usr/share/doc/setup-*/uidgid file
if [ \$UID -gt 199 ] && [ \"\`/usr/bin/id -gn\`\" = \"\`/usr/bin/id -un\`\" ]; then
    umask 002
else
    umask 022
fi          

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r \"\$i\" ]; then      
        if [ \"\${-#*i}\" != \"\$-\" ]; then
            . \"\$i\"
        else  
            . \"\$i\" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64
export JRE_HOME=\${JAVA_HOME}/jre
export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib
export PATH=\${JAVA_HOME}/bin:\$PATH 
" > /etc/profile
echo "安装jdk1.8完毕"


echo "开始安装Zookeeper集群搭建"
cd /opt
wget https://archive.apache.org/dist/zookeeper/stable/zookeeper-3.4.10.tar.gz
tar zxvf zookeeper-3.4.10.tar.gz

echo "创建/opt/zookeeper-3.4.10/conf/zoo.cfg"
echo "开始编辑/opt/zookeeper-3.4.10/conf/zoo.cfg"
echo "
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/root/zookeeper/data
dataLogDir=/root/zookeeper/logs
clientPort=2181
server.1=$1:2888:3888
server.2=$2:2888:3888
server.3=$3:2888:3888
" > /opt/zookeeper-3.4.10/conf/zoo.cfg
echo "编辑/opt/zookeeper-3.4.10/conf/zoo.cfg完毕"

echo "创建/root/zookeeper/data/myid"
cd /root
mkdir zookeeper
cd zookeeper
mkdir data
echo "2" > /root/zookeeper/data/myid
echo "创建/root/zookeeper/data/myid完毕"


echo "开启防火墙端口"
firewall-cmd --zone=public --add-port=2181/tcp --permanent
firewall-cmd --zone=public --add-port=2888/tcp --permanent
firewall-cmd --zone=public --add-port=3888/tcp --permanent
firewall-cmd --zone=public --add-port=9092/tcp --permanent
firewall-cmd --reload
echo "开启防火墙端口成功"


echo "启动zookeeper"
cd /opt/zookeeper-3.4.10/bin/
./zkServer.sh start
echo "zookeeper启动成功"

三、zookeeper_3.sh

#!/bin/bash
#linux基本软件和jdk1.8+zookeeper_3高可用集群安装脚本

echo "开始安装vim"
rpm -qa|grep vim
yum -y install vim*
echo "vim安装完毕"

echo "安装telnet和xinetd和设置开机启动"
rpm -qa telnet-server
rpm -qa xinetd
yum list |grep telnet
yum -y install telnet-server.x86_64
yum -y install telnet.x86_64
yum list |grep xinetd
yum -y install xinetd.x86_64
systemctl enable xinetd.service
systemctl enable telnet.socket
echo "telnet和xinetd和设置开机启动安装完毕"

echo "开启telnet和xinetd的service"
systemctl start telnet.socket
systemctl start xinetd
echo "开启telnet和xinetd的service完毕"

echo "开启防火墙端口"
firewall-cmd --zone=public --add-port=23/tcp --permanent
firewall-cmd --reload
echo "开启防火墙端口完毕"

echo "安装net工具包"
x=`rpm -qa | grep net-tools`
if [ `rpm -qa | grep net-tools |wc -l` -ne 0 ];then
echo "net-tools已存在"
else
yum install -y net-tools
fi
echo "安装net工具包完毕"

echo "安装wget"
x=`rpm -qa | grep wget`
if [ `rpm -qa | grep wget |wc -l` -ne 0 ];then
echo "wget已存在"
else
yum -y install wget
fi
x=`rpm -qa | grep setup`
if [ `rpm -qa | grep setup |wc -l` -ne 0 ];then
echo "setup已存在"
else
yum -y install setup
fi
x=`rpm -qa | grep perl`
if [ `rpm -qa | grep perl |wc -l` -ne 0 ];then
echo "perl已存在"
else
yum -y install perl
fi
echo "安装wget成功"

echo "安装ntp时间同步"
rpm -qa|grep ntp
yum install -y ntp
echo "安装ntp时间同步完毕"
echo "设开机启动ntp时间同步"
systemctl start ntpd.service
systemctl enable ntpd.service
echo "设开机启动ntp时间同步完毕"


echo "开始安装jdk1.8"
echo "下载jdk"
x=`rpm -qa | grep jdk`
if [ `rpm -qa | grep jdk |wc -l` -ne 0 ];then
echo "jdk1.8已存在"
else
yum install java-1.8.0-openjdk* -y
fi
echo "
# /usr/share/doc/setup-*/uidgid file
if [ \$UID -gt 199 ] && [ \"\`/usr/bin/id -gn\`\" = \"\`/usr/bin/id -un\`\" ]; then
    umask 002
else
    umask 022
fi          

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r \"\$i\" ]; then      
        if [ \"\${-#*i}\" != \"\$-\" ]; then
            . \"\$i\"
        else  
            . \"\$i\" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-1.el7_6.x86_64
export JRE_HOME=\${JAVA_HOME}/jre
export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib
export PATH=\${JAVA_HOME}/bin:\$PATH 
" > /etc/profile
echo "安装jdk1.8完毕"


echo "开始安装Zookeeper集群搭建"
cd /opt
wget https://archive.apache.org/dist/zookeeper/stable/zookeeper-3.4.10.tar.gz
tar zxvf zookeeper-3.4.10.tar.gz

echo "创建/opt/zookeeper-3.4.10/conf/zoo.cfg"
echo "开始编辑/opt/zookeeper-3.4.10/conf/zoo.cfg"
echo "
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/root/zookeeper/data
    dataLogDir=/root/zookeeper/logs
    clientPort=2181
        server.1=$1:2888:3888
    server.2=$2:2888:3888
    server.3=$3:2888:3888
" > /opt/zookeeper-3.4.10/conf/zoo.cfg
echo "编辑/opt/zookeeper-3.4.10/conf/zoo.cfg完毕"

echo "创建/root/zookeeper/data/myid"
cd /root
mkdir zookeeper
cd zookeeper
mkdir data
echo "3" > /root/zookeeper/data/myid
echo "创建/root/zookeeper/data/myid完毕"


echo "开启防火墙端口"
firewall-cmd --zone=public --add-port=2181/tcp --permanent
firewall-cmd --zone=public --add-port=2888/tcp --permanent
firewall-cmd --zone=public --add-port=3888/tcp --permanent
firewall-cmd --zone=public --add-port=9092/tcp --permanent
firewall-cmd --reload
echo "开启防火墙端口成功"


echo "启动zookeeper"
cd /opt/zookeeper-3.4.10/bin/
./zkServer.sh start
echo "zookeeper启动成功"

  • 把zookeeper_2.sh和zookeeper_3.sh上传到节点2虚拟机、虚拟机节点3的/home目录下,同样执行以上命令,把三台zookeeper服务启动起来

    • ./zookeeper_2.sh 192.168.25.81 192.168.25.82 192.168.25.83
    • ./zookeeper_3.sh 192.168.25.81 192.168.25.82 192.168.25.83

测试

cd /opt/zookeeper-3.4.10/bin/
./zkServer.sh status

把192.168.25.83节点的leader服务停掉

./zkServer.sh stop

可以看出192.168.25.82节点的变成leader服务

再开启192.168.25.83节点的服务,发现变成follower

./zkServer.sh start

如果提示Starting zookeeper … already running as process ……,表示之前有启动过zookeeper,但是没有正常关闭。 进入和bin同层级的data目录下,删除zookeeper_server.pid文件,再执行启动命令。

2、3个节点kafka服务器启动

一、kafka_zookeeper_1.sh

#!/bin/bash
#kafka+zookeeper_1高可用集群安装脚本

echo "开始Kafka 集群搭建"
cd /opt
wget http://apache.01link.hk/kafka/2.0.0/kafka_2.11-2.0.0.tgz
tar zxvf kafka_2.11-2.0.0.tgz
mv kafka_2.11-2.0.0 kafka
mkdir /root/kafka
mkdir /root/kafka/logs/
echo "开始编辑/opt/kafka/config/server.properties"
echo "
broker.id=1
listeners=PLAINTEXT://:9092
port=9092
host.name=$1
advertised.host.name=$2
advertised.port=9092
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/root/kafka/logs
num.partitions=1
num.recovery.threads.per.data.dir=1
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000  
zookeeper.connect=$3:2181,$4:2181,$5:2181
zookeeper.connection.timeout.ms=6000
" > /opt/kafka/config/server.properties
echo "编辑/opt/kafka/config/server.properties完毕"

echo "启动kafka"
cd /opt/kafka
bin/kafka-server-start.sh config/server.properties &
echo "kafka启动成功"

注意!!!:

每个节点的broker.id不一样,不然会有冲突

按照官方文档的说法,advertised.host.name 和 advertised.port 这两个参数用于定义集群向 Producer 和 Consumer 广播的节点 host 和 port,如果不定义,会默认使用 host.name 和 port 的定义。但在实际应用中,发现如果不定义 advertised.host.name 参数,使用 Java 客户端从远端连接集群时,会发生连接超时,抛出异常:org.apache.kafka.common.errors.TimeoutException: Batch Expired

经过过 debug 发现,连接到集群是成功的,但连接到集群后更新回来的集群 meta 信息却是错误的。metadata 中的 Cluster 信息中节点的 hostname 是一串字符,而不是实际的ip地址。这串其实是远端主机的 hostname,这说明在没有配置 advertised.host.name 的情况下,Kafka 并没有像官方文档宣称的那样改为广播我们配置的 host.name,而是广播了主机配置的 hostname 。远端的客户端并没有配置 hosts,所以自然是连接不上这个 hostname 的。要解决这一问题,把 host.name 和 advertised.host.name 都配置成绝对的 ip 地址就可以了。

  • 一、把kafka_zookeeper_1.sh上传到节点1虚拟机/home目录下,用以下命令执行脚本权限

    • cd /home
    • chmod 777 ./*.sh
  • 执行脚本命令

    • ./kafka_zookeeper_1.sh host.name advertised.host.name 节点1虚拟机ip地址 节点2虚拟机ip地址 节点3虚拟机ip地址
    • ./kafka_zookeeper_1.sh 192.168.25.81 192.168.25.81 192.168.25.81 192.168.25.82 192.168.25.83

    参数说明 :

      host.name :节点1虚拟机ip地址
      advertised.host.name :节点1虚拟机ip地址
    

  • 二、把kafka_zookeeper_2.sh上传到节点2虚拟机/home目录下,用以下命令执行脚本权限

    • cd /home
    • chmod 777 ./*.sh
  • 执行脚本命令

    • ./kafka_zookeeper_2.sh host.name advertised.host.name 节点1虚拟机ip地址 节点2虚拟机ip地址 节点3虚拟机ip地址
    • ./kafka_zookeeper_2.sh 192.168.25.82 192.168.25.82 192.168.25.81 192.168.25.82 192.168.25.83

    参数说明 :

      host.name :节点2虚拟机ip地址
      advertised.host.name :节点2虚拟机ip地址
    

  • 三、把kafka_zookeeper_3.sh上传到节点3虚拟机/home目录下,用以下命令执行脚本权限

    • cd /home
    • chmod 777 ./*.sh
  • 执行脚本命令

    • ./kafka_zookeeper_3.sh host.name advertised.host.name 节点1虚拟机ip地址 节点2虚拟机ip地址 节点3虚拟机ip地址
    • ./kafka_zookeeper_3.sh 192.168.25.83 192.168.25.83 192.168.25.81 192.168.25.82 192.168.25.83

    参数说明 :

      host.name :节点3虚拟机ip地址
      advertised.host.name :节点3虚拟机ip地址
    

  • 四、测试

在节点1创建test的topic

cd /opt/kafka
bin/kafka-topics.sh --create --zookeeper 192.168.25.81:2181,192.168.25.82:2181,192.168.25.83:2181 --replication-factor 3 --partitions 3 --topic test

查看topic信息

cd /opt/kafka
bin/kafka-topics.sh --describe --zookeeper 192.168.25.81:2181,192.168.25.82:2181,192.168.25.83:2181 --topic test

创建生产者,并输入信息

cd /opt/kafka
bin/kafka-console-producer.sh --broker-list 192.168.25.81:9092 -topic test

在节点2查看节点3消费者信息,也可以自己分别测试

bin/kafka-console-consumer.sh --bootstrap-server 192.168.25.83:9092 --topic test --from-beginning

继续输入

继续输出