暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

你的数据库文件系统优化好了吗?

巨杉数据库 2020-08-23
1562

本文是数据库优化系列第三篇,主要介绍针对文件系统的优化工作。了解系列内容欢迎前往文章底部往期链接~

一、前言

数据库服务,本质上就是为用户提供标准的数据处理流程。它的目标是让用户能够以一种更加优雅的方式快速地访问或者处理想要的数据,说到底就是对数据执行增、删、查、改。用户是通过数据库对业务数据进行处理,而数据库与物理硬件之间,则是通过操作系统上的文件系统,进行数据处理。

在资深的 DBA 中,如果围绕数据库进行性能优化,可能会有各式各样的调优手段,但是如果是为服务器 I/O 进行数据库性能调优,那么文件系统缓存优化是一个重要的手段。
Linux 内核参数千千万,文件系统缓存调调也很棒。本文将以 SequoiaDB 官网信息中心关于文件系统缓存的调优建议为基础,给各位读者们说道说道关于 Linux 文件系统缓存参数所代表的含义。

二、文件系统存储优化

2.1 什么是文件系统

可能会有一些刚接触数据库的朋友,所以在开始介绍文件系统缓存前,先来简单普及一下“什么是文件系统”。
大家肯定都听过大名鼎鼎的“冯诺依曼结构”,知道计算机--服务器是由中央处理器、内存和一堆外设组成,而物理存储资源,是属于计算机的外部设备。但是大家在使用计算机时,是否有考虑过,我们日常在计算机上珍藏那些图片、影片,是如何被保存在计算机的磁盘中?

其实,我们时刻都在和操作系统上的文件系统打交道,只是它是一个幕后影子,真正地做到了润物细无声。

当我们在电脑上保存一张图片时,实际操作系统首先是把这张图片的数据暂时保存在文件系统的缓存中,然后在之后合适的时间里,再异步的将图片数据写入到物理磁盘中。所以操作系统上的文件系统,实际上就是我们从开机一瞬间就在使用,我们与计算机的一些数据交换,都是通过文件系统进行的。

2.2 文件系统缓存

在刚才举的例子中,就给用户介绍到了文件系统缓存。我个人将它比喻为物理磁盘上盖的一层松软海绵。
因为计算机的物理磁盘,它的数据读取/写入速度远远低于 CPU 的计算速度,所以为了让计算机更好利用 CPU 时间,用户在向物理磁盘发送写入数据时,操作系统首先将数据暂时保存在文件系统的缓存--内存中。操作系统在事后再慢慢地将文件系统缓存的数据写入到磁盘中。
文件系统缓存存在的意义就是避免计算机 CPU 时间空等慢悠悠的外部设备,以提高计算机的整体计算能力。

如何测试磁盘的物理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=sync
      dd if=/dev/zero of=out.file bs=512K count=2048 oflag=dsync
      dd 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 文件系统缓存与数据库之间的关系

      文件系统缓存之于数据库服务,等于将物理磁盘的 I/O 操作用内存来暂时代替,以内存的读写性能换取短暂的磁盘延后持久化的技术手段,为数据库性能带来极大的提升。
      但是文件系统缓存对于数据库性能提升虽好,但是并非全无害处,最大的弊端就是真实数据将延后写入物理磁盘。如果是单机数据库系统,服务器突然宕机,那么用户很大概率将会面临数据文件损坏、数据丢失的高风险事件。
      所以任何一名资深的 DBA 在配置 Linux 内核参数时,都会非常认真的对待关于文件系统缓存的相关参数。

      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 = 300
        vm.dirty_writeback_centisecs = 100
        vm.dirty_background_ratio = 5
        vm.dirty_ratio = 80
        • 服务器内存资源较为充足,需要面临瞬间业务高峰

        如果在服务器内存资源充足,并且经常要面临瞬间的业务高峰(例如:网上促销日),这种情况,用户就应该考虑充分发挥文件系统缓存松软海绵的缓冲效果,尽可能使用文件系统缓存以应对瞬间的大量数据写入,以提高数据库的数据处理能力。
          vm.dirty_expire_centisecs = 1000
          vm.dirty_writeback_centisecs = 500
          vm.dirty_background_ratio = 70
          vm.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_SIZE
              cat /proc/meminfo |grep Dirty
              将显示脏页数据的总大小

              总结
              要想数据库性能好,文件系统缓存少不了,但是也不能贪杯。用户应该要和实际的业务相结合,在综合评估了服务器内存资源和业务特点后,有针对性地调整Linux 系统中那几个关键的内核参数,以达到 DB 与 Linux 文件系统缓存完美融合的理想境界。

              往期技术干货

              巨杉Tech | 常见问题参数调优实践(数据库优化系列一)

              社区投稿 | NUMA架构与数据库的一些思考(数据库优化系列二)
              分布式数据库的数据备份/恢复,这些你一定要了解
              社区投稿 | 巨杉数据库对接数仓数据实践与体验
              社区投稿 | SequoiaDB监控与开发实践分享
              巨杉Tech | 谈谈数据库内核调优

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

              文章转载自巨杉数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论