kafka小结

消息队列好处:1削峰2解耦3异步

消息队列的两种模式(或者说队列模型GitHub SnailClimb)

  • 一对一,消费者主动拉取数据,消息收到后消息清除

  • 一对多,消费者消费数据之后不会清除消息,即一条消息可以由多个消费者消费

    • 一种队列主动退给消费者,但是各个消费者消费速度往往不一致(比如队列推的带宽是50M/s,消费者1的接受带宽是100M/s ,消费者2的接受带宽是10M/s;那么消费者1资源浪费,消费者2又吃不消)

    • 是消费者主动拉的(消费者的消费速度由自己决定;缺点是要维护一个长轮询,消费者要时不时地去看队列有没有新数据)

架构(producer consumer topic partition broker)

分区原因:1并发度2负载均衡

Kafka文件存储机制(topic-partition-segment,.index,.log)

由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据定位

效率低下,Kafka 采取了分片索引机制,将每个 partition 分为多个 segment。每个 segment

对应两个文件——“.index”文件和“.log”文件。

生产者

生产者分区策略

1指明partition

2未指明partition但是有key.

3未指明partition也无key,用round robin,即:第一次调用时随机生成一个整数(后 面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法

ack(保证生产者的数据不丢)
  • 0– 会丢失数据
  • 1– 会丢失数据
  • -1(all) – 会数据重复
ISR

当生产者给topic发数据时,且ack=-1,leader等待ISR里的follower同步完成后发送ack给producer。

exactly once(针对Producer 到 Server 之间)

exactly once = at least once(由ack=-1保证) + 幂等性(由【开启幂等性的 Producer 在

初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而

Broker 端会对做缓存,当具有相同主键的消息提交时,Broker 只

会持久化一条。

】保证)

消费者

消费者分区分配策略
  • round robin(就消费组而言的)【消费组中消费者订阅的主题集合里的分区1个1个地交给消费者集合】
  • range(默认)(就topic而言)【一个topic里的分区分摊给订阅它的消费者们,x个分区/y个消费者】【当消费者组里的消费者个数发生变化时会触发分配策略】
数据一致性问题(针对消费者消费数据时)
问题描述

leader未挂之前 L(leader) 消费到10条,F1(follower1)消费到8条,F2(follower2)消费到9条

假设L是leader,F1和F2是ISR中的2个follower,如果此时leader挂了,F1当选成新leader了,那么就存在一个问题:F1 有8条,F2有9条,F1和F2的数据不一致了。或者说leader挂了,F2当选成新leader了,然后L又活过来了,此时F2有9条,L有10条,数据也不一致。那么数据存储方面,3个副本存的不一样。那将来消费的时候都不一样。所以说这里有一个存储一致性的问题,这里就要提2个概念,HW和LEO

两个概念
  • HW—消费一致性(消费时只消费到HW处)
  • LEO—存储一致性(存储时,当新leader起来之后,剩余的follower先截断至HW,再向leader同步)
Producer API

消息发送流程【Kafka 的 Producer 发送消息采用的是异步发送的方式。在消息发送的过程中,涉及到了两个线程——main 线程和 Sender 线程,以及一个线程共享变量——RecordAccumulator。main 线程将消息发送给 RecordAccumulator,Sender 线程不断从 RecordAccumulator 中拉取消息发送到 Kafka broker。】

其他
  • 消费者只有第一次开启的时候去获取存在外部文件的offset

  • Offset自动提交会造成消费者这边的数据丢失(延迟比较短相当于先提交再处理【先提交了offset,之后处理过程一次性存不下太多数据,就只处理了部分数据,剩余数据就丢失了】)和数据重复(延迟比较长相当于先处理后提交【处理完了之后正准备提交offset,但此时提交offset的程序挂掉了,那offset提交不了,之后消费者又重发了一遍数据让你消费】)

  • 手动提交offset(2种方式:同步提交、异步提交(都会在数据处理完之后提交offset,但是即便先处理后提交仍然存在数据重复问题可以结合关系型数据库的事务去解决)