缓存印象

缓存给人的感觉就是可以提高程序运行速度,比如在桌面环境中,第一次打开一个大型程序可能需要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 文件缓存 (一)的更多相关文章

  1. Linux 文件缓存 (二)

    close系统调用入口1. 首先来到系统调用入口,主要使用__close_fd进行了具体的处理过程,并没有耗时操作.(current->files表示进程当前打开文件表信息,fd为需要关闭的文件 ...

  2. Linux的文件系统及文件缓存知识点整理

    Linux的文件系统 文件系统的特点 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储. 文件系统中也要有索引区,用来方便查找一个文件分成的多个块都存放在了什么位置. 如果文件系统中有的文件 ...

  3. Linux服务之nginx服务篇五(静态/动态文件缓存)

    一.nginx实现静态文件缓存实战 1.nginx静态文件缓存 如果要熟练使用nginx来实现文件的缓存,那下面的几个指令你必须要牢记于心 (1)指令1:proxy_cache_path 作用:设置缓 ...

  4. Linux ARP缓存配置和状态查看命令

    查看Linux ARP缓存老化时间 cat /proc/sys/net/ipv4/neigh/eth0/base_reachable_time同目录下还有一个文件gc_stale_time,官方解释如 ...

  5. Linux 文件服务---------- nfs Server

    Linux 文件服务nfs (Network file system)#网络文件系统 ---> 远程文件调用samba #文件共享(unix /linux /windows ) ,只能适用于局域 ...

  6. 【转】漫谈linux文件IO--io流程讲的很清楚

    [转]漫谈linux文件IO--io流程讲的很清楚 这篇文章写的比较全面,也浅显易懂,备份下.转载自:http://blog.chinaunix.net/uid-27105712-id-3270102 ...

  7. Linux 文件系统管理

    Linux 文件系统管理 课程大纲  文件系统构成及命令  硬盘分区及管理  磁盘配额  备份与恢复   文件系统构成 /usr/bin ./bin:存放所有用户可以执行的命令 /usr/s ...

  8. centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课

    centos    LAMP第二部分apache配置  下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转  配置apache的访问日志  配置静态文件缓存  配置防盗链 ...

  9. llinux 目录结构 及Linux文件分享

    llinux 基础命令 及个人Linux文件分享 一, root用户名 @ 分隔符 kingle 主机名 ~当前所在目录 # root权限 $ 没分配权限用户 二, 书写格式:空格 [命令参数] 空格 ...

随机推荐

  1. apt错误

    安装软件遇到错误,不管安装什么软件都有错误. apt-get install softname 报错如下:E: Sub-process /usr/bin/dpkg returned an error ...

  2. Swift 里字符串(二)创建

     最终都要走到__StringStorage 的 create(realCodeUnitCapacity,countAndFlags) 方法里去. 默认实现是 UTF8 internal stati ...

  3. Ubuntu16.04 / OpenCV / Python 源码安装

    为什么需要源码安装? 1. 对 Python 版的 OpenCV,Ubuntu 有两种安装方式: 源码安装:官网(https://opencv.org/releases.html)下载源代码,在机器上 ...

  4. Python字典按值排序、包含字典的列表按字典值排序的方法

    operator.itemgetter函数 operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),要注意,operator.i ...

  5. VUE输入框显示时自动聚焦

    directives: { focus: { inserted: function (el, {value}) { if (value) { el.focus() } } } } 注意点:1.用v-i ...

  6. spring boot整合RabbitMQ(Direct模式)

    springboot集成RabbitMQ非常简单,如果只是简单的使用配置非常少,springboot提供了spring-boot-starter-amqp项目对消息各种支持. Direct Excha ...

  7. mongodb与关系型数据库优缺点比较

    1.与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问速度②文档结构的存储方式,能够更便捷的获取数据③内置GridFS,支持大容量的存储.④内置Sharding.⑤第 ...

  8. ssh和ssh-copy-id以及批量多机无密码登陆详解

    本文主要围绕着ssh服务以及如何通过ssh-copy-id实现无密码登陆. 1. sshd 服务以及配置   2.ssh-copy-id命令的使用以及原理.3.批量多机互相信任. 1. sshd 服务 ...

  9. Java直接用javac来编译带package的类

    在没有package语句的java类, 我们可以直接使用: javac Test.java 就可以了, 如果Test.java中包含package语句,如:package abc; 编译后,是要求Te ...

  10. 【LeetCode题解】142_环形链表2(Linked-List-Cycle-II)

    目录 描述 解法一:哈希表 思路 Java 实现 Python 实现 复杂度分析 解法二:双指针 思路 Java 实现 Python 实现 复杂度分析 描述 给定一个链表,返回链表开始入环的第一个节点 ...