ZooKeeper分布式服务与Kafka消息队列+ELKF整合方案

前言

ZooKeeper 是一个分布式的、开放源码的分布式应用程序协调服务,提供配置维护、命名服务、分布式同步、组服务等功能;

Kafka 是一个开源的分布式流处理平台,它被设计用来处理实时数据流,包括发布和订阅消息系统、日志收集以及作为事件流数据平台;

在 Kafka 集群中,ZooKeeper 用于协调和管理 Kafka broker 的状态、集群的配置信息以及其他关键元数据。结合使用时,ZooKeeper 提供了 Kafka 所需的集群管理和协调功能,使得 Kafka 集群更加稳定可靠,同时也简化了 Kafka 集群的管理和运维。

目录

[一、ZooKeeper 服务](#一、ZooKeeper 服务)

[1. 简介](#1. 简介)

[2. 工作机制](#2. 工作机制)

[3. 特点](#3. 特点)

[4. Zookeeper 数据结构](#4. Zookeeper 数据结构)

[5. 应用场景](#5. 应用场景)

[6. 选举机制](#6. 选举机制)

[6.1 第一次启动选举机制](#6.1 第一次启动选举机制)

[6.2 非第一次启动选举机制](#6.2 非第一次启动选举机制)

[6.2.1 Leader 选举两种情况](#6.2.1 Leader 选举两种情况)

[6.2.2 Leader 选举流程时状态](#6.2.2 Leader 选举流程时状态)

[二、部署 Zookeeper 集群](#二、部署 Zookeeper 集群)

[1. 环境准备](#1. 环境准备)

[2. 下载 zookeeper 安装包](#2. 下载 zookeeper 安装包)

[3. 安装 zookeeper](#3. 安装 zookeeper)

[4. 创建数据目录和日志目录](#4. 创建数据目录和日志目录)

[5. 创建 myid 文件](#5. 创建 myid 文件)

[6. 配置 Zookeeper 启动脚本](#6. 配置 Zookeeper 启动脚本)

[7. 分别启动 Zookeeper](#7. 分别启动 Zookeeper)

[三、Kafka 消息队列](#三、Kafka 消息队列)

[1. 概述](#1. 概述)

[2. 使用消息队列的好处](#2. 使用消息队列的好处)

[2.1 解耦](#2.1 解耦)

[2.2 可恢复性](#2.2 可恢复性)

[2.3 缓冲](#2.3 缓冲)

[2.4 灵活性及峰值处理能力](#2.4 灵活性及峰值处理能力)

[2.5 异步通信](#2.5 异步通信)

[3. 消息队列的两种模式](#3. 消息队列的两种模式)

[3.1 点对点模式](#3.1 点对点模式)

[3.2 发布/订阅模式](#3.2 发布/订阅模式)

[4. Kafka 的特性](#4. Kafka 的特性)

[5. Kafka 系统架构](#5. Kafka 系统架构)

[5.1 架构介绍](#5.1 架构介绍)

[5.2 Partation 数据路由规则](#5.2 Partation 数据路由规则)

[5.3 分区原因](#5.3 分区原因)

[四、部署 Kafka 集群](#四、部署 Kafka 集群)

[1. 环境准备](#1. 环境准备)

[2. 下载 Kafka 安装包](#2. 下载 Kafka 安装包)

[3. 安装 Kafka](#3. 安装 Kafka)

[4. 配置 Zookeeper 启动脚本](#4. 配置 Zookeeper 启动脚本)

[5. 分别启动 Kafka](#5. 分别启动 Kafka)

[6. Kafka 命令行操作](#6. Kafka 命令行操作)

[7. 创建主题一般故障](#7. 创建主题一般故障)

五、Kafka+ELKF

[1. 修改 filebeat 的主配置文件](#1. 修改 filebeat 的主配置文件)

[2. 在 filebeat 节点安装 apache](#2. 在 filebeat 节点安装 apache)

[3. 新建一个 Logstash kafka 配置文件](#3. 新建一个 Logstash kafka 配置文件)

[4. 查看所有的索引](#4. 查看所有的索引)

[5. 登录 Kibana 添加索引](#5. 登录 Kibana 添加索引)


一、ZooKeeper 服务

1. 简介

Zookeeper 是一个开源的分布式的,为分布式框架提供协调服务的 Apache 项目。

2. 工作机制

是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的那些观察者做出相应的反应。也就是说 Zookeeper = 文件系统 + 通知机制。

3. 特点

① 一个领导者,多个跟随着组成的集群

② 集群中只要有半数以上存活,就可以正常服务,适合安装奇数台服务器,最少3台

③ 全局数据一致,每个 server 保存一份相同的数据副本,client 无论连接到哪个 server,数据都是一致的

④ 更新请求顺序执行,来自同一个 client 的更新请求按其发送顺序依次执行,即先进先出

⑤ 数据更新原子性,一次数据更新要么成功,要么失败

⑥ 实时性,在一定时间范围内,client 能读到最新数据

4. Zookeeper 数据结构

ZooKeeper 数据模型的结构与 Linux 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode。每一个 ZNode 默认能够存储1MB的数据,每个 ZNode 都可以通过其路径唯一标识。

当 Kafka 与 ZooKeeper 集成时,Kafka 会使用 ZooKeeper 来存储其元数据和配置信息。如果用户与 Kafka 断开连接,Kafka 可能会丢失对 ZooKeeper 中特定路径下数据的访问权限或连接状态。当用户再次连接时,Kafka 可以利用先前定义的路径来重新建立与 ZooKeeper 的连接,并恢复先前的状态,以便继续正常运行。

5. 应用场景

① 统一命名服务:

  • 在分布式环境中,应用/服务需要统一的命名以便于识别。例如,将IP地址转换为易记的域名

② 统一配置管理:

  • 配置同步:在分布式环境下,要求集群中所有节点的配置信息是一致的,如 Kafka 集群。通过ZooKeeper,配置信息可以被写入一个 Znode,并且各个客户端服务器可以监听这个 Znode。任何对 Znode 中数据的修改都会被 ZooKeeper 通知到各个客户端服务器
  • 快速同步:修改后的配置信息能够快速同步到各个节点上

③ 统一集群管理:

  • 实时状态监控:在分布式环境中,实时了解每个节点的状态是必要的,因为可以根据节点状态做出调整。ZooKeeper 可以实现实时监控节点状态变化,将节点信息写入 ZooKeeper 上的一个 ZNode,并监听这个 ZNode 以获取实时状态变化

④ 服务器动态上下线:

  • ZooKeeper 可以让客户端实时感知服务器的上下线变化

⑤ 软负载均衡:

  • 在 ZooKeeper 中记录每台服务器的访问数,从而让访问数最少的服务器去处理最新的客户端请求

6. 选举机制

在 ZooKeeper 中,选举是通过投票机制来实现的。每个服务器都有权投票给自己和其他服务器,并且一旦某个服务器获得超过半数的选票,它就会成为新的 Leader。

6.1 第一次启动选举机制

|---------|---------------------------------------------------|------|------------------------------------------------------------------------------------|
| 服务器启动 | 票数 | myid | 状态角色 |
| server1 | server1:1 | 1 | looking |
| server2 | server1:0 server2:2 | 2 | looking |
| server3 | server1:0 server2:0 server2:3 | 3 | server1:follower server2:follower server3:leader |
| server4 | server1:0 server2:0 server3:3 server4:1 | 4 | server1:follower server2:follower server3:leader server4:follower |
| server5 | server1:0 server2:0 server3:3 server4:1 server5:1 | 5 | server1:follower server2:follower server3:leader server4:follower server5:follower |

① server1 启动,发起一次选举。投自己一票。此时服务器1为一票,不够半数以上(3票),选举无法完成,server1 状态保持为 looking;

② server2 启动,再发起一次选举。server1、server2 各投自己一票并交换选票信息:此时server1 发现 server2 的 myid 比自己目前投票推举的(server1)大,更改选票为推举 server2。此时server1 票数0票,server2 票数2票,没有半数以上结果,选举无法完成,server1、server2 状态保持 looking;

③ server3 启动,发起一次选举。此时server1、server2 都会更改选票为 server3。此次投票结果:server1 为0票,server2 为0票,server3 为3票。此时server3 的票数已经超过半数,server3当选 leader。server1、server2 更改状态为 follower,server3 更改状态为 leader;

④ server4 启动,发起一次选举。此时server1,2,3已经不是 looking 状态,不会更改选票信息。交换选票信息结果:server3 为3票,server4 为1票。此时server4 服从多数,更改选票信息为server3,并更改状态为 follower;

⑤ server5 启动,同 server4 一样为 follower。

6.2 非第一次启动选举机制

6.2.1 Leader 选举两种情况

当 ZooKeeper 集群中的一台服务器出现以下两种情况之一时,就会开始进入Leader选举:

① 服务器初始化启动

② 服务器运行期间无法和 Leader 保持连接

6.2.2 Leader 选举流程时状态

当一台机器进入 Leader 选举流程时,当前集群也可能会处于以下两种状态:

① 集群中本来就已经存在一个 Leader

  • 仅需要和 Leader 机器建立连接,并进行状态同步即可

② 集群中确实不存在 Leader

假设 ZooKeeper 由5台服务器组成,SID(唯一标识符,通常也称为 myid)分别为1、2、3、4、5,ZXID(事务ID)分别为8、8、8、7、7,并且此时 SID 为3的服务器是Leader。此时,3和5服务器出现故障,因此开始进行 Leader 选举。

在进行 Leader 选举时,按照以下规则进行:

  • 如果EPOCH值大的服务器直接胜出
  • 如果EPOCH相同,比较事务ID(ZXID),事务ID大的胜出
  • 如果EPOCH和事务ID都相同,则比较服务器ID(SID),服务器ID大的胜出

在ZooKeeper中,Epoch(时代)是用来标识一轮Leader选举过程的编号。每当进行一次新的Leader选举时,Epoch会递增,用于区分不同的选举轮次。由于没有 Leader 时同一轮投票过程中的逻辑时钟值是相同的,所以不存在 EPOCH 最大值;同时也不存在 ZXID 最大值。因此,该示例最终 server4 成为新的 Leader。

二、部署 Zookeeper 集群

1. 环境准备

|-----------------|----------|----------|-----------------|-----------------------------|-----------|
| 服务器ip | 节点名称 | myid/角色 | 软件版本 | jdk版本 | 操作系统 |
| 192.168.190.104 | zk-kfk01 | 1/follow | zookeeper-3.5.7 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.105 | zk-kfk02 | 2/follow | zookeeper-3.5.7 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.106 | zk-kfk03 | 3/leader | zookeeper-3.5.7 | openjdk version "1.8.0_131" | centos7.4 |

bash 复制代码
systemctl stop firewalld.service 
setenforce 0
[root@localhost ~]# java -version
openjdk version "1.8.0_131"        # 自带java环境openjdk

# 编辑域名解析,制作映射,加快传输速度
echo 192.168.190.104 zk-kfk01 >> /etc/hosts
echo 192.168.190.105 zk-kfk02 >> /etc/hosts
echo 192.168.190.106 zk-kfk03 >> /etc/hosts

2. 下载 zookeeper 安装包

三台节点一起配置:

bash 复制代码
[root@localhost ~]# cd /opt/
[root@localhost opt]# wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.7/apache-zookeeper-3.5.7-bin.tar.gz
[root@localhost opt]# ls
apache-zookeeper-3.5.7-bin.tar.gz

3. 安装 zookeeper

三台节点一起配置:

bash 复制代码
[root@localhost opt]# tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz
[root@localhost opt]# mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper-3.5.7
[root@localhost opt]# cd /usr/local/zookeeper-3.5.7/conf/
[root@localhost conf]# ls
configuration.xsl  log4j.properties  zoo_sample.cfg 
[root@localhost conf]# cp zoo_sample.cfg zoo.cfg
[root@localhost conf]# vim zoo.cfg    # 修改配置文件
  2 tickTime=2000                     # 通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒
  5 initLimit=10                      # Leader和Follower初始连接时能容忍的最多心跳数(tickTime的数量),这里表示为10*2s
  8 syncLimit=5                       # Leader和Follower之间同步通信的超时时间,这里表示如果超过5*2s,Leader认为Follwer死掉,并从服务器列表中删除Follwer
 12 dataDir=/usr/local/zookeeper-3.5.7/data    # 修改,指定保存Zookeeper中的数据的目录,目录需要单独创建
 13 dataLogDir=/usr/local/zookeeper-3.5.7/logs # 添加,指定存放日志的目录,目录需要单独创建
 15 clientPort=2181                   # 客户端连:接端口
 30 server.1=192.168.190.104:3188:3288
 31 server.2=192.168.190.105:3188:3288
 32 server.3=192.168.190.106:3188:3288
server.A=B:C:D
# A是一个数字,表示这个是第几号服务器。集群模式下需要在zoo.cfg中dataDir指定的目录下创建一个文件myid,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。
# B是这个服务器的地址。
# C是这个服务器Follower与集群中的Leader服务器交换信息的端口。
# D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

4. 创建数据目录和日志目录

三台节点一起配置:

bash 复制代码
[root@localhost ~]# mkdir /usr/local/zookeeper-3.5.7/data
[root@localhost ~]# mkdir /usr/local/zookeeper-3.5.7/logs

5. 创建 myid 文件

在每个节点的 dataDir 指定的目录下创建一个 myid 的文件,dataDir 是用于存储 ZooKeeper 服务器数据的目录。

bash 复制代码
[root@zk-kfk01 ~]# echo 1 > /usr/local/zookeeper-3.5.7/data/myid
[root@zk-kfk02 ~]# echo 2 > /usr/local/zookeeper-3.5.7/data/myid
[root@zk-kfk03 ~]# echo 3 > /usr/local/zookeeper-3.5.7/data/myid

6. 配置 Zookeeper 启动脚本

三台节点一起配置:

bash 复制代码
vim /etc/init.d/zookeeper
#!/bin/bash
#chkconfig:2345 20 90     # 在运行级别2、3、4、5下,在启动优先级顺序为20,在关闭顺序为90。
#description:Zookeeper Service Control Script
ZK_HOME='/usr/local/zookeeper-3.5.7'              # 定义了 ZooKeeper 的安装路径
case $1 in                                        # 开始一个 case 语句,根据传入的参数进行不同的操作
start)                                            # 如果参数是 "start",则执行 ZooKeeper 启动命令
	echo "---------- zookeeper 启动 ------------" 
	$ZK_HOME/bin/zkServer.sh start
;;
stop)                                             # 如果参数是 "stop",则执行 ZooKeeper 停止命令
	echo "---------- zookeeper 停止 ------------"
	$ZK_HOME/bin/zkServer.sh stop
;; 
restart)                                          # 如果参数是 "restart",则执行 ZooKeeper 重启命令。
	echo "---------- zookeeper 重启 ------------"
	$ZK_HOME/bin/zkServer.sh restart
;;
status)                                           # 如果参数是 "status",则执行 ZooKeeper 查看状态命令
	echo "---------- zookeeper 状态 ------------"
	$ZK_HOME/bin/zkServer.sh status
;;
*)                                                # 如果参数不匹配以上任何情况,则显示使用说明
    echo "Usage: $0 {start|stop|restart|status}"
esac
# 管理ZooKeeper服务,通过传入不同的参数来启动、停止、重启和查看状态

7. 分别启动 Zookeeper

bash 复制代码
[root@zk-kfk01 ~]# chmod +x /etc/init.d/zookeeper
[root@zk-kfk01 ~]# chkconfig --add zookeeper
# 将 "zookeeper" 服务添加到系统的服务管理列表中,并且配置它在系统启动时自动运行
# 前提创建一个名为 "zookeeper" 的服务脚本(通常是放在 /etc/init.d/ 目录下)

依次启动,不要一起启动:
[root@zk-kfk01 ~]# service zookeeper start
[root@zk-kfk02 ~]# service zookeeper start
[root@zk-kfk03 ~]# service zookeeper start
---------- zookeeper 启动 ------------
/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

[root@zk-kfk01 ~]# service zookeeper status  # 查看当前状态
---------- zookeeper 状态 ------------
/bin/java
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower

三、Kafka 消息队列

1. 概述

Kafka 即消息队列,简称 MQ。在高并发环境下,当同时处理大量请求访问服务器,往往请求会发生阻塞。如大量访问数据库,导致锁表引发雪崩效应;使用消息队列,可以异步处理请求:流量消峰、应用解耦从而缓解压力。当 Kafka 组合集群每秒可以处理几十万条数据请求,大大增加了抗高并发能力。

当前比较常见的 MQ 中间件有 ActiveMQ(淘汰)、RabbitMQ(用的多)、RocketMQ(企业常用)、Kafka(大数据分析、大量数据收集) 等。

2. 使用消息队列的好处

2.1 解耦

通过消息队列来实现系统内部各个组件或模块之间的解耦合,即两边遵守约定,则允许通信。

假设有一个电子商务平台,其中订单系统、库存系统和物流系统需要相互通信。通过消息队列解耦,它们可以实现以下功能:

  • 订单下单:当顾客下单时,订单系统将订单信息发布到消息队列中,而不需要直接调用库存系统或物流系统的接口
  • 库存更新:库存系统订阅了订单系统发布的消息队列,一旦接收到订单信息,它会检查库存并更新库存状态
  • 物流处理:同时,物流系统也订阅了订单系统发布的消息队列,一旦接收到订单信息,它会开始安排物流配送

这种架构下,各个系统之间并不直接依赖于彼此的接口,而是通过消息队列进行松耦合的通信。

2.2 可恢复性

通过消息队列,即使某个处理消息的组件出现故障,系统仍然可以保持稳定运行。消息会被安全地存储在队列中,等待故障组件重新上线后进行处理,从而提高了整个系统的可靠性。

2.3 缓冲

消息队列可以作为缓冲层,帮助控制系统中数据流的速度。

2.4 灵活性及峰值处理能力

消息队列可以帮助系统应对突发的访问量增加,确保关键组件能够应对压力而不至于崩溃。这提供了系统在面对异常情况下的弹性和稳定性。

2.5 异步通信

允许用户将消息放入队列,而不需要立即处理;可以提高系统的响应速度和整体效率,同时也降低了对实时处理的需求。

3. 消息队列的两种模式

3.1 点对点模式

即一对一,消息收到后消息清除。在点对点模式中,消息生产者将消息发送到队列中,然后消息消费者从队列中主动拉取并处理消息。一旦消息被某个消费者处理完毕,它就会从队列中清除,因此同一条消息只能被一个消费者处理。这种模式适用于需要确保每条消息只被处理一次的场景。

3.2 发布/订阅模式

即一对多,又叫观察者模式,消费者消费数据之后不会清除消息。观察者的作用是接收消息队列中特定主题或频道上的消息,并通知消费者或其他观察者。在发布/订阅模式中,消息生产者将消息发布到特定的主题(topic)中,而多个消息消费者可以订阅这个主题并独立地消费消息。与点对点模式不同,发布到主题的消息会被所有订阅者接收和消费。这种模式适用于需要将消息广播给多个订阅者的场景,例如直播。

4. Kafka 的特性

① 高吞吐量、低延迟

  • Kafka 每秒可以处理几十万条消息,它的延迟最低只有几毫秒。每个 topic 可以分多个 Partition,Consumer Group 对 Partition 进行消费操作,提高负载均衡能力和消费能力

② 可扩展性

  • kafka 集群支持热扩展

③ 持久性、可靠性

  • 消息被持久化到本地磁盘,并且支持数据备份冗余

④ 容错性

  • 允许集群中节点失败(多副本情况下,若副本数量为 n,则允许 n-1 个节点失败)

⑤ 高并发

  • 支持数千个客户端同时读写

5. Kafka 系统架构

5.1 架构介绍

① Broker 服务器

Broker 服务器是 Kafka 中的服务器单元,每个 Broker 可以理解为一个 Kafka 实例,负责存储和管理消息。一台 Kafka 服务器就是一个 Broker,一个集群由多个 Broker 组成,一个 Broker 可以容纳多个 Topic。

② Topic 主题

主题是消息的逻辑容器,类似于消息队列中的队列。生产者发布消息到主题,消费者从主题订阅消息。每个主题可以划分为多个分区,以便实现数据的分布和负载均衡。

③ Partition 分区

为了实现扩展性和高吞吐量,一个主题可以分割为多个分区,每个分区是一个有序的队列。分区允许主题的数据分布到多个 broker 上,并且提供了并行处理消息的能力。Kafka 保证每个分区内的消息顺序,但不保证不同分区之间的消息顺序。或者说 Kafka 只保证 Partition 内的记录是有序的,而不保证 Topic 中不同 Partition 的顺序。

每个 Topic 至少有一个 Partition,当生产者产生数据的时候,会根据分配策略选择分区,然后将消息追加到指定的分区的队列末尾。

5.2 Partation 数据路由规则

① 指定了 Patition:如果消息的生产者明确指定了分区(Partition),则消息将被直接发送到该分区中;

② 未指定 Patition 但指定 Key(相当于消息中某个属性):如果消息的生产者没有指定分区,但指定了一个键(Key),则根据该键的值进行哈希运算,并取模以确定消息应该发送到的分区;

③ Patition 和 Key 都未指定:如果消息的发送者既没有指定分区,也没有指定键,则系统将根据轮询的方式从可用的分区中选取一个分区。

关于分区的一些补充信息:

  • 消息偏移量编号: 每条消息都有一个自增的编号,用于标识消息的偏移量,从0开始标识顺序。
  • 分区中的数据存储方式: 每个分区使用多个 Segment 文件来存储数据。
  • 严格保证消息消费顺序的情况下: 如果有严格保证消息消费顺序的需求(比如商品秒杀、抢红包等),可以将分区数目设置为1,这样可以保证消息在消费时的顺序性。

关于 Broker 存储数据的情况:

  • Broker 存储 Topic 数据: 如果某个 Topic 有 N 个分区,那么集群中的每个 Broker 存储该 Topic 的一个分区。
  • Broker 数量与 Topic 分区数的关系: 如果某个 Topic 有 N 个分区,而集群中有 N+M 个 Broker,那么其中的 N 个 Broker 分别存储该 Topic 的一个分区,而剩下的 M 个 Broker 不存储该 Topic 的分区数据。
  • Broker 数量少于 Topic 分区数的情况: 如果某个 Topic 有 N 个分区,但集群中的 Broker 数量少于 N 个,那么一个 Broker 可能会存储该 Topic 的一个或多个分区。在实际生产环境中,应尽量避免这种情况,因为这可能导致 Kafka 集群数据不均衡。

5.3 分区原因

  • 方便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,而一个 Topic 又可以有多个 Partition 组成,因此整个集群就可以适应任意大小的数据了;
  • 以 Partition 为单位读写,Kafka 使用分区来方便集群扩展和提高并发性,

① Replica 副本

为了防止节点故障导致数据丢失,Kafka 提供了副本机制。每个分区都有若干个副本,其中一个是 Leader,负责读写,其他是 Follower,负责备份。

② Leader 领导者

每个 Partition 有多个副本,其中有且仅有一个作为 Leader,Leader 是当前负责数据的读写的 Partition。

③ Follower 跟随者

Follower 跟随 Leader,负责备份数据。如果 Leader 故障,会从 Follower 中选举出新的 Leader。

④ producer 生产者

生产者即数据的发布者,将消息发布到 Kafka 的 topic 中,可以指定数据存储的分区。Broker 接收到生产者发送的消息后,Broker 将该消息追加到当前用于追加数据的 Segment(通过 Segment.io 收集的数据所存储的文件)文件中。

⑤ Consumer 消费者

从 Kafka 中拉取数据进行消费,可以消费多个 topic。

⑥ Consumer Group(CG)消费者组

多个消费者组成一个消费者组,每个组内的消费者负责消费不同分区的数据,防止数据被重复读取;将多个消费者集中到一起去处理某一个 Topic 的数据,可以更快的提高数据的消费能力。

⑦ offset 偏移量

唯一标识一条消息的位置信息,消费者通过偏移量确定下次读取消息的位置。消息最终还是会被删除的,默认生命周期为 1 周(7*24小时)。

⑧ Zookeeper

Kafka 使用 Zookeeper 存储集群的元信息,例如 broker 的地址和分区的状态,同时用于管理消费者组的偏移量。Kafka 0.9 版本之前,consumer 默认将 offset 保存在 Zookeeper 中;从 0.9 版本开始,consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,该 topic 为 __consumer_offsets。

总之,zookeeper 的作用就是,生产者 push 数据到 kafka 集群,就必须要找到 kafka 集群的节点在哪里,这些都是通过 zookeeper 去寻找的。消费者消费哪一条数据,也需要 zookeeper 的支持,从 zookeepe r获得 offset,offset 记录上一次消费的数据消费到哪里,这样就可以接着下一条数据进行消费。

四、部署 Kafka 集群

1. 环境准备

|-----------------|----------|----------|----------------------------------|-----------------------------|-----------|
| 服务器ip | 节点名称 | myid/角色 | 软件版本 | jdk版本 | 操作系统 |
| 192.168.190.104 | zk-kfk01 | 1/follow | zookeeper-3.5.7 kafka_2.13-2.7.1 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.105 | zk-kfk02 | 2/follow | zookeeper-3.5.7 kafka_2.13-2.7.1 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.106 | zk-kfk03 | 3/leader | zookeeper-3.5.7 kafka_2.13-2.7.1 | openjdk version "1.8.0_131" | centos7.4 |

2. 下载 Kafka 安装包

三台节点一起操作:

bash 复制代码
官方下载地址:http://kafka.apache.org/downloads.html
[root@zk-kfk01 opt]# wget https://archive.apache.org/dist/kafka/2.7.1/kafka_2.13-2.7.1.tgz
[root@zk-kfk01 opt]# ls
kafka_2.13-2.7.1.tgz

3. 安装 Kafka

三台节点一起操作:注意 broker.id 和 listeners 地址

bash 复制代码
[root@zk-kfk01 opt]# tar zxvf kafka_2.13-2.7.1.tgz
[root@zk-kfk01 opt]# mv kafka_2.13-2.7.1 /usr/local/kafka
修改配置文件:
[root@zk-kfk01 opt]# cd /usr/local/kafka/config/
[root@zk-kfk01 config]# cp server.properties{,.bak}  # 备份配置文件
[root@zk-kfk01 config]# vim server.properties
 21 broker.id=0(1,2)      # broker的全局唯一编号,每个broker不能重复,另外两台broker.id=1、broker.id=2
 31 listeners=PLAINTEXT://192.168.190.103:9092 (104,105) 
# 指定监听的IP和端口,如果修改每个broker的IP需区分开来,也可保持默认配置不用修改
 42 num.network.threads=3  # broker处理网络请求的线程数量,一般情况下不需要去修改
 45 num.io.threads=8       # 用来处理磁盘IO的线程数量,数值应该大于硬盘数
 48 socket.send.buffer.bytes=102400 # 发送套接字的缓冲区大小
 51 socket.receive.buffer.bytes=102400 # 接收套接字的缓冲区大小
 54 socket.request.max.bytes=104857600 # 请求套接字的缓冲区大小
 60 log.dirs=/usr/local/kafka/logs     # kafka运行日志存放的路径,也是数据存放的路径
 65 num.partitions=1       # topic在当前broker上的默认分区个数,会被topic创建时的指定参数覆盖
 69 num.recovery.threads.per.data.dir=1 # 用来恢复和清理data下数据的线程数量
103 log.retention.hours=168 # segment文件(数据文件)保留的最长时间,单位为小时,默认为7天,超时将被删除
110 log.segment.bytes=1073741824 # 一个segment文件最大的大小,默认为 1G,超出将新建一个新的segment文件
123 zookeeper.connect=192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181  
# 配置连接Zookeeper集群地址

修改环境变量:
[root@zk-kfk01 ~]# vim /etc/profile
export KAFKA_HOME=/usr/local/kafka  # 将一个名为 KAFKA_HOME 的环境变量设置为 /usr/local/kafka,这表示 Kafka 的安装路径
export PATH=$PATH:$KAFKA_HOME/bin   # 将 Kafka 的 bin 目录添加到系统的 PATH 环境变量中
[root@zk-kfk01 ~]# source /etc/profile # 重新加载 /etc/profile 文件中设置的环境变量

4. 配置 Zookeeper 启动脚本

三台节点一起操作:

bash 复制代码
[root@zk-kfk01 ~]# vim /etc/init.d/kafka
#!/bin/bash
#chkconfig:2345 22 88
#description:Kafka Service Control Script
KAFKA_HOME='/usr/local/kafka'               # 定义了 Kafka 的安装路径
case $1 in                                  # 开始一个 case 语句,根据传入的参数进行不同的操作
start)                                      # 如果参数是 "start",则执行 Kafka 启动命令
	echo "---------- Kafka 启动 ------------"
	${KAFKA_HOME}/bin/kafka-server-start.sh -daemon ${KAFKA_HOME}/config/server.properties
;;
stop)                                       # 如果参数是 "stop",则执行 Kafka 停止命令
	echo "---------- Kafka 停止 ------------"
	${KAFKA_HOME}/bin/kafka-server-stop.sh
;;
restart)                                    # 如果参数是 "restart",则先执行 Kafka 停止命令再执行 Kafka 启动命令
	$0 stop 
	$0 start
;;
status)                                     # 如果参数是 "status",则检查 Kafka 进程是否在运行,并输出相应的状态信息
	echo "---------- Kafka 状态 ------------"
	count=$(ps -ef | grep kafka | egrep -cv "grep|$$")
	if [ "$count" -eq 0 ];then
        echo "kafka is not running"
    else
        echo "kafka is running"
    fi
;;
*)                                          # 如果参数不匹配以上任何情况,则显示使用说明
    echo "Usage: $0 {start|stop|restart|status}"
esac
# 管理 Kafka 服务,可以通过传入不同的参数来启动、停止、重启和查看状态

5. 分别启动 Kafka

bash 复制代码
[root@zk-kfk02 ~]# chmod +x /etc/init.d/kafka
[root@zk-kfk02 ~]# chkconfig --add kafka
依次启动 kafaka:
[root@zk-kfk01 ~]# service kafka start   # 启动 Kafka
[root@zk-kfk02 ~]# service kafka start
[root@zk-kfk03 ~]# service kafka start
---------- Kafka 启动 ------------
[root@zk-kfk01 ~]# service kafka status  # 查看状态
---------- Kafka 状态 ------------
kafka is running

6. Kafka 命令行操作

① 创建一个名为 "test" 的 Kafka 主题(topic):任意一台机器即可

bash 复制代码
[root@zk-kfk01 ~]# kafka-topics.sh --create --zookeeper 192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181 --replication-factor 2 --partitions 3 --topic test
# kafka-topics.sh: 这是 Kafka 提供的一个脚本工具,用于管理 Kafka 中的主题。
# --create: 这是告诉 kafka-topics.sh 要创建一个新的主题。
# --zookeeper 192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181: 这是指定 ZooKeeper 的连接信息,用于管理 Kafka 集群。在这里,指定了三个 ZooKeeper 实例的地址和端口号。
# --replication-factor 2: 这表示设置每个分区的副本数量为 2。副本是为了数据的冗余和容错性而存在的。
# --partitions 3: 这表示要创建 3 个分区。
# --topic test: 这表示要创建一个名为 "test" 的主题。
# 在 Kafka 集群中创建一个名为 "test" 的主题,该主题有 3 个分区,并且每个分区有 2 个副本。

② 查看当前服务器中的所有 topic

bash 复制代码
[root@zk-kfk01 config]# kafka-topics.sh --list --zookeeper 192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181
test

③ 查看 test topic 的详情

bash 复制代码
[root@zk-kfk01 config]# kafka-topics.sh --describe --zookeeper 192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181 test
Topic: test	PartitionCount: 3	ReplicationFactor: 2	Configs:  
# 表示主题 "test" 共有 3 个分区。每个分区的复制因子为 2,即每个分区都有两个副本
	Topic: test	Partition: 0	Leader: 0	Replicas: 0,2	Isr: 0,2
	Topic: test	Partition: 1	Leader: 1	Replicas: 1,0	Isr: 1,0
	Topic: test	Partition: 2	Leader: 2	Replicas: 2,1	Isr: 2,1
# Partition: x 指明了每个分区的编号。
# Leader: x 显示了每个分区的 leader 副本所在的 broker 编号。
# Replicas: x,y 展示了每个分区的所有副本所在的 broker 编号。
# Isr: x,y 描述了每个分区的"在同步副本集"(In-Sync Replica)中的副本编号

④ 发布消息

bash 复制代码
[root@zk-kfk01 config]# kafka-console-producer.sh --broker-list 192.168.190.104:9092,192.168.190.105:9092,192.168.190.106:9092  --topic test
>123456

⑤ 消费消息

bash 复制代码
[root@zk-kfk02 config]# kafka-console-consumer.sh --bootstrap-server 192.168.190.104:9092,192.168.190.105:9092,192.168.190.106:9092 --topic test --from-beginning
123456

[root@zk-kfk03 config]# kafka-console-consumer.sh --bootstrap-server 192.168.190.104:9092,192.168.190.105:9092,192.168.190.106:9092 --topic test --from-beginning
123456
# --from-beginning:会把主题中以往所有的数据都读取出来

⑥ 修改分区数

bash 复制代码
修改主题 "test" 的分区数量为 6:
kafka-topics.sh --zookeeper 192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181 --alter --topic test --partitions 6

⑦ 删除 topic

bash 复制代码
kafka-topics.sh --delete --zookeeper 192.168.190.104:2181,192.168.190.105.21:2181,192.168.190.106:2181 --topic test

7. 创建主题一般故障

故障示例:

bash 复制代码
[root@zk-kfk01 config]# kafka-topics.sh --create --zookeeper 192.168.190.104:2181,192.168.190.105:2181,192.168.190.106:2181 --replication-factor 2 --partitions 3 --topic test
Error while executing topic command : Replication factor: 2 larger than available brokers: 0.
[2024-04-13 20:17:55,154] ERROR org.apache.kafka.common.errors.InvalidReplicationFactorException: Replication factor: 2 larger than available brokers: 0.
# 指定的副本因子大于可用的 broker 数量。这可能是由于 ZooKeeper 中注册的 broker 数量与实际运行的 broker 数量不匹配导致的。

排查过程:

① 确保 broker 数量足够

② 查看 server.properties 配置

bash 复制代码
broker.id         
listeners=PLAINTEXT://ip:9092
确保编号唯一;监听地址是否正确

③ 查看端口是否正常

bash 复制代码
telenet 主机名 2181

④ 关闭 kafka,再挨个启动

bash 复制代码
service kafka stop
service kafka start

五、Kafka+ELKF

ELKF 部署请参考:ELK、ELKF企业级日志分析系统介绍-CSDN博客

环境配置:

|-----------------|----------|----------|----------------------------------|-----------------------------|-----------|
| 服务器ip | 节点名称 | myid/角色 | 软件版本 | jdk版本 | 操作系统 |
| 192.168.190.100 | node1 | | elasticsearch-5.5.0、kibana-5.5.1 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.101 | node2 | | elasticsearch-5.5.0 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.102 | logstash | | apache、logstash-5.5.1 | | centos7.4 |
| 192.168.190.103 | filebeat | | filebeat、apache | | centos7.4 |
| 192.168.190.104 | zk-kfk01 | 1/follow | zookeeper-3.5.7 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.105 | zk-kfk02 | 2/follow | zookeeper-3.5.7 | openjdk version "1.8.0_131" | centos7.4 |
| 192.168.190.106 | zk-kfk03 | 3/leader | zookeeper-3.5.7 | openjdk version "1.8.0_131" | centos7.4 |

数据流向:

1. 修改 filebeat 的主配置文件

bash 复制代码
[root@filebeat ~]# cd /usr/local/filebeat
[root@filebeat filebeat]# vim filebeat.yml
filebeat.prospectors:
- type: log
  enabled: true
  paths:
    - /var/log/httpd/access_log
  tags: ["access"]
  
- type: log
  enabled: true
  paths:
    - /var/log/httpd/error_log
  tags: ["error"]
......
注释 Logstash output 相关配置,避免冲突
#----------------------------- kafka output --------------------------------
output.kafka:
  enabled: true
  hosts: ["192.168.190.104:9092","192.168.190.105:9092","192.168.190.106:9092"]
# 指定 Kafka 集群配置
  topic: "httpd"  # 指定 Kafka 的 topic
[root@filebeat filebeat]# ./filebeat -e -c filebeat.yml # 启动 filebeat

2. 在 filebeat 节点安装 apache

bash 复制代码
[root@filebeat filebeat]# yum install -y httpd
[root@filebeat filebeat]# systemctl start httpd.service

3. 新建一个 Logstash kafka 配置文件

bash 复制代码
[root@logstash ~]# cd /etc/logstash/conf.d/
[root@logstash conf.d]# vim kafka.conf
input {
    kafka {
        bootstrap_servers => "192.168.190.104:9092,192.168.190.105:9092,192.168.190.106:9092"  
# kafka集群地址
        topics  => "httpd"             # 拉取的kafka的指定topic
        type => "httpd_kafka"          # 指定 type 字段
        codec => "json"                # 解析json格式的日志数据
		auto_offset_reset => "latest"  # 拉取最近数据,earliest为从头开始拉取
		decorate_events => true        # 传递给elasticsearch的数据额外增加kafka的属性数据
    }
}

output {
  if "access" in [tags] {
    elasticsearch {
      hosts => ["192.168.190.100:9200"]
      index => "httpd_access-%{+YYYY.MM.dd}"
    }
  }
  
  if "error" in [tags] {
    elasticsearch {
      hosts => ["192.168.190.100:9200"]
      index => "httpd_error-%{+YYYY.MM.dd}"
    }
  }
  
  stdout { codec => rubydebug }
}
[root@logstash conf.d]# logstash -f kafka.conf
# 启动 logstash;或者 ./filebeat -e -c filebeat.yml &

网页端访问apache:
http://192.168.190.102/

4. 查看所有的索引

生产黑屏操作es时查看所有的索引:

bash 复制代码
[root@node1 ~]# curl -X GET "localhost:9200/_cat/indices?v"
health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   httpd_error-2024.04.13   zHoWjUNPR2uggajGdK13_g   5   1         36            0    716.6kb        358.3kb
green  open   system-2024.04.10        A8E0O-f9Q4OsN5SsoqkXDw   5   1       7132            0      4.4mb          2.2mb
green  open   index-demo1              3voNtLzAQIqDJn3Ip2ODKA   5   1          1            0      9.3kb          4.6kb
green  open   logstash-2024.04.10      1KY7jcRlSfGHhtklVpIchg   5   1          2            0       18kb            9kb
green  open   httpd_access-2024.04.13  0EK1CjoZRCmOboLgtVhesQ   5   1         60            0    260.3kb        113.9kb
green  open   apache_error-2024.04.10  un_LRAJzTSmL9aq6DUL5zg   5   1         13            0    124.5kb         62.2kb
green  open   filebeat-2024.04.11      rX5Vy-73Q1aSUKBI3LGe0Q   5   1       6031            0      3.9mb          1.9mb
green  open   .kibana                  ev0JtIH6SyOpycSjI2TGQQ   1   1          6            1     69.7kb         34.8kb
green  open   apache_access-2024.04.10 lCL7_nw3QDmGr2YmbYUOuQ   5   1         12            0    113.8kb         56.9kb

es-head web 界面查看:

5. 登录 Kibana 添加索引

浏览器访问 http://192.168.190.100:5601,添加索引"httpd*",查看图表信息及日志信息。

相关推荐
猿java7 小时前
使用 Kafka面临的挑战
java·后端·kafka
路上^_^7 小时前
00_概览_kafka
分布式·kafka
CopyLower15 小时前
Kafka 消费者状态及高水位(High Watermark)详解
分布式·kafka
信徒_18 小时前
kafka
分布式·kafka
灰色孤星A1 天前
Kafka学习笔记(三)Kafka分区和副本机制、自定义分区、消费者指定分区
zookeeper·kafka·kafka分区机制·kafka副本机制·kafka自定义分区
雪球不会消失了1 天前
Kafka快速入门
分布式·kafka
death bell2 天前
kafka基本概念以及用法
分布式·kafka·linq
空名_Noname2 天前
【转载翻译】消息队列 - ActiveMQ、RabbitMQ、Kafka、ZeroMQ
c++·kafka·rabbitmq·activemq·zeromq
漫无目的行走的月亮3 天前
Ubuntu下安装Zookeeper集群
linux·ubuntu·zookeeper
漫无目的行走的月亮3 天前
使用微服务Spring Cloud集成Kafka实现异步通信(消费者)
spring cloud·微服务·kafka