SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-10-03

存储型 VPS 不擅长处理哪些任务?

存储型 VPS 虽有数 TB 容量,但机械硬盘通常低于 100 IOPS,且只有 1 到 2 个共享 vCPU。了解随机读写、数据库和持续计算为何变慢,以及如何拆分部署。

存储型 VPS 不擅长处理的任务

存储型 VPS 本质上是大容量磁盘加一台小型计算机。它非常适合对大文件执行顺序处理。但对于每秒需要大量随机磁盘操作,或需要持续占用处理器时间的任务,它的表现很差。这两项限制都直接取决于您购买的套餐。

下面的一切都由两个硬件事实决定。机械硬盘的 IOPS(每秒输入/输出操作数)受机械结构限制,无论容量多大,每块硬盘通常都低于 100。一个或两个共享 vCPU(虚拟处理器核心)足以提供文件服务,但几乎无法承担其他任务。这里提到的所有故障,最终都可以归因于这两个数值,通常是第一个。

了解这些机制的意义在于,您可以据此预测自己的工作负载会产生什么结果,而不必仅根据别人列出的清单逐项核对。

你实际购买的规格形态

截至 2026 年 9 月,德国主机商提供的存储型配置大致相同:1 或 2 个共享 vCPU、几 GB RAM,以及数 TB 的机械硬盘或网络附加卷。Contabo 将其作为 Storage VPS 销售。netcup 则为其 root server 系列附加大容量 HDD 卷。Hetzner 的 Storage Box 更进一步,完全移除了计算机:你会获得 SFTP、基于 SSH 的 rsync、SMB 和 BorgBackup,但没有 shell,也没有 root。购买前请查看当前套餐页面,因为具体配置会变化。

这种形态会带来 4 个限制。

  • 每个磁盘每秒只能完成不到 100 次随机操作。 容量不会改变这一点。20 TB 硬盘的寻道速度与 4 TB 硬盘相同。
  • 处理器配额是 1 或 2 个共享核心。 共享意味着其他租户会与您竞争这些核心,这会体现为 steal time。读取高负载 VPS 上的 steal time 可帮助您判断实际获得了多少处理器资源。
  • RAM 很少,因此内核只能缓存很少的元数据。 您还在遍历目录树时,目录项和 inode 就可能被移出缓存,因此相同的查找又会访问磁盘。
  • 网络附加卷会为每个操作增加延迟。 较深的队列可以隐藏这种延迟。每次写入都要等待的进程无法建立队列。

寻道上限为何比 TB 容量更重要

一块 7200 rpm 的硬盘大约需要等待 4.2 ms,让盘片转到目标位置;这相当于半圈。平均寻道还需要约 9 ms。一次随机读取因此约耗时 13 ms,单个磁盘每秒只能处理不到 100 次随机操作。下面的计算取 80 次。这个数值由硬盘的机械结构决定,因此容量更大的型号不会改善它。

顺序读写可以完全避开这项开销。磁头保持当前位置,盘片持续向其提供数据,因此同一块硬盘的连续传输速度可以轻松超过每秒 100 MB。这就是为什么一台存储 VPS 可以通过读取单个大文件占满网络链路,却在遍历包含许多小文件的目录时变得非常缓慢。差异完全来自磁头移动。有关同一方案吞吐能力的内容,请参阅 存储 VPS 的磁盘速度预期。

网络附加卷会隐藏底层机制,但仍受同样的上限限制。您的请求必须经过网络才能到达存储集群,因此每次操作都要承担这段往返延迟。通过同时发起多个请求,可以分摊这项开销。逐个等待写入确认的单线程进程无法获得这种帮助,而数据库正是以这种方式工作的。本地 NVMe 与网络附加卷之间的差距主要来自延迟,而不是带宽。

为什么存储型 VPS 上的数据库会变慢

每个严谨的数据库只有在数据写入稳定存储后,才会确认写入完成。PostgreSQL 会将更改追加到其 WAL(预写式日志),并调用 fdatasync,然后才通知客户端事务已提交。MySQL 使用 InnoDB 时也是如此。在机械硬盘上,执行同步操作前必须等待盘片转到对应位置,因此每秒可持久化提交数通常只有几十或一两百。这是硬件上限,无法通过修改配置提高。

读取操作同样会受到影响。未命中缓存的索引查找属于随机读取,而 4 GB 内存无法容纳真实数据库的工作集。每次未命中都需要执行一次寻道,因此触及 500 行的查询计划可能耗时数秒。

你会在三个地方看到这一点。iostat -x 1 来自 sysstat 软件包,它会报告 %util 是否长期接近 100,以及 w_await 是否达到几十或几百毫秒,而每秒 MB 数仍然很低。PostgreSQL 会记录 checkpoints are occurring too frequently。应用超时会成批出现,而不是均匀发生,因为检查点会刷新脏页,所有提交都必须排队等待刷新完成。

不要争论,直接测量。pg_test_fsync 随 PostgreSQL 服务器软件包一起提供,在 Debian 和 Ubuntu 上位于 /usr/lib/postgresql/16/bin/;Ubuntu 24.04 安装的版本是 16。它会报告平台支持的每种同步方法的每秒操作数,其中最高值就是你的提交上限。

sudo apt update && sudo apt install -y postgresql
/usr/lib/postgresql/16/bin/pg_test_fsync

任何小型服务器都值得配置连接池;在小型 VPS 上在 Postgres 前部署 pgbouncer可以节省实际内存,但不会增加 IOPS。如果工作负载包含写入操作,应将数据库部署在 NVMe 服务器上,这里只存放其转储文件。

为什么媒体库转码会卡住

转码会先解码视频,再重新编码。这属于处理器计算,过程中磁盘几乎处于空闲状态。在两个共享 CPU 核心上使用软件 x264 时,单路 1080p 转码的速度会低于实时播放速度。ffmpeg 会在进度行中输出 speed= 字段,低于 speed=1x 就表示编码器跟不上播放器。Jellyfin 和 Plex 会向观看者显示为缓冲。

硬件编码通常是解决办法,但这里通常无法使用。Intel Quick Sync 和 VAAPI(视频加速 API)都需要将 GPU 设备传递给虚拟机,而共享存储方案不会提供 GPU。规划方案前先运行 ls -l /dev/dri。目录不存在或为空表示使用软件编码,因此 CPU 核心数就是性能上限。

首次扫描媒体库也可能出乎意料。扫描过程会读取每个文件以提取元数据,并为每个项目写入缩略图,因此会同时产生处理器负载和大量小文件写入,而这台服务器恰好不擅长这两项操作。直接播放则相反:它只需顺序读取一个大文件,而这正是此类硬件擅长的工作。存储 VPS 上哪些媒体服务器任务确实可行对此有更详细的说明。

为什么构建和软件包安装不适合在这里执行

编译属于处理器密集型工作,同时伴随元数据密集型磁盘访问。C++ 构建会读取数千个头文件,并写入数千个目标文件。npm install 会将数十万个小文件解压到 node_modules。Docker 构建会提取各个层,访问模式相同。每个文件都会产生元数据操作;在小内存服务器上,构建仍需使用目录项时,它们可能已经被逐出缓存。

通常首先触发的是内存限制。在没有 swap 的 4 GB 方案上,一个大型编译单元就可能使服务器超出限制,dmesg 会记录结果:

Out of memory: Killed process 2231 (cc1plus) total-vm:2138744kB, anon-rss:1904512kB

随后构建会因编译器驱动程序报告的一个难以判断的错误而停止,因为子进程已被终止,父进程只能知道它已经消失。添加 swap 可以让构建继续运行。在机械磁盘上使用 swap 会将内存不足转化为大量寻道,因此构建可能在数小时后完成,而不是快速失败。

为什么 rsync 处理数百万个小文件要耗费一整夜

rsync 在移动任何内容前都会比较两端。对于每个文件,它都会分别对源端和目标端执行 stat,这意味着两端各进行一次元数据读取。当 RAM 无法容纳目录数据时,每次未命中缓存的 stat 都会变成一次寻道。此时,运行时间取决于文件数量,而不是文件总大小。

ChartOne seek per file at 80 random IOPS: hours to walk the tree
The data behind this chart
[
  {
    "label": "100,000 files",
    "duration_h": 0.3
  },
  {
    "label": "500,000 files",
    "duration_h": 1.7
  },
  {
    "label": "1,000,000 files",
    "duration_h": 3.5
  },
  {
    "label": "5,000,000 files",
    "duration_h": 17.4
  }
]

这个计算结果很严苛。即使只有 100,000 个文件,也需要 0.3 小时,相当于纯磁头移动约二十分钟。遍历一百万个文件需要 3.5 小时。五百万个文件——普通邮件存储或照片归档都可能达到这个规模——需要 17.4 小时的寻道时间;无论网络速度多快,这都是整个运行过程的理论下限。

这些数据是根据上文的 80 IOPS 得出的上限,不是针对某个具体方案的实测结果。第二次运行时,缓存可以提供帮助;网络卷的表现也会有所不同。关键在于增长趋势:文件数量翻倍,实际耗时就翻倍;文件大小翻倍,耗时几乎不变。

因此,应改变数据的组织方式。会打包输入数据的备份工具会写入少量大型容器,而不是数百万个小文件。BorgBackup 和 restic 都会将数据块存储在大型分段文件中,因此源端的一百万个文件会在目标端变成顺序写入流。对于一次性复制,tar 通过 SSH 管道传输也能达到相同效果。如果必须使用普通的 rsync,切勿添加 --checksum:该选项会在两端读取每个字节,把元数据问题变成对两棵目录树的完整读取。

同一规则也适用于那些看起来不像复制任务的作业。在大型目录树上运行 du -sh、邮件服务器重建索引,以及 ZFS scrub 读取整个存储池,本质上都是遍历操作。应将这些任务安排在磁盘没有其他需求的时间窗口内,因为在小型存储池上安排 scrub主要是为了避免它与备份任务冲突。

存储 VPS 真正擅长的用途

与其硬件特性匹配的任务,才能充分发挥这台服务器的优势。

  • 备份目标。 Borg 和 restic 会按顺序写入大文件,数据库转储也是如此。将 VPS 用作异地备份目标正是这类硬件的适用场景。
  • 由其他机器负责转码的媒体库。 将文件存放在这里,再让一台小型 NVMe 设备通过网络执行编码。
  • 归档和冷数据。 写入一次,很少读取;读取时按流传输。磁头移动量几乎为零。
  • 批量分发。 提供大文件下载和做种时,几乎不需要寻道,就能充分利用网络链路。
  • 在 EU 内保存第二份副本。 数据驻留及其成本通常是购买这类服务的主要原因,而德国供应商选项是保存这份副本成本最低的方式。

将计算放在小型 VPS 上,将数据放在大型 VPS 上

可以解决上述大多数故障的模式,用一句话就能概括:将处理任务放在快速的小型 VPS 上,将数据放在存储服务器上。存储型 VPS 与普通 VPS 的区别正好对应这两个部分,而将存储型 VPS 与主 VPS 配对则介绍了具体配置工作。

可以通过两种方式连接。使用 NFS(网络文件系统)或 SSHFS 通过私有网络挂载存储,或者不进行挂载,按计划使用 Borg 或 rsync 复制数据。复制更稳健,因为挂载会将每次存储故障都转化为应用错误,而按计划执行的复制只会延迟运行并重试。

遵循两条规则可以让这种拆分稳定运行。不要将数据库数据目录或 Docker overlay2 目录放在远程挂载点上,因为它们都属于前文所述的高频随机访问模式,还会叠加网络延迟。缓存和会话数据应保存在本地磁盘上:它们占用空间小、会持续重写,即使丢失也不会造成损失。

SQLite 通过 NFS 使用时需要特别注意。它的锁定依赖文件锁,而网络文件系统对文件锁的实现并不一致,故障可能表现为 database is locked 或 disk I/O error,有时还会导致无提示的数据损坏。任何使用嵌入式数据库的应用,都应将该数据库文件放在本地磁盘上。在 VPS 上运行 Nextcloud 时会直接遇到这一点,因为它的数据库和文件扫描器负责处理元数据,而文件本身反而较为简单。

对于离开你控制范围的数据,应使用加密;但在处理能力有限的服务器上,加密会占用处理器时间。先使用 grep -m1 -o aes /proc/cpuinfo 检查是否支持硬件 AES。aes 有输出表示加密开销较小;没有输出则表示开销会落在那一两个核心上。AES-NI 对 VPS 的作用解释了其中的差异,在存储型 VPS 上加密数据介绍了配置方法。

如果你最终决定将硬件放在自己的建筑内,那么家庭 NAS 与存储型 VPS 的比较会如实说明这种取舍,包括你会受限于的上传速度。

提交方案前必须执行的一项测量

在试用方案上执行此测试,或者购买方案后的第一个小时内执行,并且要在迁移任何内容之前完成。最能预测故障的是同步 4k 写入,因为数据库提交执行的就是这种操作,而且这种模式几乎没有隐藏性能问题的空间。

sudo apt update && sudo apt install -y fio
fio --name=commit --filename=/mnt/storage/fio-test --size=1G \
  --rw=write --bs=4k --ioengine=sync --fdatasync=1 \
  --runtime=60 --time_based --group_reporting
rm -f /mnt/storage/fio-test

从输出中读取两项内容。write: IOPS= 行表示卷每秒能够完成多少次持久化 4k 写入。其下方的 fsync/fdatasync/sync_file_range: 块显示每次同步操作的延迟,包括第 99 百分位延迟;最慢的事务会受到这一数值的影响。

按实际遇到的顺序解读结果。几十表示该方案是一次写入型存储:适合作为备份目标,但无法承载数据库。几百表示前面有写缓存的普通机械硬盘。几千表示该卷由 SSD 提供支持,此时限制因素已从磁盘变为处理器。

要了解另一半性能情况,请使用同一工具执行顺序测试,并确认该方案能够跑满网络链路。

fio --name=seq --filename=/mnt/storage/fio-test --size=4G \
  --rw=write --bs=1M --ioengine=libaio --iodepth=8 --direct=1 \
  --runtime=60 --time_based --group_reporting
rm -f /mnt/storage/fio-test

如果命令因 fio: looks like your file system does not support direct=1/buffered=0 停止,说明文件系统不支持无缓冲 I/O;网络卷经常存在这种情况。删除 --direct=1,改为添加 --end_fsync=1,这样结果会包含 flush 操作,而不是只测量页缓存。

还可以执行一个 10 秒的快速检查。安装 ioping,然后由 ioping -c 20 /mnt/storage 输出每个请求的延迟,ioping -R /mnt/storage 执行寻道速率测试,并以每秒操作数报告结果。接近 80 的寻道速率表示底层是一块独立的机械硬盘。

有一项检查经常被过度信任:lsblk -d -o name,rota,size 会在 ROTA 列中用 1 标记旋转设备。但在 virtio 下,即使底层是机械硬盘,该标志也经常显示为 0,因此只能将其作为参考,并让 fio 做出判断。在选择方案之前,先确定实际需要多少存储空间,并完整执行一次存储 VPS 购买检查清单;容量之后容易增加,但工作负载特征无法轻易改变。

FAQ

我可以在存储 VPS 上运行数据库吗?

只能运行负载较低的数据库。每次提交的事务都会以 fdatasync 结束;对于机械硬盘,同步操作需要等待盘片,因此每秒可持久化提交数通常只有几十或一两百。决定之前,使用 pg_test_fsync 或上文的 fio 命令进行测量。工作集可以放入 RAM、以读取为主的小型数据库通常运行良好。持续写入的数据库应放在 NVMe VPS 上,只将转储文件存储在大容量磁盘上。

为什么我的媒体服务器在存储 VPS 上会缓冲?

因为它正在进行转码,这是处理器工作,而不是磁盘工作。查看 ffmpeg 进度行:speed= 值低于 1x 时,编码器无法跟上播放速度,播放器就会耗尽缓冲区。检查 ls -l /dev/dri 是否存在硬件编码器,并预计共享方案通常不提供该功能。解决方法是将媒体库存储在这里,在另一台机器上进行转码;或者保留客户端可以直接播放的格式。

Hetzner Storage Box 和存储 VPS 是同一种产品吗?

不是。Storage Box 只通过 SFTP、rsync、SMB 和 BorgBackup 提供协议访问,不提供 shell 和 root,因此无法在其中运行自己的软件。存储 VPS 是一台由您管理的真实 Linux 机器。如果只需要一个备份目标,应选择 Storage Box;如果需要让程序与数据在同一位置运行,则应选择 VPS。存储 VPS 与托管存储盒对比详细介绍了这些差异。

将数百万个小文件复制到存储 VPS 的最快方法是什么?

不要逐个复制这些文件。BorgBackup 和 restic 会将输入打包为较大的分段文件,因此目标端看到的是顺序写入流,而不是数百万次元数据操作。对于单次复制,通过 SSH 管道传输 tar 也能达到相同效果。如果必须使用 rsync,请关闭 --checksum,并预计第一次遍历会受文件数量限制,而不是受带宽限制。

如何判断我的方案使用的是 HDD 还是 SSD?

对于旋转设备,lsblk -d -o name,rota,size 会在 ROTA 列显示 1;但 virtio 对旋转磁盘通常会报告 0,因此不能仅凭该标志判断。请改为进行测量。4k 同步写入测试如果返回几十 IOPS,且同步延迟达到数毫秒,说明使用的是机械硬盘。几千 IOPS 且延迟低于 1 毫秒,则说明使用的是闪存。规划时应以实际测得的数值为准。