上一篇 下一篇 分享链接 返回 返回顶部

SSD 选 TLC 还是 QLC?香港服务器固态硬盘的写入寿命、速度与真实成本一篇看懂

发布人:Minchunlin 发布时间:2025-09-28 09:08 阅读量:1834


凌晨 3:40,我站在香港葵涌机房 8 楼里。值班工程师刚端来罐热咖啡,我还没来得及喝,监控就又冒红:写吞吐从 2.8GB/s 掉到 600MB/s,一路滑到 200MB/s。

罪魁祸首不是网卡,不是 CPU,而是那组“看上去超香”的 QLC 容量盘在写入 SLC 缓存耗尽后进入了“真实面目”。那一刻,我很清楚:这篇文该写了——TLC vs QLC,不是嘴上讨论,是得在机房踩着地砖做决定。

下面是我在香港服务器环境里做的完整实操与复盘,包括硬件配置、参数对比、fio 压测脚本、CentOS 7 的落地步骤、分层方案、成本模型,以及那些半夜逼你成长的坑和补救动作。希望你读完,像在现场一样,能拍板:你的业务,选 TLC,还是 QLC,或者两者怎么“拧”在一起才最合算。

现场与约束

位置:香港葵涌机房(冷通道 17~19℃,湿度 45% 左右)

单机配置(实测环境):

  • 机型:2U Supermicro(前置 8 x U.2 NVMe 托架)
  • CPU:AMD EPYC 7543P(32C/64T)
  • 内存:256GB DDR4
  • 系统:CentOS 7.9(3.10 内核)

磁盘:

  • TLC:3.84TB U.2 NVMe(企业级,带 PLP)×2
  • QLC:15.36TB U.2 NVMe(企业级,带 PLP)×4

网卡:2 × 25GbE

目标业务:在线日志与明细仓(近实时写入 + 高并发查询),写多读多,窗口 30 天热数据

运维要求:可滚动扩容,可控写放大,夜间变更不扰业务

TLC vs QLC:核心差异一句话

TLC(三层单元):抗写强、持续写稳、随机写强,但单位容量更贵。

QLC(四层单元):容量大、读多写少时极具性价比,但持续写容易“雪崩”(SLC 缓存用光后),随机写弱、耐久度低(DWPD 低)。

关键现实:不是 QLC 不行,而是“写多写猛”的业务不该直接把 QLC 当写盘。要么选 TLC,要么做分层/写缓存,让 QLC 吃“冷静的活”。

典型产品参数(我这次上机房用/测过的“同级别”)

注:以下为我在现场批次中拿到的典型档位与实测区间,不同批次/固件会有差异,仅用于选型判断。

类型 盘型 容量 形态 典型 DWPD(5 年) 典型 TBW(估算) 实测顺序读 实测顺序写(SLC 未耗尽/耗尽后) 实测 4K 随机读/写(QD32) 备注
TLC 企业 NVMe 3.84TB U.2 ~1.0 ~7000 TB ~3.5 GB/s ~3.2 GB/s / ~3.0 GB/s ~650k / ~180k IOPS 性能稳定、耐久好
QLC 企业 NVMe 15.36TB U.2 ~0.5–0.6 ~16000 TB ~3.0 GB/s ~2.8 GB/s / 0.6–0.8 GB/s ~350k / ~40–60k IOPS 容量大,持续写容易掉速
QLC 企业 SATA 7.68TB 2.5" ~0.2 ~2800 TB ~520 MB/s ~500 MB/s / 80–120 MB/s ~70k / ~8–12k IOPS 仅适合冷数据/备份

TBW 估算公式:

TBW = 容量(TB) × DWPD × 365 × 年限

例如:3.84TB × 1 × 365 × 5 ≈ 7008 TB。

真实成本:别只看“买盘价”,要看“每 TB 写入成本”

我们在香港渠道这批的落地采购价(税前,仅做案例参考):

盘型 容量 票面价格(HKD) 估算 TBW(TB) 每 TBW 成本(HKD/TB 写入)
企业 TLC NVMe 3.84TB 2,200 7008 0.314
企业 QLC NVMe 15.36TB 6,800 16,258 0.418
企业 QLC SATA 7.68TB 2,400 2,803 0.856

启示:

  • QLC NVMe 的容量成本很棒,但每 TB 写入成本未必比 TLC 更优。
  • 当业务写放大(WAF)高时,QLC 的 TBW 会被很快“吃完”。
  • 用 TLC 做写缓存 + QLC 做容量,能把两边的优势拼起来。

写放大(WAF)与寿命预估:用你的业务数字算一次

寿命(天) ≈ TBW /(日均写入 × WAF)

业务场景 日均逻辑写入 典型 WAF(经验值) 物理写入/日 TLC 3.84TB 预估寿命 QLC 15.36TB 预估寿命
MySQL OLTP(binlog + 双写 + 2 副本) 2 TB ~3.5 7 TB ~1001 天(~2.74 年) ~2322 天(~6.36 年)
ClickHouse(高并发导入+合并) 5 TB ~2.5 12.5 TB ~561 天(~1.54 年) ~1300 天(~3.56 年)
ES/日志平台(短刷新) 3 TB ~2.0 6 TB ~1168 天(~3.2 年) ~2709 天(~7.4 年)

解读:QLC 的DWPD 低,但容量大导致 TBW 同样可能很高;若你的业务日均写入大且 WAF 高,单盘容量也要拉上去,否则 TLC 小盘也扛不住。

不过,QLC 的持续写速大概率扛不住“写猛”场景,所以分层/写缓存是关键。

压测方法与结果(fio 命令可直接抄)

  • 测试前:确保盘已 TRIM,环境空载;CentOS 7 上安装 fio、nvme-cli、smartmontools。
  • 警告:fio 会清空测试文件路径下的数据。

1)顺序写(128K),看 SLC 缓存“崩塌点”

# 生成 200G 测试文件,观察长时间写入
fio --name=seqwrite --filename=/mnt/data/fio_seq.bin \
    --rw=write --bs=128k --iodepth=32 --numjobs=4 \
    --size=200G --ioengine=libaio --direct=1 --group_reporting

现象:

  • TLC:从头到尾 3.0~3.2GB/s,曲线平直。
  • QLC:前 300~800GB 保持 2.5~2.8GB/s,随后下坠到 0.6~0.8GB/s(视型号与温度)。

2)4K 随机写(QD32),看业务抖动

fio --name=randwrite --filename=/mnt/data/fio_rand.bin \
    --rw=randwrite --bs=4k --iodepth=32 --numjobs=8 \
    --size=50G --ioengine=libaio --direct=1 --time_based --runtime=120 \
    --group_reporting

现象:

  • TLC:10~20 万 IOPS 区间稳定波动。
  • QLC:常在 4~6 万 IOPS,温度高或缓存紧张时掉到低谷。

3)4K 随机读(QD64),看热点检索

fio --name=randread --filename=/mnt/data/fio_rand.bin \
    --rw=randread --bs=4k --iodepth=64 --numjobs=8 \
    --size=50G --ioengine=libaio --direct=1 --time_based --runtime=120 \
    --group_reporting

现象:

QLC 的随机读并不差,查询类工作负载一般可接受。

三种架构方案:我在现场给出的“能落地”的选择

方案 A:全 TLC(简单稳定,CapEx 高)

  • 适用:重写入、SLA 严苛的核心在线库(订单、账务)。
  • 优点:性能/寿命稳定,运维省心。
  • 缺点:单位容量成本高,扩容频繁时钱包疼。

方案 B:TLC 写缓存 + QLC 容量(推荐)

  • 思路:TLC 只负责写入与热元数据,QLC 专职容量与读取。
  • 技术路径(CentOS 7 原生):LVM dm-cache(writeback) 或 bcache。
  • 优点:把 QLC 的容量优势吃满,同时把 QLC 的写弱点挡在门外。
  • 缺点:需要监控与回写策略调优;缓存盘故障要有应急预案(必须企业级带 PLP)。

方案 C:ZFS(SLOG=TLC,DATA=QLC)

  • 思路:用 TLC 做 SLOG(同步写日志) 和 metadata/special vdev,QLC 做数据盘;读多写少、带同步写的场景收益明显。
  • 优点:写入延迟与一致性好控,数据服务特性丰富。
  • 缺点:CentOS 7 上装 ZFS 需要 DKMS,维护复杂度高;建议熟手。

部署实操(CentOS 7):用 LVM dm-cache 搭“TLC+QLC”分层

下方假设:/dev/nvme0n1(TLC),/dev/nvme1n1(QLC)。操作前先备份。

1)基础准备与对齐

yum install -y nvme-cli lvm2 xfsprogs smartmontools

# 确认 4K 逻辑扇区,如非 4K 可格式化(谨慎!会清盘)
nvme id-ns /dev/nvme1n1 | egrep "lbaf|flbas"
# nvme format /dev/nvme1n1 --lbaf=1  # 仅当你确认需要并理解风险

2)创建 PV/VG/LV(QLC 为数据,TLC 为缓存池)

pvcreate /dev/nvme1n1 /dev/nvme0n1
vgcreate vg_data /dev/nvme1n1 /dev/nvme0n1

# 数据 LV 在 QLC 上(举例 10TB)
lvcreate -L 10T -n lv_data vg_data /dev/nvme1n1

# 缓存池(TLC 上):数据与元数据(按比例准备)
lvcreate -L 1.8T -n lv_cache vg_data /dev/nvme0n1
lvcreate -L 20G  -n lv_cache_meta vg_data /dev/nvme0n1
lvconvert --type cache-pool --poolmetadata vg_data/lv_cache_meta vg_data/lv_cache

# 绑定缓存(建议先 writeback,再按监控调整)
lvconvert --type cache --cachepool vg_data/lv_cache --cachemode writeback vg_data/lv_data

# 优化缓存策略(smq 更适合通用场景)
lvchange --cachesettings cache_policy=smq vg_data/lv_data

3)文件系统与挂载(XFS 示例)

mkfs.xfs -f /dev/vg_data/lv_data
mkdir -p /data
echo "/dev/vg_data/lv_data /data xfs noatime,nodiratime,logbufs=8,logbsize=256k 0 0" >> /etc/fstab
mount -a

4)TRIM 与定时维护

# 周期 TRIM(对 NVMe 友好,避免长期写放大)
echo -e "[Unit]\nDescription=Weekly fstrim\n[Service]\nType=oneshot\nExecStart=/sbin/fstrim -av" > /etc/systemd/system/fstrim.service
echo -e "[Unit]\nDescription=Weekly fstrim timer\n[Timer]\nOnCalendar=weekly\nPersistent=true\n[Install]\nWantedBy=timers.target" > /etc/systemd/system/fstrim.timer
systemctl enable --now fstrim.timer

5)队列与中断(视负载微调)

# NVMe 默认 scheduler=none,一般保持
cat /sys/block/nvme0n1/queue/scheduler

# 合理的 readahead(示例 128)
echo 128 > /sys/block/nvme1n1/queue/read_ahead_kb

# 绑核示例(减少抖动,按 NUMA 分布微调)
for irq in $(grep nvme /proc/interrupts | awk '{print $1}' | sed 's/://'); do
  echo 2 > /proc/irq/$irq/smp_affinity  # 绑到 CPU1(示意)
done

6)监控要点(一定要上)

# NVMe 健康
nvme smart-log /dev/nvme1n1
nvme list

# SMART(SATA/混合)
smartctl -a /dev/sdX

# LVM 缓存状态
lvs -a -o +cache_policy,cache_settings,cache_used_blocks,cache_total_blocks

线上“坑”与当场补救

QLC 写入“悬崖”

症状:长时间高写后速率断崖,从 GB/s 掉到几百 MB/s。

补救:

  • 立刻切换写入口到 TLC 缓存层;
  • 降低导入并发,让回写匀速进行;
  • 开临时 冷热分层策略,把近期热数据限制在 TLC 或混闪层。

温度触发降速

症状:盘温 >70℃ 时突然抖动。

补救:

  • 调整机箱风扇曲线、换正压风道、下掉非必要挡板;
  • 机柜内分层:QLC 靠近进风侧,TLC 放中间,网卡/CPU 背后保持通风。

4K/512e 混乱造成写放大

症状:小 IO 抖动、放大异常。

补救:统一 4K 逻辑扇区(必要时 nvme format --lbaf=1),XFS/EXT4 保持默认对齐。

缓存盘故障预案

要点:缓存层务必用企业级带 PLP 的 TLC;生产启 writeback 时,双盘镜像或 RAID1,并有主备回切脚本。

TRIM/Discard 忽略

  • 结果:长时间运行后写放大上升、性能回不来。
  • 动作:开启周期 fstrim;数据库引擎层减少无谓短生命周期临时文件。

什么时候选 TLC?什么时候选 QLC?——给你一张“决策速查表”

业务特征 建议
高写入(>3TB/日/节点)+ 低延迟 SLA 全 TLC 或 TLC 主写 + QLC 只做冷/温数据
读多写少(<1TB/日/节点)+ 大容量 QLC 可主力,前端用轻量 TLC 缓存做加速
批量导入 + 白天查询 TLC 写缓存 + 夜间分层回写 QLC
预算紧 + 数据留存长 QLC NVMe 优先于 QLC SATA(带来更宽裕的读能力与恢复速度)
容灾/多副本系统(高 WAF) 放大后再算 TBW 决策,常见为 TLC 前置

我给团队落地的“标准化选型单”

  • 在线库/支付/账务:全 TLC(3.84TB × N 或 7.68TB × N),RAID10 或应用层多副本。
  • 日志/明细仓(当前这个项目):TLC(写缓存 1.8~3.6TB)+ QLC(容量 10~30TB),LVM dm-cache(writeback + smq),按监控调回写速率。
  • 归档/冷备:QLC SATA + 定期校验 + 离线副本(成本最低)。
  • 强一致写多(如同步写 KV):ZFS + TLC SLOG + QLC DATA,谨慎评估内核与驱动维护成本。

复盘:怎么让“真实成本”更低?

  • 算全生命周期:盘价 + 机柜位 + 功耗 + 运维时间(夜间窗口就是钱)。
  • 把写放大从源头压低:应用层批量写、合并小 IO、适度延迟刷新。
  • 边写边分层:TLC 接“新写”,QLC 吃“静态”;冷热阈值靠数据分布而非拍脑袋。
  • 监控前置:温度、缓存命中、回写队列、水位报警;有脚本自动“限流/切层”。

尾声:清晨 7:10,窗外亮了,告别“悬崖式掉速”

那晚,我们把写入口全部切到 TLC,给回写限了个“舒适”的 800MB/s,QLC 盘温也被风道重新调教到 55℃ 左右。吞吐线从锯齿变成了平滑曲线。
走出机房,天已经亮了,维港那边泛着白。杯底的咖啡凉透了,但心里踏实:“TLC vs QLC”不是站队,是“按业务拆解 + 用工程手段缝合”。
下一次你在机房里做选择,盯住三件事就行:写入强度、持续写行为、全生命周期成本。
有了这些,你的 SSD 选型,自然“不会崩”。

附:常用命令清单(可贴到 runbook)

# 盘信息
nvme list
nvme smart-log /dev/nvmeXn1
smartctl -a /dev/sdX

# LVM 缓存观测
lvs -a -o +cache_policy,cache_settings,cache_used_blocks,cache_total_blocks

# fio 模板
fio --name=seqwrite --filename=/data/fio_seq.bin --rw=write --bs=128k --iodepth=32 --numjobs=4 --size=200G --ioengine=libaio --direct=1 --group_reporting
fio --name=randwrite --filename=/data/fio_rand.bin --rw=randwrite --bs=4k --iodepth=32 --numjobs=8 --size=50G --ioengine=libaio --direct=1 --time_based --runtime=120 --group_reporting
fio --name=randread  --filename=/data/fio_rand.bin --rw=randread  --bs=4k --iodepth=64 --numjobs=8 --size=50G --ioengine=libaio --direct=1 --time_based --runtime=120 --group_reporting

总结一句话:

  • 强写入 + 稳定性优先:TLC。
  • 读多写少 + 追求容量成本:QLC,但务必配 TLC 写缓存/分层。
  • 评估口径统一到 TBW/WAF 与“每 TB 写入成本”,把“看上去很美”的 QLC,变成真正可控的生产力。
目录结构
全文