kafka为什么可以做到单机每秒几十万的消息写入?

💡磁盘顺序写,超高的写入性能

那么什么是磁盘顺序写呢?

首先我们先来了解一下磁盘的构造吧,如下图所示。

pastedImage_3_25_2024__9_50_58_540

磁盘内部就好像古时候的唱片机,有磁头盘片, 盘片又有扇区的区分,然后盘片旋转进行读取数据数据。

根据地址读写一个“磁盘快”的流程如下:

1.根据柱面号移动磁臂,让磁头指向指定柱面。

2.激活盘面号对应的磁头

3.磁盘旋转,扇区号所代表的扇区从磁头划过就完成了对指定扇区的读/写。

下面我们以 7200rpm 的硬盘为例,先来计算1 次随机读写耗时:

首先是磁臂根据柱面号移动到指定柱面的时间,称为寻道时间,一般为 7.5 ~ 14 ms。

然后是磁盘旋转,找到指定扇区:

每分钟 7200 转,则每秒转数:7200 / 60 = 120;
转 1 圈花费时间:120 / 1000ms = 8.33 ms;
平均只需转半圈即可找到指定扇区,所以旋转延迟时间取 4.165 ms。
最后是磁头进行读写操作的传输时间,这取决于要读写的字节数。

那么,N 次随机读写的耗时就是:

N 次寻道时间 + N 次旋转延迟时间 + N 次传输时间

而N 次顺序读写的耗时为:
1 次寻道时间 + 1 次旋转延迟时间 + N 次传输时间

并且还有对比图显示普通磁盘顺序写每秒写入量甚至高达53.2M/s,相对磁盘随机写,这性能提升可以说是巨大的。

jacobs3

所以顺序写对比磁盘磁盘随机写 减少了 寻道和旋转延迟的时间,大大提高了磁盘的写入性能。这就是磁盘循序写的关键。


💡那么kafka是怎么做到磁盘顺序写的呢?

答案就是append only 日志末尾添加的机制,也就是每次有数据写入kafka,它是将数据message 添加到消息文件的末尾,从而实现磁盘顺序写的机制,

避免了磁盘随机读写,从而实现超高性能。

appendonly追加数据


💡我有疑问,那突发流量怎么办?一下子几十万数据流量进来怎么扛得住呢?

是呀,虽然磁盘顺序写已经可以处理大部分的情况,但是突发流量呢,比如1s内 几百M的数据流入进来怎么办?

面对这个问题,kafka中间件主要是采用的page Cache 页缓存技术,也就是说使用操作系统本身的内存来进行存储。

由上图可知,内存顺序的读写速度可以说是最快的,所以可以采取这种中转的方式 , 让数据先留存在内存中, 然后在定时的刷新到硬盘中,以此解决这种突发流量的问题。


💡那么这种页缓存模式有什么优点呢?

1.避免Object消耗:如果是使用 Java 堆,Java对象的内存消耗比较大,通常是所存储数据的两倍甚至更多。简而言之存储元素变小了,空间利用率提高了。

2.避免GC问题:随着JVM中数据不断增多,垃圾回收将会变得复杂与缓慢,使用系统缓存就不会存在GC问题。意思就是页缓存主要采用的LRU缓存淘汰的策略方式进行的,也就是访问多的留下,少得则面临回收淘汰。(LRU-最少使用算法)

首先,操作系统层面的缓存利用率会更高,因为存储的都是紧凑的字节结构而不是独立的对象。其次,操作系统本身也对于Page Cache做了大量优化,提供了 write-behind、read-ahead以及flush等多种机制。再者,即使服务进程重启,系统缓存依然不会消失,避免了in-process cache重建缓存的过程,防止数据的丢失,提供了高可用性。


🗣️那么为什么后续什么是零拷贝啊?零拷贝只拷贝一次?它是如何让kafka可以那么快的?

那么请留意后期的推文,或者关注我集中更新哦~

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你今天学习了吗?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值