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权限 $ 没分配权限用户 二, 书写格式:空格 [命令参数] 空格 ...
随机推荐
- [Swift实际操作]七、常见概念-(7)日历Calendar和日期组件DateComponents
本文将为你演示日历和日期组件的使用.通过日历的日期部件,可以获得日期的各个部分. 首先引入需要用到的界面工具框架 import UIKit 初始化一个日期对象,其值为当前的日期. let dt = D ...
- js中call、apply、bind的使用
写在前面的话 这三个方法都是来自Function.prototype上,所以所有的函数都可以使用. 他们有一个共同点,就是可以指定函数执行时的内部this指向. call和apply的区别在于参数的方 ...
- Pycharm使用Git
Pycharm使用Git 1.设置git程序路径 2.设置github连接 3.创建git respository 4.提交文件 5.共享给GitHub 6.修改文件push到版本库 7.从版本库ch ...
- javascript数据结构与算法--二叉树遍历(中序)
javascript数据结构与算法--二叉树遍历(中序) 中序遍历按照节点上的键值,以升序访问BST上的所有节点 代码如下: /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * ...
- 原生js 实现jquery addClass,removeClass
代码如下: function hasClass(obj, cls) { let reg = new RegExp("(\\s|^)" + cls + "(\\s|$)&q ...
- 48位MAC转化为唯一的128位IPV6地址
根据EUI_64规范,一个MAC地址生成唯一的一个IPV6地址. ①.反转MAC的第七位为1. ②.在24bit后加入FFFE. ③.在最前面加上FE80::. 示例:
- FoxitReader软件下载并安装(图文详解)
不多说,直接上干货! FoxitReader官方网址:https://www.foxitsoftware.com/downloads/ 结束 欢迎大家,加入我的微信公众号:大数据躺过的坑 ...
- Redis笔记(一):Redis安装教程
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis是目前应用最广泛的内存数据存储技术,相比之前的Me ...
- android学习-IPC机制之ACtivity绑定Service通信
bindService获得Service的binder对象对服务进行操作 Binder通信过程类似于TCP/IP服务连接过程binder四大架构Server(服务器),Client(客户端),Serv ...
- Go RabbitMQ (一)
RabbitMQ 简介 RabbitMQ是一个消息代理,用来负责接收和转发消息. 术语 生产者:生产者是负责发送消息的 队列:队列是RabbitMQ用来存储消息的,受主机内存和磁盘大小的限制,本质上是 ...