03 | 如何利用系统缓存优化程序的运行效率?

前言

上一节,我们学习了内存性能中 Buffer 和 Cache 的概念。简单复习一下,Buffer 和 Cache 的设计目的,是为了提升系统的 I/O 性能。它们利用内存,充当起慢速磁盘与快速 CPU 之间的桥梁,可以加速 I/O 的访问速度。

Buffer 和 Cache 分别缓存的是对磁盘和文件系统的读写数据。

  • 从写的角度来说,不仅可以优化磁盘和文件的写入,对应用程序也有好处,应用程序可以在数据真正落盘前,就返回去做其他工作。
  • 从读的角度来说,不仅可以提高那些频繁访问数据的读取速度,也降低了频繁 I/O 对磁盘的压力。

既然 Buffer 和 Cache 对系统性能有很大影响,那我们在软件开发的过程中,能不能利用这一点,来优化 I/O 性能,提升应用程序的运行效率呢/p>

答案自然是肯定的。下面,用几个案例帮助你更好地理解缓存的作用,并学习如何充分利用这些缓存来提高程序效率。为了方便理解,下文中的Buffer 和 Cache 仍然用英文表示,避免跟“缓存”一词混淆。而文中的“缓存”,通指数据在内存中的临时存储。

缓存命中率

如果我们想利用缓存来提升程序的运行效率,应该怎么评估这个效果呢句话说,有没有哪个指标可以衡量缓存使用的好坏呢/p>

所谓缓存命中率,是指直接通过缓存获取数据的请求次数,占所有数据请求次数的百分比。
命中率越高,表示使用缓存带来的收益越高,应用程序的性能也就越好。

实际上,缓存是现在所有高并发系统必需的核心模块,主要作用就是把经常访问的数据(也就是热点数据),提前读入到内存中。这样,下次访问时就可以直接从内存读取数据,而不需要经过硬盘,从而加快应用程序的响应速度。

这些独立的缓存模块通常会提供查询接口,方便我们随时查看缓存的命中情况。不过 Linux 系统中并没有直接提供这些接口,所以这里要介绍一下cachestat 和 cachetop ,它们正是查看系统缓存命中情况的工具。

  • cachestat 提供了整个操作系统缓存的读写命中情况。
  • cachetop 提供了每个进程的缓存命中情况。

这两个工具都是 bcc 软件包的一部分,它们基于 Linux 内核的 eBPF(extended Berkeley Packet Filters)机制,来跟踪内核中管理的缓存,并输出缓存的使用和命中情况。

使用 cachestat 和 cachetop 前,我们首先要安装 bcc 软件包。比如,在 Ubuntu 系统中,你可以运行下面的命令来安装:

注意:bcc-tools 需要内核版本为 4.1 或者更新的版本,如果你用的是 CentOS,那就需要手动升级内核版本后再安装。

操作完这些步骤,bcc 提供的所有工具就都安装到 /usr/share/bcc/tools 这个目录中了。不过这里提醒你,bcc 软件包默认不会把这些工具配置到系统的 PATH 路径中,所以你得自己手动配置:

配置完,你就可以运行 cachestat 和 cachetop 命令了。比如,下面就是一个 cachestat 的运行界面,它以 1 秒的时间间隔,输出了 3 组缓存统计数据:

可以看到,cachestat 的输出其实是一个表格。每行代表一组数据,而每一列代表不同的缓存统计指标。这些指标从左到右依次表示:

  • TOTAL ,表示总的 I/O 次数;
  • MISSES ,表示缓存未命中的次数;
  • HITS ,表示缓存命中的次数;
  • DIRTIES, 表示新增到缓存中的脏页数;
  • BUFFERS_MB 表示 Buffers 的大小,以 MB 为单位;
  • CACHED_MB 表示 Cache 的大小,以 MB 为单位。

再来看一个 cachetop 的运行界面:

它的输出跟 top 类似,默认按照缓存的命中次数(HITS)排序,展示了每个进程的缓存命中情况。具体到每一个指标,这里的 HITS、MISSES 和 DIRTIES ,跟 cachestat 里的含义一样,分别代表间隔时间内的缓存命中次数、未命中次数以及新增到缓存中的脏页数。而 READ_HIT 和 WRITE_HIT ,分别表示读和写的缓存命中率。

指定文件的缓存大小

除了缓存的命中率外,还有一个指标你可能也会很感兴趣,那就是指定文件在内存中的缓存大小。你可以使用 pcstat 这个工具,来查看文件在内存中的缓存大小以及缓存比例。

pcstat 是一个基于 Go 语言开发的工具,所以安装它之前,你首先应该安装 Go 语言

安装完 Go 语言,再运行下面的命令安装 pcstat:

全部安装完成后,你就可以运行 pcstat 来查看文件的缓存情况了。比如,下面就是一个 pcstat 运行的示例,它展示了 /bin/ls 这个文件的缓存情况:

这个输出中,Cached 就是 /bin/ls 在缓存中的大小,而 Percent 则是缓存的百分比。这里它们都是 0,这说明 /bin/ls 并不在缓存中。

接着,如果你执行一下 ls 命令,再运行相同的命令来查看的话,就会发现 /bin/ls 都在缓存中了:

知道了缓存相应的指标和查看系统缓存的方法后,接下来,我们进入今天的案例学习。

  • 机器配置:Ubuntu 18.04,2 CPU,8GB 内存。
  • 预先按照上面的步骤安装 bcc 和 pcstat 软件包,并把这些工具的安装路径添加到到 PATH 环境变量中。
  • 预先安装 Docker 软件包,使用

案例一

dd 作为一个磁盘和文件的拷贝工具,经常被拿来测试磁盘或者文件系统的读写性能。不过,既然缓存会影响到性能,如果用 dd 对同一个文件进行多次读取测试,测试的结果会怎么样呢/p>

我们来动手试试。首先,打开两个终端,连接到 Ubuntu 机器上,确保 bcc 已经安装配置成功。

然后,使用 dd 命令生成一个临时文件,用于后面的文件读取测试:

继续在第一个终端,运行 pcstat 命令,确认刚刚生成的文件不在缓存中。如果一切正常,你会看到 Cached 和 Percent 都是 0:

$ pcstat file+-------+----------------+------------+-----------+-----来源:码农谷阿莫
                                                        

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年10月19日
下一篇 2019年10月19日

相关推荐