zoukankan      html  css  js  c++  java
  • 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       2.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 "1" > /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       2.8G        60G

    可以看到此时cached一项已经从72GB一下子减少到了70MB,不过这样做一般情况下是不应该的。我们需要让系统尽可能的利用可用内存来提供程序运行速度,光有内存可用量并没什么实质的用处。缓存主要还是被页缓存占用,执行第一项后基本也就不会缩小了。执行这个操作不会对以后的缓存策略造成影响,这个操作只是手工触发一次清空(刷出)缓存的操作。

    缓存验证

    首先生成一个随机文件,大小为1GB

    dd if=/dev/urandom of=rnd.dat bs=1MB count=1024

    如果刚刚清空了页面缓存此时在用free命令时cached一项应该就在1GB左右

    root@controller:~# free -h
                 total       used       free     shared    buffers     cached
    Mem:           62G        13G        49G       904K        69M       1.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
    1024+0 records in
    1024+0 records out
    1024000000 bytes (1.0 GB) copied, 2.58692 s, 396 MB/s
    root@controller:~# free -h
                 total       used       free     shared    buffers     cached
    Mem:           62G        13G        49G       904K       1.3M       1.0G
    -/+ buffers/cache:        12G        50G
    Swap:          63G       9.9M        63G
    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.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=1
    1+0 records in
    1+0 records out
    1024000000 bytes (1.0 GB) copied, 3.91219 s, 262 MB/s
    
    root@controller:~# dd if=/dev/zero of=rnd.dat bs=1024MB count=1 oflag=direct
    1+0 records in
    1+0 records out
    1024000000 bytes (1.0 GB) copied, 2.66657 s, 384 MB/s

    direct即不使用缓存直接进行写入操作,direct模式居然比使用缓存的还要快,这非常不合理。如果使用strace跟踪第一条命令的话,会发现很多时间其实用在了close调用上。

    root@controller:~# strace -tt dd if=/dev/zero of=rnd.dat bs=1024MB count=1
    20:24:00.207073 execve("/bin/dd", ["dd", "if=/dev/zero", "of=rnd.dat", "bs=1024MB", "count=1"], [/* 23 vars */]) = 0
    20:24:00.207857 brk(0)                  = 0x84c000
    .......
    20:24:00.212135 open("/dev/zero", O_RDONLY) = 3
    20:24:00.212246 dup2(3, 0)              = 0
    20:24:00.212342 close(3)                = 0
    20:24:00.212432 lseek(0, 0, SEEK_CUR)   = 0
    20:24:00.212528 open("rnd.dat", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
    20:24:00.625270 dup2(3, 1)              = 1
    20:24:00.625401 close(3)                = 0
    20:24:00.625502 mmap(NULL, 1024012288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1cd975c000
    20:24:00.625646 read(0, ""..., 1024000000) = 1024000000
    20:24:01.183562 write(1, ""..., 1024000000) = 1024000000
    20:24:02.454654 close(0)                = 0
    20:24:02.454884 close(1)                = 0
    20:24:04.815079 open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 0
    20:24:04.815331 fstat(0, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0
    20:24:04.815444 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1d16dd3000
    20:24:04.815553 read(0, "# Locale name alias data base.
    #"..., 4096) = 2570
    20:24:04.815704 read(0, "", 4096)       = 0
    20:24:04.815796 close(0)                = 0
    20:24:04.815885 munmap(0x7f1d16dd3000, 4096) = 0
    20:24:04.816016 open("/usr/share/locale/en_HK/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    20:24:04.816120 open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    20:24:04.816215 open("/usr/share/locale-langpack/en_HK/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    20:24:04.816307 open("/usr/share/locale-langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
    20:24:04.816442 write(2, "1+0 records in
    1+0 records out
    ", 311+0 records in
    1+0 records out
    ) = 31
    20:24:04.816594 write(2, "1024000000 bytes (1.0 GB) copied", 321024000000 bytes (1.0 GB) copied) = 32
    20:24:04.816747 write(2, ", 4.1912 s, 244 MB/s
    ", 21, 4.1912 s, 244 MB/s
    ) = 21
    20:24:04.816869 close(2)                = 0
    20:24:04.816959 exit_group(0)           = ?
    20:24:04.822877 +++ exited with 0 +++

    close(1)用了比write还多的时间,有理由相信,在close调用上面进行了相关的文件同步写入工作。

  • 相关阅读:
    python 读写excel,基于win32com实现
    nginx中lua语言获取传参字符串转json打印key,value
    nginx中lua语言打印匹配正则表达式的内容
    nginx 对于post,get参数访问做xss,sql注入过滤
    javaWeb第五天---MVC设计模式
    javaWeb第四天-----jspELJSTL
    javaWeb第三天---http协议和会话技术
    javaWeb第一天
    JDBC第二天---JDBC工具类
    jdbc第三天---配置文件、dao模式
  • 原文地址:https://www.cnblogs.com/lailailai/p/4497352.html
Copyright © 2011-2022 走看看