Kafka
Kafka概述
是一个分布式的基于发布/订阅模式的消息队列(Message Queue)
消息队列
点对点模式(一对一,消费者主动拉取数据,消息收到后消息消除)
生产消息到queue,然后消息消费者从queue中取出并消费消息,消费后queue不在存储,消费者不能重复消费已经被消费过的消息,queue有多个消费者,但是一条消息只有一个消费者消费
发布/订阅模式(一对多,消费者消费数据后不会消除消息)
发布/订阅还有两种模式
消费者主动拉取数据(kafka的模式 )
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费消息,发布到topic的消息会被所有订阅者消费
缺点是:需要监听,队列中没有数据也需要进行监听,需要维护一个长轮询
队列推数据
好处:
解耦合,缓冲(生产大于消费的时候),可恢复性,峰值的处理能力,异步通信
kafka的基础架构
生产者,消费者,kafka集群,zookeeper注册消息
kafka工作流程
kafka中消息以topic分类,生产者生产消息,消费者消费消息,都是面向topic的
topic是逻辑的概念,而partition是物理的概念,每个partition对应于一个log文件,该log文件中存储的就是producer生产的数据,Producer生产的数据会不断的追加到该log的末端,且每条数据都有自己的offset,消息者组中每个消费者,都会实时记录自己消费到哪个offset,以便出错时,从上次的位置继续消费
如下:一个topic(TopicA),三个partition(0,1,2),两个副本(1个leader,1个follower)
kafka文件存储机制
由于生产者生产的消息回不断追加到log文件的末尾,为防止log文件过大导致数据定位效率低下,kafka采取了分片和索引机制,将每个partition分为多个segment(分片),默认是一个.log文件大小是1G,配置文件可修改,每个segmeng对应两个文件:.index文件和.log文件,这些文件在一个文件夹下,文件夹的命名是:topic名称+分区序号
index和log文件以当前segment的第一条消息的offset命名
.index文件存储大量的索引信息,.log文件存储大量的数据,索引文件的元数据指向对应数据文件中message的物理偏移量地址
kafka使用
安装,启动
下载版本
解压,修改server.properties
broker.id=0 #每一台都不一样
delete.topic.enable=true
log.dirs=/opt/module/kafka/logs
zookeeper.connect=192.168.0.119:2181,192.168.0.121:2181,192.168.0.120:2181启动
先启动zookeeper集群
bin/kafka-server-start.sh ../config/server.properties
#后台启动
bin/kafka-server-start.sh -daemon ../config/server.properties
kafka命名行使用
查看当前服务器所有的topic
bin/kafka-topics.sh --zookeeper localhost:2181 --list
创建topic
bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic first --partitions 2 --replication-factor 2
topic: 定义topic名
--partitions:定义分区数
--replication-factor:定义副本数,每个分区都有对应的分区数
删除topic
bin/kafka-topics.sh --zookeeper localhost:2181 --delete --topic first
需要在server.properties中配置:delete.topic.enable=true,否则只是标记删除
描述topic详情
bin/kafka-topic.sh --zookeeper localhist:2181 --describe --topic first
命令行模拟生产者
bin/kafka-console-producer.sh --topic first --broker-list localhost:9092
命令行模拟消费者
bin/kafka-console-consumer.sh --topic first --bootstrap-server localhost:9092 --from-beginning
kafka生产者
分区策略
分区的原则
producer发送的数据封装成ProducerRecord对象