kafka技术文档

一、 kafka概述

1、kafka是什么

Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。

发布/订阅模式

消息的发布者不会将消息发给特定的订阅者,而是将发布的消息分为不同的类别,订阅者只接受感兴趣的消息。

消息队列

1)三个特点
  • 缓冲/消峰: 有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
  • 解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
  • 异步通信: 允许用户把一个消息放入队列,但并不立即处理它,然后在需要的时候再去处理它们。
2)两种模式
  • 点对点模式:消费者主动拉取数据,消息收到后清除消息
  • 发布/订阅模式:可以有多个topic主题;消费者消费数据后,不删除数据;每个消费者相互独立,都可以消费到数据

2、kafka高效读写数据

1)Kafka 本身是分布式集群,可以采用分区技术,并行度高
2)读数据采用稀疏索引,可以快速定位要消费的数据
3)顺序写磁盘,写的过程是一直追加到文件末端,省去了大量磁头寻址的时间。
4)页缓存 + 零拷贝技术

  • 页缓存:

PageCache页缓存: Kaka重度依赖底层操作系统提供的PageCache功能。**当上层有写操作时,操作系统只是将数据写入PageCache。当读操作发生时,先从PageCache中查找,如果找不到,再去磁盘中读取。**实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。

参数描述
log.flush.interval.messages强制页缓存刷写到磁盘的条数,默认是 long 的最大值,9223372036854775807。一般不建议修改,交给系统自己管
log.flush.interval.ms每隔多久,刷数据到磁盘,默认是 null。一般不建议修改,
  • 零拷贝技术

将数据直接从磁盘文件复制到网卡设备中,而不需要经由应用程序之手

在这里插入图片描述

二、kafka架构

1.为方便扩展,并提高吞吐量,一个topic分为多个partition
2.配合分区的设计,提出消费者组的概念,组内每个消费者并行消费
3.为提高可用性,为每个partition增加若干副本,类似NameNode HA

  • Producer:消息生产者,就是向Kafka broker发消息的客户端

  • Consumer:消息消费者,向Kafka Broker取消息的客户端

  • Consumer Group:消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费,消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。

  • Broker:一台服务器就是一个Broker,一个集群由多个broker组成。一个broker可以容纳多个topic

  • Topic:可以理解为一个队列,生产者和消费者面向的都是一个topic

  • Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker上,一个topic可以分为多个partition,每个partition是一个有序队列。------leader

  • Repica:副本,一个leader和多个Follower

    todo:controller
    
  • Leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数
    据的对象都是 Leader。

  • Follower:每个分区多个副本中的“从”,实时从 Leader 中同步数据,保持和
    Leader 数据的同步。Leader 发生故障时,某个 Follower 会成为新的 Leader。

  • controller:完成主题管理(创建、删除、增加分区),分区重分配,集群成员管理和数据服务等工作

文件存储

1、文件存储机制

topic是逻辑概念,partition是物理层面的概念,每个partition对应一个log文件夹,producer生产数据会不断追加到log文件末端,防止log文件过大导致定位效率低下,Kafka采取了分片和索引机制,将每个partition分为多个segment。每个segment包括:“.index”文件、“.log”文件和.timeindex等文件。这些文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号,例如:first-0。

todo 文件作用及内容描述
  • .log:日志文件(消息存储文件)
  • .index:消息的物理地址的偏移量索引文件
  • .timeindex:映射时间戳和相对offset的时间戳索引文件
  • .snapshot:对幂等型或者事务型producer所生成的快照文件
  • leader-epoch-checkpoint:保存了每一任leader开始写入消息时的offset, 会定时更新
  • 其他文件(可能包含 “.deleted”“.cleaned”“.swap”等临时文件)

在这里插入图片描述
实用工具查看log文件以及索引文件

kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index

在这里插入图片描述

kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.log 

在这里插入图片描述

步骤
①根据目标offset定位到Segment文件
②找到小于等于目标offset的最大offset对应索引项 --》即定位.index
③定位到log文件
④向下遍历找到record

参数说明
log.segment.bytesKafka 中 log 日志是分成一块块存储的,此配置是指 log 日志划分成块的大小,默认值 1G。
log.index.interval.bytes默认 4kb,kafka 里面每当写入了 4kb 大小的日志(.log),然后就往 index 文件里面记录一个索引。 稀疏索引。

2、文件清理策略

Kafka 中默认的日志保存时间为 7 天,可以通过调整如下参数修改保存时间。

  • log.retention.hours,最低优先级小时,默认 7 天。
  • log.retention.minutes,分钟。
  • log.retention.ms,最高优先级毫秒。
  • log.retention.check.interval.ms,负责设置检查周期,默认 5 分钟。

日志超过设置时间,进行日志清理策略,有delete和compact两种方式
1)log.cleanup.policy = delete 所有数据启用删除策略

  • 基于时间:默认打开。以 segment 中所有记录中的最大时间戳作为该文件时间
  • 基于大小:默认关闭。超过设置的所有日志总大小,删除最早的 segment。

log.retention.bytes,默认等于-1,表示无穷大。

2) log.cleanup.policy = compact 所有数据启用压缩策略
对于相同key的不同value值,只保留最后一个版本。

副本概念

1、副本作用

副本它的作用是提高数据可靠性,kafka默认副本数是一个,在生产环境中一般配置俩个,保证数据的可靠性,如果太多的副本会增加磁盘存储空间,增加网络上数据传输,降低效率。

Kafka 分区中的所有副本统称为 AR,AR又分为ISR和OSR
ISR(in -sync Replicas):
①达到时间阈值和消息条数阈值,如果 Follower 长时间未向 Leader 发送通信请求或同步数据,则该 Follower 将被踢出 ISR。
②Leader 发生故障之后,就会从 ISR 中选举新的 Leader。

OSR(out -sync Replicas):
表示 Follower 与 Leader 副本同步时,延迟过多的副本。

2、选举机制

Leader 发生故障后,就会从 ISR 中选举出新的 Leader。
当follower变成主节点后,其他follower开始从新的leader同步offset。如果新leader的LEO低于follower,那么follower多余的数据会被删除;最终保证和主节点的数据—致。
kafka leader选举流程
(1)查看 Leader 分布情况

kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic hello

在这里插入图片描述
(2)停掉节点broker=1的节点

 bin/kafka-server-stop.sh

(3)查看leader分区情况:broker=1被提出ISR
在这里插入图片描述
broker=1的节点不可用
在这里插入图片描述
(4)启动节点broker=1的节点 leader分区情况
在这里插入图片描述

三、分配策略

消费
一个consumer group中有多个consumer组成,一个 topic有多个partition组成,现在的问题是,到底由哪个consumer来消费哪个partition的数据。
可以通过配置参数partition.assignment.strategy,修改分区的分配策略。

参数名称描述
heartbeat.interval.msKafka 消费者和 coordinator 之间的心跳时间,默认 3s。该条目的值必须小于 session.timeout.ms,也不应该高于session.timeout.ms 的 1/3。
session.timeout.msKafka 消费者和 coordinator 之间连接超时时间,默认 45s。超过该值,该消费者被移除,消费者组执行再平衡。
max.poll.interval.ms消费者处理消息的最大时长,默认是 5 分钟。超过该值,该消费者被移除,消费者组执行再平衡。
partition.assignment.strategy消 费 者 分 区 分 配 策 略 , 默 认 策 略 是 Range +CooperativeSticky。Kafka 可以同时使用多个分区分配策略。可 以 选 择 的 策 略 包 括 : Range 、 RoundRobin 、 Sticky 、CooperativeSticky

1.Range

Range 是对每个 topic 而言的。
首先对同一个 topic 里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。

通过 partitions数/consumer数 来决定每个消费者应该消费几个分区。如果除不尽,那么前面几个消费者将会多消费 1 个分区。

2.RoundRobin

RoundRobin 针对集群中所有Topic而言。

RoundRobin 轮询分区策略,是把所有的 partition 和所有的consumer 都列出来,然后按照 hashcode 进行排序,最后通过轮询算法来分配 partition 给到各个消费者。

3.Sticky

粘性分区定义:可以理解为分配的结果带有“粘性的”。即在执行一次新的分配之前,考虑上一次分配的结果,尽量少的调整分配的变动,可以节省大量的开销。

粘性分区是 Kafka 从 0.11.x 版本开始引入这种分配策略,首先会尽量均衡的放置分区到消费者上面,在出现同一消费者组内消费者出现问题的时候,会尽量保持原有分配的分区不变化。

四、生产者发送消息

案例一

将数据发往指定 partition 的情况下,例如,将所有数据发往分区 1 中。
生产者端
在这里插入图片描述

案例二

没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值
key 值为 a,b,f
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、offset

offset是什么

生产者把数据存放在leader分区,存放完毕后,消费者组开始消费分区数据,消费过程中会有offset,就是指消费者消费到哪里

offset维护位置

0.9之前,维护在zookeeper中,但是会造成一个问题,每个消费者都会和zookeeper进行通讯,造成大量网络通讯问题,效率比较低下
0.9之后。默认将offset存放在kafka一个内置的topic中,名称为_consumer_offsets

_consumer_offsets 主题里面采用 key 和 value 的方式存储数据。key 是 group.id+topic+分区号,value 就是当前 offset 的值。每隔一段时间,kafka 内部会对这个 topic进行compact,也就是每个 group.id+topic+分区号就保留最新数据。

offset提交方式

自动提交

参数名称描述
enable.auto.commit默认值为 true,消费者会自动周期性地向服务器提交偏移量。
auto.commit.interval.ms如果设置了 enable.auto.commit 的值为 true, 则该值定义了消费者偏移量向 Kafka 提交的频率,默认 5s。
todo 数据量阈值?(没有找到这个参数 是不是没有数据量阈值)

手动提交

手动提交offset的方法有两种:分别是commitSync(同步提交)和commitAsync(异步提交)。

commitSync(同步提交):必须等待offset提交完毕,再去消费下一批数据。
commitAsync(异步提交) :发送完提交offset请求后,就开始消费下一批数据了。

相同点:都会将本次提交的一批数据最高的偏移量提交
不同点:同步提交阻塞当前线程,一直到提交成功,并且会自动失败重试(由不可控因素导致,也会出现提交失败);而异步提交则没有失败重试机制,故有可能提交失败。

todo 确认异步有没有重试机制

https://cloud.tencent.com/developer/article/1772208
在这里插入图片描述
可能产生的问题:
场景一:重复消费
1) Consumer:每5s提交offset
2)如果提交offset后的2s,consumer挂了
3)再次重启consumer,则从上一次提交的offset处继续消费,导致重复消费

场景二: 漏消费
异步提交offset:当offset被提交时,数据还在内存中未落盘,此时刚好消费者线程被kill掉,那么offset已经提交,但是数据未处理,导致这部分内存中的数据丢失。

六、kafka安全

  • 生产幂等性

幂等性就是指Producer不论向Broker发送多少次重复数据,Broker端都只会持久化一条,保证了不重复。

幂等性的实现原理,kafka引入了PID和Sequence Number。
PID。每个新的Producer在初始化的时候会被分配一个唯一的PID,这个PID对用户是不可见的。
Sequence Numbler。(对于每个PID,该Producer发送数据的每个<Topic, Partition>都对应一个从0开始单调递增的Sequence Number)

幂等性无法实现跨分区和跨会话数据不重复,因为服务器在重启之后,首先PID,就是刚才所说的生产者分配的ID会被打乱,所以无法实现跨会话,然后就是partition的主键会被打乱,所以幂等性无法实现跨分区的数据不重复

开启事务:

弥补了这一缺陷,需要开始事务
事务它的实现原理: Producer 端引入了一个 TransactionalId 来解决这个问题,它可以用来标识一个事务操作,便于这个事务的所有操作都能在一个地方(同一个 TransactionCoordinator)进行处理,这个操作把消费和生产的处理在一 个原子单元内完成,操作要么全部完成、要么全部失败。

建一个单分区的topic,然后控制台起一个消费者推送相同key相同value的数据,消费出来看有没有持续追加

  • 消费幂等性

    消费拉取数据 -> 执行业务逻辑 -> commit

    幂等性即指不论消费多少次同一数据或是重复数据,所执行的业务逻辑结果不会发生变化;

    以 kafka_sync_hyperdriver为例,即最后写到数据库中有且只有一条数据

    业务逻辑是计数聚合类,如sum,count这种,在消费逻辑要保证去重(内存、redis),这种情况如果消费程序重启可能会导致无法保证幂等性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值