文件缓存对于性能有重要影响,在大多数情况下,读缓存再多大多数时候都是有好处的。写缓存比较复杂,linux内核将磁盘写入缓存,过段时间再将异步刷入到磁盘中,这对于加速磁盘IO有好处,但是当数据没有写入到磁盘的时候,可能存在数据丢失的情况。
当然,也存在缓存被写爆的时候。可能出现一次性向磁盘写入了过多的数据,造成了系统卡顿,这些卡顿是因为系统认为,缓存太大用异步的方式来不及写入磁盘,所以切换到同步模式写入磁盘。
可以根据负载情况,调节linux系统的缓存刷新。
vm.dirty_background_ratio:内存可以填充脏数据的百分比,这些脏数据随后会被写入磁盘。
pdflush/flush/kdmflush这些后台进程会稍后清理脏数据。比如,我有32G内存,那么有3.2G的脏数据可以待着内存里,超过3.2G的话就会有后台进程来清理。
vm.dirty_ratio:可以用脏数据比最大系统内存量,当系统达到这个值后,必须将所有的脏数据提交到磁盘,同时新的IO被阻塞,直到脏数据被写入磁盘,这是IO卡顿的原因,但是也保证了内存中不会存在过多的脏数据。
vm.dirty_background_bytes和vm.dirty_bytes是另一种指定这些参数的方法。如果设置_bytes版本,则_ratio版本将变为0,反之亦然。
vm.dirty_expire_centisecs :指定脏数据存活的时间,默认设置是30s,当pdflush/flush/kdmflush 运行的时候,会检查是否有数据超过了这个限制,如果有则将它异步写入到磁盘中。
vm.dirty_writeback_centisecs:指定多长时间唤醒pdflush/flush/kdmflush,然后检查是否需要清理缓存。
可以通过下列方式查看内存中有多少脏数据:
cat /proc/vmstat | egrep "dirty|writeback"
方法1:减少缓存
在很多情况下,我们有快速的磁盘子系统,它们有自己的大电池支持的NVRAM缓存,所有将东西保存在系统页面缓存中是有风险的。让我们尝试以更及时的方式向磁盘发送IO,为了做到这一点,我们减少/etc/sysctl.conf中的vm.dirty_background_ratio和vm.dirty_ratio的数据,并执行sysctl -p。
这是基于linux虚拟机管理程序的典型方法,不建议设置为0,一些后台IO可以很好地将应用程序性能与磁盘阵列在SAN上的较短时间的较高延迟解耦。
方法2:增加缓存
在某些情况下,显著提高缓存可能对性能有积极影响。在这种情况下,linux客户机上包含的数据不是关键的,可能会丢失,而且应用程序通常会重复或者以可以重复的方式写入相同的文件。因此,允许内存中存在更多的脏页,只需要每隔一段时间向磁盘写入一次。
有时回提高vm.dirty_expire_centises这个参数的值,来允许脏数据更长时间的停留。除了增加数据丢失的风险,如果缓存满了并且需要同步,还会有长时间IO卡顿的风险。
方法3:增减都用
有时系统需要应对突如其来的高峰数据,可能会拖慢磁盘。这种情况,我们允许大量的IO写入到缓存中,在后台刷新慢慢处理。
vm.dirty_background_ratio = 5 vm.dirty_ratio = 80
这个时候,系统后台进程在脏数据达到5%的时候就开始异步清理,但是在80%之前系统不会强制同步写盘。这个时候,需要调整RAM的大小以便能够缓存所有数据。