C#入门Kafka

1, 搭建 Kafka 环境

本章的内容比较简单,我们将使用 Docker 快速部署一个单节点的 Kafka 或 Kafka 集群,在后面的章节中,将会使用已经部署好的 Kafka 实例做实验,然后我们通过不断地实验,逐渐了解 Kafka 的知识点以及掌握客户端的使用。

这里笔者给出了单机和集群两种部署方式,但是为了便于学习后面的章节,请以集群的方式部署 Kafka。

安装 docker-compose

使用 docker-compose 部署 Kafka 可以减少很多没必要的麻烦,一个脚本即可完成部署,省下折腾时间。

安装 docker-compose 也是挺简单的,直接下载二进制可执行文件即可。

INSTALLPATH=/usr/local/bin
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o ${INSTALLPATH}/docker-compose

sudo chmod +x ${INSTALLPATH}/docker-compose

docker-compose --version
如果系统没有映射 /usr/local/bin/ 路径,执行命令完成后,如果发现找不到 docker-compose 命令,请将文件下载到 /usr/bin,即替换 INSTALLPATH=/usr/local/bin 为 INSTALLPATH=/usr/bin。

单节点 Kafka 的部署

创建一个 docker-compose.yml 文件,文件内容如下:

---version:'3'services:zookeeper:image:confluentinc/cp-zookeeper:7.3.0container_name:zookeeperenvironment:ZOOKEEPER_CLIENT_PORT:2181ZOOKEEPER_TICK_TIME:2000broker:image:confluentinc/cp-kafka:7.3.0container_name:brokerports:# To learn about configuring Kafka for access across networks see# https://www.confluent.io/blog/kafka-client-cannot-connect-to-broker-on-aws-on-docker-etc/-"9092:9092"depends_on:-zookeeperenvironment:KAFKA_BROKER_ID:1KAFKA_ZOOKEEPER_CONNECT:'zookeeper:2181'KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXTKAFKA_ADVERTISED_LISTENERS:PLAINTEXT://192.168.3.156:9092,PLAINTEXT_INTERNAL://broker:29092KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR:1KAFKA_TRANSACTION_STATE_LOG_MIN_ISR:1KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR:1volumes:-/data/kafka/broker/logs:/opt/kafka/logs-/var/run/docker.sock:/var/run/docker.sock
请替换 PLAINTEXT://192.168.3.156 中的 IP 。

然后执行命令开始部署应用:

docker-compose up -d

接着,安装 kafdrop,这是一个 Kafka 管理界面,可以很方便地查看一些信息。

docker run -d --rm  -p 9000:9000 \
-e JVM_OPTS="-Xms32M -Xmx64M" \
-e KAFKA_BROKERCONNECT=192.168.3.156:9092 \
-e SERVER_SERVLET_CONTEXTPATH="/" \
obsidiandynamics/kafdrop

Kafka 集群的部署

Kafka 集群的部署方法有很多,方法不尽相同,其中使用的配置参数(环境变量)也很多,这里笔者只给出自己在使用的快速部署参数,读者可以参阅官方文档,以便定制配置。

笔者的部署脚本中其中一些重要的环境变量说明如下:

  • KAFKA_BROKER_ID: 当前 Broker 实例的 id,Broker id 不能重复;

  • KAFKA_NUM_PARTITIONS:默认 Topic 的分区数量,默认为 1,如果设置了这个配置,自动创建的 Topic 会根据这个大小设置分区数量。

  • KAFKA_DEFAULT_REPLICATION_FACTOR:默认 Topic 分区的副本数;

  • KAFKA_ZOOKEEPER_CONNECT:Zookeeper 地址;

  • KAFKA_LISTENERS:Kafka Broker 实例监听的 ip;

  • KAFKA_ADVERTISED_LISTENERS:外部如何访问当前实例,用于 Zookeeper 监控;

创建一个 docker-compose.yml 文件,文件内容如下:

---version:'3'services:zookeeper:image:confluentinc/cp-zookeeper:7.3.0container_name:zookeeperenvironment:ZOOKEEPER_CLIENT_PORT:2181ZOOKEEPER_TICK_TIME:2000kafka1:image:confluentinc/cp-kafka:7.3.0container_name:broker1ports:-19092:9092depends_on:-zookeeperenvironment:KAFKA_BROKER_ID:1KAFKA_NUM_PARTITIONS:3KAFKA_DEFAULT_REPLICATION_FACTOR:2KAFKA_ZOOKEEPER_CONNECT:'zookeeper:2181'KAFKA_LISTENERS:PLAINTEXT://0.0.0.0:9092KAFKA_ADVERTISED_LISTENERS:PLAINTEXT://192.168.3.158:19092volumes:-/data/kafka/broker1/logs:/opt/kafka/logs-/var/run/docker.sock:/var/run/docker.sockkafka2:image:confluentinc/cp-kafka:7.3.0container_name:broker2ports:-29092:9092depends_on:-zookeeperenvironment:KAFKA_BROKER_ID:2KAFKA_NUM_PARTITIONS:3KAFKA_DEFAULT_REPLICATION_FACTOR:2KAFKA_ZOOKEEPER_CONNECT:'zookeeper:2181'KAFKA_LISTENERS:PLAINTEXT://0.0.0.0:9092KAFKA_ADVERTISED_LISTENERS:PLAINTEXT://192.168.3.158:29092volumes:-/data/kafka/broker2/logs:/opt/kafka/logs-/var/run/docker.sock:/var/run/docker.sockkafka3:image:confluentinc/cp-kafka:7.3.0container_name:broker3ports:-39092:9092depends_on:-zookeeperenvironment:KAFKA_BROKER_ID:3KAFKA_NUM_PARTITIONS:3KAFKA_DEFAULT_REPLICATION_FACTOR:2KAFKA_ZOOKEEPER_CONNECT:'zookeeper:2181'KAFKA_LISTENERS:PLAINTEXT://0.0.0.0:9092KAFKA_ADVERTISED_LISTENERS:PLAINTEXT://192.168.3.158:39092volumes:-/data/kafka/broker3/logs:/opt/kafka/logs-/var/run/docker.sock:/var/run/docker.sock
由于三个 Broker 实例都在同一个虚拟机上面,因此这里通过暴露不同的端口,避免 Broker 冲突。

然后执行命令开始部署应用:

docker-compose up -d

接着部署 kafdrop:

docker run -d --rm  -p 9000:9000 \
-e JVM_OPTS="-Xms32M -Xmx64M" \
-e KAFKA_BROKERCONNECT=192.168.3.158:19092,192.168.3.158:29092,192.168.3.158:39092 \
-e SERVER_SERVLET_CONTEXTPATH="/" \
obsidiandynamics/kafdrop

现在,已经部署好了 Kafka 环境以及管理面板。

2, Kafka 概念

在本章中,笔者会介绍 Kafka 的一些基本概念,文中的内容是笔者个人理解总结,可能会有错误或其它问题,如有疑问,欢迎指出。

基本概念

一个简单的 生产消息 -> 保存到 Broker -> 消费消息 的结构图示例如下:

在这里,出现了四个对象:

生产者 Producer:产生 Message 的客户端;

消费者 Consumer :消费 Message 的客户端;

主题 Topic:逻辑上的东西;

消息 Message: 数据实体;

当然图中每一个对象本身都是很复杂的,这里为了便于学习,画了个简单的图,现在我们先从最简单的结构图开始了解这些东西。

这里的图比较简单,大概是这样的, Kafka 中有多个 Topic,Producer 可以向指定的 Topic 生产一条消息,而 Consumer 可以消费指定 Topic 的消息。

Producer 和 Consumer 都是客户端应用,只是在执行的功能上有所区分,理论上 Kafka 的客户端库都是将两者的代码写在同一个模块,例如 C# 的 confluent-kafka-dotnet,同时具有生产者和消费者的 API。

然后就是这个 Message 了,Message 主要结构是:

Key
Value 
其它元数据

其中 Value 是我们自定义消息内容的地方。

关于 Message,我们这里简单了解即可,在后面的章节中会继续深入介绍。

在 Kafka 中,每个 Kafka 实例称为 Broker,每个 Broker 中可以保存多个 Topic。每个 Topic 可以划分为多个分区,每个分区保存的数据是不一样的,这些分区可以在同一个 Broker 中,也可以在散布在不同的 Broker 中。

一个 Broker 可以存储不同 Topic 的不同分区,也可以存储同一个 Topic 的不同分区。

如果一个 Topic 有多个分区,一般来说其并发量会有所提高,通过增加分区数实现集群的负载均衡,一般情况下,分区均衡需要散布在不同的 Broker 才能合理地负载均衡,不然分区都在同一个 Broker 时,瓶颈在单个机器上。

如果 Broker 的实例比较少,但是 Topic 划分了多个分区,那么这些分区会被部署到同一个 Broker 上。

主题分区可以有效提高生产者或消费者的并发量,因为将消息分别存储到不同的分区中,可以同时往多个分区推送消息,会比只向一个分区推送消息的速度快。

前面提到,每个 Message 都有 Key 和 Value,Topic 可以根据 Message 的 Key 将一个 Message 存储到不同的分区。当然,我们也可以在生产消息的时候,指定向一个分区推送消息。

分区可以提高并发,但是如果一个 Broker 挂了,数据便会丢失,怎么办?

在 Kafka 中,分区可以设置多个分区副本,这些副本跟分区并不在同一个 Broker 上,这个当 Broker 挂了后,这些分区可以利用副本在其它 Broker 上复活。

[info] 提示
在 《Kafka权威指南(第2版)》 的 21 页中,指导了如何合理设置分区数量,以及分区的优势和缺点。

关于 Kafka 脚本工具

前面介绍了 Kafka 的一些简单概念,为了更加好地了解 Kafka,我们可以利用 Kafka 的脚本做一些实验。

打开其中一个 Kafka 容器(docker exec 命令进入容器),然后执行命令查看自带的二进制脚本:

ls -lah /usr/bin/ | grep kafka

可以看到,里面有很多 CLI 工具,每种 CLI 工具说明文档可以到这里查看:

https://docs.cloudera.com/runtime/7.2.10/kafka-managing/topics/kafka-manage-basics.html

下面笔者介绍部分 CLI 工具的使用方法。

主题管理

kafka-topics 是用于主题管理的 CLI 工具,kafka-topics 提供基本操作如下所示:

  • 操作:

  • --create:创建主题;

  • --alter:变更这个主题,修改分区数等;

  • --config:修改主题相关的配置;

  • --delete:删除该主题;

在管理主题时,我们可以设置主题配置,主题配置存储时,其格式示例为 default.replication.factor ,如果用 CLI 工具操作,那么传递的参数示例为 --replication-factor,因此我们通过不同工具操作主题时,参数名称可能不同一样。

主题的所有配置参数可以查看官方文档:
https://kafka.apache.org/090/documentation.html

kafka-topics 一些常用参数:

  • --partitions :分区数量,该主题划分成多少个分区;

  • --replication-factor:副本数量,表示每个分区一共有多少个副本;副本数量需要小于或等于 Broker 的数量;

  • --replica-assignment:指定副本分配方案,不能与 --partitions--replication-factor 同时使用;

  • --list: 列出有效的主题;

  • --describe:查询该主题的信息信息。

下面是使用 CLI 手工创建主题的命令,创建主题时设置分区、分区副本。

kafka-topics --create --bootstrap-server 192.168.3.158:19092 \
--replication-factor 3 \
--partitions 3 \
--topic hello-topic
使用 CLI 时,可以通过 --bootstrap-server 配置连接到一个 Kafka 实例,或者通过 --zookeeper 连接到 Zookeeper,然后 CLI 自动找到 Kafka 实例执行命令。

查看主题的详细信息:

kafka-topics --describe --bootstrap-server 192.168.3.158:19092 --topic hello-topic
Topic: hello-topic	TopicId: r3IlKv8BSMaaoaT4MYG8WA	PartitionCount: 3	ReplicationFactor: 3	Configs: 
	Topic: hello-topic	Partition: 0	Leader: 3	Replicas: 3,1,2	Isr: 3,1,2
	Topic: hello-topic	Partition: 1	Leader: 1	Replicas: 1,2,3	Isr: 1,2,3
	Topic: hello-topic	Partition: 2	Leader: 2	Replicas: 2,3,1	Isr: 2,3,1
可以看到,创建的分区会被均衡分布到不同的 Broker 实例中;对于 Replicas 这些东西,我们后面的章节再讨论。

也可以打开 kafdrop 查看主题的信息。

如果一个 Topic 的分区数量大于 Broker 数量呢?前面笔者已经提到,如果分区数量比较大时,部分 Broker 中会存在同一个主题的多个分区。

下面我们来实验验证一下:

kafka-topics --create --bootstrap-server 192.168.3.158:19092 \
--replication-factor 2 \
--partitions 4 \
--topic hello-topic1

可以看到,Broker 2,分到了 hello-topic1 的两个分区。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值