原文:https://mp.weixin.qq.com/s/iSE2ixzorhe-CZXW_Potkg
在过去的几十年,随着计算,网络和存储领域的技术创新以及业务类型的多样化,数据中心经历了从大型主机,到X86服务器,从虚拟化技术到一切皆服务的云计算的漫长演进历程。
存储技术为满足层出不穷应用的海量数据存储需求,从物理介质到技术架构也同样发生了天翻地覆的变革。无论技术如何更新换代,其目的都是为了更好的提供高性能,高容量,高可用的数据服务。而高性能尤其是IT决策过程中一个重要因素,一套好的解决方案可以既节约钱又可以节省时间。本文会对存储系统的性能,以及如何测试存储系统的性能做详细介绍。
什么是存储性能?简单的说,就是指单个或一套存储系统表现有多好有多快。0-100公里加速时间,最高速度,最大功率,最大扭矩等等指标通常被用来衡量一辆车的性能好坏:扭矩越大加速越快,功率越大速度越高。存储系统也有类似的度量性能的指标和方法,下面先来理解几个概念:
一个I/O就是单个读/写请求。I/O的目标可以是一块硬盘或SSD,也可以是SAN存储系统,也可以是文件系统中的某个文件。从应用到操作系统,从网络到存储系统,从内存到物理硬盘,I/O在不同的上下文有着不同的解读。
I/O请求的大小
通常用百分比表示一个设备用来服务请求的时间占比。
指真正处理一个请求所需要花费的时间。
指一个请求排队等候处理所花费的时间。设备利用率较低排队请求少则等待时间短,反之则等待时间长。
延时指从发起I/O请求到收到响应需要花费的时间,包含服务时间和等待时间。多数情况下延时是反应存储系统性能最关键的单一指标。
IOPS(I/O Operations Per Second)代表每秒的I/O请求,它是存储世界里最典型的一个性能指标,用来表示单位时间内有多少I/O请求可以被处理。IOPS通常需要和延时作为一个整体来看:相同延时情况下IOPS越高则存储系统处理能力越强,如果单纯达到高IOPS但时延也高,则并不能说明存储系统的性能更好。
IOPS乘以I/O大小就可以算出吞吐,用来表示每秒发起请求的数据量。比如I/O大小为4KB,IOPS为100K,得出的吞吐是400MB/s。
了解了这几个概念后,我们知道可以通过延时衡量一个存储系统响应快慢与否,通过IOPS和吞吐了解每秒处理能力强弱。
不同的业务模型(workload)对存储系统的性能影响巨大,是非常重要的性能考量因素。
请求的I/O大小对吞吐有直接的影响。总体来说,大I/O会给带来更高的吞吐,也会导致需要更多的时间传输和处理,但同时也减少了额外开销(overhead);小I/O会产生更高的IOPS,时延更低。大多数真实的应用的I/O大小是混合的:
典型文件系统或Oracle:8KB
备份软件:64KB
流媒体:256K
现实中大多数的应用访问模型都是读写混合的,真正的纯读或纯写很少。通常读消耗更少的系统资源,性能表现更好:
顺序存取(sequential access)取指大量顺序的I/O请求连续相邻的数据块,现代存储会通过模型识别进行预读来提升读性能。典型的业务有备份恢复,日志,视频点播等。
随机存取(random access)指I/O请求随机的分布在存储介质的各个区域,比如高并发读写大量小文件,会导致IOPS和吞吐的性能下降。典型的业务有OLTP,Home directories,MS Exchange等。
就单个线程而言,顺序I/O比随机I/O更快。增加并发的顺序I/O的线程数量会导致存储系统需要同时从不同的位置查找,读写,尽管每个线程都是顺序I/O,但整个存储系统看起来在做随机I/O。适度的线程数量可以实现并发达到较优的延时,而过度并发会消耗更多的系统资源,造成排队和繁忙。
通过直接 I/O 方式进行数据传输,数据均直接在用户地址空间的缓冲区和磁盘之间直接进行传输,中间少了页缓存的支持。
而Buffer I/O为了提高读写效率和保护磁盘,使用了页缓存机制,不过由于页缓存处于内核空间,不能被应用程序(用户进程)直接寻址,所以还需要将页缓存数据再拷贝到内存对应的用户空间中。这样,需要两次数据拷贝才能完成用户进程对数据的读取操作。写操作也是一样,将页缓存的数据写入磁盘的时候,必须先拷贝到内核空间对应的主存,然后在写入磁盘中。
图1 Direct I/O vs Buffered I/O
下面例举几个典型应用的I/O模型:
应用类型 | IO大小 | 读写比例 | 随机与顺序读写比例 |
---|---|---|---|
OLTP-Data | 8KB | 70%读/30%写 | 100%随机 |
OLTP-Log | 512B - 64KB | 100%写 | 100%顺序 |
OLAP-TMP | 256KB | 50%读/50%写 | 100%随机 |
VDI | 512B-16KB | 20%读/80%写 | 100%顺序 |
Media Streaming | 64KB | 98%读/2%写 | 100%顺序 |
Web File Server | 4KB、8KB、64KB | 95%读/5%写 | 75%随机/25%顺序 |
Web Server Log | 8KB | 100% Write | 100%顺序 |
OS Paging | 64KB | 90%读/10%写 | 100%顺序 |
Exchange Server | 4KB | 67%读/33%写 | 100%随机 |
Workstation | 8KB | 80%读/20%写 | 80%随机/20%顺序 |
机械硬盘(hard disk)因为物理结构的局限磁头寻道,磁盘有转速以及延时,导致顺序存取比随机存取性能更好。
在顺序读写时不需要频繁的移动磁头,从而减少了寻道开销可以把时间花在读写实际数据上;顺序读写则把本该用来读写实际数据的时间浪费在不停的寻道,等待上。所以使用机械硬盘的传统存储系统通过复杂算法,缓存技术进行优化尽量减少随机存取带来的性能损耗。
图2 机械硬盘
固态硬盘(SSD)物理上基于闪存颗粒没有了磁盘和磁头,从而避免了旋转和移动带来的时间浪费,可以更快的响应I/O请求,提供更低的延时。但SSD只能写入被擦除的页,写入命令会在写入闪存之前调用闪存擦除周期,导致写比读慢。而写入/擦除循环会导致单元磨损,从而带来有限的写入寿命。固态硬盘会通过损耗均衡算法确保损耗均匀延长使用寿命,而后台的垃圾回收会消耗系统资源对前台操作造成负面影响。因此,全闪存存储系统设计时会扬长避短:既能发挥介质革新带来的性能提升,又能减少它带来的劣势。
图3 固态硬盘
图4 非全新写入流程和垃圾回收流程
I/O从应用程序发起,经由操作系统,网卡,网络/交换路由设备,到达存储系统,再由存储系统的I/O调用栈处理后最终到达磁盘。这套复杂系统的性能取决于整个环节中最慢的组件,只有平衡各组件的性能才能优化并挖掘整套系统性能的全部潜力。
存储厂商通常会通过以下几方面升级优化提升性能,因此在考量存储系统性能时需要充分考虑业务模型的差异,存储介质的差异以及影响性能的各种因素,才能在贴近真实的场景下用正确的方法测试存储系统的性能:
企业级存储价格昂贵,实现复杂,通常没有现成的性能对比数据辅助IT决策。怎么办?最有效的方法是定制化实施适合自己的性能测试。在了解了不同业务模型对性能的差异、存储系统的度量指标以及影响存储系统性能的相关因素之后,进行存储系统的性能测试其实并不难。
首先我们需要明确测试目标,需要得到哪个维度的存储性能:IOPS,吞吐量,延时还是混合指标?不同的测试目标需要权衡使用不同的业务模型来达成:
所以,我们测试吞吐需要使用大数据块,配合深队列顺序读写;测试延时需要使用小数据块单队列。不同的测试目标下权衡不同的参数,才能搜集正确的性能指标。
此外,虽然IOPS,吞吐,延时这三个指标最有代表性,但现实世界里的业务模型通常是混合的,而且存储设备的网络拓扑和背景负载也不一样,因此进行性能测试需要考虑充分并尽量做到apple-to-apple类比:服务器的规格配置,网络拓扑及延时,闪存的类型,操作系统的类型及版本,I/O工具的类型及版本等等。
工具选择
测试块设备
测试磁盘的工具往往就是调用块设备驱动的接口进行读写测试。可以用来评估块设备性能的I/O工具很多,例如fio, vdbench, IOMeter, dd等等,它们各有特色。这里拿fio为例,通过配置参数 –iodepth, --bs, --rw即可调整队列深度,I/O大小,读写类型,通过指定–write_bw_log,–write_iops_log,–write_lat_log参数并配合-log_avg_msec使用可以按指定时间间隔采集时间点的吞吐,iops和延时数据并输出到指定文件,后期方便观察分析IO稳定性。
块设备之上是文件系统,测试需要针对文件系统层提供的功能进行测试,包括文件的打开关闭速度以及顺序读写随机位置读写的速度,以及进程并发数目等各个方面进行详细的测试等等。常用的测试工具有fio,vdbench,IOZone,sysbench等等。以IOZone为例,它能够产生并测量各种的操作性能,包括read, write, re-read, re-write, read backwards, read strided, fread, fwrite, random read, pread ,mmap, aio_read, aio_write等操作。Iozone目前已经被移植到各种体系结构计算机和操作系统上,广泛用于文件系统性能测试、分析与评估的标准工具。使用IOZone 可以在多线程,多CPU,并指定CPU Cache 空间大小以及同步或者异步IO读写模式的情况下进行文件操作的性能测试。
图5 IOZone
文件系统之上是应用,测试典型的OLTP数据库场景也可以使用不同的工具进行:ORION使用和 Oracle 相同的 I/O 软件集生成一个合成的 I/O 负载,可以在不需要创建和运行Oracle数据的情况下模拟OLTP和数据仓库负载。pgbench是面向PostgreSQL的一个基准测试工具。默认情况下(工具默认提供),pgbench 测试基于TPC-B场景,每个事务包括5个SELECT、UPDATE 和INSERT命令。可以通过编写自己的事务脚本文件按需进行定制化测试;sysbench是一个模块化、跨平台、多线程的性能基准测试工具,支持MySSL,PostgreSQL,Oracle。除此之外它还可以测试CPU,内存,文件系统等等。redis-benchmark是Redis官方自带的Redis性能测试工具。
图6 sysbench内置的OLTP场景
图7 sysbench测试结果
开箱即测得出的结果往往因为资源消耗不多,内部数据未老化导致数据偏好,因此测试之前需要进行初始化:例如预埋足够多的数据,触发SSD预留空间的写分配,触发垃圾回收;使用不可重删压缩的数据顺序写块设备以覆盖SSD更多的物理空间;格式化文件系统/预置足够多的数据库记录等等。
另外,测试时间要足够长,排除噪音并搜集长稳测试的性能数据,反应真实的性能的同时观察IO波动。
测试工具通常会输出格式化的报告,包含I/O相关的性能指标。除此之外,可以视情况收集系统的资源使用情况作为辅助数据进行性能分析:
图8 性能分析
测试结束后,测试工程师搜集测试结果进行汇总并初步分析。尝试分析出现噪音,毛刺的原因并排错;分析数值偏高或偏低的可能原因;与相关产品、开发人员对齐初步结论,必要时重新测试。几轮之后得到可靠的性能数据后,接下来需要提炼测试结论,针对不同的观众输出相应的报告,这里有一些小技巧:
一目了然,尽量可视化,通过对比差异呈现优劣。
调理清晰,主次分明:headlines first!详细数据分析往后放。
覆盖关键指标,并开宗明义用简单直白的文字提炼结论
针对产品经理的报告,尽量站在客户的角度写;针对开发和测试人员,则需要充分考虑并注明背后技术架构、工作环境的差异。
到这里我们已经流程化了一套存储性能测试方法,搜集到一组特定场景下的性能数据作为基线,它不一定具备普适性但却具有良好的参考价值。
接下来,可以通过微调测试环境进行更多场景的性能测试并与基线做对比;也可以通过性能分析工具进一步分析系统中的瓶颈或潜在的问题。
看到这里,相信各位看官已经掌握了影响存储系统性能的因素以及存储性能测试的基本思路和常用工具,在面对天花乱坠的性能宣传时可以结合实际情况订制合适的性能测试方法亲自验证一番。
后续会针对大家感兴趣的话题进一步做专题。
FIO GitHub - axboe/fio: Flexible I/O Tester
vdbench Vdbench Downloads
sysbench GitHub - akopytov/sysbench: Scriptable database and system performance benchmark
IOzone https://www.iozone.org
pgbench PostgreSQL: Documentation: 10: pgbench