内容


使用 vdbench 评估短暂存储 I/O 性能

为什么缓存是增强 SmartCloud 输入/输出性能的一个重要元素

Comments

为了理解 SmartCloud 环境中的短暂存储性能,我们使用 vdbench 设置了一项基准测试。vdbench 是一个 I/O 工作负载生成器,用于验证数据完整性和度量直接附加和网络连接的存储的性能。它是一个免费的工具,容易使用,而且常常用于测试和基准测试。

我们得出的结论是,缓存是 I/O 基准测试中的一个重要元素。本文介绍我们设置基准测试的步骤并展示结果。但是首先我们会简要介绍我们使用的以下产品和工具。

我们的基准测试设置

首先从 SmartCloud 开始,这是一个以基于内核的虚拟机 (KVM) 为基础构建的公共云服务,是 x86 架构上的 Linux® 的一个全面的虚拟化解决方案。SmartCloud 是一个完整的基础架构即服务 (IaaS) 产品。可将它用作构建平台即服务 (PaaS) 和软件即服务 (SaaS) 解决方案的基础。

SmartCloud 的关键特性包括:

  • 自助配置虚拟服务器机器和虚拟存储空间(持久性存储)
  • 网络功能
  • 即用即付的结算策略
  • 自动配置资源
  • 开放 API 可用于开发脚本和软件来增强自动化
  • VM 大小涵盖从一个虚拟 CPU 和 2GB 内存到 16 个 CPU 和 32GB RAM。
  • Windows® 和 Linux 操作系统都可部署,包括 Red Hat Enterprise Linux 和 SUSE Linux。

SmartCloud 提供了 3 种类型的存储:

  • 短暂存储与一个 VM 被配给之后相关联。
  • 持久存储是一种网络附加存储,通过动态附加到一个活动实例/与该实例分离来访问。
  • 对象存储与 Nirvanix 联合提供,可配置为非结构化数据的一种按需存储解决方案。

在我们的基准测试中,我们将重点看看短暂存储。

我们使用 vdbench 来测试原始磁盘和文件系统。它有一个 Web 用户界面可显示详细的性能报告。vdbench 由 Sun Microsystems 的 Henk Vandenbergh 开发,以前称为 StorageTek。vdbench 是使用 Java® 编写的。它在 Solaris、Windows、HP-UX、AIX、Linux、Mac OS X、zLinux 和原生 VMware 上经过了测试。

短暂存储的更多信息

短暂存储在配置一个 VM 时创建。它的生命周期与它绑定到的实例直接相关。短暂存储从位于节点内的本地磁盘创建。基于共享基础架构上正在执行的操作,它的吞吐量具有显著变化。

对于配置短暂存储不小于 60GB,对于配置的最大 VM,最大可达 2048GB。如果没有必要使用完整的实例存储,您可为虚拟机配置最低的短暂存储量 (60 GB)。配置最低存储可减少大型虚拟机类型的配置时间。在删除实例后,虚拟机实例存储就会被擦除。

图 1. 为一个 VM 配置短暂存储
为一个 VM 配置短暂存储

相反,要将数据存储更长时间,可使用持久存储块。与短暂存储相比,持久存储没有与 VM 绑定的寿命,它是独立计算的。持久存储可动态附加到 VM 或从 VM 分离,因为它是一个网络附加存储 (NAS) 原始磁盘,必须从来宾内格式化和装载,如下所示。

图 2. 通过网络附加的 VM 实现持久存储
通过网络附加的 VM 实现持久存储

在我们的基准测试中,我们通过使用 Red Hat Linux 配置一个 VM 来创建短暂存储。它类似于下图:

图 3. 使用 Red Hat Linux 为短暂存储配置 VM
使用 Red Hat Linux 为短暂存储配置 VM
使用 Red Hat Linux 为短暂存储配置 VM

设置基准测试

您应该已安装并正在运行 SmartCloud。接下来,您必须分配一个虚拟块设备和一个 ext3 文件系统,然后安装 vdbench。

分配一个虚拟块设备

以下代码将分配一个虚拟块设备:

清单 1. 分配一个虚拟块设备
[idcuser@vhost1291 /]$ dd if=/dev/urandom of=/home/idcuser/disk1.raw bs=512 count=2097152
 oflag=sync,direct
[idcuser@vhost1291 ~]$ sudo parted disk1.raw mklabel msdos
[idcuser@vhost1291 ~]$ sudo losetup -f disk1.raw
[idcuser@vhost1291 ~]$ sudo losetup -a
/dev/loop0: [fc02]:234430 (/home/idcuser/disk1.raw)
[idcuser@vhost1291 ~]$ sudo fdisk /dev/loop0
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-130, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-130, default 130):
Using default value 130
Command (m for help): w
[idcuser@vhost1291 ~]$ sudo fdisk -ul /dev/loop0
Disk /dev/loop0: 1073 MB, 1073741824 bytes
255 heads, 63 sectors/track, 130 cylinders, total 2097152 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: 0x0008f4b6
Device Boot Start End Blocks Id System
/dev/loop0p1 63 2088449 1044193+ 83 Linux
[idcuser@vhost1291 ~]$ sudo losetup -o 32256 -f /dev/loop0
[idcuser@vhost1291 ~]$ sudo losetup -a
/dev/loop0: [fc02]:234430 (/home/idcuser/disk1.raw)
/dev/loop1: [0005]:5396 (/dev/loop0), offset 32256
[idcuser@vhost1291 ~]$ sudo mkfs -t ext3 /dev/loop1
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 262136 blocks
13106 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 36 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
[idcuser@vhost1291 ~]$ sudo losetup -d /dev/loop1
[idcuser@vhost1291 ~]$ sudo losetup -d /dev/loop0
[idcuser@vhost1291 ~]$ mkdir partition1
[idcuser@vhost1291 ~]$ sudo mount -t ext3 -o sync,loop,offset=32256 disk1.raw partition1/

分配一个 ext3 文件系统

以下代码分配一个 ex3 文件系统:

清单 2. 分配一个 ext3 文件系统
[idcuser@vhost1291 ~]$ sudo dd if=/dev/urandom of=fs_1GB.ext3 bs=512 count=2097152
 oflag=sync,direct
[idcuser@vhost1291 /]$ sudo chmod 664 fs_1GB.ext3
[idcuser@vhost1291 /]$ sudo mkfs -t ext3 -q fs_1GB.ext3
fs_1GB.ext3 is not a block special device.
Proceed anyway? (y,n)
y
[idcuser@vhost1291 /]$ sudo mount -t ext3 -o sync,loop fs_1GB.ext3 /mnt/fs_mount
[idcuser@vhost1291 mnt]$ fdisk -l fs_1GB.ext3
Disk /fs_1GB.ext3: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Disk /fs_1GB.ext3 doesn't contain a valid partition table
[idcuser@vhost1291 /]$ sudo umount -l /mnt/fs_mount/
[idcuser@vhost1291 /]$ sudo losetup -d /dev/loop0

安装 vdbench

现在是时候下载和安装 vdbench。

  1. 打开 Sourceforge 并下载该工具。
  2. 使用 WinSCP 工具将它传输到 SmartCloud 中的 VM 中。将它解压到 Linux VM 的 /var/www/html 目录。
    清单 3. 解压 WinSCP
    [root&vhost4377 idcuser]# mv vdbench502.zip /var/www/html/
    [root&vhost4377 idcuser]# cd /var/www/html/
    [root&vhost4377 html]# mkdir vdbench502
    [root&vhost4377 html]# unzip vdbench502.zip –d vdbench502/
    [root&vhost4377 html]# cd vdbench502
  3. 要运行该工具,您需要安装 Java 运行时环境,在本例中安装 Oracle JDK。
    清单 4. 安装 Java 运行时环境
    [idcuser&vhost4377 ~]$ sudo –s | cd
    [root&vhost4377 ~]# wget
     http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-i586.rpm
    [root&vhost4377 ~]# rpm –ivh jdk-7u3-linux-i586.rpm
    [root&vhost4377 ~]# vi .bashrc
    JAVA_HOME=/usr/java/jdk1.7.0_03
    CLASSPATH=.:$JAVA_HOME/lib/tools.jar
    PATH=$JAVA_HOME/bin:$PATH
    export JAVA_HOME CLASSPATH PATH
    [root&vhost4377 ~]# source .bashrc
  4. 启动基准测试之前,使用默认的参数检查安装是否成功完成。
    [root&vhost4377 vdbench502]# ./vdbench -t

编写一个 parmfile

要更详细地控制工具参数,编写一个 parmfile,您可在其中指定不同的选项。

对于一个虚拟块设备

对于一个虚拟块设备,配置以下参数:

HD:主机定义

  • 如果您希望展示当前主机,则设置 hd= localhost。如果希望指定一个远程主机,hd= label。
  • system= IP 地址或网络名称。
  • clients= 用于模拟服务器的正在运行的客户端数量。

SD:存储定义

  • sd= 标识存储的名称。
  • host= 存储所在的主机的 ID。
  • lun= 原始磁盘、磁带或文件系统的名称。vdbench 也可为您创建一个磁盘。
  • threads= 对 SD 的最大并发 I/O 请求数量。默认为 8。
  • hitarea= 调整读取命中百分比的大小。默认为 1m。
  • openflags= 用于打开一个 lun 或一个文件的 flag_list。

WD:工作负载定义

  • wd= 标识工作负载的名称。
  • sd= 要使用的存储定义的 ID。
  • host= 要运行此工作负载的主机的 ID。默认设置为 localhost。
  • rdpct= 读取请求占请求总数的百分比。
  • rhpct= 读取命中百分比。默认设置为 0。
  • whpct= 写入命中百分比。默认设置为 0。
  • xfersize= 要传输的数据大小。默认设置为 4k。
  • seekpct= 随机寻道的百分比。可为随机值。
  • openflags= 用于打开一个 lun 或一个文件的 flag_list。
  • iorate= 此工作负载的固定 I/O 速率。

RD:运行定义

  • rd= 标识运行的名称。
  • wd= 用于此运行的工作负载的 ID。
  • iorate= (#,#,...) 一个或多个 I/O 速率。
  • curve:性能曲线(待定义)。
  • max:不受控制的工作负载。
  • elapsed= time:以秒为单位的运行持续时间。默认设置为 30。
  • warmup= time:加热期,最终会被忽略。
  • distribution= I/O 请求的分布:指数、统一或确定性。
  • pause= 在下一次运行之前休眠的时间,以秒为单位。
  • openflags= 用于打开一个 lun 或一个文件的 flag_list。

对于一个文件系统

对于一个文件系统,配置以下参数:

HD:主机定义。与虚拟块设备相同。

FSD:文件系统定义

  • fsd= 标识文件系统定义的名称
  • anchor= 将在其中创建目录结构的目录
  • width= 要在定位符下创建的目录数
  • depth= 要在定位符下创建的级别数
  • files= 要在最低级别创建的文件数
  • sizes= (size,size,...) 将创建的文件大小
  • distribution= bottom(如果希望仅在最低级别创建文件)和 all(如果希望在所有目录中创建文件)
  • openflags= 用于打开一个文件系统 (Solaris) 的 flag_list

FWD:文件系统工作负载定义

  • fwd= 标识文件系统工作负载定义的名称。
  • fsd= 要使用的文件系统定义的 ID。
  • host= 要用于此工作负载的主机的 ID。
  • fileio= random 或 sequential,表示文件 I/O 将执行的方式。
  • fileselect= random 或 sequential,标识选择文件或目录的方式。
  • xfersizes= 数据传输(读取和写入操作)处理的数据大小。
  • operation= mkdir、rmdir、create、delete、open、close、read、write、getattr 和 setattr。选择要执行的单个文件操作。
  • rdpct= (仅)读取和写入操作的百分比。
  • threads= 此工作负载的并发线程数量。每个线程需要至少 1 个文件。

RD:运行定义

  • fwd= 要使用的文件系统工作负载定义的 ID。
  • fwdrate= 每秒执行的文件系统操作数量。
  • format= yes / no / only / restart / clean / directories。在开始运行之前要执行的操作。
  • operations= 覆盖 fwd 操作。选项相同。

运行之后的输出文件夹文件

每次运行后,vdbench 会创建一个包含以下文件的输出文件夹:

errorlog.html
当为测试启用了数据验证时,它可包含一些数据块中的错误的相关信息:
  • 无效的密钥读取
  • 无效的 lba 读取(一个扇区的逻辑字节地址)
  • 无效的 SD 或 FSD 名称读取
  • 数据损坏,即使在使用错误的 lba 或密钥时
  • 数据损坏
  • 坏扇区
flatfile.html
包含 vdbench 生成的一种逐列的 ASCII 格式的信息。
histogram.html
一种包含报告柱状图的响应时间、文本格式的文件。
logfile.html
包含 Java 代码写入控制台窗口的每行信息的副本。logfile.html 主要用于调试用途
parmfile.html
显示已包含用于测试的每项内容的最终结果
resourceN-M.html、resourceN.html、resourceN.var_adm_msgs.html
  • 摘要报告
  • stdout/stderr 报告
  • 主机 N 的摘要报告
  • 最后 “nn” 行文件 /var/adm/messages 和 /var/adm/messages。每个 M 个 JVM/Slave 的目标主机 N 和主机 N 上为 0。
sdN.histogram.html、sdN.html
每个 N 存储定义的柱状图和存储定义 “N” 报告。
summary.html
主要报告文件,显示为在每个报告间隔的每次运行生成的总工作负载,以及除第一个间隔外的所有间隔的加权平均值。
  • interval:报告间隔序号
  • I/O rate:每秒观察到的平均 I/O 速率
  • MB sec:传输的数据的平均 MB 数
  • bytes I/O:平均数据传输大小
  • read pct:平均读取百分比
  • resp time:以读/写请求持续时间度量的平均响应时间。所有 vdbench 时间都以毫秒为单位。
  • resp max:在此间隔中观察到的最大响应时间。最后一行包含最大值总数。
  • resp stddev:响应时间的标准偏差
  • cpu% sys+usr:处理器繁忙 = 100(系统 + 用户时间)(Solaris、Windows、Linux)
  • cpu% sys:处理器利用率:系统时间
swat_mon.txt,swat_mon_total.txt
  • vdbench 与 Sun StorageTekTM Workload Analysis Tool (Swat) Trace Facility (STF) 相结合,支持您重放使用 Swat 创建的一个轨迹的 I/O 工作负载。
  • Swat 使用 Create Replay File 选项创建和处理的轨迹文件会创建文件 flatfile.bin(flatfile.bin.gz 用于 vdbench403 和更高版本),其中包含 Swat 所识别的每个 I/O 操作的一条记录。
  • 这些文件包含一个格式化的报告,可将该报告导入 Swat Performance Monitor (SPM) 中来创建性能图表。

基准测试和结果

我们运行了 3 个不同的测试。

测试 1

在第一个测试中,使用一个 parmfile 定义对单个原始磁盘的单次运行测试。

名为 sd1 的存储指向大小为 4MB 的设备 /dev/rdsk/c0t0d0s0

定义了工作负载 wd1 来在存储 sd1 上运行,其中读取操作占 100%,每个操作涉及到一个 4KB 数据块。

定义了运行,以 100 个操作/秒的速度使用工作负载 wd1 10 秒。

清单 5. 定义了对单个原始磁盘的一次运行测试的 Parmfile
*SD: Storage Definition
*WD: Workload Definition
*RD: Run Definition
*
sd=sd1,lun=/dev/rdsk/c0t0d0s0,size=4m
wd=wd1,sd=sd1,xfersize=4096,readpct=100
rd=run1,wd=wd1,iorate=100,elapsed=10,interval=1
*Single raw disk, 100% random read of 4KB blocks at I/O rate of 100 for 10 seconds

测试 2

在此测试期间,parmfile 定义了对一个文件系统和对远程主机 129.35.213.249 的一次测试。HD 包含安装在远程主机上的 vdbench 的完整路径,以及用于通信的 shell(ssh 或 own rsh)。

在本例中,vdbench 表示 rshUser=root 是拥有远程主机上的进程的用户。文件系统的定义支持创建一个包含 3 个级别的结构,每个级别包含两个目录和两个文件(借助于选项 distribution=all)。工作负载包含 80% 的读取操作(20% 的写入操作)、一个随机文件选择操作和随机文件 I/O。操作涉及到 4KB 的数据块。

该运行以最大速率使用此工作负载 600 秒,每秒抽样一次并在启动时格式化文件系统。

清单 6. 定义对一个文件系统和一个远程主机的一次测试的 Parmfile
hd=resource1,system=129.35.213.249,vdbench=/var/www/html/vdbench,shell=vdbench,user=root
fsd=fsd1,anchor=/fs,width=2,depth=3,files=2,distribution=all,
 size=4m,openflags=(o_dsync,o_rsync)
fwd=fwd1,fsd=fsd1,host=resource1,xfersize=4096,operation=read,rdpct=80,
 fileselect=random,fileio=random,threads=1
rd=run1,fwd=fwd1,fwdrate=max,format=yes,elapsed=600,interval=3

测试 3

在此测试中,parmfile 定义一个要在其中执行测试的 SmartCloud 主机。存储是一个临时创建的 1GB 大的虚拟块设备,称为 disk1.raw。

所有设置都以再现最坏的情形(没有任何命中区域)为导向,以加快响应速度,使用 open-flags 来打开文件或设备以避免使用缓冲区缓存 (o_direct)。

工作负载定义强化了同时避免读取和写入命中 (rhpct=0whpct=0) 的概念,随机寻道百分比为 100%。该测试执行 11 次,每次按照一条定义的曲线执行 1500 秒。第一次运行尝试发现最大的 i/o 速率。其他运行将 I/O 速率增加 10%,一直从 10 增加到 100。每次运行生成一个具有指数分布的工作负载。

清单 7. 定义要在其上执行测试的 SmartCloud 主机的 Parmfile
hd=resource1,system=129.35.209.189,vdbench=/var/www/html/vdbench503,
 shell=vdbench,user=root
sd=sd1,lun=/home/idcuser/disk1.raw,hitarea=0m,offset=32256, openflags=o_direct 
wd=wd1,sd=sd1,host=resource1,xfersize=4096,rdpct=40,rhpct=0,whpct=0, seekpct=100
rd=run1,wd=wd1,iorate=curve,curve=(10-100,10),format=yes,elapsed=1500,
 warmup=18,distribution=exponential,pause=60,interval=6,threads=1

基准测试分析中使用的 VM 包括:

  • 1 个客户端 VM Red Hat Enterprise Linux 6.1 Silver 32_bit(2 个 vCPU,RAM:4GB,磁盘:410 GB)
  • 1 个资源 VM Red Hat Enterprise Linux 6.1 Copper 32_bit(1 个 vCPU,RAM:2GB,磁盘:60GB)
图 4. 基准测试分析中的 VM
基准测试分析中的 VM
基准测试分析中的 VM

结果

图 5 显示了启用了缓存后(没有 o_direct 标志)读取操作(绿色)的响应时间和写入操作(黄色)的响应时间。很明显,读取非常稳定,而写入逐渐饱和,接近初始的 “不受控曲线” 运行的平均值的 60%。启用缓存后,第一次运行 ("unc") 偏向于对数据块的第一次访问,所以它无法代表后续运行的真实性能。

图 5. 响应时间
响应时间
响应时间

图 6 显示了相同的情形,但没有启用缓冲区缓存。响应时间的趋势是规则的,因为性能更多地受磁盘真实的底层利用率影响。在任何事件中都可以明显地看到,启用了缓存的情形的度量值的数量级更高。所以,启用缓存后的结果更好、更稳定。

图 6. 未启用缓冲区缓存的结果
未启用缓冲区缓存的结果
未启用缓冲区缓存的结果

图 7 显示了所有 I/O 操作的平均速率 (MB/秒)。已启用了缓存。可以看到趋势是线性的,而且非常规则。一定要注意,该图表给出了每次运行的均值,这源自第一次不受控的运行的均值。有一些值高于 7MB/秒,有时接近 60MB/秒,其中 60% 为写入操作;此结果非常好。

图 7. 所有 I/O 操作的平均速率(MB/秒)
所有 I/O 操作的平均速率(MB/秒)
所有 I/O 操作的平均速率(MB/秒)

图 8 显示了相同的情形,但禁用了缓存缓冲区。与前一个图表中一样,趋势不是规则的。可以看到运行 80% 和 90% 的性能有所下降。您可能会想,同一个云节点上有另一个 VM 也在使用该磁盘。最后,可以看到速率的度量数量级比启用缓存时低得多。

图 8. 禁用缓存缓冲区时的结果
禁用缓存缓冲区时的结果
禁用缓存缓冲区时的结果

问题和学到的教训

测试带来了哪些问题?我们学到了什么?

问题

缓存是 I/O 基准测试中的一个关键方面。缓存是一个非常难以处理的变量,因为它依赖于许多因素。缓存影响着读取/写入性能,但只有在多次访问单个数据块或在启用了延迟写入时。

有时您可能对存储设备的真实和机械性能感兴趣,测试使用它的最糟情形。为此,每个操作系统都允许使用不同规则打开一个文件。

借助 O_DIRECT,对于用户空间缓冲区传递给读取/写入系统调用[一个]参数来调用的物理内存,内核会直接从/向它执行 DMA。所以用户空间内存与内核缓存之间的复制不会花费 CPU 和内存带宽(比如缓存查找、每页锁定等)。

这无疑适用于一种经典的基础架构,如图 9 所示。

图 9. 一种经典的基础架构
一种经典的基础架构
一种经典的基础架构

如图 10 所示,使用 SmartCloud 创建的虚拟化基础架构上会发生什么?

图 10. 一种虚拟化的基础架构
一种虚拟化的基础架构
一种虚拟化的基础架构

学到的教训

在这些测试期间,我们认识到,禁用缓存支持在几乎所有情形中都不是一种好的选择。禁用缓存只能用于基准测试用途。

在我们的研究中,我们的想法是发现一个虚拟化的共享云基础架构的行为:如果启用了缓存,性能可能类似于一种专用的私有虚拟基础架构。

在云环境中,其他客户端的使用会影响到许多无法预测的变量;这一般会影响 I/O 性能。

在一个没有启用缓存的选项的共享架构中,这些负面影响被放大,所以推断预期的响应时间或 I/O 速率变得非常难。为虚拟机保留的缓存内存越多,性能就会越好和越稳定。

结束语

从我们的初步假设和结果开始,放大基准测试并在单个资源站 VM 上执行多 I/O 类测试将会非常有趣。这种扩展可使用 vdbench 完成。

扩展基准测试以包含不同的测试会话,对比 SmartCloud 提供的三种不同存储类型,这会很有趣;在执行此操作的过程中,我们可为 SmartCloud 用户创建一个指南。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Cloud computing
ArticleID=948179
ArticleTitle=使用 vdbench 评估短暂存储 I/O 性能
publish-date=10142013