内核缓存区和write行为

2024-06-21 16:58
文章标签 行为 缓存 内核 write

本文主要是介绍内核缓存区和write行为,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  应用缓冲技术能很明显的提高系统效率。内核与外围设备的数据交换,内核与用户空间的数据交换都是比较费时的,使用缓冲区就是为了优化这些费时的操作。其实核心到用户空间的操作本身是不buffer的,是由I/O库用buffer来优化了这个操作。比如read本来从内核读取数据时是比较费时的,所以一次取出一块,以避免多次陷入内核。
      内核缓冲区的 主要思想就是一次读入大量的数据放在缓冲区,需要的时候从缓冲区取得数据
      管理员模式和用户模式之间的切换需要消耗时间,但相比之下,磁盘的I/O操作消耗的时间更多,为了提高效率,内核也使用缓冲区技术来提高对磁盘的访问速度磁盘是数据块的集合,内核会对磁盘上的数据块做缓冲。内核将磁盘上的数据块复制到内核缓冲区中,当一个用户空间中的进程要从磁盘上读数据时,内核一般不直接读磁盘,而是将内核缓冲区中的数据复制到进程的缓冲区中。当进程所要求的数据块不在内核缓冲区时,内核会把相应的数据块加入到请求队列,然后把该进程挂起,接着为其他进程服务。一段时间之后(其实很短的时间),内核把相应的数据块从磁盘读到内核缓冲区,然后再把数据复制到进程的缓冲区中,最后唤醒被挂起的进程。
      注:理解内核缓冲区技术的原理有助于更好的掌握系统调用read&write,read把数据从内核缓冲区复制到进程缓冲区,write把数据从进程缓冲区复制到内核缓冲区,它们不等价于数据在内核缓冲区和磁盘之间的交换
      从理论上讲,内核可以在任何时候写磁盘,但并不是所有的write操作都会导致内核的写动作。内核会把要写的数据暂时存在缓冲区中,积累到一定数量后再一 次写入。有时会导致意外情况,比如断电,内核还来不及把内核缓冲区中的数据写道磁盘上,这些更新的数据就会丢失。
      应用内核缓冲技术导致的结果是:提高了磁盘的I/O效率;优化了磁盘的写操作;需要及时的将缓冲数据写到磁盘。

 

Write行为

从write()调用返回时,内核已经将缓冲区所提供的数据到内核的缓冲区,但是无法保证数据已经写出到其预定的目的地。的确,写入调用返回的速度实在太快了,可能没有时间完成该项目的工作。处理器和硬盘之间的性能差异使得此类令人头痛的行为显而易见。

 

事实上,如果用户空间应用程序发出write()系统调用,Linux内核会先进行若干检查,接着将数据复制进缓冲区。稍后,内核会在后台收集所有“脏”(有数据写入)缓冲区(内容跟相应磁盘块不同的所有缓冲区),将它们安排成最佳顺序,接着写进磁盘。这让写入调用的执行快如闪电,几乎立即返回,这也让内核可以将写入操作延后到较空闲的时段再进行,并且是多笔写入操作会整批一起进行。

 

延后进行的写入操作并不会改变POSIX的语义。举例来说,数据刚写入缓冲区而尚未写回磁盘,此时如果发出读取请求,此请求可从缓冲区得到满足,而且不会因此而读取到地盘上的旧数据。此行为会实际提高性能,因为读取请求可从内存中的缓冲区得到满足,而不必从磁盘。当读取和写入请求如预期般交替出现时,结果也和预期一样,也就是说,数据被写回磁盘之前系统不会崩溃!即使应用程序相信写入请求已经成功完成了,但事实上数据尚未写回磁盘。

 

延后写入的另一个问题是无法安排写入顺序,尽管应用程序可能会安排写入请求的顺序,好让他们能够按照特定的顺序写回磁盘,内核会以它认为合适的方式重新安排写入请求的顺序,主要是基于新能的考虑。除非系统崩溃,否则这通常不是一个问题,因为所有缓冲区最后都会写回磁盘,所以一切都很好。即使如此,绝大多数的应用程序实际上并不关心写入请求的顺序。

 

延迟写入必须探讨的最后一个问题是汇报I/O错误。写回磁盘期间可能会发生任何无法向发出写入请求的进程汇报的I/O错误,例如磁盘驱动器故障。的确,缓冲区与这些进程毫无关系。假如有多个进程“弄脏”(将数据写入)单一缓冲区,而这些进程可能在数据写入缓冲区之后并且在数据写回磁盘之前先借宿了。

 

内核会试图尽量降低延后写入的风险,为了确保数据可以被及时写出,内核未缓冲区设立了一个时间上限,而且会在时间超过上限之前写出所有“脏”缓冲区。用户可通过/proc/sys/vm/dirty_expire_centiseconds来设定此值,此值以厘秒(百分之一秒)为单位。

这篇关于内核缓存区和write行为的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1081796

相关文章

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

防止缓存击穿、缓存穿透和缓存雪崩

使用Redis缓存防止缓存击穿、缓存穿透和缓存雪崩 在高并发系统中,缓存击穿、缓存穿透和缓存雪崩是三种常见的缓存问题。本文将介绍如何使用Redis、分布式锁和布隆过滤器有效解决这些问题,并且会通过Java代码详细说明实现的思路和原因。 1. 背景 缓存穿透:指的是大量请求缓存中不存在且数据库中也不存在的数据,导致大量请求直接打到数据库上,形成数据库压力。 缓存击穿:指的是某个热点数据在

PHP APC缓存函数使用教程

APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中间代码的框架。 APC的缓存分两部分:系统缓存和用户数据缓存。(Linux APC扩展安装) 系统缓存 它是指APC把PHP文件源码的编译结果缓存起来,然后在每次调用时先对比时间标记。如果未过期,则使用缓存的中间代码运行。默认缓存 3600s(一小时)。但是这样仍会浪费大量C

缓存策略使用总结

缓存是提高系统性能的最简单方法之一。相对而言,数据库(or NoSQL数据库)的速度比较慢,而速度却又是致胜的关键。 如果使用得当,缓存可以减少相应时间、减少数据库负载以及节省成本。本文罗列了几种缓存策略,选择正确的一种会有很大的不同。缓存策略取决于数据和数据访问模式。换句话说,数据是如何写和读的。例如: 系统是写多读少的吗?(例如基于时间的日志)数据是否是只写入一次并被读取多次?(例如用户配

Ubuntu22.04回退系统内核

文章目录 起因回退操作卸载内核禁止内核升级 起因 最近因为系统内核自动升级,导致显卡驱动检测不到,炼丹环境被破坏。无奈只能重装驱动,于是跟着手册操作发现驱动要求的是内核版本是5.15.0-25-generic,而我通过uname -r发现这时候的内核版本是6.8.0-40-generic,看来只能回退了。 我搜索了网上很多的文章,没有一篇文章能够完全解决这个问题,所以在我多次尝

跟我一起玩《linux内核设计的艺术》第1章(四)——from setup.s to head.s,这回一定让main滚出来!(已解封)

看到书上1.3的大标题,以为马上就要见着main了,其实啊,还早着呢,光看setup.s和head.s的代码量就知道,跟bootsect.s没有可比性,真多……这确实需要包括我在内的大家多一些耐心,相信见着main后,大家的信心和干劲会上一个台阶,加油! 既然上篇已经玩转gdb,接下来的讲解肯定是边调试边分析书上的内容,纯理论讲解其实我并不在行。 setup.s: 目标:争取把setup.