-
kafka概述
-
定义
Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue)主要应用于大数据实时处理领域。
-
使用消息队列的好处
-
解耦
-
可恢复性
-
缓冲
-
灵活性&峰值处理能力
-
异步通信
-
-
消息队列的两种模式
-
点对点模式(一对一)
-
发布/订阅模式(一对多)
-
-
基础架构
1)Producer :消息生产者,就是向kafka broker发消息的客户端;
2)Consumer :消息消费者,向kafka broker取消息的客户端;
3)Consumer Group (CG):消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内的一个消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
4)Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
5)Topic :可以理解为一个队列,生产者和消费者面向的都是一个topic;
6)Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列;
7)Replica:副本,为保证集群中的某个节点发生故障时,该节点上的partition数据不丢失,且kafka仍然能够继续工作,kafka提供了副本机制,一个topic的每个分区都有若干个副本,一个leader和若干个follower。
8)leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
9)follower:每个分区多个副本中的“从”,实时从leader中同步数据,保持和leader数据的同步。leader发生故障时,某个follower会成为新的leader。
-
-
kafka入门
-
环境配置
-
修改配置文件server.properties参数
-
broker.id与zookeeper中的broker.id一致,不得重复
-
log.dirs为运行数据的存放路径
-
2.8版本的kafka不需要zookeeper的依赖
-
先起zookeeper再起kafka
-
-
-
命令行
-
bin/kafka-topics.sh 能够查看所有有关主题的命令
-
bin/kafka-console-producer(comsumer).sh 查看所有有关生产者(消费者)的命令
-
--topic 定义topic名
--replication-factor 定义副本数
--partitions 定义分区数
--from-beginning:会把主题中现有的所有的数据都读取出来。
-
-
-
架构
-
工作流程与文件存储机制
-
一个topic下的每一个分区都单独维护一个offset,不同分区中的数据是不同的数据
-
消费者的分区维护是一个消费者组一个主题的一个分区维护一个offset。
-
topic是逻辑上的概念,而partition是物理上的概念,每个partition对应于一个log文件,该log文件中存储的就是producer生产的数据,producer生产的数据为追加写,每条都有自己的offset
Kafka采取了分片和索引机制,将每个partition分为多个segment,每个segment默认1G,每个segment对应两个文件:.log与.index
要找offset=3会先找到000.index,再找到0006.index,说明offset=3的索引在000.index中,再从000.index文件中找到offset=3的数据.log索引信息756,用index=756再从000.log文件中查找
-
-
-
kafka生产者
-
消息发送流程
-
方式:异步发送
-
两个线程:main线程与sender线程
-
线程共享变量——RecordAccumulator
main线程发数据给它,sender线程从它那拉取数据至broker
-
相关参数
batch.size:只有数据积累到batch.size之后,sender才会发送数据。
linger.ms:如果数据迟迟未达到batch.size,sender等待linger.time之后就会发送数据。
-
-
分区策略
-
原因:1.方便在集群中扩展 2.可以提高并发
-
分区原则
-
指明partition的情况下,直接走指明的值
-
无指明partition值但有key值,用key的hash值对topic的partition数进行取余
-
都没有的情况下,采用粘性分区策略,会随机选择一个分区,并尽可能一直使用该分区,待该分区的batch已满或者已完成,kafka再随机一个分区进行使用.
-
-
-
数据可靠性的保证
-
ISR
-
在ISR队列中,都是正常的follower,如果超过replica.lag.time.max.ms(10s)这个参数,认为该follower发生故障,踢出ISR队列.
-
若leader故障,则从isr队列中选取新的leader
-
-
ACK应答机制
-
0:这一操作提供了一个最低的延迟,partition的leader接收到消息还没有写入磁盘就已经返回ack,当leader故障时有可能丢失数据;
1: partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,那么将会丢失数据;
-1(all): partition的leader和follower全部落盘成功后才返回ack。但是如果在follower同步完成后,broker发送ack之前,leader发生故障,那么会造成数据重复。
-
-
故障处理细节
-
follower故障
先踢出ISR队列,恢复后重新从磁盘中读取上次记录的HW,将高于HW的部分截取掉,向leader进行同步,如果该follower的LEO大于HW,则重新加入ISR队列
-
leader故障
从ISR队列中选取第一个作为leader,其余的follower将高于HW的部分截取掉,然后进行重新同步
-
-
-
Exactly Once (精准一次性)
-
ack为0则为至多一次(At Most Once)
akc为-1则为最少一次(At Least Once)
At Least Once + 幂等性 = Exactly Once(精准一次性)
-
所谓的幂等性就是指Producer不论向Server发送多少次重复数据,Server端都只会持久化一条只需要将Producer的参数中enable.idempotence设置为true即可。
-
开启幂等性的Producer在初始化的时候会被分配一个PID,发往同一Partition的消息会附带Sequence Number。而Broker端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker只会持久化一条。
-
但是重启PID就会变化,同时不同的Partition也具有不同主键,所以幂等性无法保证跨分区跨会话的Exactly Once
-
为了实现跨分区跨会话的事务,需要引入一个全局唯一的Transaction ID,并将Producer获得的PID和Transaction ID绑定。这样当Producer重启后就可以通过正在进行的Transaction ID获得原来的PID。
-
-
-
kafka消费者
-
消费方式
-
consumer采用pull(拉)模式从broker中读取数据。push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的,如果 来不及处理消息,可能会使节点宕机或者拒绝服务。而pull模式则可以根据consumer的消费能力以适当的速率消费消息。
-
-
分区分配策略
-
RoundRobin 消费者轮循消费不同分区
-
Range 根据消费者个数进行平均区段分配,如一号消费者0,1,2分区,二号3,4分区
-
Sticky 从0.11.x版本开始引入这种分配策略,首先会尽量均衡的放置分区到消费者上面,在出现同一消费者组内消费者出现问题的时候,会尽量保持原有分配的分区不变化。
-
-
offset维护
-
Kafka 0.9版本之前,consumer默认将offset保存在Zookeeper中,从0.9版本开始,consumer默认将offset保存在Kafka一个内置的topic中,该topic为__consumer_offsets。
-
__consumer_offsets:
-
消费者偏移量,存储消费者读取位置信息
-
所有在kafka中消费过信息的消费者的偏移量
-
把偏移量存好之后,消费者再次消费信息时可以避免重复和丢失信息
-
内置主题,50个分区,1个副本,分区只能加不能减
-
-
-
自动提交offset
-
需要用到的类:
KafkaConsumer:需要创建一个消费者对象,用来消费数据
ConsumerConfig:获取所需的一系列配置参数
ConsuemrRecord:每条数据都要封装成一个ConsumerRecord对象
-
自动提交offset的相关参数:
enable.auto.commit:是否开启自动提交offset功能
auto.commit.interval.ms:自动提交offset的时间间隔
-
-
重置offset
当没有当前消费者的初始偏移量(新的消费者组),或者服务器不存在当前偏移量(默认7天删除)发生offset重置
-
auto.offset.reset = earliest | latest | none |
(1)earliest:自动将偏移量重置为最早的偏移量
(2)latest(默认值):自动将偏移量重置为最新偏移量
(3)none:如果未找到消费者组的先前偏移量,则向消费者抛出异常
-
-
手动提交offset
-
两种方式:同步与异步.
同步会阻碍当前线程,并且会自动失败重试(不可控因素导致失败)
异步没有失败重试机制,快一些,主要采用异步方式
-
应该处理完消息之后再进行提交(commit方法),相当于ack=-1机制,保证数据不丢
-
消费者的精准一次性:处理完消息后手动提交,并且要绑定事务
-
-
Consumer事务(精准一次性消费)
-
如果想完成Consumer端的精准一次性消费,那么需要kafka消费端将消费过程和提交offset过程做原子绑定
-
-
-
API
-
Producer API
-
流程
异步发送消息,两个线程 main线程与Sender线程 以及一个线程共享变量——RecordAccumulator
main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka broker。
相关参数:
batch.size:只有数据积累到batch.size之后,sender才会发送数据。
linger.ms:如果数据迟迟未达到batch.size,sender等待linger.time之后就会发送数据。
-
异步发送
需要用到的类:
KafkaProducer:需要创建一个生产者对象,用来发送数据
ProducerConfig:获取所需的一系列配置参数
ProducerRecord:每条数据都要封装成一个ProducerRecord对象
-
分区器
-
同步发送
-
-
Consumer API
-
自动提交offset
需要用到的类:
KafkaConsumer:需要创建一个消费者对象,用来消费数据
ConsumerConfig:获取所需的一系列配置参数
ConsuemrRecord:每条数据都要封装成一个ConsumerRecord对象
自动提交offset的相关参数:
enable.auto.commit:是否开启自动提交offset功能
auto.commit.interval.ms:自动提交offset的时间间隔
-
重置offset
auto.offset.reset = earliest | latest | none |
-
手动提交offset 同步比异步可靠性更好
-
-
-
kafka监控
-
安装kafka-eagle
-
kafka入门
最新推荐文章于 2023-10-16 10:25:31 发布