我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Linux读写机制及如何优化

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Linux读写机制及如何优化

这篇文章主要介绍了Linux读写机制及如何优化的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Linux读写机制及如何优化文章都会有所收获,下面我们一起来看看吧。

Linux读写机制及如何优化

缓存

缓存是用来减少高速设备访问低速设备所需平均时间的组件,文件读写涉及到计算机内存和磁盘,内存操作速度远远大于磁盘,如果每次调用read,write都去直接操作磁盘,一方面速度会被限制,一方面也会降低磁盘使用寿命,因此不管是对磁盘的读操作还是写操作,操作系统都会将数据缓存起来。

Page Cache

页缓存(Page Cache)是位于内存和文件之间的缓冲区,它实际上也是一块内存区域,所有的文件IO(包括网络文件)都是直接和页缓存交互,操作系统通过一系列的数据结构,比如inode, address_space, struct page,实现将一个文件映射到页的级别,这些具体数据结构及之间的关系我们暂且不讨论,只需知道页缓存的存在以及它在文件IO中扮演着重要角色,很大一部分程度上,文件读写的优化就是对页缓存使用的优化

Dirty Page

页缓存对应文件中的一块区域,如果页缓存和对应的文件区域内容不一致,则该页缓存叫做脏页(Dirty Page)。对页缓存进行修改或者新建页缓存,只要没有刷磁盘,都会产生脏页

查看页缓存大小

linux上有两种方式查看页缓存大小,一种是free命令

$ free            total       used       free     shared    buffers     cachedMem:      20470840    1973416   18497424        164     270208    1202864-/+ buffers/cache:     500344   19970496Swap:            0          0          0

cached那一列就是页缓存大小,单位Byte

另一种是直接查看/proc/meminfo,这里我们只关注两个字段

Cached:          1202872 kBDirty:                52 kB

Cached是页缓存大小,Dirty是脏页大小

脏页回写参数

Linux有一些参数可以改变操作系统对脏页的回写行为

$ sysctl -a 2>/dev/null | grep dirtyvm.dirty_background_ratio = 10vm.dirty_background_bytes = 0vm.dirty_ratio = 20vm.dirty_bytes = 0vm.dirty_writeback_centisecs = 500vm.dirty_expire_centisecs = 3000

vm.dirty_background_ratio是内存可以填充脏页的百分比,当脏页总大小达到这个比例后,系统后台进程就会开始将脏页刷磁盘(vm.dirty_background_bytes类似,只不过是通过字节数来设置);vm.dirty_ratio是绝对的脏数据限制,内存里的脏数据百分比不能超过这个值。如果脏数据超过这个数量,新的IO请求将会被阻挡,直到脏数据被写进磁盘;vm.dirty_writeback_centisecs指定多长时间做一次脏数据写回操作,单位为百分之一秒;vm.dirty_expire_centisecs指定脏数据能存活的时间,单位为百分之一秒,比如这里设置为30秒,在操作系统进行写回操作时,如果脏数据在内存中超过30秒时,就会被写回磁盘.

这些参数可以通过 sudo sysctl -w vm.dirty_background_ratio=5 这样的命令来修改,需要root权限,也可以在root用户下执行 echo 5 > /proc/sys/vm/dirty_background_ratio 来修改

文件读写流程

在有了页缓存和脏页的概念后,我们再来看文件的读写流程

读文件
1.用户发起read操作2.操作系统查找页缓存 a.若未命中,则产生缺页异常,然后创建页缓存,并从磁盘读取相应页填充页缓存 b.若命中,则直接从页缓存返回要读取的内容3.用户read调用完成
写文件
1.用户发起write操作2.操作系统查找页缓存 a.若未命中,则产生缺页异常,然后创建页缓存,将用户传入的内容写入页缓存 b.若命中,则直接将用户传入的内容写入页缓存3.用户write调用完成4.页被修改后成为脏页,操作系统有两种机制将脏页写回磁盘5.用户手动调用fsync()6.由pdflush进程定时将脏页写回磁盘

页缓存和磁盘文件是有对应关系的,这种关系由操作系统维护,对页缓存的读写操作是在内核态完成,对用户来说是透明的

文件读写的优化思路

不同的优化方案适应于不同的使用场景,比如文件大小,读写频次等,这里我们不考虑修改系统参数的方案,修改系统参数总是有得有失,需要选择一个平衡点,这和业务相关度太高,比如是否要求数据的强一致性,是否容忍数据丢失等等。优化的思路有以下两点:

最大化利用页缓存

减少系统api调用次数

第一点很容易理解,尽量让每次IO操作都命中页缓存,这比操作磁盘会快很多,第二点提到的系统api主要是read和write,由于系统调用会从用户态进入内核态,并且有些还伴随这内存数据的拷贝,因此在有些场景下减少系统调用也会提高性能

readahead

readahead是一种非阻塞的系统调用,它会触发操作系统将文件内容预读到页缓存中,并且立马返回,函数原型如下

ssize_t readahead(int fd, off64_t offset, size_t count);

在通常情况下,调用readahead后立马调用read并不会提高读取速度,我们通常在批量读取或在读取之前一段时间调用readahead,假设如下场景,我们需要连续读取1000个1M的文件,有如下两个方案,伪代码如下

直接调用read函数
char* buf = (char*)malloc(10*1024*1024);for (int i = 0; i read(fd, buf, size);   // do something with buf   close(fd);}
先批量调用readahead再调用read
int* fds = (int*)malloc(sizeof(int)*1000);int* fd_size = (int*)malloc(sizeof(int)*1000);for (int i = 0; i for (int i = 0; i read(fds[i], buf, fd_size[i]);   // do something with buf   close(fds[i]);}

感兴趣的可以写代码实际测试一下,需要注意的是在测试前必须先回写脏页和清空页缓存,执行如下命令

sync && sudo sysctl -w vm.drop_caches=3

可通过查看/proc/meminfo中的Cached及Dirty项确认是否生效

通过测试发现,第二种方法比第一种读取速度大约提高10%-20%,这种场景下是批量执行readahead后立马执行read,优化空间有限,如果有一种场景可以在read之前一段时间调用readahead,那将大大提高read本身的读取速度

这种方案实际上是利用了操作系统的页缓存,即提前触发操作系统将文件读取到页缓存,并且操作系统对缺页处理、缓存命中、缓存淘汰都由一套完善的机制,虽然用户也可以针对自己的数据做缓存管理,但和直接使用页缓存比并没有多大差别,而且会增加维护代价

mmap

mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系,函数原型如下

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。如下图所示

Linux读写机制及如何优化

mmap除了可以减少read,write等系统调用以外,还可以减少内存的拷贝次数,比如在read调用时,一个完整的流程是操作系统读磁盘文件到页缓存,再从页缓存将数据拷贝到read传递的buffer里,而如果使用mmap之后,操作系统只需要将磁盘读到页缓存,然后用户就可以直接通过指针的方式操作mmap映射的内存,减少了从内核态到用户态的数据拷贝

mmap适合于对同一块区域频繁读写的情况,比如一个64M的文件存储了一些索引信息,我们需要频繁修改并持久化到磁盘,这样可以将文件通过mmap映射到用户虚拟内存,然后通过指针的方式修改内存区域,由操作系统自动将修改的部分刷回磁盘,也可以自己调用msync手动刷磁盘

关于“Linux读写机制及如何优化”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Linux读写机制及如何优化”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Linux读写机制及如何优化

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Linux读写机制及如何优化

这篇文章主要介绍了Linux读写机制及如何优化的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Linux读写机制及如何优化文章都会有所收获,下面我们一起来看看吧。缓存缓存是用来减少高速设备访问低速设备所需平均时间
2023-06-27

Linux文件读写机制怎么优化

这篇文章给大家分享的是有关Linux文件读写机制怎么优化的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Linux是一个可控性强的,安全高效的操作系统。本文只讨论Linux下文件的读写机制,不涉及不同读取方式如re
2023-06-13

HBase如何优化随机读写性能

HBase是一个基于Hadoop的分布式、可扩展、高可靠性的大数据存储系统,主要用于处理大规模的数据读写操作。为了优化HBase的随机读写性能,可以采取以下措施:调整刷写策略:HBase的刷写策略对性能有很大影响。可以通过调整刷写策略来减少
HBase如何优化随机读写性能
2024-10-19

如何优化手机网站制作

本篇内容主要讲解“如何优化手机网站制作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何优化手机网站制作”吧!1.做好整体规划 手机网站是随着这几年智能手机的普及开始兴起的,只有一小部分人再尝试
2023-06-10

如何使用MySQL MVCC 优化数据库读写操作?

如何使用MySQL MVCC 优化数据库读写操作?摘要:随着数据库应用的不断增加,数据库的性能以及并发访问的效率成为开发者关注的重点。MySQL的MVCC(多版本并发控制)是一种有效的优化数据库读写操作的机制,本文将介绍MVCC的概念、原理
2023-10-22

如何在 Golang 中使用缓冲区优化文件读写?

通过使用缓冲区,可以优化 golang 中的文件读写性能:缓冲区存储从磁盘读取或写入的数据,从而减少磁盘操作次数。使用缓冲区的读写函数示例:readfilebuffered 和 writefilebuffered。实际案例:使用缓冲区可将
如何在 Golang 中使用缓冲区优化文件读写?
2024-05-15

如何优化Linux主机启动速度

优化Linux主机启动速度是一个涉及多个方面的过程,包括硬件选择、内核配置、系统服务和守护进程的管理等。以下是一些有效的优化方法:使用SSD硬盘优势:使用SSD硬盘可以显著提高系统启动速度,因为SSD的读写速度远超传统HDD。建议:如果
如何优化Linux主机启动速度
2024-09-27

js中垃圾回收机制如何优化

这篇文章主要介绍js中垃圾回收机制如何优化,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、数组array优化将[]赋值给一个数组对象,是清空数组的捷径(例如: arr = [];),但是需要注意的是,这种方式又创建
2023-06-15

PHP开发中如何优化文件读写和目录操作

在PHP开发中,文件读写和目录操作是非常常见的需求和操作。然而,不合理的文件读写和目录操作会导致性能下降和资源浪费。因此,优化文件读写和目录操作是优化网站性能的一个重要方面。本文将介绍一些优化文件读写和目录操作的方法,并提供具体的代码示例。
2023-10-21

如何优化PHP开发中的数据缓存和读写性能

在PHP开发中,数据缓存和读写性能是一个非常重要的问题。合理地使用数据缓存可以大大提高系统的响应速度和性能。本文将介绍一些优化PHP开发中数据缓存和读写性能的方法,并提供具体的代码示例。一、选择合适的缓存方式文件缓存:将数据以文件的形式存储
2023-10-21

编程热搜

目录