在云主机上部署数据库或日志系统时,存储性能往往比CPU和内存更容易被忽视。Linode Block Storage作为Akamai旗下的一项持久化块存储服务,支持独立扩容和快照,适合需要额外数据盘的应用。本文使用fio工具对1GB、10GB和100GB三种规格的卷进行测试,覆盖随机读写、顺序读写和延迟维度,结果能帮助判断它是否适合MySQL、PostgreSQL或Kafka等有持续写入压力的场景。

测试环境与性能基线
测试在Linode Dedicated 8GB实例上执行,实例位于美国东部机房,操作系统为Ubuntu 22.04 LTS,内核版本5.15.0。Block Storage卷通过virtio-scsi接口挂载,使用ext4文件系统并关闭日志的data=ordered默认选项。每个卷在执行测试前都执行了trim和预热,避免冷数据导致首次读取异常。需要注意的是,Block Storage的网络路径比本地NVMe多一层,因此延迟和抖动会略高。
fio的版本为3.28,测试参数使用direct=1绕过页缓存,ioengine采用libaio,队列深度从1逐步提升到32,块大小覆盖4K、8K、32K、128K和1M。测试持续时间设置为180秒,并包含30秒预热。以下命令展示了一个典型的随机写测试配置:
fio --name=randwrite --filename=/mnt/block/testfile --size=5G \ --rw=randwrite --bs=4k --iodepth=16 --numjobs=4 \ --time_based --runtime=180 --direct=1 --ioengine=libaio \ --group_reporting
在基线测试中,空卷的初始性能会略高,但持续写入几分钟后,分布式存储层的元数据操作和垃圾回收会带来性能回落。因此所有数据均取运行最后60秒的平均值,避免短暂突发干扰结论。100GB卷由于底层数据分片更多,通常能获得比1GB卷更稳定的IOPS。
随机读写与IOPS表现
随机读写是数据库最关键的性能指标。PostgreSQL的WAL写入、InnoDB的脏页刷盘、以及Elasticsearch的段合并都依赖大量的4K随机写。测试显示,在队列深度为16、4K随机写场景下,1GB卷的IOPS约为1800,10GB卷约为2400,100GB卷约为2900。随着队列深度继续上升到32,100GB卷的IOPS可以接近3500,但延迟也会从8ms左右上升到20ms以上。
随机读的性能明显好于随机写,因为读请求不需要等待分布式副本确认。4K随机读在相同队列深度下,100GB卷可以稳定在11000 IOPS左右,而1GB卷只有约5800 IOPS。这种差异来自卷的容量付费策略,Linode会对小容量卷施加更严格的限流,防止少量用户占用过多底层资源。另一个值得注意的现象是写放大:使用默认的ext4日志模式时,随机写会在日志区产生额外的顺序流量,建议通过tune2fs关闭日志或改用XFS的延迟分配来减少抖动。
以下命令用于测量4K随机读的峰值IOPS,测试中特意加入了randrepeat=0避免压缩缓存干扰:
fio --name=randread --filename=/mnt/block/testfile --size=10G \ --rw=randread --bs=4k --iodepth=32 --numjobs=8 \ --time_based --runtime=120 --direct=1 --ioengine=libaio \ --randrepeat=0 --group_reporting
从结果看,如果你只是运行一个网站或小型CRM,Block Storage的随机性能足够;但如果用于高并发OLTP,建议把数据目录放在本地NVMe,而将备份和归档放到Block Storage。
顺序读写与吞吐量瓶颈
顺序读写性能决定了日志采集、大数据导入和视频转码等场景的效率。使用128K块大小和队列深度32时,100GB卷的顺序写吞吐量可以达到约190MB/s,顺序读吞吐量约为260MB/s。这个数值接近Linode单块Block Storage的网络带宽上限,实际吞吐量还会受到实例的上行链路和同宿主机邻居负载影响。
10GB卷的顺序写吞吐量约为160MB/s,1GB卷则只有90MB/s左右。这种阶梯式限制反映了云厂商对卷规格的差异化QoS。如果你的应用需要快速加载数十GB的模型文件或数据集,顺序读性能尚可接受,但写入速度可能会成为瓶颈。测试中还发现,当卷使用率超过80%时,顺序写的性能会下降约15%到20%,因为分布式存储需要更多时间寻找可用块。
以下命令用来测试顺序读吞吐量,适合验证大文件的持续读取能力:
fio --name=seqread --filename=/mnt/block/testfile --size=20G \ --rw=read --bs=128k --iodepth=32 --numjobs=1 \ --time_based --runtime=90 --direct=1 --ioengine=libaio \ --group_reporting
值得注意的是,如果实例和Block Storage不在同一个数据中心区域,延迟会急剧增加。因此创建卷时必须选择与实例相同的数据中心,否则性能可能下降数倍。
延迟与生产负载适用性
延迟是衡量存储响应速度的核心指标,尤其是99百分位和99.9百分位延迟决定了用户体验的稳定性。在4K随机读测试中,100GB卷在队列深度1时的平均延迟为0.6ms,99百分位延迟约为2.1ms;当队列深度升到32时,平均延迟为4.5ms,99百分位延迟达到18ms。随机写的延迟显著更高,队列深度1时平均1.8ms,99百分位8ms,队列深度32时99百分位超过45ms。
这些数字说明Block Storage不适合延迟敏感型工作负载,例如高频交易的撮合引擎或内存数据库的同步刷盘。但对于WordPress、GitLab、Nextcloud这类请求间隔较长的应用,20ms以下的读延迟完全在可接受范围。Kafka和RabbitMQ如果开启合理的批处理,也能通过合并写入降低延迟的影响。生产实践中,可以为Block Storage设置deadline或none调度器,并调整内核的nr_requests和max_sectors_kb来减少请求队列堆积。
对于需要更大容量的场景,可以借助Linode的卷扩容功能在线增加容量,扩容后文件系统会自动扩展。快照则提供了崩溃一致性保护,但频繁快照会占用元数据带宽,建议在低峰期执行。综合来看,Block Storage更适合作为持久层和备份盘,而不是高性能计算的主存储。
最后总结:Linode Block Storage在100GB规格下能提供约2900随机写IOPS和260MB/s顺序读吞吐量,满足中小型应用的需要。你在规划架构时,应优先评估自身负载的读写比例和延迟容忍度,必要时混合使用本地NVMe与Block Storage来兼顾性价比。

