kafka基本概念
生产者发送消息给hello这个主题,会根据一定的策略选择主题下的一个分区,然后该消息就会追加的分区消息列表的尾端。每个主题会被一个消费者组订阅,主题下的一个分区只会被消费者组里的一个消费者消费。消费者通过偏移量offset来记录下一步我应该消费哪一个消息。
1、主题和分区
Kafka 将一组消息归纳为一个主题,而每个主题又被分成多个分区(Partition)。每个分区由一系列有序、不可变的消息组成,是一个有序消息列表。
每个分区在物理上对应为一个文件夹,分区的命名规则为主题名称后接“一”连接符,之后再接分区编号,分区编号从0开始,编号最大值为分区的总数减1。
因为主题会有多个分区,所以在整个主题的范围内,是无法保证消息的顺序的,单个分区则可以保证。
2、Broker集群与分区副本
一个独立的Kafka服务器叫Broker,多个broker可以组成一个高可用的kafka集群,每个集群中broker会选举出一个集群控制器。控制器会进行管理,包括将分区分配给broker和监控broker。
在kafka系统中,每个主题在创建时会要求指定它的副本数,默认是1,通过副本机制来保证kafka分布式集群数据的高可用性。
比如主题hello有三个分区,两个副本。在三个broker组成的集群中,broker0 包含了分区 hello-0和hello-2(实际上就是两个文件目录),broker1 包含了分区 hello-0和hello-1,broker2 包含了分区 hello-1和hello-2。 在整个分区的所有副本节点中,kafka会选择一个broker节点作为leader副本,该节点负责数据的读和写,follower副本从leader副本中同步复制数据。以hello-0分区为例,假如broker0挂掉,broker1就会成为新的leader副本。
这种分区复制带来的好处是,提供了消息冗余。一旦首领分区副本broker失效,其他分区副本broker可以接管领导权,这就保证了高可用性。
当kafka集群节点数大于等于3时,通常将副本数设置成3。设置太少,高可用性就会很低。因为副本之间需要复制数据,如果设置太多,会影响一定的性能。
3、消费者群组
我们可以为每个消费者指定一个消费者群组,如果不指定消费者群组,则该消费者属于默认消费组test-consumer-group。消费者群组可以保证每个分区只被一个消费者使用。
消费者和分区之间的这种映射关系叫做消费者对分区的所有权关系,很明显,一个分区只有一个消费者,而一个消费者可以有多个分区。
3、偏移量
每个消息在被添加到分区时,都会被分配一个 offset(称之为偏移量),它是消息在此分区中的唯一编号, kafka 通过 offset 保证消息在分区内的顺序, offset 的顺序不跨分区,即 kafka 只保证在同一个分区内的消息是有序的; 对于应用层的消费群组来说,每次消费一个消息并且提交以后,会保存当前消费到的最近的一个 offset。消费者群组通过分区里的偏移量(offset)来确认下一次应该从哪儿开始消费。
快速体验
1、下载安装包http://https://www.apache.org/dyn/closer.cgi?path=/kafka/1.1.0/kafka_2.11-1.1.0.tgz
2、tar -zxvf kafka_2.11-1.1.0.tgz解压安装包
3、进入 config 修改配置文件server.properties
broker.id=0 : 每一个 broker,都必须设置一个唯一的整数作为id。
配置监听的地址
消息日志文件存储地址
配置zookeeper连接地址:多个用,分割
复制两个配置文件
> cp config/server.properties config/server-1.properties
> cp config/server.properties config/server-2.properties
分配配置
config/server-1.properties:
broker.id=1
listeners=PLAINTEXT://192.168.6.133:9093
log.dirs=/tmp/kafka-logs-1
zookeeper.connect=localhost:2181
config/server-2.properties:
broker.id=2
listeners=PLAINTEXT://192.168.6.133:9094
log.dirs=/tmp/kafka-logs-2
zookeeper.connect=localhost:2181
4、启动kafka
[root@haha-01 kafka_2.11-1.1.0]# nohup bin/kafka-server-start.sh config/server.properties &
[1] 37174
[root@haha-01 kafka_2.11-1.1.0]# nohup bin/kafka-server-start.sh config/server-1.properties &
[2] 37486
[root@haha-01 kafka_2.11-1.1.0]# nohup bin/kafka-server-start.sh config/server-2.properties &
[3] 37809
5、查看到三个kafka节点都启动成功。
6、创建topic 为hello
replication-factor:每个partition的副本个数。任意将每一个分区复制到n个broker上。
partitions:分区数
下面指定了一个3个分区,每个分区2个副本的topic
[root@haha-01 kafka_2.11-1.1.0]# bin/kafka-topics.sh --create --zookeeper 192.168.6.133:2181 --replication-factor 2 --partitions 3 --topic hello
Created topic "hello".
[root@haha-01 kafka_2.11-1.1.0]#
broker0保存 0 和 2 分区
broker1保存 0 和 1 分区
broker2保存 1 和 2 分区
7、查看topic的分区信息
[root@haha-01 kafka_2.11-1.1.0]# bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic hello
Leader:每一个分区都有一个broker为Leader,它负责该分区内的所有读写操作,其他Leader被动的复制Leader broker。如果Leader broker 挂了,那么其他broker中的一个将自动成为该分区的新Leader。
replicas:表示该分区副本分布在哪几个节点
isr:表示活着的节点
同时可以查看zookeeper中保存的kafka信息
将kafka的一个实例给kill掉
[root@haha-01 kafka_2.11-1.1.0]# jps
42160 Kafka
42786 Kafka
26612 QuorumPeerMain
42472 Kafka
43373 Jps
[root@haha-01 kafka_2.11-1.1.0]# kill -9 42160
[root@haha-01 kafka_2.11-1.1.0]# jps
42786 Kafka
26612 QuorumPeerMain
43415 Jps
42472 Kafka
再次查看分区信息,发现活着的节点中没有了broker0
再次启动broker0
[root@haha-01 kafka_2.11-1.1.0]# nohup bin/kafka-server-start.sh config/server.properties &
[4] 44012
[root@haha-01 kafka_2.11-1.1.0]# nohup: ignoring input and appending output to ‘nohup.out’
[root@haha-01 kafka_2.11-1.1.0]# jps
42786 Kafka
26612 QuorumPeerMain
44327 Jps
42472 Kafka
44012 Kafka
[root@haha-01 kafka_2.11-1.1.0]#
再次查看分区信息发现0节点又回来了。
8、消息的发布和消费
发布消息
bin/kafka-console-producer.sh --broker-list localhost:9092,localhost:9093,localhost:9094 --topic hello
消费消息
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092,localhost:9093,localhost:9094 --from-beginning --topic hello --consumer-property group.id=group1
group.id 为消费者组的id
查看消费者组
bin/kafka-consumer-groups.sh --new-consumer --bootstrap-server localhost:9092,localhost:9093,localhost:9094 --list
7、查看所有的topic列表
[root@haha-01 kafka_2.11-1.1.0]# bin/kafka-topics.sh --list --zookeeper localhost:2181
__consumer_offsets
hello
[root@haha-01 kafka_2.11-1.1.0]#
从这里可以看出,实际上kafka的topic信息都保存到了zookeeper上。
8、删除topic
server.properties 需要添加delete.topic.enable=true 所以要先停止kafka的所有服务,然后修改配置文件,重新启动三台实例。
[root@haha-01 kafka_2.11-1.1.0]# bin/kafka-topics.sh --delete --zookeeper localhost:2181 --topic hello
Topic hello is marked for deletion.
Note: This will have no impact if delete.topic.enable is not set to true.
[root@haha-01 kafka_2.11-1.1.0]# bin/kafka-server-stop.sh config/server.properties
当我们执行了上面的命令后,会在/admin/delete_topics 目录下创建一个临时目录,目录名就是标记删除的主题名。
kafka在启动的时候会开启一个线程,删除这种被标记为删除的主题分区。我们查看对应的日志文件会发现该分区已经标记为删除,一会儿,该文件就会被删除。