kafka设计目标

2023-02-16  本文已影响0人  CoderInsight

问题导览

Kafka 是采用 Scala 语言开发的一个分布式、多分区、多副本且基于 zookeeper 协调的分布式发布与订阅消息系统

详细剖析

2.kafka设计目标

Kafka 是采用 Scala 语言和Java语言开发的一个分布式、多分区、多副本且基于 zookeeper 协调的分布式发布与订阅消息系统

(1),Kafka特征?

(2).如何实现高吞吐率?

(3),为什么Kafka速度那么快??

参考资料:
[1,Kafka如何在千万级别时优化JVM GC问题?](D:\BigData\Kafka\KafkaSplits\Kafka如何在千万级别时优化JVM GC问题?.pdf)

Kafka是大数据领域无处不在的消息中间件,目前广泛使用在企业内部的实时数据管道,并帮助企业构建自己的流计算应用程序。

Kafka虽然是基于磁盘做的数据存储,但却具有高性能、高吞吐、低延时的特点,其吞吐量动辄几万、几十上百万,这其中的原由值得我们一探究竟。

1), 顺序读写

引用一组Kafka官方给出的测试数据(Raid-5,7200rpm):
Sequence I/O: 600MB/s
Random I/O: 100KB/s

    众所周知Kafka是将消息记录持久化到本地磁盘中的,一般人会认为磁盘读写性能差,可能会对Kafka性能如何保证提出质疑。实际上不管是内存还是磁盘,快或慢关键在于寻址的方式,磁盘分为顺序读写与随机读写,内存也一样分为顺序读写与随机读写。基于磁盘的随机读写确实很慢,但磁盘的顺序读写性能却很高,一般而言要高出磁盘随机读写三个数量级,一些情况下磁盘顺序读写性能甚至要高于内存随机读写。
    磁盘的顺序读写是磁盘使用模式中最有规律的,并且操作系统也对这种模式做了大量优化,Kafka就是使用了磁盘顺序读写来提升的性能。Kafka的message是不断追加到本地磁盘文件末尾的,而不是随机的写入,这使得Kafka写入吞吐量得到了显著提升。

2), Page Cache(页缓存)

为了优化读写性能,Kafka利用了操作系统本身的Page Cache(页缓存),就是利用操作系统自身的内存而不是JVM空间内存。这样做的好处有:

  • (1)避免Object消耗:如果是使用Java堆,Java对象的内存消耗比较大,通常是所存储数据的两倍甚至更多。
  • (2)避免GC问题:随着JVM中数据不断增多,垃圾回收将会变得复杂与缓慢,使用系统缓存就不会存在GC问题。
Kafka重度依赖底层操作系统提供的PageCache功能。
当上层有写操作时,操作系统只是将数据写入 PageCache,同时标记Page属性为Dirty。
当读操作发生时,先从PageCache中查找,如果发生缺页才进行磁盘调度,最终返回需要的数据。
实际上PageCache是把尽可能多的空闲内存都当做了磁盘缓存来使用。同时如果有其他进程申请内存,回收PageCache的代价又很小,所以现代的OS都支持PageCache。使用PageCache功能同时可以避免在JVM内部缓存数据,JVM虽然可以为我们提供了强大的GC能力,但是同时也引入了一些问题,所以并不适用于Kafka的设计。

3), 零拷贝(Zero-Copy)

Kafka中的零拷贝的实现是采用的 Sendfile 的方式实现的

传统网络的IO操作流程.png
整个过程共经历两次Context Switch,四次System Call。同一份数据在内核Buffer与用户Buffer之间重复拷贝,效率低下。其中2、3两步没有必要,完全可以直接在内核区完成数据拷贝。这也正是Sendfile所解决的问题,经过Sendfile优化后,整个I/O过程就变成了下面这个样子。
Kafka中采用SendFile之后的网络的IO操作流程.png
通过以上的介绍不难看出,Kafka的设计初衷是尽一切努力在内存中完成数据交换,无论是对外作为一整个消息系统,或是内部同底层操作系统的交互。

内核层直接将文件内容传送给网络 socket,避免应用层数据拷贝,减小 IO 开销;

如果Producer和Consumer之间生产和消费进度上配合得当,完全可以实现数据交换零I/O。

(4),如何保证数据的有序性?

(5).kafka数据的数据丢失问题,以及如何保证数据不丢失?

1).数据可能出现丢失的情况?

2).Broker 如何保证数据不丢失?

3).Consumer 如何保证数据不丢失?

如果在消息处理完成之前就提交了offset,那么就有可能造成数据的丢失;那么我么可以将自动提交关闭,然后在处理完成之后选择手动提交;

enable.auto.commit=false : 关闭自动提交 Offset,进行手动维护Offset

(6).Kafka对于不同的重复消费的问题?

1).同一个 Consumer 重复消费

比如当某个数据刚好消费完成,但是正准备提交Offset 的时候,消费时间超时,则Broker认为该条消息未消费成功,这时就会产生消费重复的问题。
解决方案:适当延长Offse自动提交的时间。

2).不同的 Consumer 重复消费

当 Consumer 消费了信息,但是还没有提交Offset 时宕机,那么这些已经被消费过的信息会被重复消费。
解决方案:将自动提交更改为手动提交。

3).也可以从架构设计上防止重复消费

上一篇 下一篇

猜你喜欢

热点阅读