ECC 与内存可靠性 —— Parity / SECDED / Chipkill

服务器内存最重要的不是容量、不是带宽,是 不翻车。本文讲服务器内存可靠性的几个关键机制:奇偶校验、ECC、Chipkill。

内存为什么会出错

内存出错的来源主要三类:

1. 软错误(Soft Error)

宇宙射线、α 粒子、电荷干扰等导致单个 bit 翻转——没有物理损坏,重启或者重写就好

数据中心里实测的软错误率,每 GB 内存大约每月 1-25 次。一台 1TB 的服务器每月可能有几千次单 bit 翻转——绝大多数会被 ECC 自动纠正,没纠正过的会成为不可解释的服务异常或宕机。

2. 硬错误(Hard Error)

颗粒物理损坏、连线虚焊、温度漂移导致永久错误。这种重启也修不好。

3. 系统级故障

整颗 DRAM 颗粒挂掉、整条 DIMM 失效、通道故障——需要更高级的冗余机制。

第一道防线:Parity(奇偶校验)

最简单的检错——每 8 bit 加 1 bit 校验:

1
2
3
数据:    1 0 1 1 0 0 1 0   (4 个 1)
偶校验: 0 (1 总数仍是偶数)
奇校验: 1 (1 总数变成奇数)

特点:

  • 能检 1 bit 错,不能纠
  • 不能检 2 bit 错(两个错抵消了)
  • 用 1 bit/byte 的开销

应用:早期 286/386 时代的 PC、内存总线本身的 parity 信号、PCIe 链路也用类似机制。

服务器内存基本不用 parity——直接上更强的 ECC。

第二道防线:ECC(Error-Correcting Code)

服务器内存的标配。基于汉明码(Hamming code)等设计:

SECDED:单错纠正、双错检测

1
72 bit 总宽度 = 64 bit 数据 + 8 bit 校验

Single Error Correction, Double Error Detection

  • 1 bit 错:自动纠正(软件无感知,但 BIOS 会记录到 EDAC/MCE)
  • 2 bit 错:检测但不能纠(系统报 MCE,通常宕机或隔离页面)
  • 3 bit 错及以上:可能误纠,可能漏检

实现方式:64 bit 数据计算出 8 bit 校验码,写入时一起存;读出时重新计算校验码并对比 syndrome,定位错误位。

graph LR
  CPU --> ENC[ECC 编码
64b → 72b] ENC --> DRAM[(DRAM
72b 存储)] DRAM --> DEC[ECC 解码
纠错/报错] DEC --> CPU

服务器 RDIMM 的”× 9 颗粒”就是为这个 8 bit 校验位准备的。

EDAC 接口

Linux 上看 ECC 错误:

1
2
3
4
5
6
7
# 查看每个内存控制器/通道的错误计数
ls /sys/devices/system/edac/mc/
cat /sys/devices/system/edac/mc/mc*/ce_count # 已纠正错误
cat /sys/devices/system/edac/mc/mc*/ue_count # 未纠正错误

# rasdaemon 可解析详细错误
rasdaemon --help

服务器运维一定要监控这两个值——CE 增长突然变快说明某根条快要 UE 了。

第三道防线:Chipkill / SDDC

SECDED 只能纠 1 bit。如果整颗 DRAM 颗粒挂掉——一颗 ×4 颗粒一下子坏 4 bit,SECDED 根本扛不住。

Chipkill(IBM 命名)/ SDDC(Single Device Data Correction,Intel 命名)/ AMD ECC整颗芯片级纠错:

实现思路

1
2
3
4
5
6
原 SECDED:    每行 8 bit ECC,能纠 1 bit
Chipkill: 把数据交错铺到多颗 ×4 颗粒上
一颗颗粒挂掉 = 多个 word 各错 4 bit,
对每个 word 而言都是"少量错"
加上更强的 ECC 编码(如 SDDC、Reed-Solomon)
整颗颗粒丢失也能恢复

效果:一颗 DRAM 颗粒整个挂掉,业务不中断。Chipkill 是企业级服务器内存的标准能力。

Chipkill 的几种实现等级

名称 厂家 能力
SDDC Intel 单颗 ×4 颗粒失效可恢复
DDDC(双设备) Intel(Xeon SP 起) 两颗颗粒失效可恢复
AMD Chipkill AMD(EPYC) 类似 SDDC
ASR/Mirror Intel 整通道镜像(双倍内存代价)

Page Retire / Online Sparing

ECC 检测到反复出错的页面,OS 可以自动停用这块内存:

1
2
3
4
DIMM 0 上某物理页 0x1234 多次报 CE
→ 内核标记此页为"已坏"
→ 后续不再分配
→ 业务无感知

Linux 内核的 mcelograsdaemon 配合可以自动完成 page retire。这是服务器”长时间不重启也稳定”的关键。

内存镜像(Memory Mirroring)

更极端的可靠性方案——两组内存互为镜像

1
2
3
4
通道 0  ┐  写两份
通道 1 ┘
读时哪边先到用哪边
一组挂掉切到另一组

代价:一半的内存容量被牺牲掉

只用于金融、电信、超关键业务。一般场景 Chipkill + page retire 就够。

内存热插拔

部分高端服务器(如 IBM Power、HPE Superdome)支持内存热插拔——机器不停电的情况下换条子。需要:

  • 主板硬件支持(绝大多数 Intel/AMD 双路服务器不支持,只有四路/八路高端机型才有)
  • BIOS / UEFI 支持
  • OS 支持(Linux 通过 mem hotplug 接口)

云厂商的整机柜方案多用”整节点替换“代替”内存热插拔”——容错粒度上移到节点级。

ECC 全栈视角

graph TB
  L1[on-die ECC
颗粒内部 SEC
DDR5 颗粒自带] L2[side-band ECC
通道传输 SECDED
RDIMM 标配] L3[Chipkill / SDDC
整颗颗粒失效
服务器 CPU 内存控制器] L4[Page Retire
OS 层退出坏页] L5[内存镜像
整通道镜像
仅高端] L1 --> L2 --> L3 --> L4 --> L5

每多一层,能容忍的故障级别更高,代价(容量、性能、价格)也更高。绝大多数服务器跑到 L4 就够了

服务器内存可靠性的几个常见误区

误区 1:”on-die ECC 让 RDIMM ECC 没必要了”

❌ on-die ECC 只防颗粒内部位翻转。颗粒到 CPU 这条路(电气干扰、信号反射)依然要 side-band ECC。

误区 2:”ECC 越强越好”

ECC 强度有性能和容量代价。SDDC 比 SECDED 多用 ~12.5% 容量做校验。按业务需求选

误区 3:”服务器 ECC 和桌面 ECC 区别不大”

差很多。桌面 ECC(Intel W、AMD Ryzen Pro 工作站)一般只有 SECDED,没 Chipkill;通道少;不支持镜像。

误区 4:”长时间稳定就说明没出错”

❌ 长时间稳定可能正是因为 ECC 在默默纠错。建议把 EDAC/MCE 计数器纳入监控,异常增长比绝对数字更重要。

一份运维核对清单

推荐做法
必装 RDIMM/LRDIMM DDR5 服务器全部上 ECC
启用 Chipkill BIOS 默认开(不要关)
rasdaemon 后台跑 每台都装
监控 CE/UE 计数 接入监控告警
Page Retire 启用 Linux 默认
重要业务考虑镜像 仅金融/电信
定期 memtest 上线前验机一遍

待补充:rasdaemon 配置示例、不同发行版默认行为差异(RHEL/Ubuntu/Anolis)。

小结

  • 内存出错主要分软错误和硬错误,1TB 机器每月有数千次软错误
  • Parity 只检不纠,ECC SECDED 单错可纠双错可检
  • Chipkill / SDDC 是整颗颗粒失效的兜底
  • ECC 全栈要看 on-die / side-band / Chipkill / page retire / mirror 五层
  • on-die ECC 不能取代 side-band ECC,服务器仍然必须用 RDIMM
  • 监控 CE/UE 比单纯”无故障”更靠谱

下一篇讲 NVDIMM 和持久内存,包括 Optane 退役后留下的真空。