kafka提供了一些命令行工具,用于管理集群的变更。
主题操作
创建主题
创建一个主题需要用到3个参数:
- 主题名字:想要创建主题的名字,名字可以包含字母、数字、下划线以及英文状态下的破折号和句号
- 复制系数:主题的副本数量
- 分区:主题的分区数量
命令行格式:
kafka-topic.sh --zookeeper <zookeeper connect> --create --topic <String> --replication-factor <integer> --partitions <integer>
示例:创建一个名叫my-topic的主题,主题包含3个分区,每个分区拥有2个副本
$ ./kafka-topic.sh --zookeeper node01:2181,node02:2181,node03:2181 --create --topic my-topic --replication-factor 2 --partitions 3
增加分区
如果要在单个消费者群组内运行更多的消费者,那么分区数量也需要响应的增加,因为一个分区只能由群组里的一个消费者读取。
为基于键的主题添加分区是困难的,因为改变了分区数量,键到分区之间的映射也会发生变化;因此,对于基于键的主题,建议一开始就设置好分区数量,避免后期对其进行调整。
命令行格式:
kafka-topic.sh --zookeeper <zookeeper connect> --alter --topic <String> --partitions <integer>
示例:将my-topic主题分区增加到5
$ ./kafka-topic.sh --zookeeper node01:2181,node02:2181,node03:2181 --alter --topic my-topic --partitions 5
减少分区是无法进行的,因为如果删除了分区,分区里的数据也一并删除,导致数据不一致;如果一定要减少分区数量,只能删除整个主题,然后重新创建它。
删除主题
将不再使用的主题继续留在集群中就会占用一定数量的磁盘空间和文件句柄,所以对于不需要的主题应该将它删除掉。
删除主题首先需要将broker中的
delete.topic.enable
参数修改为true
,否则删除主题的请求会被忽略。
命令行格式:
kafka-topic.sh --zookeeper <zookeeper connect> --delete --topic <String>
示例:删除主题test
$ ./kafka-topic.sh --zookeeper node01:2181,node02:2181,node03:2181 --delete -topic test
列出集群里的所有主题
通过--list
参数可以列出集群里的所有主题,主题之间没有特定的顺序。
示例:列出集群里的所有主题
$ ./kafka-topic.sh --zookeeper node01:2181,node02:2181,node03:2181 --list
显示结果:
列出主题详细信息
主题工具可以通过使用--describe
参数来获取主题的详细信息。该信息包含分区数量、主题的覆盖配置以及每个分区副本清单。
如果只想要列出指定主题的详细信息,则可以加上--topic
参数。如下示例:查看my-topic主题的详细信息:
$ ./kafka-topic.sh --zookeeper node01:2181,node02:2191,node03:2181 --describe --topic my-topic
describe命令还提供了一些参数,用于过滤输出结果,但这些参数不能够使用--topic
参数:
--topic-with-overrides
:找出所有包含覆盖配置的主题,只会列出包含了与集群不一样配置的主题
以下两个参数用于找出有问题的分区:
--under-replicated-partitions
:列出所有包含不同步副本的分区--unavailable-paritions
:列出所有没有首领的分区,这些分区已经处理离线状态,对于消费者和生产者来说是不可用的
消费者群组
kafka中,有两个地方保存着消费者群组信息。
-
旧版本
信息保存在
zookeeper
上,对消费者群组进行操作时,需要通过--zookeeper
参数指定zookeeper的地址 -
新版本
信息保存在
broker
上,对消费者群组进行操作时,需要通过--bootstrap-server
参数指定broker的主机名和端口
列出并描述群组
## 旧版本
$ ./kafka-consumer-groups.sh --zookeeper node01:2181,node02:2191,node03:2181 --list
## 新版本
$ ./kafka-consumer-groups.sh --bootstrap-server node01:9092,node02:9092,node03:9092 --list
删除群组
只有旧版本的消费者客户端才支持删除群组操作,并且删除群组之前必须关闭所有的消费者。
$ ./kakfa-consumer-groups.sh --zookeeper node01:2181,node02:2191,node03:2181 --delete --group <群组名>
动态配置变更
动态配置是当集群处于运行状态时,覆盖主题配置和客户端的配额参数;这些参数一旦设置完毕后成为集群的永久配置,被保存在zookeeper上,broker启动的时候会读取他们。不管是在工具里还是文档里,所说的动态配置参数都是基于“主题”实例或者“客户端”实例的,都是可以被“覆盖”的。
以下只给出命令格式,具体的参数请参看官方文档:http://kafka.apache.org/documentation/#topicconfigs
覆盖主题的默认配置
命令行格式:
kafka-config.sh --zookeeper <zookeeper connect> --alter --entity-type topics --entity-name <topic name> --add-config <key>=<value>[,<key>=<value>...]
覆盖客户端的默认配置
命令行格式:
kafka-config.sh --zookeeper <zookeeper connect> --alter --entity-type clients --entity-name <client ID> --add-config <key>=<value>[,<key>=<value>...]
列出被覆盖的配置
该命令只能用于显示被覆盖的配置,不包含集群的默认配置。在进行自动化时,如果过要实现这个工具来获得主题和客户端的配置信息,必须同时为它提供集群的默认配置信息。
命令行格式:
kafka-config.sh --zookeeper <zookeeper connect> --describe --entity-type topics --entity-name <topic name>
移除被覆盖的配置
动态的配置完全可以被移除,从而恢复到集群的默认配置。
命令行格式:
kafka-configs.sh --zookeeper <zookeeper connect> --alter --entity-type topics --entity-name <topic name> --delete-config <key>
分区管理
kafka提供了两个脚本用于分区管理:
- 用于重新选举首领
- 用于将分区分配给broker
结合两个工具使用可以实现集群流量的负载均衡。
首选的首领选举
使用多个分区副本可以提升可靠性,但只有其中的一个副本可以成为首领,并且只有首领所在的broker可以进行生产和消费活动。进行首领选举时,集群的元数据会被写到zookeeper的节点上,如果元数据超过了节点允许的大小(默认1MB),那么选举会失败。因此,需要将分区清单的信息写到一个JSON文件里,并将请求分为多个步骤进行:
JSON文件格式:
{
"partitions": [
{
"partition": 1,
"topic": "foo"
},
{
"partition": 2,
"topic": "foobar"
}
]
}
通过在json文件中指定分区清单来启动副本选举:
$ ./kafka-preferred-replia-election.sh --zookeeper <zookeeper connect> --path-to-json-file <json文件名>
修改分区副本
以下三个场景可能需要修改分区副本:
- 主题分区在整个集群里的不均衡分布造成了集群负载的不均衡
- broker离线造成分区不同步
- 新加入的broker需要从集群里获得负载
我们可是使用kafka-reassign-partitions.sh
工具来修改分区,使用步骤如下:
- 根据broker清单和主题清单生产一组迁移步骤;
- 执行迁移步骤;
- 可选。使用生成的迁移步骤验证分区重分配的进度和完成情况
在生成迁移步骤时需要先创建一个包含主题清单的JSON文件,格式如下:
{
"topic": [
{
"topic":"foo"
},
{
"topic":"foo1"
}
],
"version": 1
}
接下来为topic.json文件里的主题生成迁移步骤:
$ ./kafka-reassign-partitions.sh --zookeeper node01:2181,node02:2181,node03:2181 --generate --topics-to-move-json-file topics.json --broker-list 0,1
执行了该命令后,会在控制台上输出两个JSON对象,分别描述了当前的分区分配情况以及建议的分区分配方案。我们可以把第一个JSON对象保存起来以便用于回滚;将第二个JSON对象保存到另一个文件中,例如:reassign.json
;然后利用kafka-reassign-partitions.sh
工具执行第二个步骤:
$ ./kafka-reassign-partitions.sh --zookeeper node01:2181,node02:2181,node03:2181 --execute --reassignment-json-file reassign.json
可选的第三步,验证reassign.json文件里指定的分区重分配情况:
$ ./kafka-reassign-partitions.sh --zookeeper node01:2181,node02:2181,node03:2181 --verify --reassignment-json-file reassign.json
修改复制系数
当在创建分区时指定了错误的复制系数,那么就有必要修改他们。这可以通过创建一个JSON对象来完成,对象格式使用分去重新分配的执行步骤中的格式,显示指定分区所需的副本数量。例如:假设主题my-topic有一个分区,该分区的复制系数为1;
{
"partitions": [
{
"topic":"my-topic",
"partition":0,
"replicas": [
1
]
}
],
"version": 1
}
在重新分配的执行步骤中使用以下JSON将复制系数改为2:
{
"partitions": [
{
"topic":"my-topic",
"partition":0,
"replicas": [
1,
2
]
}
],
"version": 1
}
也可以通过类似方式减小分区的复制系数
副本验证
可以使用kafka-replica-verification.sh
工具来验证集群分区副本的一致性;它会从指定副本是获取消息,并检查所有副本是否具有相同的消息。
示例:对以my-开头的主题副本进行验证
./kafka-replica-verification.sh --broker-list node01:9092,node02:9092,node03:9092 --topic-white-list "my-.*"
消费和生产
kafka提供了kafka-console-consumer.sh
和kafka-console-producer.sh
两个工具,让用户不需要编写整个应用就可以与kafka主题进行交互。
控制台生产者
kafka-console-producer.sh
工具用于向kafka主题写入消息。该命令每一行视为一条消息,消息键值以tab字符分隔。有两个参数是必须指定的:
--broker-list
:指定一个或多个broker,以逗号分隔;格式:hostname:port--topic
:指定生成消息的目标主题
示例:向主题my-topic生成两个消息
$ ./kafka-console-producer.sh --broker-list node01:9092,node02:9092,node03:9092 --topic my-topic
控制台生产者常用的行为参数:
参数 | 说明 |
---|---|
–key-serializer CLASSNAME | 指定消息键的编码器类名,默认为kafka.serializer.DefaultEncoder |
–value-serializer CLASSNAME | 指定消息值的编码器类名,默认kafka.serializer.DefaultEncoder |
–compression-codec STRING | 指定生成消息所使用的压缩类型node、gzip、snappy和lz4,默认gzip |
–sync | 指定以同步的方式生成消息 |
控制台消费者
kafka-console-consumer.sh
工具用于从一个或多个主题上去读消息。使用命令行读取消息以空行分隔,默认情况下会打印没有经过格式化的原始消息字节。
读取消息需要指定两个东西:
-
指定kafka集群的地址
新版本:必须使用
--new-consumer
和--broker-list
,如:--broker-list node01:9092,node02:9092,node03:9092
旧版本:提供
--zookeeper
参数,如:--zookeeper node01:2181,node02:2181,node03:2181
-
指定待读取的主题,参数有三个,允许只指定一个参数:
--topic
:指定单个待读取主题--whitelist
:白名单正则表达式匹配的主题将会被读取--blacklist
:黑名单正则表达式匹配的主题不会被读取
示例:读取单个主题my-topic
$ ./kafka-console-consumer.sh --zookeeper node01:2181,node02:2181,node03:2181 --topic my-topic
控制台常用配置:
参数 | 说明 |
---|---|
–formatter CLASSNAME | 指定消息格式化器的类名,用于解码消息 |
–from-beginning | 指定从最旧的偏移量开始读取消息 |
–max-message NUM | 指定在退出之前最多读取NUM个消息 |
–partition NUM | 指定只读取ID为NUM的分区(新版本消费者) |
消息格式化器有四个:
-
kafka.tools.DefaultMessageFormatter
默认,还可以通过
--property
传递一些配置选项print.timestamp
:为true,则会打印每条消息的时间戳print.key
:为true,额外还会打印消息的键print.separator
:指定打印消息的键和消息的分隔符line.separator
:指定消息之间的分隔符key.deserializer
:指定打印消息的键使用的反序列化器类名value.deserializer
:指定打印消息的值使用的反序列化器类名
-
kafka.tools.LogginMessageFormatter
将消息输出到日志,而不是输出到标准的输出设备
-
kafka.tools.ChecksumMessageFormatter
只打印消息的校验和
-
kafka.tools.NoOpMessageFormatter
读取消息但是不打印消息
客户端ACL
命令行工具kafka-acls.sh
工具,用于处理与客户端访问控制相关的问题,具体内容查看文档http://kafka.apache.org/documentation/#security_authz_cli
参考资料
Neha Narkhede, Gwen Shapira ,Todd Palino(著) , 薛命灯 (译) . Kafka 权威指南 . 人民邮电出版社 . 2018.1