文件系统缓存调优检查表(性能之巅-内存部分笔记)

目标

为你的操作系统开发出以下的步骤:

  1. 一个文件系统调优检查表。这应该列出文件系统缓存,以及如何检查他们的大小、使用情况和命中率;
  2. 一个文件系统负载特征归纳表。包括如何得到各项详细信息,并优先使用系统现有的文件系统观察工具。

文件系统调优检查表

文件系统的缓存 表 3.2 磁盘I/O缓存层级示例

缓存 实例
应用程序缓存 apache/gameserver
服务器缓存 memcached/redis
数据库缓存 mysql 缓存
目录缓存 DNLC
文件元数据缓存 inode缓存
操作系统缓存区高速缓存 segvn
文件系统主缓存 ZFS ARC
文件系统次缓存 ZFS L2ARC
设备缓存 ZFS vdev
块设备 缓存区高速缓存
磁盘控制器缓存 RAID卡缓存
存储阵列缓存 -
磁盘内置缓存 -

Linux-文件系统缓存

cache && buffer

free, ps,top,vmstat 命令查看,主要是通过 /proc/meminfo 算出来的,其中 used 字段,是通过 used=total-free 得到,是个间接值。

[LawrenceChi@LOCAL-96-156 ~]$ free ;top -b -n 1 | grep -e "Mem:" -e "Swap:"; vmstat 1 5;vmstat -a 1 5;
             total       used       free     shared    buffers     cached
Mem:       8062400    6961432    1100968          0     390780    3838792
-/+ buffers/cache:    2731860    5330540
Swap:      2097144      55724    2041420
Mem:   8062400k total,  6961944k used,  1100456k free,   390780k buffers
Swap:  2097144k total,    55724k used,  2041420k free,  3838796k cached
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  55724 1100952 390780 3838796    0    0     0    12    0    4  4  1 95  0  0
 0  0  55724 1100960 390784 3838796    0    0     0    88  490  556  0  0 99  0  0
 0  0  55724 1100960 390784 3838796    0    0     0     0  537  570  0  0 99  0  0
 0  0  55724 1100836 390784 3838928    0    0     0     0 1298  833  2  1 97  0  0
 0  0  55724 1100868 390784 3838960    0    0     0     0  535  570  1  1 99  0  0
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 1  0  55724 1100868 2023192 4141020    0    0     0    12    0    4  4  1 95  0  0
 0  0  55724 1101496 2023228 4140004    0    0     0    16  861  654  1  1 98  0  0
 0  0  55724 1101496 2023300 4140048    0    0     0   180 1085  767  1  1 98  0  0
 0  0  55724 1101496 2023336 4140056    0    0     0     0  611  558  1  1 99  0  0
 0  0  55724 1101380 2023444 4140076    0    0     0     0 1215  781  2  1 97  0  0
[LawrenceChi@LOCAL-96-156 ~]$

cache 是文件系统读缓存。
buffer是文件系统写缓存,通过查看 /proc/meminfo 中的Dirty,查看有多少“脏页”。

文件是否已经在缓存中及处理

文件系统读缓存,可以通过vmtouch工具来检查文件是否已经在缓存中。

vmtouch 判断文件是否在缓存中原理

  1. fopen 需要检测的文件,mmap到内存;
  2. 通过 mincore 系统调用,判断文件页是否已经在内存中;
  3. ummap,输出统计结果。
  4. 可以按照文件、文件夹进行统计;

vmtouoch 将文件加载到缓存中的原理

  1. fopen 需要检测的文件,mmap到内存;
  2. 每一个页(page)访问一次,触发文件缓存机制;
  3. 退出;

vmtouch 将文件从缓存中释放掉的原理

  1. fopen 文件, mmap到内存;
  2. posix_fadvise 系统调用 进行内存释放。 关于 posix_fadvise不应定真正释放内存,这里有一篇文章说明文件脏数据的对内存释放的影响;
  3. ummap, flcose。

缓存占用空间

cat /proc/meminfo 中 Buffers、Cached可以看到文件系统缓存占用情况:

[LawrenceChi@LOCAL-96-157 gameserver]$ cat /proc/meminfo
MemTotal:        8062400 kB
MemFree:          201160 kB
Buffers:          294268 kB
Cached:          3373396 kB
SwapCached:        83540 kB
Active:          3994004 kB
Inactive:        2531980 kB
Active(anon):    1891580 kB
Inactive(anon):   968060 kB
Active(file):    2102424 kB
Inactive(file):  1563920 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       2097144 kB
SwapFree:         824900 kB
Dirty:               232 kB
Writeback:             0 kB
AnonPages:       2775564 kB
Mapped:            62636 kB
Shmem:              1308 kB
Slab:            1030904 kB
SReclaimable:     878300 kB
SUnreclaim:       152604 kB
KernelStack:       16280 kB
PageTables:       161188 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     6128344 kB
Committed_AS:   19296144 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      159412 kB
VmallocChunk:   34359571032 kB
HardwareCorrupted:     0 kB
AnonHugePages:   1036288 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       10240 kB
DirectMap2M:     8378368 kB

vmstat命令中关于内存、缓存的选项说明

vmstat -m

The -m switch displays slabinfo.
释放页面缓存,把那个比较连个 vmstat 得到变少的数据统计。
buffer_head/radix_tree_node:这是页面缓存

Free pagecache only use following command
# sync; echo 1 > /proc/sys/vm/drop_caches
lawrencechi@LawrencechideMacBook-Pro ~/Downloads » cat clean.1.txt| awk '{ if($7<$2){b=$2-$7; printf("%s, after-befor= %d\n",$0,b);}}'  | sort -t"=" -k 2 -n -r | head -n 10
buffer_head              969164 970584    104     37               buffer_head                8500  59977    104     37               , after-befor= 960664
radix_tree_node           38661  40180    560      7               radix_tree_node            4418  14392    560      7               , after-befor= 34243
filp                      21109  24260    192     20               filp                      20890  24260    192     20               , after-befor= 219
cred_jar                   1809   2620    192     20               cred_jar                   1705   2620    192     20               , after-befor= 104
proc_inode_cache         111179 111558    656      6               proc_inode_cache         111122 111558    656      6               , after-befor= 57
size-32                   19411  19600     32    112               size-32                   19356  19600     32    112               , after-befor= 55
size-128                   3420   3630    128     30               size-128                   3367   3630    128     30               , after-befor= 53
anon_vma_chain            93932 102025     48     77               anon_vma_chain            93884 102025     48     77               , after-befor= 48
size-1024                  2048   2384   1024      4               size-1024                  2004   2384   1024      4               , after-befor= 44
task_delay_info            1029   1292    112     34               task_delay_info             990   1292    112     34               , after-befor= 39
Free dentries and inodes use following command
# sync; echo 2 > /proc/sys/vm/drop_caches

这次得到的结果是:dentry,pro_inode_cache,ext4_inode_cache

lawrencechi@LawrencechideMacBook-Pro ~/Downloads » cat clean.2.txt| awk '{ if($7<$2){b=$2-$7; printf("%s, after-befor= %d\n",$0,b);}}'  | sort -t"=" -k 2 -n -r | head -n 15
dentry                   1392310 1392420    192     20  dentry                    14288  81380    192     20        , after-befor= 1378022
buffer_head              969164 970584    104     37    buffer_head               11576  59718    104     37    , after-befor= 957588
proc_inode_cache         111179 111558    656      6    proc_inode_cache             50    168    656      6    , after-befor= 111129
ext4_inode_cache          99263  99296   1016      4    ext4_inode_cache           1187   2644   1016      4    , after-befor= 98076
radix_tree_node           38661  40180    560      7    radix_tree_node            4685  14091    560      7    , after-befor= 33976
size-64                   44416  44840     64     59    size-64                   12858  41772     64     59    , after-befor= 31558
inode_cache                6530   6588    592      6    inode_cache                4266   4488    592      6    , after-befor= 2264
size-128                   3420   3630    128     30    size-128                   2013   3450    128     30    , after-befor= 1407
anon_vma_chain            93932 102025     48     77    anon_vma_chain            93401 102025     48     77    , after-befor= 531
vm_area_struct           101400 110903    200     19    vm_area_struct           101000 110903    200     19    , after-befor= 400
anon_vma                  54374  59340     40     92    anon_vma                  54095  59340     40     92    , after-befor= 279
filp                      21109  24260    192     20    filp                      20854  24260    192     20    , after-befor= 255
pid                        1324   1560    128     30    pid                        1245   1560    128     30    , after-befor= 79
fs_cache                    629    944     64     59    fs_cache                    563    944     64     59    , after-befor= 66
task_delay_info            1029   1292    112     34    task_delay_info             969   1292    112     34    , after-befor= 60
Free pagecache, dentries and inodes in cache memory# sync; echo 3 > /proc/sys/vm/drop_caches

结论,在使用 vmstat -m进行分析内存缓存的时候,我们最重要关注是:
buffer_head/radix_tree_node/dentry,pro_inode_cache,ext4_inode_cache

缓存项 说明
buffer_head 每个buffer_head管理的单元是内存页中对应的一个磁盘块,也就是说buffer_head管理单元是 “页”的一个子集. buffer_head理解、解析
radix_tree_node radix树(基数树)数据缓存.Linux 内核数据结构:Radix树 Radix tree(wiki)
dentry 高速目录缓存
pro_inode_cache /proc 文件系统缓存,可以侧面反映进程开启情况
ext4_inode_cache NULL

cache 命中率计算

Linux Page Cache Hit Ratio

vmstat -s

The -s switch displays a table of various event counters and memory statistics. This display does not repeat.

[LawrenceChi@LOCAL-96-157 ~]$ vmstat -s
8062400  total memory
7753332  used memory
4019728  active memory
2819196  inactive memory
309068  free memory
314848  buffer memory
3536000  swap cache
2097144  total swap
1106356  used swap
990788  free swap
30702361 non-nice user cpu ticks
12601 nice user cpu ticks
21383073 system cpu ticks
2601397816 idle cpu ticks
4037027 IO-wait cpu ticks
15937 IRQ cpu ticks
1583247 softirq cpu ticks
0 stolen cpu ticks
106072566 pages paged in
405098416 pages paged out
685075 pages swapped in
2390879 pages swapped out
495740634 interrupts
2065133133 CPU context switches
1457495157 boot time
13714053 forks
[LawrenceChi@LOCAL-96-157 ~]$

性能之巅读书笔记-1、2、3、4、5章

性能定义

性能是一个很主观的概念,从某种程度上,一个给定指标是“好”或者“坏”取决于应用开发人员和最终用户的性能预期。同构定义清晰的目标,对性能指标化,量化,才能够把主管的性能进行客观化。

性能问题排查方法

“在取得问题之前就把事情理论化是一个严重的错误。不理智的人扭曲事实来适应理论,而不是改变理论来适应事实。”

建立系统模型

受测系统,注意扰动是会影响测试结果的。扰动的来源包括定时执行的系统活动、系统其它用户或者其它工作负载、云环境中其它租户引起的活动等。

组件和资源可以模型化成排队系统。

性能问题概念

延时

时间单位指标

单位 简写 与1秒的比例
m 60
s 1
毫秒 ms 10^-3
微秒 us 10^-6
纳秒 ns 10^-9
皮秒 ps 10^-12

时间量级

事件 延时 相对时间比例
1个CPU周期 0.3ns 1s
L1缓存访问 0.9ns 3s
L2缓存访问 2.8ns 9s
L3缓存访问 12.9ns 43s
主存访问(从CPU访问DRAM) 120ns 6分
固态硬盘I/O(闪存) 50-150us 2-6天
旋转硬盘I/O 1-10ms 1-12月
互联网:旧金山到纽约 40ms 4年
互联网:旧金山到英国 81ms 8年
互联网:旧金山到澳大利亚 183ms 19年
TCP包重传 1-3s 105-317年
OS虚拟化系统重启 4s 423年
SCSI命令超时 30s 3千年
硬件虚拟化系统重启 40s 4千年
物理系统重启 5m 32千年

调整的影响

性能调整发生在越靠近工作执行的地方,效果越显著。对于工作负载驱动的应用程序,所执行的工作就是应用程序本身。

指标

使用率

基于时间

基于容量

饱和度

方法论

性能调整领域是“你知道的越多,你不知道的也就越多”。这和学习系统是一样的原理:你了解得越多,你就能意识到未知的未知就越多,然后这些未知的未知就会变成你可以去查看的已知的未知

街灯讹方法(反面)

随机变动讹方法(反面)

责怪他人讹方法(反面)

Ad Hoc 核对清单法

技术人员根据核对清单,一一进行检查。

问题陈述法

1.为什么会认为有性能问题?
2.系统之前运行得好吗?
3.最近有什么改动?软件?硬件?负载?
4.问题能够用延时或者运行时间来表述吗?
5.问题影响其他人和应用程序吗?
6.环境是怎么样的?用了哪些软件和硬件?是什么版本呢?是怎么样的配置?

科学法

问题-》假设-》预测-》实验-》分析

诊断循环法

工具法

USE方法(重点)

utilization、saturation、errors。 对于所有的资源,查看它的使用率、饱和度和错误。

工作负载特征归纳

向下挖掘分析

R方法

事件追踪

基础线统计

系能监控

排队论

静态性能调试

缓存调优

微基准测试

容量规划

统计

量化性能

平均值

1.几何平均值
2.调和平均值
3.随着时间变化的平均值
4.衰退平均值

标准方差、百分位数、中位数

变异系数

多模态分布

异常值