概述
大体过了两遍论文,大体就是以优化 Linux 移动终端存储设备 IO 性能为目标,然后通过对IO相关的基础知识补充,从vfs一直到设备层中间所涉及到的,最后提出了针对 Linux 移动终端的存储设备 IO 性能优化方案。
收获:
1 IO测试工具 FIO
I/O 的基准测试通常包含各种各样的需求场景,比如:I/O 操作是顺序访问还 是随机访问;IO 操作是读写 I/O 还是通过访问 mmap 的空间 I/O;IO 操作是单一 进程发出的 I/O 还是多个进程同时发出的 I/O;进程是受 I/O 限制还是受 CPU 限 制等等一系列因素。利用 FIO 测试工具,测试人员不需要每次都根据不同情况来 编写用于性能评估的程序,就可以模拟各种 IO 场景。FIO 是一款 IO 性能测试工 具,用于对硬件进行压力测试和验证。
可以设置的参数:
IO 类型 该参数定义了相关文件的读写类型,比如:随机读/写,顺 序读/写,混合顺序读/写,混合随机读写。
块大小 该参数定义了文件操作的基本单位 IO 大小 该参数定义了整个 IO 操作的数据量
IO 深度 如果采用异步 IO 操作,该参数代表了 IO 队列的深度
IO 类型 该参数表明采用直接 IO 方式还是 IO 缓存方式
文件数 该参数表明需要将整个 IO 负载划分为多少个文件
线程数 该参数表明需要将整个 IO 负载划分为多少个线程
IO 引擎 定义了系统处理 IO 的方式。比如:内存文件映射、普通的 文件读/写、异步读/写等。
2 优化方案思路(还是得看应用场景)
(1)文件系统参数优化主要分为通用参数优化和特定于文件系统的参数优化两个方面
通用参数:
noatime
传统模式下,如果一个文件被访问,那么这个的索引节点(inode)上的相关字段(访问时间)就应该被修改,使其与文件当前的状态保持一致,所以对索引节点的访问无疑增加了额外的写操作。如果对文件系统的信息准确性没 有非常高的要求,在挂载该文件系统的时候,可以设置 noatime 参数消除索引节点的更新操作。
discard
该参数用于设置文件系统是否使用 discard/Trim 命令。在文件系统中,写操 作是以“页”为单位进行的,但是受闪存设备物理特性的限制,擦除操作通常会 影响到整个“块”。对于闪存设备而言,如果存在未使用的“空页”,那么写操作 执行的速度将会非常快,但是如果是在有旧数据的页面上写入新数据,那么写速 度将会明显下降。因此,如果想让闪存设备有良好的写入性能,就必须对空闲区域进行管理,只有文件系统知道闪存设备哪个块可以被“整理”,因此, 文件系统为了能够对该功能进行管理,在 mount 的过程中,设置了 discard 参数。 如果开启该参数,在闪存设备每次执 行删除动作时,将会直接触发内核执行 Trim 命令,从而带来时间开销。
ext4中的参数
1)no journal
通过该参数可以关闭文件系统的日志功能。在系统比较稳定的情况下可以设 置该参数提高文件系统的 IO 性能。
2)data=writeback
该参数为调度算法定义了如下的日志形式:在数据写入文件系统之前,将文 件的元数据写入日志文件。该方式相比于其他的日志形式,被认为能够提供最大 吞吐量。因为 writeback 只是对文件的元数据进行了日志记录而没有对文件内容进 行日志记录。但是如果系统崩溃,在日志恢复的过程中可能会将旧的内容写入文 件中。
3)fs geometry (mkfs -E stripe-width=,stripe=)
stripe 和 stripe-width 参数用于创建分区对齐的文件系统。
(2)调度策略算法优化和 调度策略方案选择
如果直接对内核进行修改的话,难度太大,所以可以参考该论文方式,也就是通过调整 NOOP、DEADLINE、CFQ 暴露在用户空间的接口,对这 些调度算法进行优化,不用修改内核。
我们可以利用Linux 提供的特定于该调度策略的可调节参数,使得针对特定的块设备,相应的调度策略能够提供定制的服务。但是,NOOP 调度策略的实现非常简单,基本上可以理解为先来先服务,所以内核 没有针对该调度算法提供可调节参数。
DEADLINE 可调参数介绍
- read_expire
DEADLINE 提供了 read_expire 参数来动态设置读请求的超时时 间设置。当一个读请求进入 IO 队列之后,内核就会为其分配一个超时时间。 - write_expire
写请求超时时间,含义可参考 read_expire。 - fifo_batch DEADLINE
会将请求根据 IO 方向(读/写)对请求进行分组,在组内按照扇区号进行升序排列。为了减少搜索的代价,DEADLINE 只会对组进行超时时间的 判断。fifo_batch 参数代表了组内请求的最大数目。通过该参数可以平衡系统吞吐 量和延迟。如果系统比较关注吞吐量的话,则可以将该参数设置为一个比较大的 值。如果系统比较关注延迟,则需要将该参数设置为一个比较小的值。 - writes_starved
内核使用 writes_starved 代表读写请求的最大比例, writes_starved 参数的默认值是 2。内核首先优先处理读请求,但是如果 starved 超过了 writes_starved,内核就应该将读写请求同等对待。 - front_merges
内核提供了参数 front_merges 用于设置前向合并的行为。该参数设置为 0 表示关闭前向合并的行为。
CFQ 可调整的内核参数
- back_seek_max
该参数规定了磁头向后寻址的最大范围。默认值是 16M。CFQ 之所以设置这 个可调参数主要是对后向(相反方向)的请求做出预测。CFQ 调度算法根据这个 调度参数,对当前扇区之后(相反方向)的 back_seek_max 范围内的请求“预测” 为下一个请求。 - back_seek_penalty
该参数用来计算向后寻址的代价。如果后向(反向)请求的距离在 1 back_seek_penalty ⁄ 的前向(同向)请求的范围之内(比如:该参数的默认值是 2,也就是说后向(相反方向)请求的距离如果小于等于前向请求距离的1 2 ⁄ ), CFQ 就会认为前向(同向)请求和后向(反向)请求的代价是相同的,CFQ 不会 “偏向”于任何一个请求,否则,CFQ 就会选择前向(同向)请求。因为 CFQ 继 承了电梯调度策略的思想,所以 CFQ 会尽量选择同方向上的请求从而避免后向 (反向)寻址带来的延迟。 - fifo_expire_async
异步请求超时时间设置。如果队列被激活后,则优先检查是否有请求超时, 如果有超时请求,则派发。但是,在队列激活的期间内,只会派发一个超时请求, 其余的请求按照请求的优先级,以及所访问扇区号大小来派发。该参数的默认值 是 250ms。 - fifo_expire_sync
同步请求超时时间设置。默认 125ms。通过调整该参数,可以设置 CFQ 更加 “偏向”于处理同步请求还是异步请求。 - slice_sync
如果一个队列被选中,那个该队列上的 IO 请求只会被执行一定的时间, slice_sync 参数就是用于计算时隙的。默认值为 100ms。计算公式为: time_slice = slice_sync + (slice_sync 5 ⁄ * 4 – io_priority))。如果系统需要处理的 同步请求比较多,可以将该参数设置为一个比较大的值。 - slice_async
异步请求时隙设置。默认值为 40ms。从参数的设置中可以看出,CFQ 优先 处理异步请求。 - slice_asyn_rq
该参数限制了某个具体设备上的请求队列在 slice_time 内可以调度的异步请 求的最大数目。该参数的设置与 IO 请求的优先级也有密切的关系。计算 slice_time 内可以被调度的异步请求的最大数量为: max_nr_requests = 2 * (slice_async_rq + slice_async_rq * (7 – io_priority))。该参 数的默认值是 2。 - slice_idle
该参数用于设置同步请求的空闲时间。在队列的 slice_time 的范围内,如果 该队列上没有需要处理的请求,那么 CFQ 不会跳转到另外一个请求队列上,而会在当前队列上等待 slice_idle的时间。如果在 slice_idle时间内没有新的请求产生, CFQ 才会转而处理其他队列上的请求。slice_idle 的默认值为 7ms。 - quantum
该参数限制了具体设备上派发的请求的数目。
(3)文件预读取优化
在内存资 源足够的情况下,增加页缓存的大小可以提高顺序读操作的吞吐量。
最后
以上就是健忘毛衣为你收集整理的2020/11/2 崔鹏程 移动终端Linux存储IO性能分析与优化的全部内容,希望文章能够帮你解决2020/11/2 崔鹏程 移动终端Linux存储IO性能分析与优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复