Kafka

大约 4 分钟

Kafka

1. 什么是消息队列,有哪些使用场景

一发一存一消费

1.1 应用解耦

例如A系统将消息写入到队列,B系统订阅消息

1.2 流量削峰

例如5k个请求发送到MQ,MQ只保证向后端发送2k个请求

1.3 异步处理

例如将用户注册成功的消息发送到MQ,其他系统(发送邮件,发送短信)等订阅MQ消息,并行操作

1.4 RPC

2. 如何保证消息不丢失

2.1 生产者(发不丢)

配置ack=-1retry,如果重试几次后仍有异常则记录补偿

ack:

  • 1: 只要分区的leader写入成功就是成功
  • 0: 发送消息之后不需要等待任何回应(可达最大吞吐量)
  • -1: 需等待ISR中的所有副本都成功写入后响应(最强的可靠性,但是ISR=1时不一定可靠)

2.2 broker(存不丢)

Kafka通过副本机制保证

2.3 消费者(消费不丢)

将Kafka的位移提交由自动改为手动

3. 如何保证顺序性

Kafka保证了单分区时有序的

3.1 单分区

消息发送到一个分区,由消费者的一个线程来消费

3.2 通过分区器

Kafka生产者发送消息时配置分区器,hash计算后发送到指定分区

4. 如何避免重复消费,或者说如何保证幂等性

4.1 哪些场景可能产生重复的消息

  • 生产者重试
  • 消费者位移提前

4.2 有哪些手段保证不重复

  • 生产者不重试
  • 消费者取消自动提交位移
  • 做幂等
    • Kafka 有一个幂等的配置enable.idempotence:true
      • 消费幂等: 例如利用MySQL去重表、唯一索引、Redis唯一标识

消息投递的语义

  • At Most Once ,最多投递一次,可能丢失但是不会重复传输,一般用于对消息可靠性没有太高要求的场景,比如一些允许数据丢失的日志报表、监控信息等
  • At Least Once,至少会投递一次,消息绝不会丢失,但可能重复传输,大部分消息队列都支持,应用广泛
  • Exacly Once,每条消息肯定会被传输且只传输一次

5. 如何处理消息积压

发生积压,说明生产速度大于消费速度

在消费者端,首先要排除bug,优化消费逻辑

临时进行服务端的扩容,增加分区和消费者,消费完后进行恢复

6. 消息集群高可用

Kafka集群,多副本机制,优先副本

Kafka的分区和副本分配遵循的原则

  • 一个Topic的Partition数量大于Broker的数量,使得Partition尽量均匀分配到整个集群上
  • 同一个分区,所有的副本要尽量均匀分配到集群中的多台Broker上
  • 尽可能保证用一个分区下的主从副本,分配到不同的Broker上

7. 如何设计一个消息队列

7.1 生产者

生产者需要经历哪些才能发送(拦截器,序列化,分区器,累加器,sender线程)

7.2 传输

传输协议,RPC,序列化协议

7.3 消息队列的持久化、广播方式(推/拉)、集群

7.4 如何消费

8. Kafka的基础概念

整体体系架构由多个生产者,Kafka集群和多个消费者组成

一个主题Topic有n个分区Partition,每个分区有m个副本Replica,每个分区内有offset(位移/偏移量)

其中n是分区数,m是副本因子, Topic:Partition:Replica=1:n:moffset是分区中的唯一标识

  • AR: 分区的所有副本
  • ISR: 所有和leader副本保持一定程度同步的(包含leader)的副本
  • OSR: 与leader副本滞后过多的副本

AR = ISR + OSR

  • HW: 高水位(偏移量),消费者只能拉去到高水位之前的消息

  • LEO: 当前日子文件中下一条待写的offset

    ISR最小的LEO是分区的HW

9. Kafka为什么快

Broker(读-页缓存,写-顺序写,传输-零拷贝)

  • 顺序写盘

    文件追加写入消息,只能在日志文件尾部追加新消息,且不允许修改已写入的消息

  • 页缓存

    读磁盘时,先看待读的数据所在页是否在页缓存中,存在则返回;不存在则向磁盘中读,再到页缓存读;

    写磁盘时先检查是否在页缓存中,若不存在则先在页缓存中添加页,脏页随OS写入磁盘

  • 零拷贝

    将数据直接从磁盘文件复制到网卡设备中,而不需要经过应用程序,减少内核态和用户态的切换

    Linux中的sendfile(),Java中的FileChanel.transferTo()

生产者

发送消息时,先写入到内存缓冲,直到多条消息组成一个Batch,经过网络通信将Batch发送,

内存缓冲池优化了GC

消费者

多个消费者并行消费

#. Kafka的再均衡