kafka入门学习

一、分片

首先,kafka就是消息队列的一种,将消息分为多个不同的topic,每一个topic中,又细分为不同的patition(注:实际存储的时候,kafka是以partition为单位存储的,topic可以理解为redis中的key,起到分类作用,例如:a:0,表示a主题下的第一个partition),partition存放在broker中,同一主题下的不同的partition可以存放在同一broker中,也可以存在于不同的broker中(但是同一partition的不同副本需要存放在不同的broker中,后面会提到)。
在这里插入图片描述

分片规则

  1. 数据指定了partition,则存入对应的partition
  2. 如果没有指定partition而是指定了key,则按照key的hash值存入
  3. 如果没有指定partition和key,则按照顺序存入partition中,先0,然后1,然后2。。。。

读写规则

在集群模式下,一个Partition只对应一个Broker,一个Broker可以存放多个Partition。kafka是先随机挑选一个broker放置分区0,然后再按顺序放置其他分区。

二、broker

集群的访问

客户端维护各个Broker的映射表,此外,和redis类似,broker之间都是相互知道信息的,访问一台Broker的信息就可以得到所有broker的信息列表。

三、生产者

3.1 客户端发送消息到kafka的流程

  1. 将发送的消息封装成kafka消息包
  2. 将消息包序列化,在网络中传输
  3. 传输到kafka之后选择partition
    在这里插入图片描述

3.1.1 消息的结构

在这里插入图片描述

  • Key:根据Key的Hash对Partition数目取模来决定是哪个Partition,也就是说只要发送时指定了相同的Key,那么相关消息一定会发送到相同的Partition,Key一般而言都是字符串,最终都会被序列化为二进制。
  • Value: 发送的具体内容,比如发送的消息是“你好”,Value就是“你好”,Value最终都会被序列化为二进制。
  • Compression Type:压缩类型,其实就是压缩算法类型,这个字段决定了用哪种算法压缩Kafka消息,枚举值有none, gzip, lz4, snappy等。
  • Headers:可以通过这个字段传递额外的Header,其实就是传递一些自定义的key-value对,比如想传递TraceID,就可以通过这个字段来进行。
  • Partition + Offset:这个字段生产出来时候是空的,发送到Kafka的服务端后,会写入具体的分区的偏移,主题+分区+偏移其实就唯一对应了一条消息。
  • Timestamp:时间戳,记录消息的时间。

3.1.2 消息发送的方式

  • 同步发送:需要等待消息是否发送成功
  • 发送即忘:发送之后就不管了
  • 异步发送:发送之后等待返回结果(异步等待,不会阻塞主线程),可以设置回调函数(回调函数由sender线程执行,回调时会将sender线程激活,执行回调函数,异步执行

四、消费者

  1. 不同消费者可以在同一时间对同一主题进行消费
  2. 相同消费者可以同一时间从同一主题的不同分片读取信息。
  3. 如果一个消费者,同时消费多个分片下,无法保证消息之间的先后顺序
  4. 如果一个消费者,只消费一个分片,消费顺序即生产顺序,符合队列的先入先出特性

kafka的消息是拉取模式

4.1 消费者offset

每条消息在Kafka中会有Partition ID以及OFFSET,通过这两个信息就可以定位到一条消息。消费者组消费消息之后会提交它在某个Partition对应的OFFSET,这样子下一次就可以从下个位置(OFFSET+1)开始消费。这个offset由broker维护

4.2 主动提交和被动提交

  • 自动提交(被动提交):拉取任务后就修改offset,但是可能消息失败,比如消费者在做完事情之前崩溃重启,那这条消息就丢了。
  • 手动提交(主动提交):当某条消息的处理流程都ok了,再向Broker主动提交,这样更为稳健。一般是保证消息至少消费一次时使用
    在这里插入图片描述

4.3 消费者组

  1. 同一消费者组可以消费不同的topic

  2. 消费者组包含多个消费者

  3. topic中有多个partition

  4. partition和消费者一对一

  5. 消费者组和topic多对多

4.3.1 消费者组分区分配策略

  1. Range Assignor:基于范围的分配策略,将分区按照范围分配给消费者。
    在这里插入图片描述

  2. RoundRobin Assignor:基于轮询的分配策略,分区均匀地分配给消费者。
    在这里插入图片描述

  3. Sticky Assignor:优先保持当前的分配状态,并尽量减少在再平衡过程中的分区移动

  4. CooperativeStickyAssignor:和Sticky Assignor的策略是基本一样的,区别在于该协议将原来的一次大的全部分区重平衡,改成多次小规模分区重平衡。简单理解就是渐进式重平衡。

4.4 消费组再平衡机制

触发再平衡时机

  • 新消费者加入
  • 有消费者退出
  • 主题分区发生变化(增加分区)(分区不能减少,只能通过删除topic减少)

再平衡过程

  1. 暂停消费
  2. 触发再平衡
  3. 分配分区
  4. 消费者完成分工
  5. 恢复消费

再平衡模式

  • Eager Rebalance:追求平衡,会导致所有消费者全部暂停消费
  • Incremental Rebalance:只有部分消费者停止消费,但是可能会造成不均匀分配

协调器(Group Coordinator)

运行再broker服务器上(根据groupId决定放在哪个broker服务器上),每个消费者组都会有一个协调器,负责管理分配组内消费者和偏移量,以及接收消费者的心跳信息

Group Coordinator在收到消费者的加入请求后,会选择一个消费者作为Leader,这个Leader消费者会根据从Group Coordinator拿到的所有消费者信息,进行分配,并Group Coordinator发送SyncGroup请求,以完成分区分配。

五、实践经验

5.1 如何保证消息不丢失

成功发送

需要和客户端一起配合才能保证kafka成功接收到消息

配置策略:

  1. 无需响应
  2. 只需要leader响应
  3. 需要leader和其他broker都响应(leader是一个特殊的broker,类似于redis哨兵的leader
    在这里插入图片描述

存储持久

kafka一旦接收到消息就会进行持久化,保证存储持久

消费环节

使用偏移量记录消费位置,确保至少一次消费

5.2 如何保证消息不重复

不重复接收消息

判断消息id

Kafka是没办法解决重复消费的问题,依靠不重复消费信息

不重复消费消息

幂等消费解决:

  • redis:
    • 标识消息id,并使用分布式id
    • 使用set,确保消息不重复接收
    • 使用原子操作检查消息id,并确认是否添加
  • mysql:
    • 唯一约束
    • insert ignor
    • 事务
  • 最后可以采用redis+mysql共同完成幂等消费

最后的幂等操作交给其他组件,kafka本身不保证幂等消费消息

消息接收保证成功一次:原子操作加反馈

消息接收保证不重复:不保证

消息消费保证成功一次:原子操作加反馈

消息消费保证不重复:交给redis或mysql

5.3 如何保证消息的有序性

  1. 每个业务只使用一个分区,使得消息本身便是有序的
  2. 分区:
    • 子业务分区
    • 客户分区
    • 大小客户分区

核心就是一个partition下是有序的,尽量把没有顺序依赖的消息分到不同的分区,将需要有序的消息放在同一个分区中

5.4 如何消息不幸积压了,该如何处理

六、高可用

6.1 多副本机制

在这里插入图片描述
kafka中的副本就是分区的备份,主副本就是真正意义上正在使用的分区(图中的黄色部分),其他的副本存在与主副本不同的broker中,当作备份使用(分区的副本数量需要小于等于broker的数量

在这里插入图片描述
为消费者位移主题建立副本(在配置中指定),可以使得消费偏移量不丢失

6.2 多副本机制下的写入操作

行为:(类似于mysql的主从同步机制
在这里插入图片描述
这里的ALL并不是所有副本,而是在ISR机制中集合中的副本。

AR:所有的副本

ISR:基本和leader同步的副本

OSR:和leader同步差距较大的副本

AR = ISR + OSR

6.3 副本同步机制

同步流程:
在这里插入图片描述

LEO:每个副本都会维护一个自己的LEO,表示同步的偏移量,下次根据这个值,拉取消息进行同步

同步时通过副本broker拉取leader broker的消息

HW:先更新LEO,然后再更新HW,HW表示对外可见的消息(表示所有的副本都已经同步了该消息,具有可靠性)

Epoch机制优化同步消息:。。。。。。

七、高性能

7.1 查询数据流程

分片

topic —> partition —> 三个文件

  1. log文件:即消息本身
  2. index文件:类似于索引,辅助查询(结合offset)
  3. timeIndex文件:辅助查询
查询流程
  1. 找到topic
  2. 得到对应partition
  3. 根据offset,结合index、timeindex,进行二分查找,得到对应文件
  4. 查询log数据

7.2 顺序写

  1. 先写入os的page cache ,然后操作系统异步写入磁盘

    (顺序写内存、顺序写磁盘)

  2. 将page cache当作缓存,如果命中就不需要查询磁盘了

7.3 零拷贝

使用零拷贝技术,加快读取磁盘发送到网络的速度

7.4 批量操作

批量生产

  1. 设置发送时长,达到时间才发送而不是每次一条消息就发送一次
  2. 设置发送大小,当发送内容达到大小的时候才发送
  3. 设置缓冲区

批量消费

  1. 设置消费者一次期望得到的消息数/消息数据大小
  2. 设置消费者一次最大可消费消息数
  3. 设置最长等待时间
    在这里插入图片描述

7.5 数据压缩

将数据压缩,消费者消费的时候解压,以时间换空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值