经过前面几章的探讨,我们基本上了解了文件系统和磁盘的相关信息,同时还对能够反馈I/O性能的指标进行了说明。今天我们围绕磁盘读写整个过程,对其中常见的磁盘I/O优化方法进行一个梳理,从另一个侧面强化对磁盘性能的理解。
依然借助于之前文章中使用的如下过程图,从磁盘硬件、块设备层到文件系统,最后到应用程序,对其各个部分涉及到的优化思路进行详细讲解。

1、磁盘优化
1、磁盘无故障
首先要确保磁盘硬件不能存在故障,任何error报错都可能影响工作性能,还有磁盘的工作年限,超过工作寿命,虽然还能正常工作,性能一般会发现下降风险。
一般磁盘硬件的检查工具有disktool、smartctl等。
例如使用命令disktool show -l all,快速看一下磁盘是否有error或者磁盘温度是否过高。
root@node:~# disktool show -l all
-- Controller Information --
+---------------+--------+------------+----------------+-------+--------------+
| controller_id | locate | enclosures | virtual_drives | disks | pci_path |
+---------------+--------+------------+----------------+-------+--------------+
| 0 | c0 | 1 | 1 | 2 | 0000:5e:00.0 |
| 1 | c1 | 2 | 2 | 12 |0000:af:00.0|
+---------------+--------+------------+----------------+-------+--------------+
-- Enclosure Information --
+--------------+--------+--------+---------------------------+-----------------+
| enclosure_id | locate | status | number_of_physical_drives | number_of_slots |
+--------------+--------+--------+---------------------------+-----------------+
| 8 | c1e8 | OK | 12 | 16 |
| 252 | c1e252 | OK | 0 | 8 |
+--------------+--------+--------+---------------------------+-----------------+
-- Virtual Drive Information --
+-------+--------+------------+----------+---------+------------------+
| vd_id | locate | raid_level | path | state | number_of_drives |
+-------+--------+------------+----------+---------+------------------+
| 0 | c1v0| raid5 | /dev/sdb | optimal | 3 |
| 1 | c1v1 | raid5 | /dev/sdc | optimal | 3 |
+-------+--------+------------+----------+---------+------------------+
-- Physical Disk Information In Raid Model --
+-------+----------+----------+-----------+--------+--------+--------------------+------+--------------+---------+
| pd_id | p_locate | v_locate | interface | medium | state | sn | slot | error(m|o|p) | speed |
+-------+----------+----------+-----------+--------+--------+--------------------+------+--------------+---------+
| 8 | c0e252s0 | c0v0d8 | sata | ssd | online | BTYF01830HFC480CGN | 0 | 0|0|0 | 6.0Gb/s |
| 9 | c1e8s2 | c1v0d9 | sata | hdd | online | WKD20E4X |2 | 0|0|0 |6.0Gb/s |
| 10| c1e8s4 | c1v0d10| sata | hdd | online | WKD27F1X | 4 | 0|0|0 | 6.0Gb/s |
| 11 | c1e8s10| c1v0d11 | sata | hdd | online | WKD28DDX |10| 0|0|0 |6.0Gb/s |
| 12| c1e8s6 | c1v0d12 | sata | hdd | online | WKD26G4X | 6 | 0|0|0 | 6.0Gb/s |
| 20 | c1e8s8 | c1v1d20 | sata | hdd | online | WKD26J5X |8 | 0|0|0 |6.0Gb/s |
+-------+----------+----------+-----------+--------+--------+--------------------+------+--------------+---------+
-- Nvme device Information --
+---------+--------------+--------------------+--------------+-------------+------------------+--------------+---------------------+
| name | path | sn | percent_used | temperature | critical_warning | media_errors | num_err_log_entries |
+---------+--------------+--------------------+--------------+-------------+------------------+--------------+---------------------+
| nvme0n1 | /dev/nvme0n1 | BTYF01830HFC480CGN | 5 | 43 | 0 | 0 | 0 |
+---------+--------------+--------------------+--------------+-------------+------------------+--------------+---------------------+
-- Disk Smart Error --
-- Disk sn: BTYF01830HFC480CGN, Assessment: PASS --
+-----+-----------------------+---------+-------------+-----+
| num | name | type | when_failed | raw |
+-----+-----------------------+---------+-------------+-----+
|5| reallocated_sector_ct | Old_age | - |2 |
+-----+-----------------------+---------+-------------+-----+
2、预算可控的情况下,尽量选择ssd
之前我们说过磁盘一般分为机械盘和固态盘,两者速度差异很大,核心在于机械盘使用的是磁道寻址技术,在读写不连续数据扇区时,需要不断的调整磁头。不管是随机读写还是顺序读写,ssd固态盘都要比机械盘性能高很多,这也是最直接和简单的优化方法。
3、raid的使用
除了选用ssd之外,还可以使用raid技术(这里指硬件raid卡)将多个磁盘组合成一个逻辑磁盘,构成冗余阵列。常用的raid一般有0/1/5/10,raid0对数据完整性要求不高时使用,做系统盘的一般用raid1,兼容完整和冗余的一般用raid5或者raid10。
raid之所有能够提高磁盘性能,主要体现在下面几个方面。
- I/O并行操作:磁盘组合成raid后,磁盘驱动器是并行存在的,raid控制器会将发来的I/O请求分配给多个驱动器来处理,所以会提升整体的I/O处理能力。
- 数据切分:raid技术会将连续数据分割成小的数据块,分别存放到不同的磁盘,在读取时,可以多个磁盘同时读取再组合,虽然有数据校验开销,但仍然提升了很大性能,特别是大数据块,更加明显。
- 缓存机制:raid卡一般都有缓存机制,进行批量刷盘,磁盘I/O操作时,寻址时间大幅减少。
2、块设备层优化
1、保持驱动程序版本符合要求
使用最新版本的驱动程序,可以有效避免低版本已知的问题对性能的影响。
2、合理的使用I/O调度算法
块设备层的 I/O 调度器负责管理 I/O 请求的队列,合理选择调度器配置,可以有效地提升性能。
一般调度器有以下几种,详细说明如下
none :如果磁盘选择这种,一般就是不使用调度器,大部分用在直连SSD盘时,也就是避开文件系统的I/O。
noop :这种是I/O请求先入先出的队列,只做一些最基本的请求合并。
CFQ :这种是每个进程维护了一个 I/O 调度队列,完全公平的分配I/O请求。
deadline :这种是读和写的请求分别创建不同的 I/O
队列,这样读写性能会提高很多,同时确保达到最终期限(deadline)的请求被优先处理。这里注意高版本的Linux内核名字可能叫mq-deadline。
3、磁盘扇区大小
除了上面两种,一般磁盘都有固定的扇区大小,例如hdd(512b)、ssd(4k),在我们格式磁盘挂载到文件系统时,尽量保持整数倍。
查看物理扇区大小:
fdisk -l /dev/sda(关注 “Sector size (logical/physical)”)
格式化时指定参数:
mkfs.xfs -f -s size=4096 /dev/sda1
3、文件系统优化
1、文件系统的选择
根据不同的使用场景,选择合适的文件系统格式。例如常用的ext4、xfs、zfs等,一般情况这几种比较如下
- ext4一般Linux系统最常用的,小文件和大文件读写都比较优秀,一般用在个人办公设备或者web服务器上。
- xfs在大文件读写上做了优化,更加优秀,一般用在视频读写或者大数据存储方面。
- zfs兼顾容量和性能,在大文件存储方面甚至优于xfs,对于高可靠需求可以选择。
- fat一般用在移动设备上,轻量快速。
2、swap的合理使用
在之前的文章:为什么swap升高了,我们详细说明了swap的工作原理,页缓存的使用可以有效提升应用的读写性能,因为内存的速度比磁盘快的多,所以我们需要尽量使用内存缓存,而避免使用swap。
echo 1 > /proc/sys/vm/swappiness
通过设置swappiness的值,降低swap的使用,默认 60,值越低越优先保留页缓存的使用。
3、大页内存的使用
在文件系统内合理使用大页内存,也可以有效提升系统性能。大页内存的主要目的是减少内存碎片,以更大粒度 (2MB)
分配连续内存,避免频繁分配导致内存碎片增加。而且还可以大幅减少页表项数量,减少cpu在内存管理上面的消耗。
# 查看系统是否支持大页(输出包含 HugePages_Total 即支持)
grep HugePages /proc/meminfo
在I/O性能方面,优化了内存管理与I/O之间的协同,减少了 I/O 请求的拆分与合并开销,提升了
I/O的吞吐量。特别是存储密集型和大文件读写上优势更加明显。
4、合理利用缓存
1、文件系统内核缓存优化
文件系统依赖内核页缓存(Page Cache)、目录缓存(Dentry Cache)来减少对磁盘的I/O访问,通过让数据驻留在内存,避免频繁的物理 I/O。
可以通过控制页缓存中脏数据(就是已修改但还未写入磁盘)的比例,避免批量刷盘造成 I/O的阻塞。
# 临时生效
sysctl -w vm.dirty_ratio=40 # 单个进程脏数据达内存40%时,强制同步刷盘(避免脏数据过多)
sysctl -w vm.dirty_background_ratio=10 # 系统整体脏数据达内存10%时,后台异步刷盘(不阻塞业务)
# 永久生效(编辑/etc/sysctl.conf)
echo "vm.dirty_ratio=40" >> /etc/sysctl.conf
echo "vm.dirty_background_ratio=10" >> /etc/sysctl.conf
sysctl -p
还可以通过调整内核对目录项(Dentry)和 inode 缓存的回收优先级,来减少文件元数据查询的磁盘 I/O。
# 降低目录缓存回收优先级(默认100,值越小越优先保留缓存)
sysctl -w vm.vfs_cache_pressure=50
# 永久生效
echo "vm.vfs_cache_pressure=50" >> /etc/sysctl.conf
2、第三方缓存系统
应用程序如果只使用内核的缓存机制来提升性能时,会增加内存使用的不稳定性,可以使用第三方的缓存系统,比如 Memcached、Redis
等,可以构建完全自主控制的缓存。
5、应用程序的优化
1、对高频使用I/O操作的应用,可以单独部署,独占磁盘性能
这是最直接的方式,比如,数据库系统是高频I/O读写,可以单独设置数据库部署节点,不要让其他应用再去跟数据库系统分享磁盘性能资源。
2、读写频繁时,可以使用mmap 代替 read/write
mmap的优势在于频繁随机读写、小数据块高频访问、多进程共享数据等场景,而 read/write 更适合简单顺序读写、小文件、低内存的场景。
3、操作合并和缓存系统
以用追加写代替随机写,减少寻址开销,加快 I/O 写的速度,也可以借助缓存 I/O ,充分利用系统缓存,降低实际 I/O 的次数。
4、直接I/O,绕过文件系统
在一些重要的系统中,可以使程序直接操作磁盘,避开文件系统,因为文件系统本身是有开销的,而且通过I/O调度器也会影响性能。适合于高性能存储系统。
1502

被折叠的 条评论
为什么被折叠?



