1. 前言
其实磁盘优化和IO优化,我在前面的其他Linux调优博文中已经讲述过或者涉及过了,但是太过零碎,所以本篇就来集中深入讨论下Linux磁盘和IO调优。
2.磁盘调优
结合我多年的经验,本人认为磁盘调优最重要的是读写性能的提升和冗余度两个方面(当然还有其他优化方法,但是效果不是那么明显,只是在某些方面有提升)。因为作为和内存相连,并且是存放大量数据的地方,读写和数据安全是最最重要的。
2.1 提升磁盘的读写性能
- 磁盘读写性能优化
对于磁盘,最容易实现但也是最有效果的,就是利用硬盘发展技术,选择读写性能和可靠性更好的磁盘,比如固态硬盘(SSD),相较于传统的机械硬盘(HDD),SSD具有更高的读写速度和更低的访问延迟,是提升磁盘性能的首选,但是价格也会更贵。另外企业级磁盘驱动器也具有更高的性能和可靠性,适用于对读取和写入速度要求较高的场景。 - 使用RAID磁盘阵列技术:
RAID(冗余阵列磁盘)是一种将多个磁盘组合成一个逻辑单元的多磁盘整合技术,可以同时提高磁盘的读写性能和数据冗余度。关于RAID,写一节会详细介绍下。 - 将磁盘分区对齐:
磁盘分区对齐是指将分区的起始位置与硬盘物理层的页边界对齐。这种对齐可以显著提高数据访问的效率,因为硬盘在读写时是以页为单位进行的。如果分区没有对齐,可能会导致额外的读写操作,从而影响性能。特别是对于SSD,4K对齐可以显著提高读写速度并延长硬盘寿命。可以使用fdisk和parted命令来实现磁盘分区对齐(具体的操作不在本篇演示,有兴趣的家人们可以自行在虚拟机测试研究下,不难)。
对于SSD,确保分区起始位置与硬盘物理扇区对齐(即4K对齐),可以避免读写操作跨多个存储单元,从而提高数据读写效率。
4.文件系统选择与优化
Linux主要的文件系统有以下类型:
**EXT4:**是 Linux 系统中广泛使用的文件系统。它支持日志功能,能在系统崩溃后快速恢复文件系统的一致性。在挂载 EXT4 文件系统时,可以通过设置挂载选项来优化性能。例如,使用noatime选项可以避免每次访问文件时更新文件的访问时间,减少磁盘 I/O 操作。在/etc/fstab文件中,对于 EXT4 分区的挂载行可以添加noatime选项,像/dev/sda1 / ext4 defaults,noatime 0 0。
**XFS:**对于处理大文件和高并发写入场景表现出色。它具有高效的日志机制和可扩展性。在创建 XFS 文件系统时,可以使用-f选项强制覆盖现有文件系统(需谨慎使用),如mkfs.xfs -f /dev/sda2。在挂载时,也可以设置一些参数,如logbufs来调整日志缓冲区大小,提高性能。
**Btrfs:**提供了高级功能,如快照、压缩和数据冗余。通过使用mount命令挂载 Btrfs 文件系统时,可以启用压缩功能来减少磁盘空间占用,例如mount -o compress=zstd /dev/sda3 /btrfs_partition,其中zstd是一种高效的压缩算法。 - 文件系统参数调整:
对于 EXT4 文件系统,可以通过tune2fs命令调整文件系统参数。例如,tune2fs -m 1 /dev/sda1可以将保留的文件系统块百分比设置为 1%,减少磁盘空间预留,释放更多空间用于存储数据。
XFS 文件系统可以使用xfs_admin命令来调整一些参数。比如,通过xfs_admin -u [新的UUID] /dev/sda2可以修改文件系统的 UUID。 - 磁盘调度策略优化(这个我测试过,好像不怎么明显,有懂得大佬可以请教下):
常见的磁盘调度算法:
**CFQ(Completely Fair Queuing):**完全公平队列调度算法,将 I/O 请求按照进程进行公平排队,每个进程都能获得相对公平的磁盘 I/O 资源。它适用于多用户桌面系统和通用服务器场景。
**NOOP(No Operation):**这是一种简单的电梯算法实现,基本没有对 I/O 请求进行复杂的排序,适合固态硬盘(SSD),因为 SSD 的随机 I/O 性能较好,不需要复杂的调度算法。
**DEADLINE:**保证每个 I/O 请求在一定时间内得到服务,它对延迟敏感的应用比较友好,会优先处理接近截止时间的请求。
了解磁盘调度算法:
CFQ(Completely Fair Queuing):完全公平队列调度算法,将 I/O 请求按照进程进行公平排队,每个进程都能获得相对公平的磁盘 I/O 资源。它适用于多用户桌面系统和通用服务器场景。
NOOP(No Operation):这是一种简单的电梯算法实现,基本没有对 I/O 请求进行复杂的排序,适合固态硬盘(SSD),因为 SSD 的随机 I/O 性能较好,不需要复杂的调度算法。
DEADLINE:保证每个 I/O 请求在一定时间内得到服务,它对延迟敏感的应用比较友好,会优先处理接近截止时间的请求。
修改磁盘调度算法:可以通过echo命令修改/sys/block/[磁盘设备名]/queue/scheduler文件的内容来选择调度算法。例如,要将磁盘设备sda的调度算法设置为 DEADLINE,可以使用
echo deadline > /sys/block/sda/queue/scheduler
- 磁盘缓存优化
操作系统缓存:
Linux 内核有页缓存(page cache)和块缓存(block cache)机制。页缓存用于缓存文件系统的页面,块缓存用于缓存磁盘块。可以通过调整/proc/sys/vm/dirty_ratio和/proc/sys/vm/dirty_background_ratio参数来控制磁盘写缓存。dirty_ratio表示当系统中脏页(已修改但未写入磁盘的页面)达到这个百分比时,系统会主动将脏页写入磁盘;dirty_background_ratio是在后台开始将脏页写入磁盘的阈值。这就意味着你要根据系统的具体情况来做出权衡,如果你的系统对查询性能和实时性要求很高,那就要尽量利用大内存,反之,如果你的内存是瓶颈资源,而且对实时性和查询性能要求不高,那就要多利用磁盘。例如,
echo 5 > /proc/sys/vm/dirty_background_ratio
echo 15 > /proc/sys/vm/dirty_ratio
磁盘硬件缓存:许多磁盘和存储设备本身带有缓存。对于有缓存的磁盘,可以通过磁盘制造商提供的工具或者设备的 BIOS/UEFI 来优化缓存设置。一些高端磁盘可以设置缓存的读写策略。
2.2 提升磁盘的冗余度
- RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列),是一种磁盘组合冗余技术,常见的raid有以下几种(关于Linux的磁盘raid创建后续我会专门博文介绍,这里重点介绍raid 01/raid5/raid10):
RAID 0+1(但可理解为RAID 0与RAID 1的组合):
工作原理:先将数据条带化分布在多个硬盘上(RAID 0),然后再对这些条带化的数据进行镜像成RAID 1。但实际操作中,这种组合方式并不常见,且可能带来复杂的管理和性能问题。
性能:由于结合了RAID 0的高性能和RAID 1的数据冗余,具有较高的读写速度和数据安全性。
冗余:提供数据冗余,但冗余度取决于具体的实现方式。
磁盘空间使用率:较低,因为镜像会占用额外的磁盘空间。
RAID 5:
工作原理:RAID 5结合了RAID 0的条带化技术和数据校验信息。它将数据和校验信息分散存储在多个硬盘上,当某个硬盘出现故障时,可以利用其他硬盘上的数据和校验信息来恢复丢失的数据。
性能:RAID 5具有和RAID 0相近的数据读取速度,但写入速度稍慢,因为每次写入数据都需要计算和写入校验信息。然而,由于其提供了数据冗余和容错能力,这种性能上的折衷是可以接受的。
冗余:允许一个硬盘故障而不影响数据的完整性。
磁盘空间使用率:较高,因为不需要像RAID 1那样进行完全的数据镜像。
RAID 10(RAID 1+0)
工作原理:RAID 10是先组成RAID 1镜像对,然后再将多个镜像对组成RAID 0条带化。这种组合方式既提供了数据冗余(通过RAID 1),又提高了数据传输速度(通过RAID 0)。
性能:RAID 10提供了非常高的读写速度和数据安全性。由于数据分散存储在多个镜像对上,因此即使某个硬盘出现故障,数据仍然可以从其他镜像对上读取和恢复。
冗余:提供100%的数据冗余,因为每个数据块都有一个镜像副本。
磁盘空间使用率:较低,因为每个数据块都需要存储一个镜像副本。此外,由于RAID 10需要至少4个硬盘(每个镜像对需要2个硬盘,而RAID 0至少需要2个镜像对),因此其成本也相对较高。
不同raid组合对比如下表所示:
- LVM(Logical Volume Manager,逻辑卷管理器)与磁盘镜像
原理:LVM 可以将多个物理磁盘或分区组合成一个逻辑卷。通过在 LVM 上创建镜像逻辑卷,可以实现数据的冗余。当一个物理磁盘出现故障时,LVM 可以自动切换到镜像磁盘上。
配置方法: - 使用pvcreate命令将物理磁盘或分区创建为物理卷(PV)。例如,pvcreate /dev/sda和pvcreate /dev/sdb。
然后,使用vgcreate命令创建卷组(VG),将多个物理卷组合在一起。例如,vgcreate myvg /dev/sda /dev/sdb。 - 使用lvcreate命令创建逻辑卷(LV),并指定镜像选项。例如,lvcreate -L 200G -m1 -n mylv myvg创建一个大小为 200GB 的镜像逻辑卷。
- 格式化并挂载这个逻辑卷,如mkfs.ext4 /dev/mylv和mount /dev/mylv /mnt。
3.磁盘读写 IO监控优化最重要的2个命令
- iostat
功能:监控磁盘使用情况。
输出内容:包括CPU使用情况、设备(磁盘)的I/O统计信息等:
经验总结:
–%idle值高,表示CPU较空闲。若%idle值高但系统响应慢,可能是CPU等待分配内存,此时应加大内存容量。
–%idle小于70,I/O压力较大。
–%idle值如果持续低于10,表明系统中最需要解决的资源是CPU。
–如果%util比较大,说明I/O请求太多,硬盘可能存在瓶颈。
–await大于svctm,差值越小,说明队列时间越短;反之差值越大,队列时间越长,说明系统出现了问题。
–avgqu-sz队列长度也可衡量I/O负荷,avgqu-sz是单位时间内的平均值。 - iotop
iotop 的功能
实时监测磁盘 I/O 活动:
–iotop 可以实时显示系统中各个进程的磁盘读写情况,让用户能够清楚地了解哪些进程正在频繁进行磁盘 I/O 操作,对于及时发现磁盘性能瓶颈和排查问题非常有帮助。
识别高 I/O 消耗进程:
–通过对进程的磁盘 I/O 速度进行监测和排序,iotop 可以快速定位那些消耗大量磁盘资源的进程,有助于管理员采取针对性的措施,如优化进程的行为、调整其优先级或限制其磁盘访问。
–可以区分磁盘读取和写入操作,帮助用户确定是哪个方向的 I/O 活动较为频繁。
输出内容
进程信息:
PID:进程的标识符,用于唯一确定一个进程。
USER:启动该进程的用户。
DISK READ:进程的磁盘读取速度,通常以字节 / 秒或更易读的单位(如 KB/s、MB/s)显示。
DISK WRITE:进程的磁盘写入速度,单位与磁盘读取速度相同。
SWAPIN:表示进程从交换分区读取数据的速度。
IO>:综合的磁盘 I/O 速度,是磁盘读取和写入速度的总和。
COMMAND:正在运行的进程的命令名称。
表头说明:
TID:线程标识符(如果显示线程级别的信息)。
PRIO:进程的优先级。
NI:Nice 值,表示进程的优先级调整值。
% CPU:进程占用的 CPU 百分比。
TIME+:进程运行的累计时间。
本篇完结。
码字不易,宝贵经验分享不易,请各位支持原创,转载注明出处,多多关注作者,家人们的点赞和关注是我笔耕不辍的动力。