当前位置: 首页 > news >正文

Kafka 日志存储 — 磁盘存储

Kafka 依赖与磁盘来存储和缓存消息,采用文件追加的方式来写入消息。顺序写盘的速度快于随机写内存。

1 磁盘存储

除顺序写入外,Kafka中大量使用了页缓存、零拷贝等技术来进一步提升吞吐性能。

1.1 页缓存

页缓存是操作系统实现的一种磁盘缓存,以此来减少对磁盘I/O的操作。

图 进程读取及写入数据流程

1.1.1 刷盘

将脏页写入到磁盘的过程叫做刷盘。

vm.dirty_background_ratio

当脏页数量达到系统内存的百分之多少之后就会触发刷盘(异步)。默认值为10。

vm.dirty_ratio

当脏页数量达到系统内存的百分之多少之后就立马进行刷盘(同步)。默认值为20。

表 Linux 控制刷盘时机的参数

Kafka同样提供了同步刷盘及间断性强制刷盘的功能,但是不建议使用,刷盘任务应交由操作系统去调配。

1.1.2 未使用进程内的缓存

进程会在其内部缓存处理所需的数据,然后这些数据有可能还缓存在页缓存中,因此同一份数据有可能被缓存了两次。

在Java中,对象的内存开销非常大,通常会是真实数据大小的几倍,空间使用率低下。Java的垃圾回收会随着堆内数据的增多而变得越来越慢。

使用页面缓存可以省去进程内部的缓存消耗,同时通过紧凑的字节码来代替使用对象的方式来节省更多的空间.

此外,即使Kafka服务重启,页缓存还是会保持有效,而进程内的缓存却需要重建。

1.1.3 swap 分区

当物理内存(非磁盘,而是相对于虚拟内存)不够时,Linux会使用磁盘的一部分作为swap分区,将非活跃的进程调入swap分区,来把内存空出来给活跃的进程。

通过vm.swappiness参数来进行调节,其上限为100,表示积极使用swap分区,并把内存上的数据及时地搬运到swap分区中,下限为0,表示任何情况下都不要发生交换。

对于Kafka而言,尽量避免这种内存交换,否则会对它的各方面性能产生很大的负面影响。建议将这个参数值设置为1。

1.2 磁盘I/O流程

图 应用与磁盘I/O操作流程

写操作:用户调用fwrite把数据写入C库标准IObuffer后就返回,写操作通常是异步操作。C库不会立即将数据刷新到磁盘,会将多次小数据量相邻写操作先缓存起来合并,最终调用write一次性写入页缓存。内核的pdflush线程不停检测脏页,判断是否要写到磁盘,如果是,则发起磁盘I/O请求。

读操作:用户调用fread到C库IObuffer中读取数据,如果成功则返回,否则页缓存读取数据,如果成功则返回,否则发起磁盘I/O请求,读取后将数据缓存到页缓存和C库的IObuffer,并返回。读操作是同步操作。

I/O请求:通用块层根据I/O请求构造一个或多个bio(block I/O,阻塞式I/O模型)结构并交给调度层。调度层将bio结构进行排序和合并组织成队列:将一个或多个进程的读操作合并到一起读,将一个或多个进程的写操作合并到一起写,尽可能变随机为顺序,读必须优先满足。

1.2.1 Linux的I/O调度策略

算法

介绍

优缺点

NOOP

No Operation,无操作调度器。采用FIFO(先进先出)策略,按照I/O请求到达的顺序进行处理。在这基础上,会尝试合并相邻(物理地址相邻)的I/O请求:

当一个新的I/O请求到达时,会检查这个请求是否可以和队列种某个请求合并(减少磁盘转动次数)。

优点:低延迟、高吞吐量、简单高效。

缺点:请求饥饿问题、磁盘寻道开销大、缺乏适应性。

CFQ

Completely Fair Queuing,完全公平排队。默认的调度算法。为每个进程单独创建一个队列来管理该进程所产生的请求。根据进程的权重和时间片来调度这些请求。并且将I/O请求按照地址进行排序。

优点:公平性,确保每个进程都能获得公平的I/O带宽。较少了磁盘寻道开销。

缺点:处理大量小I/O请求时有延迟;对优先级高的请求响应不够迅速。

DEADLINE

最后期限。在CFQ基础上,解决了I/O请求“饿死”的情况。除了CFQ本身的I/O队列,还分别为读写提供了FIFO队列。读FIFO队列的最大等待时间为500ms,写FIFO队列的最大等待时间为5s。FIFO队列的优先级要比CFQ队列高。

优点:实时性强、公平性、灵活性。

缺点:复杂度高、资源开销更大

ANTICIPATORY

预期的。上面的算法考虑的焦点在于满足零散I/O请求上,对于连续的I/O请求(比如顺序读),并没有做优化。ANTICIPATORY在DEADLINE的基础上,为每个读I/O都设置了6ms的等待时间窗口,在等待期间OS收到了相邻位置的读请求,则合并请求并处理。

优点:通过预测和合并来减少磁盘的寻道次数和旋转延迟。

缺点:如果非连续读请求较少,则延迟会更长。

表 Linux 的I/O调度策略

请求饥饿:在I/O调度过程种,某些I/O请求由于调度算法的不当处理(无法公平、有效地处理所有请求)而长时间得不到服务,导致请求被“饿死”的现象(长时间等待)。

1.3 零拷贝

将数据直接从磁盘复制到网卡设备中,而不需要经过应用程序。

例如:将磁盘中的图片展示给用户。

正常流程为,将磁盘中的数据复制出来放到内存buf中,然后将这个buf通过套接字(Socket)传输给用户。这个过程中,经历了4次复制。

图 非零拷贝技术的复制过程

图 内核模式下零拷贝技术的复制过程

零拷贝技术通过DMA(Direct Memory Access)技术将文件内容复制到内核模式下的Read Buffer中,然后直接传递到网卡设备。这是在内核模式下实现了零拷贝。

http://www.lryc.cn/news/528721.html

相关文章:

  • 996引擎 - NPC-添加NPC引擎自带形象
  • GL C++显示相机YUV视频数据使用帧缓冲FBO后期处理,实现滤镜功能。
  • 【hot100】刷题记录(7)-除自身数组以外的乘积
  • 解决.NET程序通过网盘传到Linux和macOS不能运行的问题
  • 练习(复习)
  • Class2(2020):Shell基础(二)——Shell脚本设计基础
  • HBase-2.5.10 伪分布式环境搭建【Mac】
  • 计算机毕业设计Python+CNN卷积神经网络高考推荐系统 高考分数线预测 高考爬虫 协同过滤推荐算法 Vue.js Django Hadoop 大数据毕设
  • macos的图标过大,这是因为有自己的设计规范
  • 2025_1_29 C语言学习中关于指针
  • 解决ImportError: cannot import name ‘notf‘
  • HTML<label>标签
  • shiro学习五:使用springboot整合shiro。在前面学习四的基础上,增加shiro的缓存机制,源码讲解:认证缓存、授权缓存。
  • 大数据Hadoop入门1
  • 《智能家居“孤岛危机”:设备孤立如何拖垮系统优化后腿》
  • DeepSeek介绍及使用ollama本地化部署DeepSeek-R1大模型
  • 网络安全攻防实战:从基础防护到高级对抗
  • 9【如何面对他人学习和生活中的刁难】
  • kafka消费者详细介绍(超级详细)
  • 数据结构选讲 (更新中)
  • OpenBMC:简介
  • java 正则表达式匹配Matcher 类
  • 【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)
  • CSS(快速入门)
  • 使用 concurrently 实现前后端一键启动
  • 常见端口的攻击思路
  • 大数据治理实战:架构、方法与最佳实践
  • 忘记宝塔的访问地址怎么找
  • SQL教程-基础语法
  • shell脚本批量修改文件名之方法(The Method of Batch Modifying File Names in Shell Scripts)