本文是数据库优化系列第三篇,主要介绍针对文件系统的优化工作。了解系列内容欢迎前往文章底部往期链接~
数据库服务,本质上就是为用户提供标准的数据处理流程。它的目标是让用户能够以一种更加优雅的方式快速地访问或者处理想要的数据,说到底就是对数据执行增、删、查、改。用户是通过数据库对业务数据进行处理,而数据库与物理硬件之间,则是通过操作系统上的文件系统,进行数据处理。
2.1 什么是文件系统

其实,我们时刻都在和操作系统上的文件系统打交道,只是它是一个幕后影子,真正地做到了润物细无声。
当我们在电脑上保存一张图片时,实际操作系统首先是把这张图片的数据暂时保存在文件系统的缓存中,然后在之后合适的时间里,再异步的将图片数据写入到物理磁盘中。所以操作系统上的文件系统,实际上就是我们从开机一瞬间就在使用,我们与计算机的一些数据交换,都是通过文件系统进行的。
2.2 文件系统缓存
如何测试磁盘的物理I/O?相信很多用户在 Linux 上都使用过 dd 命令来测试磁盘的读写性能,但是大家是否又知道,普通的 dd 命令只是对文件系统缓存性能进行验证?这种测试方法并不能实际地验证物理磁盘真实的写入性能。
dd if=/dev/zero of=out.file bs=512K count=2048
在 dd 命令中,它提供了直接 direct I/O 的方法,让用户可以绕开文件系统缓存直接进行磁盘性能验证。
dd 命令常用的 direct I/O 方法包括:
dd if=/dev/zero of=out.file bs=512K count=2048 oflag=syncdd if=/dev/zero of=out.file bs=512K count=2048 oflag=dsyncdd if=/dev/zero of=out.file bs=512K count=2048 conv=fsync
这三种方法,它们对磁盘的写入方式有细微的区别,在官方解释中,是这样的:
oflag=dsync: Use synchronized I/O for data. For the output file, this forces a physical write of output data on each write. For the input file, this flag can matter when reading from a remote file that has been written to synchronously by some other process. Metadata (e.g., last-access and last-modified time) is not necessarily synchronized.
oflag=sync: likewise, but also for metadata
conv=fsync: Synchronize output data and metadata just before finishing. This forces a physical write of output data and metadata
翻译过来就是:
oflag=dsync,每个 I/O 写入,都需要将真实数据直接落到物理存储上;
oflag=sync,每个 I/O 写入,都需要将元数据和真实数据直接落到物理存储上;
conv=fsync,只要求在 dd 命令结束前,将所有数据落到物理存储中;
所以如果要使用 dd 命令来模拟数据库的写入性能,读者们知道应该选择哪种方法吗?
2.3 文件系统缓存与数据库之间的关系
2.3.1 文件系统缓存参数介绍
在 Linux 众多的内核参数中,有4个参数对于文件系统缓存非常的关键,分别是
vm.dirty_expire_centisecs
该参数默认值为 3000,代表是30 秒;
该参数的意义是:数据保存于文件系统的内存中,多长时间后就会被认定为“脏数据”,大家一般称为”脏页“
vm.dirty_writeback_centisecs
该参数默认值为 500,代表是 5 秒;
该参数表示,每间隔多长时间,文件系统就会自动触发将“脏页”数据刷入磁盘中
vm.dirty_background_ratio
该参数默认值为 10,代表全局系统中所有“脏页”总和超过系统总内存的 XX 百分比后,文件系统就会自动触发将“脏页”数据异步刷入磁盘中
vm.dirty_ratio
该参数默认值为 20,代表全局系统中所有“脏页”总和超过系统总内存的 XX 百分比后,文件系统将会进入 I/O 阻塞状态;
2.3.2 SequoiaDB 官方推荐配置
在 SequoiaDB 的官网信息中心里,对于文件系统缓存的配置是这样建议的:

根据 SequoiaDB 官方的推荐的配置设置,用户将能够获得一个任何数据写入都最大限度利用文件系统缓存,并且在脏页超过总内存 40% 后,要求文件系统缓存强行将脏页刷入磁盘上,平时服务器内存充足时,文件系统缓存的数据保存30秒后被标记为脏页数据。
这种推荐方式是建立在服务器大内存的基础上,只要业务峰值数据低于服务器总内存大小,就可以确保数据库拥有一个较好的数据吞吐量。
2.3.3 场景介绍
服务器内存相对小,而且应用持续写入数据
vm.dirty_expire_centisecs = 300vm.dirty_writeback_centisecs = 100vm.dirty_background_ratio = 5vm.dirty_ratio = 80
服务器内存资源较为充足,需要面临瞬间业务高峰
vm.dirty_expire_centisecs = 1000vm.dirty_writeback_centisecs = 500vm.dirty_background_ratio = 70vm.dirty_ratio = 90
2.4 如何查看文件系统缓存脏页大小
数据被临时保存在文件系统缓存中,如果超过了 vm.dirty_expire_centisecs 设置的时间,文件系统缓存中的数据将会被标记为脏页数据,Linux 系统默认数据页大小为 4KB,用户也可以通过以下命令查看具体的数据页大小:
getconf PAGE_SIZE
查看文件系统缓存中的脏页大小时,可以通过以下命令:
cat /proc/vmstat | egrep "dirty|writeback"nr_dirty 参数显示的为脏页数量,总大小为 nr_dirty * PAGE_SIZEcat /proc/meminfo |grep Dirty将显示脏页数据的总大小
往期技术干货
巨杉Tech | 常见问题参数调优实践(数据库优化系列一)

点击阅读原文,获取更多精彩内容~




