缓存印象

缓存给人的感觉就是可以提高程序运行速度,比如在桌面环境中,第一次打开一个大型程序可能需要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. [Swift实际操作]七、常见概念-(7)日历Calendar和日期组件DateComponents

    本文将为你演示日历和日期组件的使用.通过日历的日期部件,可以获得日期的各个部分. 首先引入需要用到的界面工具框架 import UIKit 初始化一个日期对象,其值为当前的日期. let dt = D ...

  2. js中call、apply、bind的使用

    写在前面的话 这三个方法都是来自Function.prototype上,所以所有的函数都可以使用. 他们有一个共同点,就是可以指定函数执行时的内部this指向. call和apply的区别在于参数的方 ...

  3. Pycharm使用Git

    Pycharm使用Git 1.设置git程序路径 2.设置github连接 3.创建git respository 4.提交文件 5.共享给GitHub 6.修改文件push到版本库 7.从版本库ch ...

  4. javascript数据结构与算法--二叉树遍历(中序)

    javascript数据结构与算法--二叉树遍历(中序) 中序遍历按照节点上的键值,以升序访问BST上的所有节点 代码如下: /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * ...

  5. 原生js 实现jquery addClass,removeClass

    代码如下: function hasClass(obj, cls) { let reg = new RegExp("(\\s|^)" + cls + "(\\s|$)&q ...

  6. 48位MAC转化为唯一的128位IPV6地址

    根据EUI_64规范,一个MAC地址生成唯一的一个IPV6地址. ①.反转MAC的第七位为1. ②.在24bit后加入FFFE. ③.在最前面加上FE80::. 示例:

  7. FoxitReader软件下载并安装(图文详解)

    不多说,直接上干货! FoxitReader官方网址:https://www.foxitsoftware.com/downloads/ 结束 欢迎大家,加入我的微信公众号:大数据躺过的坑        ...

  8. Redis笔记(一):Redis安装教程

    Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Redis是目前应用最广泛的内存数据存储技术,相比之前的Me ...

  9. android学习-IPC机制之ACtivity绑定Service通信

    bindService获得Service的binder对象对服务进行操作 Binder通信过程类似于TCP/IP服务连接过程binder四大架构Server(服务器),Client(客户端),Serv ...

  10. Go RabbitMQ (一)

    RabbitMQ 简介 RabbitMQ是一个消息代理,用来负责接收和转发消息. 术语 生产者:生产者是负责发送消息的 队列:队列是RabbitMQ用来存储消息的,受主机内存和磁盘大小的限制,本质上是 ...