单机Docker部署应用Kraft模式的Kafka集群

news/2024/11/24 13:55:38/

单机Docker部署应用Kraft模式的Kafka集群

  • 1 Docker镜像准备
    • 1.1 下载Kafka
    • 1.2 配置容器
      • 1.3 修改kafka配置
  • 2 部署Kafka集群
    • 2.1 启动节点容器
    • 2.2 生成一个 Cluster ID
    • 2.3 格式化存储目录
    • 2.4 启动kafka服务
  • 3 知识
    • 3.1 控制器服务器
    • 3.2 进程角色
    • 3.3 仲裁投票者
    • 3.4 Kafka存储工具
    • 3.5 缺失的能力
    • 3.6 Debug
      • 3.6.1 kafka-dump-log
      • 3.6.2 元数据shell


试试换个姿势阅读


1 Docker镜像准备

因为这里需要使用Docker模式3台主机,因此以ubuntu系统为基础,封装自己的镜像。

1.1 下载Kafka

下载 kafka_2.12-3.3.1.tgz 到本地(/home/linsikai/lib/node1),下载地址:kafka_2.12-3.3.1.tgz下载

1.2 配置容器

  1. 以ubuntu系统为底创建容器
$ sudo docker run -it -v /home/linsikai/tmp/node1/kraft-combined-logs:/tmp/kraft-combined-logs -v /home/linsikai/lib/node1:/lib/node --name kafka-raft-node ubuntu:latest /bin/bash
  1. 安装Java:apt-get update -y & apt-get install openjdk-11-jdk -y

注意:自kafka3.0开始,java8已被标注舍弃,并且将于kafka4.0彻底废弃。推荐使用java11、java17

  1. 安装Vim:apt-get install vim -y
  2. 封装镜像:sudo docker commit [容器id] sky/kafka-kraft:0.0.1

1.3 修改kafka配置

复制三份kafka解压数据,并分别进入kafka安装目录(/home/linsikai/lib/node1/home/linsikai/lib/node2/home/linsikai/lib/node2),打开配置文件:vim config/kraft/server.properties

  1. node1节点配置,kraft需要注意的配置项包括以下:
# The role of this server. Setting this puts us in KRaft mode
process.roles=broker,controller# The node id associated with this instance's roles
node.id=1# The connect string for the controller quorum
controller.quorum.voters=1@127.0.0.1:9033,2@127.0.0.1:9034,3@127.0.0.1:9035# The address the socket server listens on.
# Combined nodes (i.e. those with `process.roles=broker,controller`) must list the controller listener here at a minimum.
listeners=PLAINTEXT://:9023,CONTROLLER://:9033# Name of listener used for communication between brokers.
inter.broker.listener.name=PLAINTEXT# Listener name, hostname and port the broker will advertise to clients.
# If not set, it uses the value for "listeners".
advertised.listeners=PLAINTEXT://127.0.0.1:9023# A comma-separated list of the names of the listeners used by the controller.
# If no explicit mapping set in `listener.security.protocol.map`, default will be using PLAINTEXT protocol
# This is required if running in KRaft mode.
controller.listener.names=CONTROLLER# A comma separated list of directories under which to store log files
log.dirs=/tmp/kraft-combined-logs

(2)node2节点配置

# The role of this server. Setting this puts us in KRaft mode
process.roles=broker,controller# The node id associated with this instance's roles
node.id=2# The connect string for the controller quorum
controller.quorum.voters=1@127.0.0.1:9033,2@127.0.0.1:9034,3@127.0.0.1:9035# The address the socket server listens on.
# Combined nodes (i.e. those with `process.roles=broker,controller`) must list the controller listener here at a minimum.
listeners=PLAINTEXT://:9024,CONTROLLER://:9034# Name of listener used for communication between brokers.
inter.broker.listener.name=PLAINTEXT# Listener name, hostname and port the broker will advertise to clients.
# If not set, it uses the value for "listeners".
advertised.listeners=PLAINTEXT://127.0.0.1:9024# A comma-separated list of the names of the listeners used by the controller.
# If no explicit mapping set in `listener.security.protocol.map`, default will be using PLAINTEXT protocol
# This is required if running in KRaft mode.
controller.listener.names=CONTROLLER# A comma separated list of directories under which to store log files
log.dirs=/tmp/kraft-combined-logs

(3)node3节点

# The role of this server. Setting this puts us in KRaft mode
process.roles=broker,controller# The node id associated with this instance's roles
node.id=3
``
# The connect string for the controller quorum
controller.quorum.voters=1@127.0.0.1:9033,2@127.0.0.1:9034,3@127.0.0.1:9035# The address the socket server listens on.
# Combined nodes (i.e. those with `process.roles=broker,controller`) must list the controller listener here at a minimum.
listeners=PLAINTEXT://:9025,CONTROLLER://:9035# Name of listener used for communication between brokers.
inter.broker.listener.name=PLAINTEXT# Listener name, hostname and port the broker will advertise to clients.
# If not set, it uses the value for "listeners".
advertised.listeners=PLAINTEXT://127.0.0.1:9025# A comma-separated list of the names of the listeners used by the controller.
# If no explicit mapping set in `listener.security.protocol.map`, default will be using PLAINTEXT protocol
# This is required if running in KRaft mode.
controller.listener.names=CONTROLLER# A comma separated list of directories under which to store log files
log.dirs=/tmp/kraft-combined-logs

2 部署Kafka集群

2.1 启动节点容器

分别启动3台节点容器

docker run -itd --network host -v /home/linsikai/tmp/node1/kraft-combined-logs:/tmp/kraft-combined-logs -v /home/linsikai/lib/node1:/lib/node --name kafka-raft-node1 sky/kafka-kraft:0.0.1 /bin/bash
docker run -itd --network host -v /home/linsikai/tmp/node2/kraft-combined-logs:/tmp/kraft-combined-logs -v /home/linsikai/lib/node2:/lib/node --name kafka-raft-node2 sky/kafka-kraft:0.0.1 /bin/bash
docker run -itd --network host -v /home/linsikai/tmp/node3/kraft-combined-logs:/tmp/kraft-combined-logs -v /home/linsikai/lib/node3:/lib/node --name kafka-raft-node3 sky/kafka-kraft:0.0.1 /bin/bash

2.2 生成一个 Cluster ID

sudo docker exec -it [容器id] /bin/bash进入任意一个容器,执行下面:(其实也可以不用执行,测试的话写成AAAAAAA都可以,保证唯一就行)

$ ./bin/kafka-storage.sh random-uuid
TaMk2qkGSLaWEPo2ru86Kw

由以前自动生成改手动生成的原因参见:3.4小节 Kafka存储工具。

2.3 格式化存储目录

下一步是格式化存储目录。如果运行单节点,可以使用以下命令:

$ ./bin/kafka-storage.sh format -t TaMk2qkGSLaWEPo2ru86Kw -c ./config/kraft/server.properties
Formatting /tmp/kraft-combined-logs with metadata.version 3.3-IV3.

如果运行集群,需要给每个节点运行格式化命令。

注意:需要使用相同的集群 Cluster ID

2.4 启动kafka服务

最后,启动每一个kafka节点。

$ ./bin/kafka-server-start.sh ./config/kraft/server.properties# 后台运行
$ ./bin/kafka-server-start.sh -daemon ./config/kraft/server.properties

之后就可以愉快地玩耍了,例如常见topic

$ ./bin/kafka-topics.sh --create --topic foo --partitions 1 --replication-factor 1 --bootstrap-server 127.0.0.1:9023
Created topic foo.

3 知识

3.1 控制器服务器

在KRaft模式下,只有一小部分服务器可以充当controller(与基于ZooKeeper的模式不同:任何服务器都可以成为controller)。被选择的controller将参与元数据仲裁。每个controller都处于活动状态,或者是当前活动controller的热备用状态。

通常会为该角色选择3或5台服务器,这取决于成本和系统在不影响可用性的情况下应承受的并发故障数等因素。就像ZooKeeper一样,为了保持可用性,必须使大多数contrller保持活动状态。 因此,如果有3个控制器,可以容忍1个故障;使用5个控制器,可以容忍2个故障。

3.2 进程角色

现在,每个Kafka服务器都有一个名为process.roles的参数,其值如下:

  • broker:一个普通Kafka节点
  • controller:一个Kafka控制器
  • broker,controller:同时有broker、controller角色
  • 不设置:认为是ZooKeeper模式

充当broker和controller的节点称为“组合”节点。对于简单的用例,组合节点更易于操作。缺点是controller与系统的其余部分的隔离度较低。例如,如果broker上的活动导致内存不足,则服务器的controller不会与该OOM条件隔离。

3.3 仲裁投票者

系统中的所有节点都必须设置controller.quorum.voters参数。这标识了应该使用的仲裁controller,必须枚举所有controller。这类似于使用ZooKeeper时,ZooKeeper.connect配置必须包含所有ZooKeeperServer。然而与ZooKeeper配置不同是,controller.quorum.voters参数也具有每个节点的ID。格式为 id1@host1:port1,id2@host2:port2 等。

因此,如果有10个broker和3个名为 controller1、controller2、controller3 的controller,那么可能在controller1上具有以下配置:

process.roles=controller
node.id=1
listeners=CONTROLLER://controller1.example.com:9093
controller.quorum.voters=1@controller1.example.com:9093,2@controller2.example.com:9093,3@controller3.example.com:9093

每个broker和每个controller都必须设置controller.quorum.voters。请注意,controller.quorum.voters配置中提供的节点ID必须与提供给服务器的节点ID匹配。因此,在controller1上,node.id必须设置为1,依此类推。注意,controller ID不需要从0或1开始。然而,分配节点ID的最简单和最不容易混淆的方法可能只是给每个服务器一个数字ID,从0开始。还要注意,每个节点ID在特定集群中的所有节点上必须是唯一的;任何两个节点都不能具有相同的节点ID,而不管其process.roles值如何。

3.4 Kafka存储工具

如上所述,在快速开始部分中,必须使用kafka storage.sh工具为新集群生成Cluster ID,然后在启动节点之前在每个节点上运行格式化命令。

在1.0和2.0的版本里面,集群ID是自动生成的,存储数据目录是自动生成的。那为什么在3.0会这样做呢?

社区的的思考是这样子的,即自动格式化有时候会掩盖一些异常,比如,在Unix中,如果一个数据目录不能被挂载,它可能显示为空白,在这种情况下,自动格式化将是将会带来一些问题。这个特性对于 Controller 服务器维护元数据日志特别重要,因为如果三个 Controller 节点中有两个能够从空白日志开始,那么可能会在日志中没有任何内容的情况下,选出一个Leader,这会导致所有的元数据丢失(KRaft 仲裁后发生截断)。一旦发生这个问题,将会是不可逆的故障。

3.5 缺失的能力

以下特性还未完全实现:

  • 通过管理API配置SCRAM用户
  • 支持具有多个存储目录的JBOD配置
  • 修改单独阳性KRaft controller上的某些动态配置
  • 委派令牌
  • 从ZooKeeper模式升级

3.6 Debug

如果遇到问题,可能需要查看元数据日志。

3.6.1 kafka-dump-log

查看元数据日志的一种方法是使用kafka-dump-log.sh工具,如下所示:

$ ./bin/kafka-dump-log.sh  --cluster-metadata-decoder --skip-record-metadata --files /tmp/kraft-combined-logs/__cluster_metadata-0/*.log
Dumping /tmp/kraft-combined-logs/__cluster_metadata-0/00000000000000000000.log
Starting offset: 0
baseOffset: 0 lastOffset: 0 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 1 isTransactional: false isControl: true position: 0 CreateTime: 1614382631640 size: 89 magic: 2 compresscodec: NONE crc: 1438115474 isvalid: truebaseOffset: 1 lastOffset: 1 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 1 isTransactional: false isControl: false position: 89 CreateTime: 1614382632329 size: 137 magic: 2 compresscodec: NONE crc: 1095855865 isvalid: true
payload: {"type":"REGISTER_BROKER_RECORD","version":0,"data":{"brokerId":1,"incarnationId":"P3UFsWoNR-erL9PK98YLsA","brokerEpoch":0,"endPoints":[{"name":"PLAINTEXT","host":"localhost","port":9092,"securityProtocol":0}],"features":[],"rack":null}}
baseOffset: 2 lastOffset: 2 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 1 isTransactional: false isControl: false position: 226 CreateTime: 1614382632453 size: 83 magic: 2 compresscodec: NONE crc: 455187130 isvalid: true
payload: {"type":"UNFENCE_BROKER_RECORD","version":0,"data":{"id":1,"epoch":0}}
baseOffset: 3 lastOffset: 3 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 1 isTransactional: false isControl: false position: 309 CreateTime: 1614382634484 size: 83 magic: 2 compresscodec: NONE crc: 4055692847 isvalid: true
payload: {"type":"FENCE_BROKER_RECORD","version":0,"data":{"id":1,"epoch":0}}
baseOffset: 4 lastOffset: 4 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 2 isTransactional: false isControl: true position: 392 CreateTime: 1614382671857 size: 89 magic: 2 compresscodec: NONE crc: 1318571838 isvalid: truebaseOffset: 5 lastOffset: 5 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 2 isTransactional: false isControl: false position: 481 CreateTime: 1614382672440 size: 137 magic: 2 compresscodec: NONE crc: 841144615 isvalid: true
payload: {"type":"REGISTER_BROKER_RECORD","version":0,"data":{"brokerId":1,"incarnationId":"RXRJu7cnScKRZOnWQGs86g","brokerEpoch":4,"endPoints":[{"name":"PLAINTEXT","host":"localhost","port":9092,"securityProtocol":0}],"features":[],"rack":null}}
baseOffset: 6 lastOffset: 6 count: 1 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 2 isTransactional: false isControl: false position: 618 CreateTime: 1614382672544 size: 83 magic: 2 compresscodec: NONE crc: 4155905922 isvalid: true
payload: {"type":"UNFENCE_BROKER_RECORD","version":0,"data":{"id":1,"epoch":4}}
baseOffset: 7 lastOffset: 8 count: 2 baseSequence: -1 lastSequence: -1 producerId: -1 producerEpoch: -1 partitionLeaderEpoch: 2 isTransactional: false isControl: false position: 701 CreateTime: 1614382712158 size: 159 magic: 2 compresscodec: NONE crc: 3726758683 isvalid: true
payload: {"type":"TOPIC_RECORD","version":0,"data":{"name":"foo","topicId":"5zoAlv-xEh9xRANKXt1Lbg"}}
payload: {"type":"PARTITION_RECORD","version":0,"data":{"partitionId":0,"topicId":"5zoAlv-xEh9xRANKXt1Lbg","replicas":[1],"isr":[1],"removingReplicas":null,"addingReplicas":null,"leader":1,"leaderEpoch":0,"partitionEpoch":0}}

3.6.2 元数据shell

另一个检查元数据日志的工具是kafka-metadata-shell.sh。就像ZooKeeper shell一样,可以检查集群的元数据。

./bin/kafka-metadata-shell.sh  --snapshot /tmp/kraft-combined-logs/__cluster_metadata-0/00000000000000000000.log


http://www.ppmy.cn/news/253853.html

相关文章

NI Linux实时设备上升级固件

设备和对应的文件夹名称:\National Instruments\Shared\Firmware\ 设备 文件夹名称 cRIO-9030 7755 cRIO-9031 774B cRIO-9032 7841 cRIO-9033 7735 cRIO-9034 774D cRIO-9035 77dB的 带有NI-Sync的cRIO-9035 7875 cRIO-9036 77DC cRIO-9037 7840 cRIO-9038 77B9 cR…

小程序发送消息订阅报错{“errcode“:40003,“errmsg“:“invalid openid rid: 641bece8-5b5ed5f9-7c0705a8“}

检查了accessToken跟openid 都是对的 为什么就是会报错呢??? 我们做的项目有两个小程序端 一个是患者端 一个是医护端 在患者端接口给医护端发送订阅消息 结果一直拿着患者端的openid发 实际要用医护端的openId 搞了两天 。。粑粑。

No suitable device found for this connection

MobaXterm连接不上 journal -xeaudit: op"connection-activate" uuid"88e43cb2-b1e5-49a4-85bf-1e3f08f4e605" n Jan 10 04:47:03 hadoop03 network[11697]: Bringing up interface ens33: Error: Connection activation failed: uuid"88e43cb2-b1e…

TCL MS801机芯修改屏参的方法

TCL MS801机芯修改屏参的方法 一、 目的 在TV屏幕显示花屏、黑屏、倒屏等无法正常显示的情况下,可以通过串口修改屏参,使TV屏幕可正常显示。本文档介绍一些简单常见的屏参的修改方法。 二、 修改屏参的准备 串口工具; 三、 修改屏参…

Error syncing pod, skipping: failed to “StartContainer“ for “POD“ with ErrImagePull: “image pull fai

kubernetes:关于创建pod中结点始终处于creating状态的问题解决(Error syncing pod, skipping: failed to "StartContainer" for "POD" with ErrImagePull: "image pull failed for registry.access.redhat.com/rhel7/...&#…

xss漏洞复现

一.过滤了特殊符号 二、过滤了特殊符号和关键字

IM-A820L第一屏与第二屏已破(非开机动画)(应该泛泰机型通用)

第一屏是以raw图片格式存于emmc_appsboot.mbn中,也就是mmcblk0p7中 所以可以直接使用Image Search Editor来打开查找编辑 图片名称偏移地址分辨率图片模式所在文件开机图片0002FEDC444x17424emmc_appsboot.mbnS/W刷机模式图片00068834168x39924emmc_appsboot.mbnS…

IM-A820L用CWM时开启自动更新造成Recovery循环的原因(其他泛泰机型可参考)

造成循环的关键代码在phoneinfo分区中,也就是mmcblk0p10中 00021000 CE CE EC EC 00 9C 00 B0 EB 38 00 B0 D0 25 01 B0 挝祆..半8.靶%.. 00021010 00 9C 00 B0 D4 8B 58 09 E0 FF FF FF 24 04 F0 A7 .霸媂....$.皈 00021020 A4 10 F0 A7 68 94 00 B0 C5 39 00…