Fork me on Gitee

Kafka概念及基础操作

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

image-20211112112710512

  • 发送消息
 ./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

image-20211112110413610

需要关注的几个信息:

  • 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

image-20211112112748396

2.3日志文件中的保存的内容

image-20211112113108935

  • 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

image-20211112112748396

  • 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机制。会让其他消费者来消费该分区。
posted @ 2021-11-12 15:19  shine-rainbow  阅读(428)  评论(0编辑  收藏  举报