12 针对特殊需求调整 I/O 特征

前面章节中介绍的基本文件系统配置步骤在大多数情况下提供了最佳平衡性能。因此,如果您完全不确定您的应用程序的行为方式,则通常最好将此部分中的设置保留为默认值。但是,如果您的应用程序发出非常一致或非常大的 I/O 请求,则整体性能可能会从调整或更改文件系统处理物理 I/O 的方式中受益。

当所有或大部分读取和写入完全在磁盘扇区的 512 字节边界上开始和结束时,物理 I/O 最有效。磁盘 I/O 只能在扇区大小的块中发生。因此,当 I/O 请求跨越扇区边界时,系统必须执行附加操作以便将应用程序数据与同一扇区中的无关数据分隔开。系统必须确保后者在此过程中不会损坏。在最坏的情况下,跨扇区写入时,文件系统必须读取扇区,修改内存中的扇区数据,然后将扇区写回磁盘。其他单独的机械活动会使此类读取、修改和写入操作对性能造成极大损害。

遗憾的是,大部分应用程序需要读取和写入扇区边界上未良好对齐的各种大小的数据。出于此原因,与许多文件系统一样,默认情况下,Oracle HSM 将使用分页 I/O。文件系统将通过在 Solaris 分页内存的数据高速缓存中读取或写入来处理应用程序的即时 I/O 请求。文件系统将使用大小更有效且对齐得更好的物理读取和写入来异步更新高速缓存。只要它从磁盘中读取数据,就可通过预见即将执行的读取并在同一操作中将对应数据装入到高速缓存来进行大多数物理 I/O。这样,将使用虚拟内存页中高速缓存的数据来满足大多数 I/O 请求,而无需其他物理磁盘活动。分页 I/O 使用内存并对系统 CPU 施加一些额外负载,不过在大多数情况下,这些成本可以被更高的物理 I/O 效率抵消。

但在少数情况下,与分页 I/O 相关的额外开销无法通过其优势抵消。对于始终执行对齐良好的 I/O 的应用程序以及可调整达到此目的的应用程序来说,页面高速缓存毫无裨益。执行超大 I/O 的应用程序也很难从页面高速缓存中获益,因为仅第一个和最后一个扇区未对齐,而且因为大型 I/O 可能在任何情况下都太大而无法保留在高速缓存中。最终,对于流式传输遥测数据、监视视频或其他类型的实时信息的应用程序,在写入未立即提交到非易失存储时可能面临着丢失不可恢复的数据的风险。在这些情况下,最好使用直接 I/O。指定直接 I/O 后,文件系统会直接在应用程序内存与磁盘设备之间传输数据,而绕过页面高速缓存。

Oracle HSM 在选择和调整 I/O 高速缓存行为方面会为您提供相当大的自由度。在了解您的应用程序的 I/O 特征并执行针对预测的文件系统 I/O 调整 Solaris 系统和驱动程序参数中介绍的任务之后,请按照如下所示选择您的方式:

针对大型数据传输优化分页 I/O

分页 I/O 可进行调整,以便更好地与应用程序和硬件特征匹配。高速缓存的读取和写入应该足够大,以传输应用程序所传输的平均数据量或物理存储可传输的最大数据量,以两者中较大的为准。如果我们无法调整其中任一页面高速缓存行为,则高速缓存将得不到充分利用,应用程序 I/O 请求将需要更多物理 I/O,并且整体系统性能将变差。

例如,考虑在单一磁盘卷上实施的 md 数据设备与在 3+1 RAID 5 卷组上实施的 md 设备之间的差异。如果我们通过将单一 64 KB 磁盘分配单元 (disk allocation unit, DAU)从高速缓存写入后者来处理应用程序的每个写入请求,从而避免多磁盘设备可能具有的其他带宽问题,则 RAID 设备必须将 I/O 拆分为三个更小的、效率更低的 21 和 22 KB 段,之后再将数据写出到 RAID 组中的三个数据磁盘。使用此配置完成应用程序的 64 KB I/O 请求需要的工作明显多于它在我们使用页面高速缓存将请求组装成一个 3-DAU、192 KB I/O 时需要的工作。如果应用程序可以(或者能够调整为)使用设备带宽的偶数倍(192、384 或 576 KB)发出 I/O 请求,则我们可以高速缓存更多数据并使用每个物理 I/O 传输更多数据,从而进一步减少开销并相应地提升性能。

因此,确定您的应用程序的 I/O 需求并了解您的硬件的 I/O 属性。然后执行如下操作。

  1. root 用户身份登录到文件系统主机。

    root@solaris:~# 
    
  2. 备份操作系统的 /etc/vfstab 文件。

    root@solaris:~# cp /etc/vfstab /etc/vfstab.backup
    root@solaris:~# 
    
  3. 在文本编辑器中打开 /etc/vfstab 文件,并找到需要调整的文件系统对应的行。

    在本示例中,文件系统名为 qfsma

    root@solaris:~# vi /etc/vfstab
    #File
    #Device    Device   Mount     System  fsck  Mount    Mount
    #to Mount  to fsck  Point     Type    Pass  at Boot  Options
    #--------  -------  --------  ------  ----  -------  --------------------
    /devices   -        /devices  devfs   -     no       -
    ...
    qfsma      -        /qfsma    samfs   -     yes      ...
    
  4. 在文件系统的 Mount Options 字段中,添加 writebehind=n 挂载选项,其中 n8 千字节的倍数。使用逗号(无空格)分隔挂载选项。保存文件并关闭编辑器。

    writebehind 选项将确定在页面高速缓存刷新到磁盘之前,可在页面高速缓存中排队的指定文件的数量。将此参数设置为更高的值将改善性能,因为大型队列会将多个小应用程序写入合并到更少、更大、更有效的物理 I/O 中。将此参数设置为更低的值将更好地保护数据,因为更改将更快地写入非易失存储。

    默认值为 512 KB(八个 64 KB DAU),此大小一般有利于大块、顺序 I/O。但在本示例中,系列集包含两个具有分散读写文件分配的 md 磁盘设备。分散读写宽度为一个 64 KB DAU,用于将 128 KB 写入到两个 md 设备。md 设备是 3+1 RAID 5 组。因此我们需要向三个数据轴中的每个轴写入至少 128 KB,写入总计至少为 768 KB(96 个组,每组 8 KB):

    #File
    #Device    Device   Mount     System  fsck  Mount    Mount
    #to Mount  to fsck  Point     Type    Pass  at Boot  Options
    #--------  -------  --------  ------  ----  -------  --------------------
    /devices   -        /devices  devfs   -     no       -
    ...
    qfsma      -        /qfsma    samfs   -     yes      ...,writebehind=768
    :wq
    root@solaris:~# 
    
  5. 测试文件系统的 I/O 性能,并根据需要调整 writebehind 设置。

  6. 在文本编辑器中重新打开 /etc/vfstab 文件。在文件系统的 Mount Options 字段中,添加 readahead=n 挂载选项,其中 n 是 8 KB 的倍数。使用逗号(无空格)分隔挂载选项。保存文件并关闭编辑器。

    readahead 选项将确定在一次物理读取过程中读入高速缓存的数据量。当应用程序看起来似乎要按顺序读取时,文件系统会在每次物理读取过程中高速缓存即将读取的文件数据块。接下来将从高速缓存内存中处理一系列应用程序读取请求,将若干应用程序读取请求合并到一个物理 I/O 请求中。

    默认值为 1024 KB(十六个 64 KB DAU),此大小一般对大块、顺序 I/O 有利。如果数据库或类似应用程序执行其自己的 readahead,则将 Oracle HSM readahead 设置为 0 以避免冲突。否则,readahead 一般应设置为高速缓存一次物理 I/O 可传输的最大数据量。如果 readahead 设置小于应用程序通常请求和设备可提供的数据量,则完成应用程序 I/O 请求将需要不必要的物理 I/O。但是,如果 readahead 设置过高,则它可能占用非常多的内存,导致整体系统性能降级。在示例中,我们将 readahead 设置为 736 KB(三十六个 64 KB DAU)。

    #File
    #Device    Device   Mount     System  fsck  Mount    Mount
    #to Mount  to fsck  Point     Type    Pass  at Boot  Options
    #--------  -------  --------  ------  ----  -------  --------------------
    /devices   -        /devices  devfs   -     no       -
    /proc      -        /proc     proc    -     no       -
    ...
    qfsma      -        /qfsma    samfs   -     yes      ...,readahead=736
    :wq
    root@solaris:~# 
    
  7. 测试文件系统的 I/O 性能,并根据需要调整 readahead 设置。

    增加 readahead 参数的大小可增强大型文件的传输性能,但性能增强的幅度很小。因此在重置 readahead 大小之后测试系统的性能。然后向上调整 readahead 大小,直到传输速率不再提高为止。

允许在分页 I/O 和直接 I/O 之间切换

您可以将 Oracle HSM 文件系统配置为在分页 I/O 和直接 I/O 之间切换(如果这样做更符合应用程序的 I/O 行为的话)。指定可能受益于直接 I/O 的读取和写入的扇区对齐和最小大小特征,然后设置应触发切换的符合条件的读取和写入数量。执行如下操作:

  1. root 用户身份登录到文件系统主机。

    root@solaris:~# 
    
  2. 备份操作系统的 /etc/vfstab 文件。

    root@solaris:~# cp /etc/vfstab /etc/vfstab.backup
    root@solaris:~# 
    
  3. 在文本编辑器中打开 /etc/vfstab 文件并找到您要配置的文件系统的行。

    在本示例中,文件系统名为 qfsma

    root@solaris:~# vi /etc/vfstab
    #File     Device                      Mount
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   stripe=1
    
  4. 要为与 512 字节的扇区边界对齐良好的读取请求设置起始直接 I/O 的阈值大小,请将 dio_rd_form_min=n 挂载选项添加到文件系统的 Mount Options 字段,其中 n 是 KB 数。使用逗号(无空格)分隔挂载选项。

    默认情况下,dio_rd_form_min=256 KB。在示例中,我们知道我们的应用程序直到请求一次读取至少 512 KB 才会一致地生成对齐良好的读取。因此,我们将对齐良好的直接读取的阈值大小更改为 512

    #File     Device                      Mount
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   stripe=1,dio_rd_form_min=512
    
  5. 要为与 512 字节的扇区边界对齐良好的读取请求设置起始直接 I/O 的阈值大小,请将 dio_wr_form_min=n 挂载选项添加到文件系统的 Mount Options 字段,其中 n 是 KB 数。使用逗号(无空格)分隔挂载选项。

    默认情况下,dio_wr_form_min=256 KB。在示例中,我们知道我们的应用程序直到请求一次写入至少 1 MB 才会一致地生成对齐良好的写入。因此,我们将对齐良好的直接写入项的阈值大小更改为 1024 KB:

    #File     Device                      Moun
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   ...,dio_wr_form_min=1024
    
  6. 要为与 512 字节的扇区边界未对齐的读取请求设置起始直接 I/O 的阈值大小,请将 dio_rd_ill_min=n 挂载选项添加到文件系统的 Mount Options 字段,其中 n 是 KB 数。使用逗号(无空格)分隔挂载选项。

    默认情况下,dio_rd_ill_min=0 KB,因此直接 I/O 不会用于未对齐的读取。在示例中,我们知道我们的应用程序通常会为小数据块发出未对齐的读取请求。将按顺序重新读取大量此类数据。因此页面高速缓存可能对这些读取有益。切换到直接 I/O 将导致额外的无用物理 I/O 并降低性能。因此我们接受默认值并且不更改 vfstab 文件:

    #File     Device                      Mount
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   ...,dio_wr_form_min=1024
    
  7. 要为与 512 字节的扇区边界未对齐的写入请求设置起始直接 I/O 的阈值大小,请将 dio_wr_ill_min=n 挂载选项添加到文件系统的 Mount Options 字段,其中 n 是 KB 数。使用逗号(无空格)分隔挂载选项。

    默认情况下,dio_wr_ill_min=0 KB,因此直接 I/O 不会用于未对齐的写入。未对齐的写入尤其会损害性能,因为系统必须读取、修改和写入扇区。但在本示例中,我们知道我们的应用程序偶尔会发出不在扇区边界内的大型、单一写入请求。由于读取、写入和修改操作限制为连续扇区的大型块的开头和结尾,因此直接 I/O 的好处要超过分页 I/O。因此我们设置 dio_wr_ill_min=2048 KB:

    在本示例中,我们将写入未对齐数据过程中使用直接 I/O 的默认阈值更改为 2048 KB:

    #File     Device                      Mount
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   ...,dio_wr_ill_min=2048
    
  8. 要为读取启用直接 I/O,请将 dio_rd_consec=n 挂载选项添加到 Mount Options 字段,其中 n 是连续 I/O 传输的数量,该数量必须满足上面指定的大小和对齐要求才会触发切换到直接 I/O 的操作。选择一个针对受益于直接 I/O 的应用程序操作而选择的值。使用逗号(无空格)分隔挂载选项。

    默认情况下 dio_rd_consec=0,因此将禁用 I/O 切换。在示例中,我们知道,我们的应用程序请求三个连续、对齐良好的读取(其大小至少为 dio_rd_form_min 指定的最小大小,即 512 KB)后,应用程序将继续请求直到足够长以使直接 I/O 比较有价值。dio_rd_form_min 指定的最小大小是默认值 0,因此启用直接 I/O 将不影响未对齐读取请求。因此我们设置 dio_rd_consec=3

    #File     Device                      Mount 
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   ...,dio_rd_consec=3
    
  9. 要为写入启用直接 I/O,请将 dio_wr_consec=n 挂载选项添加到 Mount Options 字段,其中 n 是连续 I/O 传输的数量,该数量必须满足上面指定的大小和对齐要求才会触发切换到直接 I/O 的操作。选择一个针对受益于直接 I/O 的应用程序操作而选择的值。使用逗号(无空格)分隔挂载选项。

    默认情况下 dio_wr_consec=0,因此将禁用 I/O 切换。在示例中,我们知道,我们的应用程序请求两个连续、对齐良好的写入(其大小至少为 dio_wr_form_min 指定的最小大小,即 1024 KB)后,它将继续请求直到足够长以使直接 I/O 比较有价值。我们还知道,两个连续、未对齐写入将大于 dio_wr_form_min (2048 KB),这已经足够大,未对齐的影响相对来说不大。因此我们设置 dio_wr_consec=2

    #File     Device                      Mount 
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- ------ ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   ...,dio_wr_consec=2
    
  10. 保存 vfstab 文件并关闭编辑器。

    #File     Device                      Mount 
    #Device   to     Mount    System fsck at    Mount
    #to Mount fsck   Point    Type   Pass Boot  Options
    #-------- ------ -------- -----  ---- ----- -----------------------------
    /devices  -      /devices devfs  -    no    -
    /proc     -      /proc    proc   -    no    -
    ...
    qfsma     -      /qfsma   samfs  -    yes   ...,dio_wr_consec=2
    :wq
    root@solaris:~# 
    
  11. 挂载已修改的文件系统:

    root@solaris:~# mount /qfsms
    root@solaris:~# 
    

将文件系统配置为仅使用直接 I/O

当应用程序的 I/O 特征需要仅使用直接 I/O 时,您可以使用 forcedirectio 挂载选项来挂载整个文件系统(有关如何为独立文件或目录指定直接 I/O 的信息,请参见 Oracle HSM setfa 手册页)。

要挂载文件系统以仅使用直接 I/O,请执行如下操作:

  1. root 用户身份登录到文件系统主机。

    root@solaris:~# 
    
  2. 备份操作系统的 /etc/vfstab 文件。

    root@solaris:~# cp /etc/vfstab /etc/vfstab.backup
    root@solaris:~# 
    
  3. 在文本编辑器中打开 /etc/vfstab 文件,然后查找您要在其中使用直接 I/O 的文件系统对应的行。

    在本示例中,文件系统名为 qfsma

    root@solaris:~# vi /etc/vfstab
    #File
    #Device    Device   Mount     System  fsck  Mount    Mount
    #to Mount  to fsck  Point     Type    Pass  at Boot  Options
    #--------  -------  --------  ------  ----  -------  --------------------
    /devices   -        /devices  devfs   -     no       -
    /proc      -        /proc     proc    -     no       -
    ...
    qfsma      -        /qfsma    samfs   -     yes      stripe=1
    
  4. 在文件系统的 Mount Options 字段中,添加 forcedirectio 挂载选项。使用逗号(无空格)分隔挂载选项。保存文件并关闭编辑器。

    #File
    #Device    Device   Mount     System  fsck  Mount    Mount
    #to Mount  to fsck  Point     Type    Pass  at Boot  Options
    #--------  -------  --------  ------  ----  -------  --------------------
    /devices   -        /devices  devfs   -     no       -
    /proc      -        /proc     proc    -     no       -
    ...
    qfsma      -        /qfsma    samfs   -     yes      stripe=1,forcedirectio
    :wq
    root@solaris:~# 
    
  5. 挂载已修改的文件系统:

    root@solaris:~# mount /qfsms 
    root@solaris:~# 
    

增加目录名称查找高速缓存大小

在共享文件系统的客户机一次打开大量文件时,元数据服务器上的 Oracle Solaris 目录名称查找高速缓存 (directory name lookup cache, DNLC) 的默认大小可能会显得不足。元数据服务器将代表所有客户机查找文件名,因此文件系统性能在这些情况下可能会下降。

如果您预期会有此类工作负载,则将目录名称查找高速缓存大小参数 ncsize 更改为默认大小的两倍或三倍。有关说明,请参见 Oracle Solaris Information Library 中的《Oracle Solaris 可调参数参考手册》(请参见前言的可用文档部分)。