【运维知识大神篇】超详细的ELFK日志分析教程9(zookeeper集群部署+使用+leader选举流程+zab协议写入原理+kafka集群部署+zabbix监控zookeeper、kafka集群)

目录

部署zookeeper单点

部署zookeeper集群

zookeeper的leader选举流程

一、前情提要

二、选举流程

zookeeper基于zab协议写入数据原理

一、前期提要

二、写入流程

zookeeper客户常用命令

一、连接客户端

二、zookeeper的基本使用

使用zkWeb.jar来管理ZK集群

KAFKA单点部署

KAFKA集群部署

扩展

一、zabbix监控zookeeper、kafka集群

二、Loki+Grafana


当我们的数据足够多时,我们需要用到kafka的消息队列进行缓冲,消息队列优势有很多,例如可以削峰填谷,指流量图相对于不使用消息队列流量的流入比较平缓,减少服务器压力;还有应用解耦,当我们一部分产品功能出问题时,其他功能不会有影响;还有异步提速,我们之前发送请求给解耦服务器可能需要200毫秒,但是我们发送给mq(消息队列)可能需要50毫秒,解耦服务器提前将数据存储在消息队列中,这样用户获取数据会更快,提升了用户体验。

Kafka 是一个分布式消息系统,ZooKeeper则是分布式应用程序的协调服务。Kafka 需要借助 ZooKeeper 来完成 Kafka broker 的注册、配置管理、选举(例如 Kafka 具有主从复制能力),以及集群内的各种协调与控制。在 Kafka 中,每个 Broker 在启动时需要向 ZooKeeper 注册自己的 IP 地址、端口、副本信息等元数据信息,并且将其最新的元数据缓存在 Zookeeper。消费者使用 ZooKeeper 来发现和识别可用的 Broker,生产者利用 ZooKeeper 来发现可以接收新消息的 Broker。同时,Kafka 在多数情况下也依赖于 ZooKeeper 来处理请求路由、Topic 状态监测等功能。可以说,ZooKeeper 是 Kafka 集群中必不可少的组成部分,两者相辅相成,共同形成具有高度弹性和容错性的系统架构,我们先来介绍zookeeper。

部署zookeeper单点

1、下载zookeeper,因为之前在zookeeper部署了免密钥,所以我们在ELK103先单点部署,再用脚本同步到其他节点实现集群部署

[root@ELK103 ~]# wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.1/apache-zookeeper-3.8.1-bin.tar.gz --no-check-certificate

2、解压软件包

[root@ELK103 ~]# tar xf apache-zookeeper-3.8.1-bin.tar.gz -C /koten/softwares/

3、配置环境变量,方便调用

[root@ELK103 ~]# cat /etc/profile.d/zk.sh
#!/bin/bash

export ZK_HOME=/koten/softwares/apache-zookeeper-3.8.1-bin
export PATH=$PATH:$ZK_HOME/bin
[root@ELK103 ~]# source /etc/profile.d/zk.sh 

4、创建配置文件

[root@ELK103 ~]# cp /koten/softwares/apache-zookeeper-3.8.1-bin/conf/{zoo_sample,zoo}.cfg

5、启动zookeeper服务

此时如果有jdk的话就会启动,没有的话会提示找不到JAVA_HOME,在上面环境变量里面配置下即可。

[root@ELK103 ~]# zkServer.sh start     #启动zookeeper
ZooKeeper JMX enabled by default
Using config: /koten/softwares/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@ELK103 ~]# zkServer.sh status    #查看zookeeper
ZooKeeper JMX enabled by default
Using config: /koten/softwares/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone
[root@ELK103 ~]# zkServer.sh stop      #停止zookeeper
ZooKeeper JMX enabled by default
Using config: /koten/softwares/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
[root@ELK103 ~]# zkServer.sh restart   #重启zookeeper
ZooKeeper JMX enabled by default
Using config: /koten/softwares/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfg
ZooKeeper JMX enabled by default
Using config: /koten/softwares/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfg
Stopping zookeeper ... no zookeeper to stop (could not find file /tmp/zookeeper/zookeeper_server.pid)
ZooKeeper JMX enabled by default
Using config: /koten/softwares/apache-zookeeper-3.8.1-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

6、确定zookeeper服务后,测试zookeeper服务是否可用

[root@ELK103 ~]# zkCli.sh 
......
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 1] 

部署zookeeper集群

1、创建配置文件

[root@ELK103 ~]# cat > /koten/softwares/apache-zookeeper-3.8.1-bin/conf/zoo.cfg <<EOF
# 定义最小单元的时间范围tick。
tickTime=2000
# 启动时最长等待tick数量。
initLimit=5
# 数据同步时最长等待的tick时间进行响应ACK
syncLimit=2
# 指定数据目录
dataDir=/koten/data/zk
# 监听端口
clientPort=2181
# 开启四字命令允许所有的节点访问。
4lw.commands.whitelist=*
# server.ID=A:B:C[:D]
# ID:
#    zk的唯一编号。
# A:
#    zk的主机地址。
# B:
#    leader的选举端口,是谁leader角色,就会监听该端口。
# C: 
#    数据通信端口。
# D:
#    可选配置,指定角色。
server.101=10.0.0.101:2888:3888
server.102=10.0.0.102:2888:3888
server.103=10.0.0.103:2888:3888
EOF

2、同步zookeeper软件包及目录结构

[root@ELK103 ~]# mkdir /koten/data/zk
[root@ELK103 ~]# data_rsync.sh /koten/softwares/apache-zookeeper-3.8.1-bin/
===== rsyncing elk101: apache-zookeeper-3.8.1-bin =====
命令执行成功!
===== rsyncing elk102: apache-zookeeper-3.8.1-bin =====
命令执行成功!
[root@ELK103 ~]# data_rsync.sh /koten/data/zk
===== rsyncing elk101: zk =====
命令执行成功!
===== rsyncing elk102: zk =====
命令执行成功!
[root@ELK103 ~]# data_rsync.sh /etc/profile.d/zk.sh 
===== rsyncing elk101: zk.sh =====
命令执行成功!
===== rsyncing elk102: zk.sh =====
命令执行成功!
[root@ELK103 ~]# for ((host_id=101;host_id<=103;host_id++)) do ssh elk${host_id} "source /etc/profile.d/zk.sh";done    #执行环境变量的脚本,后面管理脚本中仍需要source

3、每个zookeeper节点创建唯一标识ID

[root@ELK103 ~]# for ((host_id=101;host_id<=103;host_id++)) do ssh elk${host_id} "echo ${host_id} > /koten/data/zk/myid";done

4、编写zookeeper集群管理脚本

[root@ELK103 ~]# cat /usr/local/sbin/manager_zk.sh
#!/bin/bash

#判断用户是否传参
if [ $# -ne 1 ];then
    echo "无效参数,用法为: $0  {start|stop|restart|status}"
    exit
fi

#获取用户输入的命令
cmd=$1

#定义函数功能
function zookeeperManger(){
    case $cmd in
    start)
        echo "启动服务"        
        remoteExecution start
        ;;
    stop)
        echo "停止服务"
        remoteExecution stop
        ;;
    restart)
        echo "重启服务"
        remoteExecution restart
        ;;
    status)
        echo "查看状态"
        remoteExecution status
        ;;
    *)
        echo "无效参数,用法为: $0  {start|stop|restart|status}"
        ;;
    esac
}


#定义执行的命令
function remoteExecution(){
    for (( i=101 ; i<=103 ; i++ )) ; do
            tput setaf 2
            echo ========== elk${i} zkServer.sh  $1 ================
            tput setaf 9
            ssh elk${i}  "source /etc/profile.d/zk.sh; zkServer.sh $1 2>/dev/null" #这里注意需要先source,我理解的是因为ssh会进入不同的shell环境
    done
}

#调用函数
zookeeperManger
[root@ELK103 ~]# chmod +x /usr/local/sbin/manager_zk.sh

5、启动zookeeper集群

[root@ELK103 ~]# manager_zk.sh start
启动服务
========== elk101 zkServer.sh start ================
Starting zookeeper ... STARTED
========== elk102 zkServer.sh start ================
Starting zookeeper ... STARTED
========== elk103 zkServer.sh start ================
Starting zookeeper ... STARTED 

6、查看集群状态

注意查看Mode是否有standalone,有的话检查脚本是否有问题,用脚本都停掉后检查那个主机是否还占用端口没有真正停掉

[root@ELK103 ~]# manager_zk.sh status
查看状态
========== elk101 zkServer.sh status ================
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
========== elk102 zkServer.sh status ================
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader
========== elk103 zkServer.sh status ================
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
[root@ELK103 ~]# ss -ntl|grep 2181
LISTEN     0      50        [::]:2181                  [::]:*       

zookeeper的leader选举流程

一、前情提要

上面我们可以看到,我们的集群启动脚本的时候,elk102成为了leader,这其实并不是随机的,是有一定的原理的,我们需要先了解两个概念,一个是myid,表示当前zookeeper server的server id,用于当前服务器的唯一标识,另一个是zxid,表示zookeeper transaction id,即zookeeper集群事务id,我们一开始集群部署,事务id肯定都为0,那么我们选举都是根据myid来选

二、选举流程

1、脚本是串行启动,启动elk101和elk102这两个节点,先检查有没有Leader 节点,如果 Leader 已经存在,那么这些节点会进入 following 状态。没有的话,两个节点进入looking状态

2、若没有leader角色,elk101和elk102这两个节点会投自己一票,此时elk101节点启动zk服务,开始发起投票,此时myid为101,zxid为0,elk102节点启动zk服务,开始发起投票,此时myid为102,zxid为0

3、两个节点接收彼此的投票信息,进行对比;首先会检查zxid,即事务id,谁的zxid较大谁会优先称为leader;如果zxid相同,则会比较myid,较大的myid作为leader服务器。一旦确定leader角色,此时leader服务器状态变更为leading,没有leader角色的节点主懂变为following

4、elk节点启动,检查有没有leader,发现集群leader在上一步已经存在,所以主动变更为following状态,elk103也变成follower

5、集群半数以上的节点投票完毕就已经确定了leader角色,无需全票通过

zookeeper基于zab协议写入数据原理

一、前期提要

zookeeper的leader与follower有点类似于ES的主分片与副本分片,都有半数以上投票机制,leader接收到写的请求,follower会跟着一起写,半数以上写入成功就算写入成功,leader有读写权限,follower是只读权限

zookeeper原子广播原理,即Zookeeper Atomic Broadcast(简称ZAB)

zookeeper是通过zab协议来保证分布式事务的最终一致性

二、写入流程

1、客户端对follower节点发起写操作

2、follower节点将请求转发给leader

3、leader生成一个新的事务并为这个事务生成一个分布式唯一ZXID,leader将这个事务提议(propose)发送给所有的followers节点

4、所有的follower角色开始写入数据,并将响应的结果返回给leader,即响应ACK

5、leader节点收到ACK后,需要当前集群半数以上的ACK写入成功,即提交本次事务

6、数据写入成功则响应客户端

zookeeper客户常用命令

一、连接客户端

zkCli.sh        连接本地

zkCli.sh -server elk101:2181        连接指定节点

zkCli.sh -server elk101:2181,elk102:2181,elk103:2181        连接集群

二、zookeeper的基本使用

掌握增删改查即可

[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 0] create /linux
Created /linux     #在/下创建linux的znode,类似于linux系统的目录
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 1] create /school koten
Created /school    #创建/school的同时写入koten的数据
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 2] create /school/class linux
Created /school/class    #在/shool下创建一个名为class的znode,znode为永久节点
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 3] create -s /school/class 123
Created /school/class0000000001    #创建/school/class,由于节点存在,所以自动在后面生成数值,-s表示创建的节点序列化且唯一
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 13] create -e /linshi 123
Created /linshi    #-e参数表示创建临时节点

[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 5] ls /   #查看/路径下有多少个znode 
[linux, school, zookeeper]
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 6] get /linux    #查看/linux是否有数据
null
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 7] get /school   
koten
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 8] stat /school    #查看/school的znode状态信息
cZxid = 0x800000005
ctime = Sun Jun 04 10:30:03 CST 2023
mZxid = 0x800000005
mtime = Sun Jun 04 10:30:03 CST 2023
pZxid = 0x800000007
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0    #0x0表示znode为永久节点
dataLength = 5
numChildren = 2
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 15] stat /linshi
cZxid = 0x800000009
ctime = Sun Jun 04 10:46:04 CST 2023
mZxid = 0x800000009
mtime = Sun Jun 04 10:46:04 CST 2023
pZxid = 0x800000009
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x6500067fbda70001    #0x...表示znode为临时节点
dataLength = 3
numChildren = 0

[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 11] set /linux 123    #修改/linux的znode数据
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 12] get /linux 
123

[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 16] delete /linux    #删除/linux的znode
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 17] deleteall /school    #递归删除/school下所有的znode数据
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 18] ls /
[linshi, zookeeper]

使用zkWeb.jar来管理ZK集群

1、下载zkWeb.jar(链接放在文末)

2、运行jar包

[root@ELK101 ~]# nohup java -jar zkWeb-v1.2.1.jar &>/tmp/zkWeb.log &

.jar  ---> java -jar 直接启动
.war  ---> 借助tomcat工具进行解压后使用。

3、浏览器访问10.0.0.101:8099,zkWeb软件默认端口是8099

点击上面节点,可以看到我们的节点树,中间显示可以添加内容保存,右边显示状态

添加节点,保存数据为123

可以看到与命令行中的一致 

[root@ELK103 ~]# zkCli.sh -server elk101:2181,elk102:2181,elk103:2181 
......
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 0] ls /
[linux666, zookeeper]
[zk: elk101:2181,elk102:2181,elk103:2181(CONNECTED) 1] get /linux666 
123

KAFKA单点部署

1、下载kafka软件包

官网下载链接:

https://kafka.apache.org/downloads

[root@ELK101 ~]# wget https://archive.apache.org/dist/kafka/3.2.1/kafka_2.13-3.2.1.tgz

2、解压软件包

[root@ELK101 ~]# tar xf kafka_2.13-3.2.1.tgz -C /koten/softwares/

3、配置环境变量

[root@ELK101 ~]# cat /etc/profile.d/kafka.sh
#!/bin/bash

export KAFKA_HOME=/koten/softwares/kafka_2.13-3.2.1
export PATH=$PATH:${KAFKA_HOME}/bin
[root@ELK101 ~]# source /etc/profile.d/kafka.sh 

4、修改配置文件 

[root@ELK101 ~]# egrep -v '^$|^*#' /koten/softwares/kafka_2.13-3.2.1/config/server.properties
broker.id=101
......
log.dirs=/koten/data/kafka
......
#集群信息+chroot信息
zookeeper.connect=elk101:2181,elk102:2181,elk103:2181/kafka-3.2.1
......

#注意:此处的chroot在kafka启动后会自动创建zookeeper的节点,这样操作方便在一个zookeeper里部署多个kafka集群,便于管理。

5、启动kafka服务

[root@ELK101 ~]# kafka-server-start.sh /koten/softwares/kafka_2.13-3.2.1/config/server.properties

此处启动需要注意,这个脚本下的JAVA_HOME是否正确

cat /koten/softwares/kafka_2.13-3.2.1/bin/kafka-run-class.sh
...
# Which java to use
if [ -z "$JAVA_HOME" ]; then
  JAVA="java"
else
  JAVA="$JAVA_HOME/java"
fi

KAFKA集群部署

脚本同步方法见该文章:【运维知识大神篇】超详细的ELFK日志分析教程8(filebeat多行匹配+filestream替换log类型+ES集群修复脚本+ES集群加密+角色访问控制+ES集群配置HTTPS加密)

1、用之前的脚本同步kafka程序包到其他节点

[root@ELK101 ~]# data_rsync.sh /koten/softwares/kafka_2.13-3.2.1/
[root@ELK101 ~]# data_rsync.sh /etc/profile.d/kafka.sh

2、修改其他节点的配置文件,主要是修改host_id

[root@ELK101 ~]# for ((host_id=101;host_id<=103;host_id++)) do ssh elk${host_id} "sed -ri 's#(broker.id=)101#\1${host_id}#g' $KAFKA_HOME/config/server.properties";done

3、各节点启动服务

[root@ELK101 ~]# for ((host_id=101;host_id<=103;host_id++)) do ssh elk${host_id} "kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties ";done

扩展

一、zabbix监控zookeeper、kafka集群

使用zabbix监控zookeeper和kafka集群有现成的模板,比较方便。

1、在三台主机上部署zabbix客户端

rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
yum clean all
yum -y install zabbix-agent-5.0.34
sed -r -i 's#^Server=127.0.0.1#Server=10.0.0.71#g' /etc/zabbix/zabbix_agentd.conf|grep Server
systemctl enable --now zabbix-agent.service 

2、依次添加三台主机

3、在最新数据可以查到zookeeper的数据

4、kafka需要通过JMX的模板去监控,所以需要配置下java-gateway

[root@Zabbix ~]# yum -y install zabbix-java-gateway
[root@Zabbix ~]# systemctl enable --now zabbix-java-gateway.service


[root@Zabbix ~]# cat /etc/zabbix/zabbix_server.conf
...
JavaGateway=127.0.0.1
...
JavaGatewayPort=10052
...
StartJavaPollers=3
[root@Zabbix ~]# systemctl restart zabbix-server.service


# 三个节点都添加
[root@ELK101 ~]# cat /koten/softwares/kafka_2.13-3.2.1/bin/kafka-server-start.sh
...
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
    export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
    export JMX_PORT="9999"  # 添加此行
fi
...
# 三个节点都启动服务
[root@ELK101 ~]# nohup kafka-server-start.sh /koten/softwares/kafka_2.13-3.2.1/config/server.properties &

5、在zabbix页面修改主机信息

增加端口

增加链接的模板 

三台主机都需要操作

6、查看最新数据,可以监控到kafka的信息了。

二、Loki+Grafana

常见的日志处理方案有ELK、EFK、ELFK、ELFK+KAFKA、Loki+grafana

Loki和Grafana是是除了类似于ELFK的日志分析系统。Loki是一个可扩展、分布式的日志聚合系统,它能够接收、索引和存储日志数据,并且可视化这些数据。Grafana则是一个流行的开源数据可视化工具,支持从各种不同的数据源中提取数据并将其以各种方式可视化。

Loki可以通过promtail采集器从各种不同的日志来源(如文件、系统日志)中采集数据,并将这些日志数据发送到Loki服务器进行处理和存储。然后,Grafana可以连接到Loki服务器并使用Loki作为其数据源来创建各种仪表板和可视化。

使用Loki和Grafana可以有效地监控应用程序产生的日志,并快速了解应用程序运行状况。而且相对于ELFK来说,Loki+grafana比较轻量,等有机会单独出一篇文章!


zookeeper图形化管理工具下载链接:https://pan.baidu.com/s/1ouRFP5TYd8C4xhtTmH-Zdw?pwd=rcdn 

我是koten,10年运维经验,持续分享运维干货,感谢大家的阅读和关注!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是koten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值