Kafka数据积压如何处理?
首先来分析一下积压的原因。总体上来说,造成挤压的条件是生产者生产数据的速度大于了消费者的速度。一般使用 rps 来表示。生产者这一端,一般连接的是业务系统,我们可以给业务数据根据重要性来分级,如果在数量超大的情况下,我们可以将一些低重要级的数据分流到其他的 kafka 上面,优先保证重要数据的处理。我们能做的就把消费者的速度搞上去。在消费者这边,可以分成两段来分析,一个是 KafkaConsumer ,一个是 data processer 。造成前者消费速度较生产者慢的凶手,最大的可能是分区上有数据倾斜。也就几个分区上的数据比其他分区上的数据特意的多。这种场景下,我们可以将倾斜的数据再分成若干个分区。如下图所示:
还有一种情况,就是所有的分区积压都很大。其实和上面的解决办法差不多,想办法把有积压的分区再切分,就有更多的分区,更多的分区意味着我们可以使用更多的消费者消费 topic 中的数据。什么办法呢?我们可以在原分区策略里面,再对分区值细分,例如,原来我们根据城市来划分分区,我们可以使用城市+区进行细分分区。
接下来来考虑一下data processor 。你想啊,从 kafka procucer 哪里拿到数据后,我们总要对数据做点什么,这个做点什么就是 data processor 。如果这个东西处理数据慢了,也会造成数据的积压。我们可以使用缓存来保存来不及处理的数据,紧接着的问题就是数据存在哪里,保存在内存,这是个好办法,从内存读取数据是较为高效的。如果数据量还是太大,内存也装不下了。那只能方到磁盘了,但是磁盘的读写速度不行啊。根本的问题还是处理数据的能力不够啊,那就要增加 data processor 的实例数量。在单个机器上处理数据的时候,我们可以选择多线程来了完成。但是现在大部分的情况都是利用现有的大数据处理框架来处理的,例如 Flink Spark streaming ,我们就可以增加上面的并行度。
总结一下:
- 从数据源的角度。数据分级后,遇到大数据量的时候,做降级处理。
- 从 kafka 消费者的角度。增加分区的数据。
- 从 data processor 的角度,缓存,增加并行度。
Kafka 分区为什么没有设计成读写分离。
为了数据的一致性。 Kafka 中, 各个 follower 会主动的拉取 leader 的数据,假设,有三个副本,那么会有两个 follower 副本,这两个副本一般会被 Kafka broker 分散到不同的机器上面,在不同机器上 folloer 同步 leader 副本的速度是不一样的,在同一时刻,follower 副本上的数据可能会不一样的,如果有两个 consumer 消费这两个副本,很可能会出现数据不一致的情况。
第三题Kafka 为什么读写速度效率高。
写:
- 内存池的设计。
- 批量发送数据,默认 200ms发送一次。
- Reactor 的网络模型
- 数据写磁盘
- zero-copy
读:
6. 跳表设计
7. 日志存储是稀疏索引也就是双重定位。
8. 顺序读。
kafka中生产数据的时候,如何保证写入的容错性?
先弄明白会出现什么样的错误。其实两种情况:“重”、“丢”。
- 使用有回调函数的 send 方法。好处是可以知道每次是否成功的写入,如果写入失败,可以将写入失败的数据写入磁盘,待程序恢复后在重新发送。这个可以保证数据不丢。
- 使用事务,好处的是可以保证数据重复。
- 设置 ack=all ,这样可以保证服务器端写入 min.sync.replica 数量后,给客户端发送确认。
- 设置合理的事务 timeout 时间。
说说Kafka的ISR副本同步队列。
此队列的里面包括 leader 和符合某个条件的 follower 副本,条件是 follower 副本不能落后 leaer 太多,如果太多的话,就会被踢出 ISR 队列。那“太多”指得是 replica.lag.time.max.ms(默认是10秒)。还有一个相关的参数是 unclear.replca.eletion.enable ,这个意思是那些被提出 ISR 的副本在重新选举的时候是否可以参与选举。为了避免丢数据的风险,应设置为 false 。
第五题


