linux页高速缓存_脏页_延迟写_I/O内核参数优化_pdflush

原创:linux01/21/2020发布pv:5uv:0ip:0twitter #linux

原文地址:https://www.douyacun.com/article/37c7ae7c04e74ad0aa75fda1b907ea48

页面缓存

查看页面缓存:

[www@00h ~]$ cat /proc/meminfo
MemTotal:        1882236 kB
MemFree:           75952 kB
MemAvailable:      58212 kB
Buffers:           14576 kB
Cached:           136732 kB
SwapCached:            0 kB
Active:          1630800 kB
Inactive:          79352 kB
Active(anon):    1584460 kB
Inactive(anon):    34188 kB
Active(file):      46340 kB
Inactive(file):    45164 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                84 kB  => 写入缓存页,Dirty的值会增加
Writeback:             0 kB  => 缓存页开始写入硬盘,Writeback值会增加直到结束
...

脏页

硬盘的读写速度远源跟不上内存的速度,内核会把读写比较频繁的数据事先放到内存中,以提高读写速度减少I/O操作,这叫高速缓存, linux是以页作为高速缓存的单位,当进程修改了高速缓冲中的数据时,该页就被称为脏页

延迟写

当将数据写入文件时,内核通常先将数据复制页面高速缓存,如果该缓冲区没有写满,并不将其写入到输出队列,而是等待其写满或者当内核需要重用这块缓冲区以便存放其他磁盘块数据时, 在将该缓冲区排入到输出队列,待其到达队首时,才进程实际的I/O操作,这种输出方式被称为延迟写

内存映射(mmap)

mmap用于把文件映射到内存空间中,简单说mmap就是把一个文件的内容在内存里面做一个映像。映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间。那么对于内核空间<---->用户空间两者之间需要大量数据传输等操作的话效率是非常高的。

页面缓存后,如何访问数据?

  1. 内核开始读时,先检查高速缓存中是否有该数据
  2. 如果有,命中缓存,没有直接从磁盘读取
  3. 内核调度块I/O,从磁盘中读取全部数据,将全部数据放入到页高速缓冲中

写缓冲

内核从磁盘读取数据时,如果从页高速缓冲中没有读取到的话,会直接从磁盘中读取数据并将数据存入页高速缓存中,保证下次使用,写缓存策略:

  • 直接I/O,不经过页高速缓存,会增大磁盘I/O开销
  • 写透缓存,写操作更新内存缓存,同时更新磁盘文件,可以保持缓存一致性
  • 回写,程序执行写操作直接将数据写入到缓存中,然后将被写入的页面标记为脏页,加入脏页链表中,回写进程会将脏页刷新到磁盘中,最终保持数据一致性

缓存回收(pdflush)

缓存回收,清除页的数据,为更重要的数据提供坑位,收缩缓存大小减小内存压力 linux回收策略:

  • LRU(最近最少使用)
  • 双链,分活跃链表/非活跃链表

pdflush写入到硬盘主要看两个参数:

  1. 数据在页缓冲中是否超过30秒,如果是标记为脏页
  2. 脏页缓存是否达到工作内存的100%

以下也会影响pdflush线程:

  • 用户进程调用sync/fsync/fdatasync
  • /proc/sys/vm/dirty_ratio: 默认30,总内存的百分比,系统所能拥有的最大脏页缓存总量
  • /proc/sys/vm/dirty_background_ratio: 默认 10, 如果需要把缓存持续的而不是一下子大量的写入磁盘,降低这个值

pdflsuh 受 /proc/sys/vm/ 下的参数控制:

[root@00h www]# ll /proc/sys/vm/|gawk '{print $9}'
admin_reserve_kbytes
block_dump
compact_memory 
dirty_background_bytes
dirty_background_ratio (10) 判断脏页缓存是否到了最大值 内存的%
dirty_ratio(30) 总内存的最大百分比,超过这个值开启pdflush写入硬盘,如果cache大于pdflush,会遇到I/O瓶颈,所有的I/O都要等待cache被pdflush进磁盘, 业务繁忙建议5-10%
dirty_bytes
dirty_expire_centisecs (3000) 缓存页里的过期时间,默认30秒
dirty_writeback_centisecs (500) 单位(1/100秒)多长时间唤醒pdflush将缓存页写入硬盘,默认:2个线程/5秒
drop_caches
extfrag_threshold
hugepages_treat_as_movable
hugetlb_shm_group
laptop_mode
legacy_va_layout
lowmem_reserve_ratio
max_map_count
memory_failure_early_kill
memory_failure_recovery
min_free_kbytes 保留内存的值
min_slab_ratio
min_unmapped_ratio
mmap_min_addr
mmap_rnd_bits
mmap_rnd_compat_bits
nr_hugepages
nr_hugepages_mempolicy
nr_overcommit_hugepages
nr_pdflush_threads 查看多少个pdflush进程
numa_zonelist_order
oom_dump_tasks
oom_kill_allocating_task
overcommit_kbytes
overcommit_memory
overcommit_ratio
page-cluster
panic_on_oom
percpu_pagelist_fraction
stat_interval
swappiness (0) linux倾向于从物理内存映射到硬盘缓存,保持硬盘缓存尽可能大。未用的页缓存会被放进swap区, 少用swapping会增加程序的响应速度;多用swapping将会提高系统的可用性。
    - 0 将会避免使用swapping
    - 100 尽量使用swapping
user_reserve_kbytes
vfs_cache_pressure
zone_reclaim_mode
  • dirty_ratio 单位百分比,表示当写缓冲内存占用内存多少的时候,开始向磁盘写数据,增大会使更多的系统内存用于磁盘写缓冲,可以极大的提高系统的写性能, 但是当你需要持续、恒定的写入场合时,应该降低其值
  • dirty_background_ratio 控制pdflush进程,在何时刷新磁盘,单位百分比,pdflush用于将内存中的内容和文件系统进行同步,每当内存中的垃圾页(dirty page)超过10%的时候,pdflush就会将这些页面备份回硬盘.增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值, 配合dirty_ratio
  • min_free_kbytes: 文件系统数据缓冲需要频繁的内存分配。加大保留内存的值能提升系统速度和稳定。小于8G的内存,保留内存为64M,大于8G的设置为256M
echo 65536 > /proc/sys/vm/min_free_kbytes
  • dirty_writeback_centisecs: 控制pdflush线程的运行间隔,单位时1/100秒,默认5秒(500),如果是持续的写入操作,降低这个值比较好,可以把剑锋的写操作削平成多次写操作,该参数的设置应该小于dirty_expire_centisecs, 也不能太小,太小I/0太频繁, 1:6 (dirty_expire_centisecs : dirty_writeback_centisecs )的比例比较好。
  • dirty_expire_centisecs: 声明Linux内核写缓冲区里面的数据多“旧”了之后,pdflush进程就开始考虑写到磁盘中去。单位是 1/100秒。缺省是 30000,也就是 30 秒的数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小也是好的,但也不能缩小太多,因为缩小太多也会导致IO提高太快。
  • min_free_kbytes: VM最低保留多少空闲内存(Kbytes)