不合格的程序猿
分类: 服务器与存储
2016-07-20 15:25:51
为了理解 SmartCloud 环境中的短暂存储性能,我们使用 vdbench 设置了一项基准测试。vdbench 是一个 I/O 工作负载生成器,用于验证数据完整性和度量直接附加和网络连接的存储的性能。它是一个免费的工具,容易使用,而且常常用于测试和基准测试。
我们得出的结论是,缓存是 I/O 基准测试中的一个重要元素。本文介绍我们设置基准测试的步骤并展示结果。但是首先我们会简要介绍我们使用的以下产品和工具。
首先从 SmartCloud 开始,这是一个以基于内核的虚拟机 (KVM) 为基础构建的公共云服务,是 x86 架构上的 Linux? 的一个全面的虚拟化解决方案。SmartCloud 是一个完整的基础架构即服务 (IaaS) 产品。可将它用作构建平台即服务 (PaaS) 和软件即服务 (SaaS) 解决方案的基础。
SmartCloud 的关键特性包括:
SmartCloud 提供了 3 种类型的存储:
在我们的基准测试中,我们将重点看看短暂存储。
我们使用 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 分离,因为它是一个网络附加存储 (NAS) 原始磁盘,必须从来宾内格式化和装载,如下所示。
图 2. 通过网络附加的 VM 实现持久存储在我们的基准测试中,我们通过使用 Red Hat Linux 配置一个 VM 来创建短暂存储。它类似于下图:
图 3. 使用 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/
以下代码分配一个 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。
[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
[idcuser&vhost4377 ~]$ sudo –s | cd [root&vhost4377 ~]# wget [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
[root&vhost4377 vdbench502]# ./vdbench -t
要更详细地控制工具参数,编写一个 parmfile,您可在其中指定不同的选项。
对于一个虚拟块设备
对于一个虚拟块设备,配置以下参数:
HD:主机定义
SD:存储定义
WD:工作负载定义
RD:运行定义
对于一个文件系统
对于一个文件系统,配置以下参数:
HD:主机定义。与虚拟块设备相同。
FSD:文件系统定义
FWD:文件系统工作负载定义
RD:运行定义
运行之后的输出文件夹文件
每次运行后,vdbench 会创建一个包含以下文件的输出文件夹:
errorlog.html 当为测试启用了数据验证时,它可包含一些数据块中的错误的相关信息:我们运行了 3 个不同的测试。
在第一个测试中,使用一个 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
在此测试期间,parmfile 定义了对一个文件系统和对远程主机 129.35.213.249 的一次测试。HD 包含安装在远程主机上的 vdbench 的完整路径,以及用于通信的 shell(ssh 或 own rsh)。
在本例中,vdbench 表示 rsh。User=root 是拥有远程主机上的进程的用户。文件系统的定义支持创建一个包含 3 个级别的结构,每个级别包含两个目录和两个文件(借助于选项 distribution=all)。工作负载包含 80% 的读取操作(20% 的写入操作)、一个随机文件选择操作和随机文件 I/O。操作涉及到 4KB 的数据块。
该运行以最大速率使用此工作负载 600 秒,每秒抽样一次并在启动时格式化文件系统。
清单 6. 定义对一个文件系统和一个远程主机的一次测试的 Parmfilehd=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
在此测试中,parmfile 定义一个要在其中执行测试的 SmartCloud 主机。存储是一个临时创建的 1GB 大的虚拟块设备,称为 disk1.raw。
所有设置都以再现最坏的情形(没有任何命中区域)为导向,以加快响应速度,使用 open-flags 来打开文件或设备以避免使用缓冲区缓存 (o_direct)。
工作负载定义强化了同时避免读取和写入命中 (rhpct=0whpct=0) 的概念,随机寻道百分比为 100%。该测试执行 11 次,每次按照一条定义的曲线执行 1500 秒。第一次运行尝试发现最大的 i/o 速率。其他运行将 I/O 速率增加 10%,一直从 10 增加到 100。每次运行生成一个具有指数分布的工作负载。
清单 7. 定义要在其上执行测试的 SmartCloud 主机的 Parmfilehd=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 包括:
图 5 显示了启用了缓存后(没有 o_direct 标志)读取操作(绿色)的响应时间和写入操作(黄色)的响应时间。很明显,读取非常稳定,而写入逐渐饱和,接近初始的 “不受控曲线” 运行的平均值的 60%。启用缓存后,第一次运行 ("unc") 偏向于对数据块的第一次访问,所以它无法代表后续运行的真实性能。
图 5. 响应时间图 6 显示了相同的情形,但没有启用缓冲区缓存。响应时间的趋势是规则的,因为性能更多地受磁盘真实的底层利用率影响。在任何事件中都可以明显地看到,启用了缓存的情形的度量值的数量级更高。所以,启用缓存后的结果更好、更稳定。
图 6. 未启用缓冲区缓存的结果图 7 显示了所有 I/O 操作的平均速率 (MB/秒)。已启用了缓存。可以看到趋势是线性的,而且非常规则。一定要注意,该图表给出了每次运行的均值,这源自第一次不受控的运行的均值。有一些值高于 7MB/秒,有时接近 60MB/秒,其中 60% 为写入操作;此结果非常好。
图 7. 所有 I/O 操作的平均速率(MB/秒)图 8 显示了相同的情形,但禁用了缓存缓冲区。与前一个图表中一样,趋势不是规则的。可以看到运行 80% 和 90% 的性能有所下降。您可能会想,同一个云节点上有另一个 VM 也在使用该磁盘。最后,可以看到速率的度量数量级比启用缓存时低得多。
图 8. 禁用缓存缓冲区时的结果测试带来了哪些问题?我们学到了什么?
缓存是 I/O 基准测试中的一个关键方面。缓存是一个非常难以处理的变量,因为它依赖于许多因素。缓存影响着读取/写入性能,但只有在多次访问单个数据块或在启用了延迟写入时。
有时您可能对存储设备的真实和机械性能感兴趣,测试使用它的最糟情形。为此,每个操作系统都允许使用不同规则打开一个文件。
借助 O_DIRECT,对于用户空间缓冲区传递给读取/写入系统调用[一个]参数来调用的物理内存,内核会直接从/向它执行 DMA。所以用户空间内存与内核缓存之间的复制不会花费 CPU 和内存带宽(比如缓存查找、每页锁定等)。
这无疑适用于一种经典的基础架构,如图 9 所示。
图 9. 一种经典的基础架构如图 10 所示,使用 SmartCloud 创建的虚拟化基础架构上会发生什么?
图 10. 一种虚拟化的基础架构在这些测试期间,我们认识到,禁用缓存支持在几乎所有情形中都不是一种好的选择。禁用缓存只能用于基准测试用途。
在我们的研究中,我们的想法是发现一个虚拟化的共享云基础架构的行为:如果启用了缓存,性能可能类似于一种专用的私有虚拟基础架构。
在云环境中,其他客户端的使用会影响到许多无法预测的变量;这一般会影响 I/O 性能。
在一个没有启用缓存的选项的共享架构中,这些负面影响被放大,所以推断预期的响应时间或 I/O 速率变得非常难。为虚拟机保留的缓存内存越多,性能就会越好和越稳定。