kafka学习

 

概念:

  • broker: 1台服务器的kafka进程,它是kafka的工作者。类似Hbase的regionServer,hdfs的Datanode
  • topic: 订阅发布模式的kafka中有消息主题
  • producer:生产者
  • customer:消费者

基础架构:

  • 元数据:kafka的部分元数据保存在ZK中
  • 数据写入:生产者将它产生的数据按照顺序挨个写入对应主题的各个分区
  • 数据读取:消费者会监听它感兴趣的主题的全部分区,从这些分区中取出最新消息

消费的顺序:

kafka一个分区内的消息是按顺序消费的

kafka多个分区之间的消息,消费顺序是无法保证的(因为网络波动)

 

Kafka Shell

  • 查看kafka中有哪些Topic

kafka-topics.sh --list --zookeeper zk地址
Zk地址可以一台可以多台

 

 

  • 创建topic

kafka-topics.sh --create --zookeeper zk地址 --topic topic名 --partitions num --replication-factor num
--replication-factor 表示副本数。 一个副本最快,2个副本安全好一点,性能下降一点,3个副本安全性最好
--partitions 分区。 分区数量建议是Broker数量的n倍

 

 

  • 查看topic详情

kafka-topics.sh --describe --zookeeper zk --topic topicname

 

  • 删除topic

kafka-topics.sh --delete --zookeeper zk --topic topicname

 

kafka默认只是标记删除,物理实体没有被删除,如果想要物理清除,那么需要在config/server.properties配置:delete.topic.enable=true。

  • 修改topic

只能增加分区数,无法修改副本数

kafka-topics.sh --alter --zookeeper zk --topic topicname --partitions num

 

  • 开启一个模拟的生产者

我们可以使用kafka内置的脚本,来模拟生产者发送消息(用于测试)

前提:需要在防火墙开放9092端口

kafka-console-producer.sh --broker-list broker列表 --topic topicname
--broker-list: 如hadoop101:9092,hadoop102:9092,hadoop103:9092
如:kafka-console-producer.sh --broker-list hadoop101:9092,hadoop102:9092,hadoop103:9092 --topic bj61

 

  • 开启一个模拟的消费者

kafka-console-consumer.sh --bootstrap-server broker列表 --topic topicname --from-beginning
--bootstrap-server: 如hadoop101:9092,hadoop102:9092,hadoop103:9092
--from-beginning: 可选配置,表示启动从头开始消费。不选,表示接着上一次消费的地方继续消费
如:kafka-console-consumer.sh --bootstrap-server hadoop101:9092,hadoop102:9092,hadoop103:9092 --topic bj61 --from-beginning

Kafka基准测试

测试集群的吞吐量

  • 生产者测试:

kafka-producer-perf-test.sh --topic topicname --num-records num --throughput -1 --record-size num --producer-props
--num-records: 测试写入多少条数据
--throughput:指定吞吐量的限流,-1表示不限制
--record-size:每条数据的大小,单位是字节
--producer-props:生产者的属性,可以在这里指定集群的地址和ACK的机制,如:
 bootstrap.servers=hadoop101:9092,hadoop102:9092,hadoop103:9092 acks=1

 

测试1万条数据,每条数据1000Byte大小

kafka-producer-perf-test.sh --topic bj60 --num-records 10000 --throughput -1 --record-size 1000 --producer-props bootstrap.servers=hadoop101:9092,hadoop102:9092,hadoop103:9092 acks=1

 

  • 消费者测试:

kafka-consumer-perf-test.sh --topic topicname --broker-list brokerlist --fetch-size num --messages num
--fetch-size:一次抓取多少
--messages num:总共测试多少条数据

 

一般情况下,消费者速率比生产快很多。

Python API

  • 安装库
pip install kafka-python -i https://pypi.tuna.tsinghua.edu.cn/simple

  • 生产者
from kafka import KafkaProducer
p = KafkaProducer(bootstrap_servers=['192.168.100.101:9092'])
p.send("bj61", b'nihao')
p.flush()

这边有个问题:本地机器必须配置hosts文件,要不然发送失败,不知为何!

  • 消费者

from kafka import KafkaConsumer
c = KafkaConsumer("bj61",
group_id="group_id",
bootstrap_servers=['hadoop101:9092'],
auto_offset_reset='earliest',
enable_auto_commit=True)
for msg in c:
    # 这个for循环不会停
    topic=msg.topic
    partition=msg.partition
    offset=msg.offset
    key=msg.key
    value=msg.value.decode("UTF-8") #value是byte,需要解码
    print("topic是:%s,分区是:%s,offset:%s,key:%s,value:%s" % (topic,partition,offset,key,value))

 

Kafka的数据存储和消费者重复消费的问题

Kafka的数据是不会主动删除的,数据会默认保存7天。可以在server.properties中log.retention.hours=168配置

如果数据不删除,作为消费者来说,肯定不想消费到重复的数据,如:发短信。

这就靠消费者offset记录机制。

enable_auto_commit=True:

表示每隔一段时间就提交一次,记录一下消费到的offset,默认5秒钟一次。如果是False,则需要自己写代码提交。c.commit()

auto_offset_reset='earliest':

假设系统宕机重新启动,表示启动的时候接着上次消费的地方继续消费。如果不设置默认是latest表示之前的数据都不管,只接受启动后收到的数据。

这边需要指定消费者组,要不然会从头开始消费,如果不指定,有可能是程序启动的时候消费者组变了,所以从头开始消费了。

 

如何确保不重复消费数据

消费者会将当前消费的offset记录下来。有两种方式:

(1)存到内置主题:_consumer_offsets:给消费者去记录自己消费到哪里了。宕机后可以接着上次offset继续消费。

记录机制:(1)每消费一条数据记录一次,性能差 (2)每隔一段时间记录一次,默认5秒钟,适用于对重复消费不敏感的业务。如:业务做了幂等性操作的。

(2)自己管理,自己记录offset,比如记录到mysql,启动的时候,自行提供本次启动从哪个offset开始

Kafka高级----分区和副本

kafka-topics.sh --create --zookeeper zk地址 --topic topic名 --partitions num --replication-factor num
--replication-factor 表示副本数。 一个副本最快,2个副本安全好一点,性能下降一点,3个副本安全性最好
--partitions 分区。 分区数量建议是Broker数量的n倍

如上shell,在创建主题的时候,我们可以通过:

--replication-factor 来设置一个主题的分区有多少副本

分区和副本的架构

 

 

如图:

  • 在Kafka中,一个主题,可以有多个分区
  • 每一个分区都会有副本,如上图,一个分区有3个副本

Kafka为了安全性,只要broker的数量足够,就会确保副本之间不在同一台机器上。

Broker的数量和副本数量是有关系的。如果有1个broker,就无法设置超过1个副本。因为副本都在同一台机器上,丢了就全部都丢了,没有意义。

  • 副本之间会做选举,内部推选出一个leader,剩下的作为follow

数据写入

在多分区,多副本的场景下,数据写入:

  • 在分区的选择上,跟随客户端的意愿(代码中可以指定具体写入哪个分区),kafka-python库策略是随机分发。
  • 选择好分区后,写入哪个副本?这是固定的,只会写入Leader
  • 写入Leader后,Leader和Follow之间同步数据

客户端ACK 如何确保生产者数据不丢失

1. 客户端只能写入Leader

2. Kafka自己会确保Leader和Follow之间的数据同步

那么客户端在写入数据到Leader之后,有3中选择:

  • 当写入Leader成功,客户端认为成功(ACK=1),安全性较好。如果Leader磁盘坏了,有可能丢失数据。大多数场景推荐,能接受1%数据丢失的风险。
  • 当写入Leader成功,并和Follow同步成功,客户端才认为数据写入成功(ACK=-1)。安全性极佳
  • 压根不管是否写入成功,随缘(ACK=0),几乎没有安全性,性能最好,生产环境中,不推荐使用

小总结

  • 客户端通过ACK来确保数据写入的过程安全
  • 一旦数据进入kafka,kafka本身通过多副本,确保数据在Kafka内的存储安全
  • 消费者没有丢失数据的风险,只要数据还在kafka,就能N次消费,只要保证记录的offset别乱就行了

消费者的数据均衡

消费者组

我们的程序在启动的时候,可以告知自己是哪一个消费者组

这是主动的行为(你自己设置)

结论

从分区的视角看:

kafka的一个分区只能给同一个消费者组的一个消费者提供数据。

 

如图,假设有一个python程序,将自己标记为:group1组,开启了4个线程,那么线程4就没有数据

 

如图,在只有1个消费者的情况下,可以消费多个分区。从分区的角度看,它是1对1的。

 

如图:如果消费者组是多个,那么一个分区可以给多个组的消费者提供数据,但依旧要满足只给同一个组的一个消费者提供数据

注意:

在企业内,消费kafka的时候,一定要注意,不要和别人使用的组是同名的。

查看消费者组列表

kafka-consumer-groups.sh --bootstrap-server hadoop101:9092 --list

 

 

查看消费者组详情

./kafka-consumer-groups.sh --bootstrap-server hadoop101:9092 --group group_id --describe

 

图中LAG,表示在这个组内有数据堆压

计算方法是:当前分区最新的offset - 当前分区已提交的消费的offset

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值