Linux 文件缓存 (一)
缓存印象
缓存给人的感觉就是可以提高程序运行速度,比如在桌面环境中,第一次打开一个大型程序可能需要10秒,但是关闭程序后再次打开可能只需5秒了。这是因为运行程序需要的代码、数据文件在操作系统中得到了缓存,第二次运行程序时可以直接中内存中读取不需要经过磁盘的读取了。除了文件内容外,系统还对文件系统的目录项进行了缓存,这样就不用依次重新从磁盘上查找目录和文件了。从此也可以看出文件/目录缓存是与文件关联的,而不是与某个特定的进程关联的。因为进程结束后,文件缓存依然存在。
缓存查看
Linux中的文件缓存可以通过free命令来进行查看,下面是从一台运行数据库服务的服务器上得到的结果:
[cadmin@bigdb ~]$ free -h
total used free shared buffers cached
Mem: 188G 187G 799M 33G 0B 72G
-/+ buffers/cache: 115G 73G
Swap: 63G .8G 60G
-h参数表示使用易于查看的数据单位(默认使用byte)
可以看到第一行的free列中空间只有799MB了,不过不必慌张,cached列中显示占用的空间中72GB用来做了缓存,缓存不是必须存在的,在内存空间紧张时可以减少缓存项。也可以手工进行释放。
丢弃缓存
[cadmin@bigdb ~]$ ls /proc/sys/vm/
admin_reserve_kbytes hugepages_treat_as_movable mmap_min_addr page-cluster
block_dump hugetlb_shm_group nr_hugepages panic_on_oom
compact_memory laptop_mode nr_hugepages_mempolicy percpu_pagelist_fraction
dirty_background_bytes legacy_va_layout nr_overcommit_hugepages scan_unevictable_pages
dirty_background_ratio lowmem_reserve_ratio nr_pdflush_threads stat_interval
dirty_bytes max_map_count numa_zonelist_order swappiness
dirty_expire_centisecs memory_failure_early_kill oom_dump_tasks user_reserve_kbytes
dirty_ratio memory_failure_recovery oom_kill_allocating_task vfs_cache_pressure
dirty_writeback_centisecs min_free_kbytes overcommit_kbytes zone_reclaim_mode
drop_caches min_slab_ratio overcommit_memory
extfrag_threshold min_unmapped_ratio overcommit_ratio
在/proc/sys/vm目录中列出了一些当前虚拟内存系统的状态和参数。我们可以 手工向drop_caches这个文件写入数值进行相应的丢弃缓存操作
1 - 丢弃页缓存(页用来缓存文件内容)
2 - 丢弃文件目录节点缓存(用来缓存元数据,目录结构)
3 - 丢弃上述两者
[root@bigdb cadmin]# sync
[root@bigdb cadmin]# echo "" > /proc/sys/vm/drop_caches
[root@bigdb cadmin]# free -h
total used free shared buffers cached
Mem: 188G 114G 74G 33G 0B 70M
-/+ buffers/cache: 114G 74G
Swap: 63G .8G 60G
可以看到此时cached一项已经从72GB一下子减少到了70MB,不过这样做一般情况下是不应该的。我们需要让系统尽可能的利用可用内存来提供程序运行速度,光有内存可用量并没什么实质的用处。缓存主要还是被页缓存占用,执行第一项后基本也就不会缩小了。执行这个操作不会对以后的缓存策略造成影响,这个操作只是手工触发一次清空(刷出)缓存的操作。
缓存验证
首先生成一个随机文件,大小为1GB
dd if=/dev/urandom of=rnd.dat bs=1MB count=
如果刚刚清空了页面缓存此时在用free命令时cached一项应该就在1GB左右
root@controller:~# free -h
total used free shared buffers cached
Mem: 62G 13G 49G 904K 69M .0G
-/+ buffers/cache: 12G 50G
Swap: 63G 9.9M 63G
(另外一台服务器上的结果),可见对文件的输出也会生成对应的缓存页。为了以后的测试我们先清空一下缓存。
root@controller:~# free -h
total used free shared buffers cached
Mem: 62G 12G 50G 904K 4.4M 37M
-/+ buffers/cache: 12G 50G
Swap: 63G 9.9M 63G
读取速度
然后我们来测试文件的读入速度,连续两次使用dd命令
root@controller:~# dd if=rnd.dat of=/dev/null bs=1MB
+ records in
+ records out
bytes (1.0 GB) copied, 2.58692 s, MB/s
root@controller:~# free -h
total used free shared buffers cached
Mem: 62G 13G 49G 904K 1.3M .0G
-/+ buffers/cache: 12G 50G
Swap: 63G 9.9M 63G
root@controller:~# dd if=rnd.dat of=/dev/null bs=1MB
+ records in
+ records out
bytes (1.0 GB) copied, 0.393087 s, 2.6 GB/s
root@controller:~# dd if=rnd.dat of=/dev/null bs=1MB
1024+0 records in
1024+0 records out
1024000000 bytes (1.0 GB) copied, 0.323672 s, 3.2 GB/s
可以看到第一次在无系统缓存的情况下读取是将近400MB/s,而第二次在有了缓存的情况下是2.6GB/s,最后一次则达到了3.2GB/s(这里使用的分区是RAID1上的,RAID卡自带缓存)。读取上的速度提升非常明显。
写入速度
首先先复制一份1GB的数据文件以备后用。使用/dev/zero作为输入来源,使用dd命令进行写入测试(不丢弃原来的缓存)
root@controller:~# dd if=/dev/zero of=rnd.dat bs=1024MB count=
+ records in
+ records out
bytes (1.0 GB) copied, 3.91219 s, MB/s root@controller:~# dd if=/dev/zero of=rnd.dat bs=1024MB count= oflag=direct
+ records in
+ records out
bytes (1.0 GB) copied, 2.66657 s, MB/s
direct即不使用缓存直接进行写入操作,direct模式居然比使用缓存的还要快,这非常不合理。如果使用strace跟踪第一条命令的话,会发现很多时间其实用在了close调用上。
root@controller:~# strace -tt dd if=/dev/zero of=rnd.dat bs=1024MB count=
::00.207073 execve("/bin/dd", ["dd", "if=/dev/zero", "of=rnd.dat", "bs=1024MB", "count=1"], [/* 23 vars */]) =
::00.207857 brk() = 0x84c000
.......
::00.212135 open("/dev/zero", O_RDONLY) =
::00.212246 dup2(, ) =
::00.212342 close() =
::00.212432 lseek(, , SEEK_CUR) =
::00.212528 open("rnd.dat", O_WRONLY|O_CREAT|O_TRUNC, ) =
::00.625270 dup2(, ) =
::00.625401 close() =
::00.625502 mmap(NULL, , PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -, ) = 0x7f1cd975c000
::00.625646 read(, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., ) =
::01.183562 write(, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., ) =
::02.454654 close() =
::02.454884 close() =
::04.815079 open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) =
::04.815331 fstat(, {st_mode=S_IFREG|, st_size=, ...}) =
::04.815444 mmap(NULL, , PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -, ) = 0x7f1d16dd3000
::04.815553 read(, "# Locale name alias data base.\n#"..., ) =
::04.815704 read(, "", ) =
::04.815796 close() =
::04.815885 munmap(0x7f1d16dd3000, ) =
::04.816016 open("/usr/share/locale/en_HK/LC_MESSAGES/coreutils.mo", O_RDONLY) = - ENOENT (No such file or directory)
::04.816120 open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = - ENOENT (No such file or directory)
::04.816215 open("/usr/share/locale-langpack/en_HK/LC_MESSAGES/coreutils.mo", O_RDONLY) = - ENOENT (No such file or directory)
::04.816307 open("/usr/share/locale-langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = - ENOENT (No such file or directory)
::04.816442 write(, "1+0 records in\n1+0 records out\n", + records in
+ records out
) =
::04.816594 write(, "1024000000 bytes (1.0 GB) copied", bytes (1.0 GB) copied) =
::04.816747 write(, ", 4.1912 s, 244 MB/s\n", , 4.1912 s, MB/s
) =
::04.816869 close() =
::04.816959 exit_group() = ?
::04.822877 +++ exited with +++
close(1)用了比write还多的时间,有理由相信,在close调用上面进行了相关的文件同步写入工作。
Linux 文件缓存 (一)的更多相关文章
- Linux 文件缓存 (二)
close系统调用入口1. 首先来到系统调用入口,主要使用__close_fd进行了具体的处理过程,并没有耗时操作.(current->files表示进程当前打开文件表信息,fd为需要关闭的文件 ...
- Linux的文件系统及文件缓存知识点整理
Linux的文件系统 文件系统的特点 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储. 文件系统中也要有索引区,用来方便查找一个文件分成的多个块都存放在了什么位置. 如果文件系统中有的文件 ...
- Linux服务之nginx服务篇五(静态/动态文件缓存)
一.nginx实现静态文件缓存实战 1.nginx静态文件缓存 如果要熟练使用nginx来实现文件的缓存,那下面的几个指令你必须要牢记于心 (1)指令1:proxy_cache_path 作用:设置缓 ...
- Linux ARP缓存配置和状态查看命令
查看Linux ARP缓存老化时间 cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time同目录下还有一个文件gc_stale_time,官方解释如 ...
- Linux 文件服务---------- nfs Server
Linux 文件服务nfs (Network file system)#网络文件系统 ---> 远程文件调用samba #文件共享(unix /linux /windows ) ,只能适用于局域 ...
- 【转】漫谈linux文件IO--io流程讲的很清楚
[转]漫谈linux文件IO--io流程讲的很清楚 这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102 ...
- Linux 文件系统管理
Linux 文件系统管理 课程大纲 文件系统构成及命令 硬盘分区及管理 磁盘配额 备份与恢复 文件系统构成 /usr/bin ./bin:存放所有用户可以执行的命令 /usr/s ...
- centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课
centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 ...
- llinux 目录结构 及Linux文件分享
llinux 基础命令 及个人Linux文件分享 一, root用户名 @ 分隔符 kingle 主机名 ~当前所在目录 # root权限 $ 没分配权限用户 二, 书写格式:空格 [命令参数] 空格 ...
随机推荐
- apt错误
安装软件遇到错误,不管安装什么软件都有错误. apt-get install softname 报错如下:E: Sub-process /usr/bin/dpkg returned an error ...
- Swift 里字符串(二)创建
 最终都要走到__StringStorage 的 create(realCodeUnitCapacity,countAndFlags) 方法里去. 默认实现是 UTF8 internal stati ...
- Ubuntu16.04 / OpenCV / Python 源码安装
为什么需要源码安装? 1. 对 Python 版的 OpenCV,Ubuntu 有两种安装方式: 源码安装:官网(https://opencv.org/releases.html)下载源代码,在机器上 ...
- Python字典按值排序、包含字典的列表按字典值排序的方法
operator.itemgetter函数 operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),要注意,operator.i ...
- VUE输入框显示时自动聚焦
directives: { focus: { inserted: function (el, {value}) { if (value) { el.focus() } } } } 注意点:1.用v-i ...
- spring boot整合RabbitMQ(Direct模式)
springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持. Direct Excha ...
- mongodb与关系型数据库优缺点比较
1.与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度②文档结构的存储方式,能够更便捷的获取数据③内置GridFS,支持大容量的存储.④内置Sharding.⑤第 ...
- ssh和ssh-copy-id以及批量多机无密码登陆详解
本文主要围绕着ssh服务以及如何通过ssh-copy-id实现无密码登陆. 1. sshd 服务以及配置 2.ssh-copy-id命令的使用以及原理.3.批量多机互相信任. 1. sshd 服务 ...
- Java直接用javac来编译带package的类
在没有package语句的java类, 我们可以直接使用: javac Test.java 就可以了, 如果Test.java中包含package语句,如:package abc; 编译后,是要求Te ...
- 【LeetCode题解】142_环形链表2(Linked-List-Cycle-II)
目录 描述 解法一:哈希表 思路 Java 实现 Python 实现 复杂度分析 解法二:双指针 思路 Java 实现 Python 实现 复杂度分析 描述 给定一个链表,返回链表开始入环的第一个节点 ...