Kafka--简介,部署
kafka官网:https://kafka.apache.org/documentation/
本文kafka版本:3.1.0
一、简介
Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。
作用:
- 发布(写入)和订阅(读取)事件流,包括从其他系统持续导入/导出数据
- 根据需要持久可靠地 存储事件流
- 在事件发生时或回顾性 地处理事件流
所有这些功能都以分布式、高度可扩展、弹性、容错和安全的方式提供。Kafka 可以部署在裸机硬件、虚拟机和容器上,也可以部署在本地和云端。可以在自行管理 Kafka 环境和使用各种供应商提供的完全托管服务之间进行选择。
主要概念和术语:
事件(event):
事件记录了业务中“发生了某事” 的事实。在文档中也称为记录或消息。当向 Kafka 读取或写入数据时,以事件的形式执行此操作。从概念上讲,事件具有键(key)、值(value)、时间戳(timestamp)和可选的元数据标头(metadata headers)。
例:
- Event key: "Alice"
- Event value: "Made a payment of $200 to Bob"
- Event timestamp: "Jun. 25, 2020 at 2:06 p.m."
生产者(Producers):向 Kafka 发布(写入)事件的客户端应用程序
消费者(Consumer):订阅(读取和处理)这些事件的那些客户端应用程序
生产者和消费者完全解耦并且彼此不可知
AMQP服务端(broker):用来接收生产者发送的消息并将这些消息路由给服务器中的队列,便于kafka将生产者发送的消息,动态的添加到磁盘并给每一条消息一个偏移量,所以对于kafka,一个broker就是一个应用程序的实例
主题(Topic):事件被组织并持久地存储在主题中。非常简化,主题类似于文件系统中的文件夹,事件是该文件夹中的文件
Kafka 中的主题始终是多生产者和多订阅者:一个主题可以有零个、一个或多个向其写入事件的生产者,以及零个、一个或多个订阅这些事件的消费者。
主题中的事件可以根据需要随时读取——与传统的消息传递系统不同,事件在消费后不会被删除。相反,您可以通过每个主题的配置设置来定义 Kafka 应该将您的事件保留多长时间,之后旧事件将被丢弃。
Kafka 的性能在数据大小方面实际上是恒定的,因此长时间存储数据是非常好的。
分区(Partitioned):一个Topic中的消息数据按照多个分区组织,分区是kafka消息队列组织的最小单位,分区里面的消息是按照从新到老的顺序进行组织,消费者从队列头订阅消息,生产者从队列尾添加消息
使用分区允许客户端应用程序同时从多个代理读取和写入数据。当一个新事件发布到一个主题时,它实际上是附加到主题的分区之一。
具有相同事件键(例如,客户或车辆 ID)的事件被写入同一个分区,并且 Kafka保证给定主题分区的任何消费者将始终以与写入事件完全相同的顺序读取该分区的事件。
备份(Replication) :为了数据具有容错性和高可用性,可以复制每个主题,甚至跨地理区域或数据中心,以便始终有多个代理拥有数据副本,一个常见的生产设置是复制因子为 3,即始终存在三个数据副本。此复制在主题分区级别执行。
二、部署,配置
kafka 2.8.0版本及以上,内置了zk,不再使用单独的zk集群,可用自带的zk启动,也可用kraft启动,但目前技术可能尚不成熟,所以线上环境还是得搭建专门的zk集群
2.1 部署zk集群(2.8+忽视)
部署kafka之前需要先部署zk,zk作为给分布式系统提供协调服务的工具被 kafka 所依赖。
在分布式系统中,消费者需要知道有哪些生产者是可用的,而如果每次消费者都需要和生产者建立连接并测试是否成功连接,那效率也太低了,显然是不可取的。
而通过使用 ZooKeeper 协调服务,Kafka 就能将 Producer,Consumer,Broker 等结合在一起,同时借助 ZooKeeper,Kafka 就能够将所有组件在无状态的条件下建立起生产者和消费者的订阅关系,实现负载均衡。
2.2 下载,安装包
本文仅介绍使用zk的部署,kraft模式将在另一文章介绍。
直接在官网上选择版本包下载到本地,再上传至服务器
包地址:https://kafka.apache.org/downloads
tar -xvf kafka_2.13-3.1.0.tgz -C /usr/local/
mv /usr/local/kafka_2.13-3.1.0/ /usr/local/kafka
2.3 配置文件
2.3.1 server.properties配置
[root@kafka ~]# grep -v "^#\|^$" /usr/local/kafka/config/server.properties
broker.id=0
listeners=PLAINTEXT://10.xx.xx.x: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=/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.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=localhost:2181
zookeeper.connection.timeout.ms=18000
group.initial.rebalance.delay.ms=0
配置文件详解:
参数 | 说明 |
broker.id | broker在集群中的唯一标识,要求是正数;当该服务器的ip发生变化时,若此id不变,则不会影响consumers的消息情况 |
listeners=PLAINTEXT://10.x.x.xx:9092 | 使用ip地址设置,更换地址需要重启kafka |
listeners=PLAINTEXT://kafka1:9092 | 使用域名设置,需要做好域名解析,支持热更新,无需重启kafka |
num.network.threads | borker进行网络处理的线程数,一般不用修改 |
num.io.threads | borker进行磁盘I/O处理的线程数 |
socket.send.buffer.bytes | 发送缓冲区buffer大小 |
socket.receive.buffer.bytes | kafka接收缓冲区大小 达到后序列化到磁盘 |
socket.request.max.bytes | 向kafka请求消息或向kafka发送消息的请求的最大数值,防止serverOOM |
log.dirs | 消息存放的目录,多目录用,分隔,新创建的topic把消息持久化在分区数最少那一个目录中 |
num.partitions | topic默认的分区数,多分区允许消费者并行获取数据,但这也会造成brokers交叉保存多个文件 |
num.recovery.threads.per.data.dir | 当Kafka启动时恢复数据和关闭时保存数据到磁盘时使用的线程个数 |
offsets.topic.replication.factor | 消息备份,集群官方推荐3,单机为1 |
transaction.state.log.replication.factor | |
transaction.state.log.min.isr | |
log.flush.interval.messages | 在持久化到磁盘前message最大接收条数 |
log.flush.interval.ms | 持久化的最大时间间隔 |
log.retention.hours | 默认消息的最大持久化时间 单位h |
message.max.bytes | 保存消息的最大大小,单位是字节 |
default.replication.factor | kafka保存消息的副本数 |
replica.fetch.max.bytes | 取消息的最大字节数 |
log.segment.bytes | 单个分片的上限,达到该大小后会生成新的日志分片 |
log.retention.check.interval.ms | 日志分片的检测时间间隔,每隔该时间会根据log保留策略决定是否删除log分片 |
zookeeper.connect |
Zookeeper连接字符串。是一个使用逗号分隔的host:port字符串 2.8.0以下版本填zk集群地址,2.8.0以上可以填本机ip或localhost 例:zookeeper.connect=192.168.198.199:2181,192.168.198.129:2181,192.168.198.151:2181 zookeeper.connect=zkserver1:2181,zkserver2:2181,zkserver3:2181 |
zookeeper.connection.timeout.ms | 连接zookeeper的超时时间 |
group.initial.rebalance.delay.ms | 在开发测试环境下该值设置为0,保证启动后马上可以使用。但在生产环境下,默认值3秒更适合 |
2.3.2 zookeeper.properties
[root@kafka kafka]# grep -v "^#\|^$" /usr/local/kafka/config/zookeeper.properties dataDir=/tmp/zookeeper clientPort=2181 maxClientCnxns=0 admin.enableServer=false
2.4 topic配置
配置topic级别参数时,相同(参数)属性topic级别会覆盖全局的,否则默认为全局配置属性值;创建topic参数可以设置一个或多个--config "Property(属性)",例:
#创建一个名为my-topic 的主题,具有自定义的最大消息大小和刷新率 /usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic my-topic --partitions 1 --replication-factor 1 --config max.message.bytes=64000 --config flush.messages=1
Property(属性) | Default(默认值) | Server Default Property(server.properties) | 说明 | 是否会被创建topic时指定的参数覆盖 |
cleanup.policy | delete | log.cleanup.policy | 日志清理策略选择有:delete和compact主要针对过期数据的处理,或是日志文件达到限制的额度 | 是 |
delete.retention.ms | 86400000 (24 hours) | log.cleaner.delete.retention.ms |
对于压缩的日志保留的最长时间,也是客户端消费消息的最长时间 同log.retention.minutes的区别在于一个控制未压缩数据,一个控制压缩后的数据 |
是 |
flush.messages | None | log.flush.interval.messages |
log文件”sync”到磁盘之前累积的消息条数,因为磁盘IO操作是一个慢操作,但又是一个”数据可靠性"的必要手段 所以此参数的设置,需要在"数据可靠性"与"性能"之间做必要的权衡 如果此值过大,将会导致每次"fsync"的时间较长(IO阻塞) 如果此值过小,将会导致"fsync"的次数较多,这也意味着整体的client请求有一定的延迟.物理server故障,将会导致没有fsync的消息丢失 |
|
flush.ms | None | log.flush.interval.ms |
仅仅通过interval来控制消息的磁盘写入时机,是不足的 此参数用于控制"fsync"的时间间隔,如果消息量始终没有达到阀值,但是离上一次磁盘同步的时间间隔达到阀值,也将触发 |
|
index.interval.bytes | 4096 | log.index.interval.bytes |
当执行一个fetch操作后,需要一定的空间来扫描最近的offset大小 设置越大,代表扫描速度越快,但是也更耗内存(一般情况下忽视这个参数) |
|
message.max.bytes | 1000000 | message.max.bytes | 表示消息的最大大小,单位是字节 | |
min.cleanable.dirty.ratio | 0.5 | log.cleaner.min.cleanable.ratio | 日志清理的频率控制,越大意味着更高效的清理,同时会存在一些空间上的浪费 | 是 |
retention.bytes | None | log.retention.bytes |
topic每个分区的最大文件大小,一个topic的大小限制 = 分区数*log.retention.bytes 设置为-1没有大小限制 log.retention.bytes和log.retention.minutes任意一个达到要求,都会执行删除 |
是 |
retention.ms | None | log.retention.minutes |
数据存储的最大时间超过这个时间会根据log.cleanup.policy设置的策略处理数据,也就是消费端能够多久去消费数据 log.retention.bytes和log.retention.minutes任意一个达到要求,都会执行删除 |
是 |
segment.bytes | 1 GB | log.segment.bytes | topic的分区是以一堆segment文件存储的,这个控制每个segment的大小 | 是 |
segment.index.bytes | 10 MB | log.index.size.max.bytes | 对于segment日志的索引文件大小限制 | 是 |
log.roll.hours | 7 days | log.index.size.max.bytes | 这个参数会在日志segment没有达到log.segment.bytes设置的大小,也会强制新建一个segment | 是 |
三、启停
先启动zk
#额外搭建的zk集群 /usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/bin/zkServer.sh stop #内置的zk /usr/local/kafka/bin/zookeeper-server-start.sh /usr/local/kafka/config/zookeeper.properties & /usr/local/kafka/bin/zookeeper-server-stop.sh
再启动kafka
#启动 /usr/local/kafka/bin/kafka-server-start.sh /usr/local/kafka/config/server.properties &
/usr/local/kafka/bin/zookeeper-server-start.sh -daemon /usr/local/kafka/config/zookeeper.properties #停止 /usr/local/kafka/bin/kafka-server-stop.sh
四、常用命令
4.1 topic
创建topic,名称为test2022,具有一个分区,一个副本:
/usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic test2022 --partitions 1 --replication-factor 1
删除topic:
/usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic test2022
查看节点上的所有topic:
/usr/local/kafka/bin/kafka-topics.sh --list --bootstrap-server localhost:9092
查看所有的topic,可匹配正则:
/usr/local/kafka/bin/kafka-topics.sh --list --bootstrap-server localhost:9092 --exclude-internal /usr/local/kafka/bin/kafka-topics.sh --list --bootstrap-server localhost:9092 --exclude-internal --topic "test.*"
查看topic的详细信息:
/usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic my-topic /usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic my-topic --exclude-internal --topic "test.*"
更改或覆盖设置:
bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name my-topic --alter --add-config max.message.bytes=128000
检查覆盖设置:
/usr/local/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name my-topic --describe
删除覆盖设置:
/usr/local/kafka/bin/kafka-configs.sh --bootstrap-server localhost:9092 --entity-type topics --entity-name my-topic --alter --delete-config max.message.bytes
增加指定topic的分区数量:
/usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --alter --topic test2022 --partitions 3 /usr/local/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --alter --topic "test.*" --partitions 3
4.2 producer
启动生产端发送消息,ctrl c退出:
[root@kafka kafka]# /usr/local/kafka/bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test2022 >hello >wrold
4.3 consumer
启动消费端接收消息,会实时显示消息:
/usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test2022
新客户端从头开始消费:
/usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test2022 --from-beginning