第12章 块设备I/O和缓冲区管理
块设备和I/O缓冲区
由于磁盘I/O速度相对较慢,文件系统通常使用I/O缓冲来减少存储设备的物理I/O数量,提高文件I/O效率,增加系统吞吐量。基本原理是使用一系列I/O缓冲区作为块设备的缓存内存,以避免每次执行读写文件操作时都进行磁盘I/O。
I/O缓冲区的基本原理
-
读取操作: 当进程尝试读取磁盘块(dev,blk)时,系统首先搜索缓冲区缓存中是否已分配给该磁盘块的缓冲区。如果存在且包含有效数据,则直接从缓冲区中读取,而无需再次从磁盘读取。
-
缓冲区分配: 如果缓冲区不存在,系统为磁盘块分配一个缓冲区,将数据从磁盘读入缓冲区,并将其保存在缓冲区缓存中。这样,下次任何进程对相同块的读/写请求都可以使用缓冲区中的数据,而无需进行实际磁盘I/O。
-
写入操作: 当进程写入磁盘块时,系统首先获取一个分配给该块的缓冲区,将数据写入缓冲区,将缓冲区标记为脏(表示数据已被修改),然后释放到缓冲区缓存中。脏缓冲区只有在被重新分配到不同的块时才会写入磁盘。
Unix缓冲区管理子系统
设备表
struct devtab {
u16 dev; // major device number
BUFFER *dev_list; // device buffer list
BUFFER *io_queue; // device I/O queue
} devtab[NDEV];
Unix getblk/brelse算法
BUFFER *getblk(dev, blk) {
while (1) {
search dev_list for a bp = (dev, blk);
if (bp in dev_list)
if (bp BUSY)
set bp WANTED flag;
sleep(bp);
continue;
}
take bp out of freelist;
mark bp BUSY;
return bp;
}
}
优点:
- 数据一致性:保证分配的每个缓冲区都是唯一的,避免了同一个(dev, blk)分配多个缓冲区。
- 缓存效果:通过将释放的缓冲区保留在设备列表中,延迟写入脏缓冲区,并通过LRU原则提高缓存效果。
- 临界区:设备中断处理程序可以安全地操作缓冲区列表,避免竞态条件。
缺点:
- 效率低下:依赖于重试循环,可能导致过多的进程切换。
- 缓存效果不可预知:每个释放的缓冲区都可被获取,可能重新分配缓冲区,导致缓存效果不确定。
- 可能会出现饥饿:基于"自由经济"原则,不能保证每个进程都成功获取缓冲区,可能导致进程饥饿。
- 仅适用于单处理器系统的休眠/唤醒操作。
新的I/O缓冲区管理算法
与休眠/唤醒相比,信号量的主要优点是:
- 计数信号量可表示可用资源的数量,例如空闲缓冲区的数量。
- 多个进程等待同一资源时,信号量上的V操作只会释放一个等待进程,无需重试。
算法设计要求
:
- 缓冲区唯一性
- 无重试循环
- 无不必要唤醒
- 缓存效果
- 无死锁和饥饿
这样的设计通过使用信号量上的P/V操作来实现。 P操作用于获取资源,V操作用于释放资源,可满足上述要求。
具体说明:
-
数据一致性: 为确保数据一致性,保证getblk不会分配多个相同(dev, blk)的缓冲区。每个释放的脏缓冲区都会被写出来,确保数据一致性。
-
缓存效果: 通过释放的缓冲区保留在空闲列表中,标记为延迟写入的缓冲区可重用,实现缓存效果。
-
临界区: 设备中断处理程序可以操作缓冲区列表,如从设备表的I/O队列中删除bp,更改其状态,然后调用brelse(bp)。进一步避免了竞态条件。
优点:
- 计数信号量提供了可表示资源数量的灵活性。
- 释放资源时,V操作只会释放一个等待进程,无需重试。
- 使用信号量上的P/V操作实现了对缓冲区的管理,更具可靠性。
缺点:
- 无法完全消除竞态条件,但通过合理设计可以最小化其影响。
这样的设计更适应多处理器系统,提高了可靠性和效率。
苏格拉底挑战
遇到的问题与解决方案:
-
缓冲区溢出:
- 问题:系统中的缓冲区数量有限,多个进程同时请求大量块设备I/O可能导致缓冲区溢出,造成数据丢失或性能下降。
- 解决方法:调整系统参数增加缓冲区数量,采用更高效的缓冲区替换算法。优化应用程序的I/O访问模式,减少对缓冲区的竞争。
-
脏缓冲区管理:
- 问题:脏缓冲区包含未写入磁盘的数据,系统崩溃或故障可能导致数据一致性问题。
- 解决方法:引入事务机制,确保写入脏缓冲区时同时记录事务信息。定期将脏缓冲区数据刷新到磁盘,降低数据丢失风险。
-
缓冲区的一致性:
- 问题:多个进程同时访问同一块可能导致数据不一致。
- 解决方法:引入锁机制或其他同步机制,确保一个缓冲区被修改时其他进程无法同时访问。使用读写锁、互斥锁等手段实现。
-
性能优化:
- 问题:缓冲区管理的性能影响整体系统性能,尤其在高负载情况下。
- 解决方法:优化缓冲区替换算法、合理设置缓冲区大小、使用高性能存储设备。定期监控系统I/O性能,进行性能调优。
-
数据一致性与性能平衡:
- 问题:频繁刷新脏缓冲区以确保数据一致性可能影响性能。
- 解决方法:权衡数据一致性和性能,采用延迟写入策略,将脏缓冲区刷新操作延迟到系统空闲时进行,降低性能影响。
-
文件系统碎片:
- 问题:频繁的块设备I/O可能导致文件系统碎片,影响磁盘空间的利用率。
- 解决方法:定期进行文件系统整理和优化,使用工具进行碎片整理,提高文件系统性能和空间利用率。