8.4. 存储

8.4.1. 存储服务器调整准则
8.4.2. 关于 ZFS 存储高速缓存
8.4.3. 关于块对齐
8.4.4. Oracle VDI 针对存储的全局设置
8.4.5. 在 Oracle Solaris 平台上管理 ZIL

8.4.1. 存储服务器调整准则

建议的磁盘布局是 RAID 10,可在条带集中镜像集,ZFS 自动在多个集之间条带化数据。该布局被 7000 系列称为“镜像“。当该磁盘布局使用 50% 的可用磁盘容量实现冗余时,对于非常小的随机读/写,它比 RAID 5 更快,这是典型的 iSCSI 访问特征。

存储服务器提供虚拟磁盘,这些虚拟磁盘由 Oracle VM VirtualBox 通过 iSCSI 进行访问。因为 iSCSI 是 CPU 密集型协议,所以存储服务器的内核数量是其性能的决定性因素。其他重要的因素为内存大小(高速缓存)、磁盘数量和可用网络带宽。

网络带宽时常变动,它由启动的桌面(*峰值网络带宽*)和缓存了使用中应用程序的桌面(*平均网络带宽*)的关系确定。启动虚拟机(XP 客户机)会产生 150 MB 的网络负载,需要维持大约 30 秒钟。如果同时启动许多桌面,在存储的 CPU 可以处理由 iSCSI 流量产生的负载的情况下,所要求的网络带宽可能会超过 1 Gb/s。这种情形通常出现在实行轮班制的公司。在这种情况下,可以将 "Pool"(池)、"Cloning"(克隆)或 "Machine State"(计算机状态)选项设置为 "Running"(运行),这会始终使桌面保持运行,因此可将 OS 引导与用户登录分离开来。另一个选项是汇聚 (trunk) 多个接口,以通过一个 IP 提供 1 Gb/s 以上的带宽。还可以使用巨型帧 (Jumbo Frame) 来加快 iSCSI 连接的速度。需要为网络的所有参与者(存储服务器、Oracle VM VirtualBox 服务器和交换机)配置巨型帧。请注意,巨型帧尚未标准化,因此存在不兼容性风险。

与 Oracle VM VirtualBox 结合使用的 Oracle VDI 使用 ZFS 的稀疏卷功能,该功能允许 VDI 为卷分配多于物理可用磁盘空间的磁盘空间(只要写入的实际数据不超过存储的容量)。通过该功能(结合克隆的桌面会重用其模板的未更改数据这一事实)可以非常有效地使用可用磁盘空间。因此,下面的磁盘空间计算是对最糟糕的情形而言,它假定与模板不同的数据完全使用所有卷。

  • 内核数量 = 使用中的虚拟磁盘数量 / 200

    示例:具有 2 个 CPU,每个 CPU 具有 4 个内核的 x7210 存储最多可提供 2 * 4 * 200 = 1600 个虚拟磁盘

  • 内存大小-越大越好。空闲内存可用作磁盘高速缓存,这会减少访问时间。

  • 磁盘数量 = 桌面数量 / 10

  • 平均网络带宽 [Mb/s] = 使用中的虚拟磁盘数量 * 0.032 Mb/s

    示例:具有一个千兆位以太网接口的 x7210 存储最多可提供 1000 / 0.032 = 31250 个虚拟磁盘

  • 峰值网络带宽 [Mb/s] = 使用中的虚拟磁盘数量 * 40 Mb/s

    示例:具有一个千兆位以太网接口的 x7210 存储最多可提供 1000 / 40 = 25 个虚拟磁盘

  • 磁盘空间 [GB] = 桌面数量 * 虚拟磁盘的大小] [GB]

    示例:容量为 46 TB 的 x7210 存储可支持 46 * 1024 GB / 2 / 8 GB = 2944 个 8 GB 磁盘(采用 RAID 10 配置)

注意

有关如何提高桌面性能的详细信息,请参见优化桌面图像部分第 6.5 节 “创建桌面映像”

8.4.2. 关于 ZFS 存储高速缓存

本节提供了有关 ZFS 高速缓存结构和性能的简要概述,以及 ZFS 如何映射至 Sun Storage 7000 系列 Unified Storage System 的硬件。

背景

十亿兆位字节文件系统·(Zettabyte·File·System,·ZFS)·是在受支持的 Solaris 和 Sun Storage 7000 系列 Unified Storage System 存储平台上的一种基础文件系统。

适应性替换高速缓存 (Adaptive Replacement Cache, ARC) 是位于主内存 (DRAM) 中的 ZFS 读高速缓存。

二级适应性替换高速缓存 (Second Level Adaptive Replacement Cache, L2ARC) 用于存储主内存之外的读高速缓存数据。Sun Storage 7000 系列 Unified Storage System 对 L2ARC 使用读优化的 SSD(称为 Readzillas)。SSD 会慢于 DRAM,但仍比硬盘快的多。L2ARC 可允许使用能够提高读取性能的较大高速缓存。

ZFS 意图日志 (ZFS Intent Log, ZIL) 可以满足 POSIX 的同步写入和崩溃恢复的需求。不可用于异步写入。ZFS 系统调用由 ZIL 记录并包含充足的信息以便在系统崩溃时进行回放。Sun Storage 7000 系列 Unified Storage System 对 ZIL 使用写入优化的 SSD(称为 Writezillas 或 Logzillas)。如果 Logzillas 不可用,则使用硬盘。

写高速缓存用于将数据存储在不稳定的(非电池备份)DRAM 中以便进行更快速的写入。如果启用了 Solaris 和 Sun Storage 7000 系列 Unified Storage System,则在 ZIL 中不会记录系统调用。

性能注意事项

调整读高速缓存大小以便在其中存储尽可能多的数据来提高性能。首先最大化 ARC (DRAM),然后添加 L2ARC (Readzillas)。

在默认情况下,Oracle VDI 对每个 Oracle VDI 使用的 iSCSI 卷启用写高速缓存。该配置非常快速且不会利用 Logzillas,因为并未使用 ZIL。如果不使用 ZIL,则当 Sun Storage 7000 系列 Unified Storage System 在桌面活动时重新引导或断电时数据可能处于危险之中。不过,这不会造成 ZFS 自身的损坏。

禁用 Oracle VDI 中的写高速缓存以便将数据丢失的风险降到最低。如果不使用 Logzillas,ZIL 则由可用的硬盘进行备份,并且性能将明显受到影响。使用 Logzillas 可以加快 ZIL 的速度。如果您有两个或四个 Logzillas,则使用“条带化“配置文件来进一步提高性能。

要关闭内存中写高速缓存,请在 Oracle VDI Manager 中选择一个存储,单击“编辑“以打开“编辑存储“向导,并取消选中“高速缓存“复选框。此更改将应用于为 Oracle VDI 虚拟机管理程序 (Hypervisor) 新创建的桌面,以及为 Microsoft Hyper-V 虚拟化平台新启动的桌面。

8.4.3. 关于块对齐

传统硬盘具有大小为 512 字节的块。Oracle Solaris 和 Sun Unified Storage 使用 ZFS 文件系统,该文件系统具有 8 千字节的默认块大小。根据虚拟机客操作系统的不同,客文件系统的一个逻辑块能够使用存储上的两个 ZFS 块。这也称为块未对齐,如 图 8.2 “未对齐块和对齐块的示例” 中所示。最好避免出现块未对齐的情况,因为这将会使存储中的 IO 双倍进行以访问客 OS 文件系统的块(假设为完整的随机访问模式且无高速缓存)。

图 8.2. 未对齐块和对齐块的示例

该图显示了虚拟磁盘的两个示例,其中一个是准确对齐的示例,另一个是未对齐示例。

Windows XP 是可能会发生块未对齐的特定示例。通常磁盘上的单分区从磁盘扇区编号为 63 处开始。若要检查 Windows 分区的对齐,请使用以下命令:

wmic partition get StartingOffset, Name, Index

以下是自该命令输出的一个示例:

Index Name                   StartingOffset 
0     Disk #0, Partition #0  32256

若要查找起始扇区,用 StartingOffset 值除以 512:

32256 ÷ 512 = 63

NTFS 簇通常大小为 4 千字节。因此第一个 NTFS 簇开始于磁盘扇区 63,结束于磁盘扇区 70。在存储中,第四个 ZFS 块映射至磁盘扇区 48 至 63,第五个 ZFS 块扇区映射至磁盘扇区 64 至 79。由于必须访问两个 ZFS 块来访问第一个 NTFS 簇,因此会出现未对齐情况,如 图 8.2 “未对齐块和对齐块的示例” 中所示。

对于准确的块对齐,StartingOffset 值必须能够被 8192(底层 ZFS 存储的默认块大小)整除。

在以下示例中,块未对齐:

wmic partition get StartingOffset, Name, Index
Index Name                   StartingOffset 
0     Disk #0, Partition #0  32256

32556 ÷ 8192 = 3.97412109

在以下示例中,块已对齐:

wmic partition get StartingOffset, Name, Index
Index Name                   StartingOffset 
0     Disk #0, Partition #0  32768

32768 ÷ 8192 = 4

在 Windows 2003 SP1 及更高版本中,diskpart.exe 实用程序具有“对齐“选项来指定分区的块对齐。对于 Windows XP,则使用第三方磁盘分区工具(例如 parted)来通过已定义的起始扇区创建分区,请参见以下示例。对于其他操作系统,请参见您的系统文档来获取有关如何对齐分区的详细信息。

有关 Windows XP 中如何准备块准确对齐的磁盘的示例

在该示例中,可引导活动 Linux 系统中的磁盘实用程序(例如 Knoppix),用于创建一个块已准确对齐的磁盘分区。

  1. 创建新的虚拟机。

  2. 将活动 Linux 系统的 ISO 映像 分配至 虚拟机的 CD/DVD-ROM 驱动器。

  3. 引导虚拟机。

  4. 打开 shell 命令并成为 root 用户。

  5. 获取磁盘扇区总数。

    使用 fdisk -ul 命令来获取有关磁盘的信息。

    在以下示例中,磁盘具有 20971520 个扇区:

    # fdisk -ul
    Disk /dev/sda doesn't contain a valid partition table
    
    Disk /dev/sda: 10.7 GB, 10737418240 bytes
    255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00000000
  6. 在磁盘上创建 MS-DOS 分区表。

    使用 parted <disk> mklabel msdos 命令以创建分区表。

    在以下示例中,会在 /dev/sda 磁盘上创建分区表:

    # parted /dev/sda mklabel msdos
  7. 创建新的分区,并指定分区的起始和结束扇区。

    使用 parted <disk> mkpartfs primary fat32 64s <end-sector>s 命令以创建分区。<end-sector> 为磁盘扇区总数减去一。例如,如果磁盘具有 20971520 个扇区,则 <end-sector> 为 20971519。

    根据所使用的 parted 版本不同,您可能会看到一则警告:未正确分配分区以获取最佳性能。忽略该警告是安全的。

    在以下示例中,会在 /dev/sda 磁盘上创建分区:

    # parted /dev/sda mkpartfs primary fat32 64s 20971519s                          
  8. 检查是否已创建分区。

    使用 parted <disk> print 命令以检查分区。

    在以下示例中,会检查 /dev/sda 磁盘的分区:

    # parted /dev/sda print
    Model: ATA VBOX HARDDISK (scsi)
    Disk /dev/sda: 10.7GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos
    
    Number  Start   End     Size    Type     File system  Flags
     1      32.8kB  10.7GB  10.7GB  primary  fat32        lba
  9. 关闭虚拟机并撤销分配 ISO 映像。

  10. 将 Windows XP 安装 ISO 映像分配至虚拟机的 CD/DVD-ROM 驱动器。

  11. 引导虚拟机并安装 Windows XP。

  12. 出现提示时,选择新创建的分区。

  13. (可选)出现提示时,将文件系统从 FAT32 更改为 NTFS。

  14. 完成安装。

  15. 以管理员身份登录到 Windows XP 客帐号。

  16. 检查 StartingOffset 值是否为 32768。

    wmic partition get StartingOffset, Name, Index
    Index Name                   StartingOffset 
    0     Disk #0, Partition #0  32768

8.4.4. Oracle VDI 针对存储的全局设置

本节提供了有关适用于存储的 Oracle VDI 全局设置的信息。使用 vda settings-getpropss 和 vda settings-setprops 命令可以列出和编辑这些设置。

全局设置

说明

storage.max.commands

在存储中并行执行的命令数。

默认设置是 10。

更改此设置需要重新启动 Oracle VDI 服务。

该设置对 Oracle VDI 安装是全局性的并适用于由其 IP 或 DNS 名称决定的物理存储。

Oracle VDI 主机数不会影响由物理存储中 Oracle VDI 执行的并行存储操作最大数目。在出现间歇性的“无响应存储“消息时则减少该数目,从而降低存储负荷。这样做会影响到克隆和再循环性能。

即便 Oracle VDI 中心代理在主机上不再运行,该选项也同样起作用。

storage.query.size.interval

Oracle VDI 服务查询存储总的和可用磁盘空间所花费的时间(秒)。

默认设置是 180 秒。

由于仅有一台 Oracle VDI 主机执行此操作,因此通常不需要更改此设置。

storage.watchdog.interval

Oracle VDI 服务查询存储可用性所花费的时间(秒)。

默认设置是 30 秒。

由于仅有一台 Oracle VDI 主机执行此操作,因此通常不需要更改此设置。

storage.fast.command.duration

Oracle VDI 服务在考虑快速存储命令是否已失败之后的时间(秒)。

默认设置是 75 秒。

更改此设置需要重新启动 Oracle VDI 服务。

使用此命令持续时间的唯一 Oracle VDI 功能是存储看门狗,该功能可以定期 Ping 存储,以查看其可用性。

storage.medium.command.duration

Oracle VDI 服务在考虑中速存储命令是否已失败之后的时间(秒)。

默认设置是 1800 秒(30 分钟)。

更改此设置需要重新启动 Oracle VDI 服务。

由 Oracle VDI 使用的大部分存储命令使用此命令持续时间。

storage.slow.command.duration

Oracle VDI 服务在考虑慢速存储命令是否已失败之后的时间(秒)。

默认设置是 108000 秒(3 小时)。

更改此设置需要重新启动 Oracle VDI 服务。

只有 Oracle VDI 使用的几个复杂存储脚本使用此命令持续时间。此类脚本不会经常运行,通常一天一次。

storage.max.commands 设置是最常更改的设置。在默认情况下,Sun Storage 7000 系列 Unified Storage System 只能并行执行四个命令,其余命令将排成队列。为了获取更佳性能,Oracle VDI VDI 会有意过量使用存储队列。如果存储变慢(例如由于负荷过重),执行队列中的命令可能会花费很长时间,并且如果命令花费时间超过在持续时间设置中指定的持续时间,则存储可能会被不正确地标记为无响应。如果此类情况经常发生,则可以减小 storage.max.commands 设置的值,但是当存储不太繁忙时这可能会导致性能的降低。

间隔设置很少需要进行更改,因为这些命令仅由 Oracle VDI 中心的主主机来执行。减小这些设置的值可以获得更多有关存储磁盘空间的最新信息,并更快速地检测无响应的存储主机,但同时也会增加存储主机上的负荷。因此最好将这些设置保留为其默认值。

持续时间设置含有良好的安全裕量。如果存储在规定的时间内无法执行命令,则仅需更改持续时间设置。

8.4.5. 在 Oracle Solaris 平台上管理 ZIL

禁用 ZFS 意图日志 (ZFS Intent Log, ZIL) 是加速 Oracle Solaris 10 10/09(及更高版本)存储平台的一种方法。还有其他多种方式可以实现这一操作,但是请注意:当在存储出现故障且同步磁盘 I/O 和数据一致性非常重要时,禁用 ZIL 会很危险。

可立即禁用 ZIL 的命令:

        echo zil_disable/W0t1 | mdb -kw
      

可立即启用 ZIL 的命令:

        echo zil_disable/W0t0 | mdb -kw
      

若要防止禁用 ZIL 命令恢复重新引导,请编辑 /etc/system 并添加以下行:

        set zfs:zil_disable=1
      

当特定 ZIL 池进行挂载时,更改 ZIL 状态会很有效,因此在设置更改(重新引导期间暗中完成)之后,必须创建、重新挂载或导入 ZIL 池。

由于 ZIL 设置对于存储是全局性的并在重新引导之后对存储的所有 ZFS 池禁用 ZIL,由 ZFS 提供服务的系统根卷可能会由于同步语义的消失而显示意外行为。

避免出现此类利益冲突的最佳做法是使用至少包含两个磁盘的服务器。第一个磁盘使用旧的 UFS 文件系统托管 OS 的系统片。其余磁盘进行 ZFS 格式化并用作 Oracle VDI 存储。通过执行此操作,可以禁用 ZIL 并且 UFS 磁盘将仍能提供同步语义,因为 ZIL 仅为 ZFS。

ZFS 和 ZIL 的参考页面:

http://www.solarisinternals.com/wiki/index.php/ZFS_Evil_Tuning_Guide#Disabling_the_ZIL_.28Don.27t.29