<span>Kafka概念及基础操作</span>
1. Kafka概述
kafka是最初由LinkedIn公司开发,是一个分布式、支持分区(partition)、多副本(replica),基于zookeeper协调的分布式消息系统,它的最大的特点就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、Strom和Spark流式处理引擎,web、ngiinx日志、访问日志,消息服务等。用Scala语言编写,LinkedIn于2010年贡献给Apache基金会并成为顶级开源的项目。
1.1 Kafka的使用场景
- 日志收集:
- 消息系统
- 用户活动跟踪
- 运营指标
1.2 Kafka的基本概念
kafka是一个分布式的,分区的消息(官方称之为commit log)服务。它提供一个消息系统应该具备的功能,但却有着独特的设计。可以这样来说,Kafka借鉴了JMS规范的思想,但是却并没有完全遵守JMS规范。
名称 | 解释 |
---|---|
Broker | 消息中间件处理节点,一个kafka节点就是一个broker,一个或者多个Broker可以组成一个Kafka集群。 |
Topic | Kafka根据topic对消息进行归类,发布到kafka集群的每条消息都需要指定一个tiopic |
Producer | 消息生产者,向Broker发送消息的客户端 |
Consumer | 消息消费者,从Broker读取消息的客户端 |
Comsumer Group | 每个Consumer属于一个特定的Consumer Group,一条消息可以被不同的Consumer Group消费,但是一个Consumer Group中只能有一个Consumer能够消费该消息 |
Partition | 物理上的概念。一个Topic可以分为多个Partition,每个Partition内部消息是有序的 |
1.3 创建topic
- 通过Kafka命令向zk中创建一个主题
./kafka-topics.sh --create --zookeeper 192.168.21.107 --replication-factor 1 --partitions 1 --topic test
- 查看当前zk中所有的主题
./kafka-topics.sh --list --zookeeper 192.168.21.107:2181
- 查看某个具体topic的信息
./kafka-topics.sh --zookeeper 192.168.21.107:2181 --topic test --describe
- 发送消息
./kafka-console-producer.sh --broker-list 192.168.21.107:9092 --topic test
-
消费消息
方式一:从当前主题中的最后一条消息的offset(偏移量)+1开始消费
./kafka-console-consumer.sh --bootstrap-server 192.168.21.107:9092 --topic test
方式二:从当前主题中的第一条开始消费
./kafka-console-consumer.sh --bootstrap-server 192.168.21.107:9092 --from-beginning --topic test
1.4 关于消息的细节
- 生产端将消息发送给broker,broker会将消息保存在本地的日志文件中
/usr/local/kafka_2.12/kafka-logs/主题-分区/00000000000000000000.log
- 消费的保存是有序的,通过offset偏移量来描述消息的有序性
- 消费者消费消息时,也是通过offset来描述当前要消费的那条消息的位置。
1.5 单播消息
在同一个kafka的topic中,启动两个消费者,一个生产者,问:生产者发送消息,这条消息是否能够同时被两个消费者消费
答:如果多个消费者在同一个消费组,那么只有一个消费者可以收到订阅的topic中的消息。换言之,同一个消费组中只能有一个消费者收到一个topic中的消息
./kafka-console-producer.sh --broker-list 192.168.21.107:9092 --topic test
启动两个消费者,但是属于同一个消费者组
./kafka-console-consumer.sh --bootstrap-server 192.168.21.107:9092 --consumer-property group.id=testGroup1 --topic test
发送消息后只有消费者组中的一台实例接收到了消息。
1.6 多播消息
不同的消费组订阅了同一个topic。那么不同的消费组中只有一个消费者能收到消息。实际上也是多个消费者中的多个消费者收到了同一个消息。
./kafka-console-consumer.sh --bootstrap-server 192.168.21.107:9092 --consumer-property group.id=testGroup1 --topic test
./kafka-console-consumer.sh --bootstrap-server 192.168.21.107:9092 --consumer-property group.id=testGroup2 --topic test
1.7 查看消费者组的详细信息
./kafka-consumer-groups.sh --bootstrap-server 192.168.21.109:9092 --describe --group testGroup1
需要关注的几个信息:
- current-offset:最后被消费的消息的偏移量
- Log-end-offset:消息总数(最后一条消息的偏移量)
- Lag: 积压了多少条消息
2. 主题和分区
2.1 主题
主题(topic)在kafka中是一个逻辑的概念,kafka通过topic将消息进行分类。不同的topic会被订阅该topic的消费者消费。
如果一个topic中的消息非常多,则该消息被保存到logr日志文件就会特别大。为了 解决这个文件大的问题,kafka提出partition分区的概念。
2.2分区
通过partition将一个topic中的消息分区来进行存储,可以带来如下好处
- 分区存储,可以解决统一存储文件过大的问题
- 提供了读写的吞吐量:读和写可以同时在多个分区中进行
创建多个分分区的主题
./kafka-topics.sh --create --zookeeper 192.168.21.107:2181 --replication-factor 1 --partitions 2 --topic test1
# 查看topic1的描述信息
./kafka-topics.sh --zookeeper 192.168.21.107:2181 --topic test1 --describe
2.3日志文件中的保存的内容
-
00000.log : 这个文件中保存的就是消息
-
_consumer_offsets-49:
kafka内部自己创建了_consumer_offsets主题包含了50个分区。这个主题用来存放消费者消费某个主题的偏移量。因为每个消费者都会自己维护着消费的主题的偏移量。也就是说每个消费者都会把消费的主题的偏移量自助上报给kafka中默认的主题:
consumer_offsets.因此kafka为了提升这个主题的并发性,默认设置了50个分区。
提交到哪个分区:通过hash函数:hash(consumerGroupId) % __consumer_offsets 主题的分区数 提交到该主题中的内容是:key是consumerGroupId+topic+分区号,value就是当前 offset的值
-
文件中保存的消息,默认保存是7天,7天后消息会被删除。
3. 副本和集群消费
3.1 副本
副本是为了主题中的分区创建多个备份,多个副本在kafka集群的多个broker中,会有一个副本作为leader,其他都是follower
# 查看topic1的描述信息
./kafka-topics.sh --zookeeper 192.168.21.107:2181 --topic test1 --describe
- leader
Kafka的读写操作,都发生在leader上。Leader负责把数据同步给follower。当Leader挂掉后,经过主从选举,会从多个follower中选举一个新的Leader.
- follower
接收leader的同步的数据
- isr
可以同步和已同步的节点会被存入到isr集合中。这里有一个细节:如果isr中的节点性能 较差,会被移除isr集合
3.2 集群消费的细节
集群配置的server.properties文件
#0 1 2
broker.id=2
port=9092
host.name=192.168.21.107
log.dirs=/usr/local/kafka_2.12/kafka-logs
- 一个partition只能被一个消费者组的一个消费者消费,目的是为了保证消费的顺序行,但是多个partition的多个消费者消费的总的顺序是得不到保证的。
- partition的数量决定了消费者组中的消费者的数量。建议同一个消费组中的消费者的数量不要超过partition的数量,否则多的消费者会消费不到。
- 如果消费者挂了,会触发rebalance机制。会让其他消费者来消费该分区。