美文网首页
Page Cache

Page Cache

作者: 欧阳_z | 来源:发表于2020-08-30 20:31 被阅读0次

1、简洁
Page Cache 存在于内核,目的是为了减少 I/O,提升应用的 I/O 速度。

2、速度对比
生成一个 200 MB 的文件用于测试:

~/tmp$ dd if=/dev/urandom of=~/tmp/200.bin bs=1M count=200

因为有缓存,可以看到速度很快:

~/tmp$ dd if=200.bin of=/dev/null bs=1M count=200
200+0 records in
200+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 0.0363743 s, 5.8 GB/s

清理缓存之后,速度比较慢:

~/tmp$ sync && sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
~/tmp$ dd if=200.bin of=/dev/null bs=1M count=200
200+0 records in
200+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 0.506025 s, 414 MB/s

一个是 5.8 GB/s ,一个是 414 MB/s,对比十分明显。

3、vmtouch

sudo apt install vmtouch

源码在 https://github.com/hoytech/vmtouch
vmtouch 可以查询 文件或目录是否有缓存,开始是100%,清理缓存之后是0%

~/tmp$ vmtouch 200.bin 
           Files: 1
     Directories: 0
  Resident Pages: 51200/51200  200M/200M  100%
         Elapsed: 0.003029 seconds
~/tmp$ sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
~/tmp$ vmtouch 200.bin 
           Files: 1
     Directories: 0
  Resident Pages: 0/51200  0/200M  0%
         Elapsed: 0.002153 seconds
~/tmp$ 

-e 选项可以仅清除指定文件的缓存:

~/tmp$ vmtouch 200.bin 
           Files: 1
     Directories: 0
  Resident Pages: 51200/51200  200M/200M  100%
         Elapsed: 0.004441 seconds
~/tmp$ vmtouch -e 200.bin 
           Files: 1
     Directories: 0
   Evicted Pages: 51200 (200M)
         Elapsed: 0.01934 seconds
~/tmp$ vmtouch 200.bin 
           Files: 1
     Directories: 0
  Resident Pages: 0/51200  0/200M  0%
         Elapsed: 0.001222 seconds

4、vmtouch 的实现原理
下面写一个测试程序,主要由 mmapmincore 两个系统调用实现,mincore 描述文件的哪些页在内核中,最低有效位表示页面是否驻留在内核中:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include <fcntl.h>

unsigned long get_file_size(const char *path)
{  
    unsigned long filesize = -1;      
    struct stat statbuff;  
    if(stat(path, &statbuff) < 0)
    {  
        return filesize;  
    }
    else
    {  
        filesize = statbuff.st_size;  
    }  
    return filesize;  
}

void vmtouch_file(char *path)
{
    int fd = open(path, O_RDONLY, 0);
    if (fd == -1)
    {
        fprintf(stderr, "open(%s): %s\n", path, strerror(errno));
        return;
    }

    long PAGE_SIZE = sysconf(_SC_PAGESIZE); // 4096
    int64_t file_bytes = get_file_size(path);
    int64_t file_pages = (file_bytes + PAGE_SIZE -1) / PAGE_SIZE;
    char *mincore_array = malloc(file_pages);
    if (mincore_array == NULL)
    {
        fprintf(stderr, "malloc: FATAL: %s\n", strerror(errno));
        goto fail;
    }

    void *mem = mmap(NULL, file_bytes, PROT_READ, MAP_SHARED, fd, 0);
    if (mem == MAP_FAILED)
    {
        fprintf(stderr, "mmap(%s): %s\n", path, strerror(errno));
        goto fail;
    }

    if (mincore(mem, file_bytes, (void*)mincore_array))
    {
        fprintf(stderr, "mincore: FATAL: %s\n", strerror(errno));
        goto fail;
    }

    int i;
    int64_t total_pages_in_core = 0;
    for (i = 0; i< file_pages; i++)
    {
        if ( mincore_array[i] & 0x1 )
        {
            total_pages_in_core++;
        }
    }

    printf("Pages: %ld/%ld  ", total_pages_in_core, file_pages);
    printf("%.3g%% \n", 100.0*total_pages_in_core/file_pages);

fail:
    if (mincore_array)
    {
        free(mincore_array);
    }
    if (mem)
    {
        if (munmap(mem, file_bytes)) 
        {
            fprintf(stderr, "munmap: %s\n", strerror(errno));
        }
    }
    if (fd != -1)
    {
        close(fd);
    }
}

int main(int argc, char* argv[])
{
    if (argc != 2)
        return -1;
    vmtouch_file(argv[1]);

    return 0;
}

测试效果,清缓存之前是100%,清缓存之后是0%

~/tmp$ vmtouch 200.bin 
           Files: 1
     Directories: 0
  Resident Pages: 51200/51200  200M/200M  100%
         Elapsed: 0.004504 seconds
~/tmp$ ./a.out 200.bin 
Pages: 51200/51200  100% 
~/tmp$ sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
~/tmp$ ./a.out 200.bin 
Pages: 0/51200  0% 
~/tmp$ vmtouch 200.bin 
           Files: 1
     Directories: 0
  Resident Pages: 0/51200  0/200M  0%
         Elapsed: 0.002726 seconds

相关文章

  • The Page Cache and Page Writebac

    page cache是kernel实现的disk cache, 这是为了减少磁盘I/O。page writebac...

  • Page Cache

    1、简洁Page Cache 存在于内核,目的是为了减少 I/O,提升应用的 I/O 速度。 2、速度对比生成一个...

  • Page Cache

    容器里面乾坤大 我想说的是 cgroup 可以限制cpu, memory, network 等等, 但是 page...

  • Page Cache

    Page Cache是通过将磁盘中的数据缓存到内存中,减少磁盘I/O操作,从而提高性能。此外,还要确保Page C...

  • Rocket MQ

    参考万亿级数据洪峰下的分布式消息引擎 - 简书 Page Cache Page Cache是文件的缓存,用于加速对...

  • Page Claim

    Linux page包括分配给进程的Page及 cache Page, 记得很早之前看过vm.swappiness...

  • 【CentOS】关于CentOS7.x free内存查看

    # free -h free里的cache/buffer就是page cache, 早期Linux文件相关的cac...

  • linux清理系统缓存脚本

    本脚本简介,用于清理buffer cache page 缓存

  • Linux内核Page Cache和Buffer Cache关系

    声明:本文转载 原文链接:Linux内核Page Cache和Buffer Cache关系及演化历史 | lday...

  • page cache和buffer cache

    文章摘自于:https://www.cnblogs.com/yrpen/p/3777963.html pageca...

网友评论

      本文标题:Page Cache

      本文链接:https://www.haomeiwen.com/subject/qtoesktx.html