【大数据】Centos环境下搭建kafka集群

159 阅读3分钟

image.png

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情


Kafka

在介绍kafka前首先描述几个用到的专有名词:

  • Broker kafka集群的一个或者多个服务器,每个服务器或者服务提供方称之为broker
  • Topic 存储的消息类别 用户只关心topic,无需关注其存储位置
  • Partition 每个topic包含一个或者多个Partition
  • Producer 生产者负责发布消息到Kafka
  • Consumer 消费者负责读取对应Topic的消息

首先kafk并非一个数据库,而是一个分布式的流平台,这就意味着其核心存在并不是用于存储数据,而是消息(数据)的发布和订阅。因此对于kafka的定义是一个由Scala和java编写的具有高吞吐量的分布式发布订阅消息系统。

因此核心是消息队列,之前比较喜欢的一个比喻是,kafka类似于快递自提柜,对于生产者【快递员】,不需要考虑消费者【取件人】的时间,只需要把快递放到自提柜,而消费者只需要去自提货拿自己想取的快递,不需要考虑快递员的送货时间。 这样的好处就是,对于消息发送方和接收方,处理步调不一致的时候,就可以通过kafka这个中间件进行“缓冲”。如生产者是syslog实时日志外送,而消费者是每天定时处理前一天的数据,这种情况下,实时日志外送就不太适合直接与处理程序对接,而是需要kafka进行数据缓冲。

生产者

负责向某个topic上发布消息,可以选择向哪个数据分区上发布消息,一个topic可以通过多个partition进行存储,由下图所示:

image.png

多个partition可以提高队列的吞吐量,而多个broker保存着多个相同的partition组作为冗余备份,生产者只需要将数据丢到对应的partition中,至于数据的负载均衡就交给kafka完成。

消费者

kafka集群保持所有的数据,直到数据过期,而消费者并不是消费数据后删除,而是消费后读取的offset线性增加,如下图:

image.png

当正常消费数据的时候,对于每一个消费者,offset也想增加,也可通过改变offset获取之前的数据。

部署集群

由于项目需要,需要搭建kakfa集群,在此记录一下:

下载kafka的tar包:

kafka.apache.org/downloads

或者直接使用:

downloads.apache.org/kafka/3.3.1…

image.png SFTP上传至服务器,并分发至不同服务器

image.png

解压缩文件

tar -xzf kafka_2.13-3.3.1.tgz

进入文件夹:

cd kafka_2.13-3.3.1/

zookeeper

kakfa服务用到了zookeeper,因此先启动zookeeper,bin目录下的zookeeper-server-start.sh

image.png

进入bin目录执行

./zookeeper-server-start.sh ../config/zookeeper.properties

确认zookeeper 正常运行

netstat -ntlp | grep 2181

image.png

配置kafka

cd ../config/
vi server.properties

配置文件如下:

server-1

broker.id=0
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=/tmp/kafka-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.retention.check.interval.ms=300000
zookeeper.connect=172.16.0.xx:2181,172.16.0.xx:2181,172.16.0.xx:2181
zookeeper.connection.timeout.ms=18000
group.initial.rebalance.delay.ms=0
host.name=172.16.0.xx

server-2

broker.id=1
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=/tmp/kafka-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.retention.check.interval.ms=300000
zookeeper.connect=172.16.0.xx:2181,172.16.0.xx:2181,172.16.0.xx:2181
zookeeper.connection.timeout.ms=18000
group.initial.rebalance.delay.ms=0
host.name=172.16.0.xx

server-3

broker.id=2
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=/tmp/kafka-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.retention.check.interval.ms=300000
zookeeper.connect=172.16.0.xx:2181,172.16.0.xx:2181,172.16.0.xx:2181
zookeeper.connection.timeout.ms=18000
group.initial.rebalance.delay.ms=0
host.name=172.16.0.xx

启动kafka

进入bin目录

./kafka-server-start.sh ../config/server.properties

image.png

image.png

image.png

Bug

【Bug】

ERROR Exiting Kafka due to fatal exception during startup. (kafka.Kafka$)
kafka.common.InconsistentClusterIdException: The Cluster ID 0WDLRbBNQnOd_ejJeDV8iw doesn't match stored clusterId Some(hwuDBpOrQWW54gFXhZnS-w) in meta.properties. The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.


【Solution】

从根目录启动

bin/kafka-server-start.sh config/server.properties
【Bug】

The Cluster ID kVSgfurUQFGGpHMTBqBPiw doesn't match stored clusterId Some(0Qftv9yBTAmf2iDPSlIk7g) in meta.properties. The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.


【Solution】

从根目录启动

删除log.dirs=/tmp/kafka-logs下的所有文件

测试

使用python编写测试脚本

producer.py

from kafka import KafkaProducer
import json

producer = KafkaProducer(
    value_serializer=lambda v: json.dumps(v).encode('utf-8'),
    bootstrap_servers=['threat01:9092','threat02:9092','threat03:9092']
)

def testProduct(i):
    msg_dict = {
        "username":f"testUser_{i}",
        "userId":f"test_{i}"
    }
    producer.send("test", msg_dict)
    producer.close()

def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('PyCharm')
    for i in range(100):
        testProduct(i)

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

consumer.py

# -*- coding: utf-8 -*-
from kafka import KafkaConsumer

consumer = KafkaConsumer('test', bootstrap_servers=['threat01:9092','threat02:9092','threat03:9092'])
for msg in consumer:
    print(msg.value)

生产侧:

image.png

消费侧:

image.png

然后就可以愉快的使用了~ Thanks♪(・ω・)ノ