400 字
1 分钟
为什么 HugePages 可以提升数据库性能
像 Oracle、PostgreSQL 这类数据库经常配置 HugePages(巨页)来提升性能。为什么 HugePages 能提升性能?
一、TLB 的工作原理
1.1 什么是 TLB?
TLB(Translation Lookaside Buffer)是 CPU 用于加速虚拟地址到物理地址转换的缓存:
flowchart LR
VA[虚拟地址] --> TLB[TLB]
TLB -->|命中| PA1[物理地址]
TLB -->|未命中| PT[页表]
PT -->|查询| PA2[物理地址]
PT -->|缓存| TLB
Note: TLB 是 CPU 的一部分<br/>硬件缓存
1.2 TLB 的结构
| TLB 特性 | 典型值 |
|---|---|
| TLB 条目数 | 64-1024 条 |
| 命中延迟 | ~1 个 CPU 周期 |
| 未命中延迟 | ~100+ CPU 周期 |
| 页大小 | 4KB(默认) |
二、4KB 页的 TLB 问题
2.1 大内存的 TLB 压力
# 假设:数据库使用 64GB 内存
pages_4k = 64 * 1024 * 1024 / 4 # 4KB 页print(f"64GB 内存需要 {pages_4k:,} 个 4KB 页")
# 64GB / 4KB = 16,777,216 页# 如果 TLB 只有 1024 条,能覆盖多少内存?coverage_4k = 1024 * 4 # KBcoverage_4k_mb = coverage_4k / 1024 # MBprint(f"TLB 只能覆盖 {coverage_4k_mb} MB 内存")# TLB 只能覆盖 4MB!2.2 TLB Miss 的成本
flowchart LR
A[访问内存] --> B{TLB 命中?}
B -->|是| C[1 周期]
B -->|否| D[访问页表]
D --> E[100+ 周期]
E --> F[更新 TLB]
F --> C
Note: TLB 未命中导致额外 ~100 周期延迟
三、HugePages 的优势
3.1 HugePages 的计算
# 2MB HugePagespages_2m = 64 * 1024 / 2 # 2MB 页print(f"64GB 内存需要 {pages_2m:,} 个 2MB 页")
# 64GB / 2MB = 32,768 页
# 同样 1024 条 TLB,能覆盖多少内存?coverage_2m = 1024 * 2 # MBcoverage_2m_gb = coverage_2m / 1024 # GBprint(f"HugePages TLB 覆盖 {coverage_2m_gb} GB 内存")
# vs 4KB: 4MB# HugePages 覆盖能力提升 512 倍!3.2 HugePages vs 4KB 对比
| 页面大小 | 64GB 内存的页数 | TLB 覆盖(1024 条) | 覆盖率提升 |
|---|---|---|---|
| 4KB | 16,777,216 | 4 MB | 1x |
| 2MB | 32,768 | 2 GB | 512x |
| 1GB | 64 | 64 GB | 16384x |
四、数据库的 HugePages 配置
4.1 PostgreSQL 配置
# 1. 计算 HugePages 大小# PostgreSQL shared_buffers = 16GB# 需要: 16GB / 2MB = 8192 个 2MB 页
# 2. 设置 /etc/sysctl.confvm.nr_hugepages = 8192
# 3. 设置 /etc/security/limits.confpostgres soft memlock unlimitedpostgres hard memlock unlimited
# 4. 重启 PostgreSQLsudo systemctl restart postgresql4.2 Oracle 配置
# 1. 计算 HugePages# SGA = 32GB# HugePages = 32GB / 2MB = 16384
# 2. 设置 /etc/sysctl.confvm.nr_hugepages = 16384
# 3. 设置 /etc/security/limits.conforacle soft memlock 33554432oracle hard memlock 33554432
# 4. 配置 Oracle# in $ORACLE_HOME/dbs/initORCL.orause_large_pages = TRUE4.3 验证配置
# 查看 HugePages 配置cat /proc/meminfo | grep -i huge
# 验证 PostgreSQL 使用cat /proc/$(pidof postgres)/smaps | grep -i huge五、HugePages 的注意事项
5.1 内存预留
# HugePages 预留后,这些内存不能被普通程序使用# vm.nr_hugepages = 1024 预留 2GB
free -h# total used free shar buff/cache available# Mem: 125Gi 2Gi 120Gi 0Gi 3Gi 120Gi# 注意:used 仍然是 2GB,即使 PostgreSQL 不用,也要预留5.2 透明大页(Transparent HugePages)
# 查看状态cat /sys/kernel/mm/transparent_hugepage/enabled# [always] madvise never
# 生产环境建议关闭echo never > /sys/kernel/mm/transparent_hugepage/enabledecho never > /sys/kernel/mm/transparent_hugepage/defrag六、总结
6.1 HugePages 提升性能的原因
| 原因 | 说明 |
|---|---|
| 减少 TLB Miss | 相同 TLB 条目覆盖更大内存 |
| 降低页表开销 | 页表更小,CPU 缓存效率更高 |
| 减少内存管理开销 | 更少的页表条目需要管理 |
6.2 HugePages 配置检查
| 检查项 | 方法 |
|---|---|
| 是否启用 | cat /proc/meminfo | grep HugePages |
| PostgreSQL 是否使用 | grep -i huge /proc/$(pidof postgres)/smaps |
| TLB 命中率 | perf stat -e dTLB-load-misses |
核心观点:HugePages 通过增大页面大小,让 TLB 能够覆盖更大的内存区域,从而减少 TLB Miss,提升数据库等大内存应用的性能。
参考资料
- HugePages in Linux — 内核文档
- PostgreSQL HugePages — PostgreSQL 文档
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
为什么 HugePages 可以提升数据库性能
https://blog.souloss.com/posts/why-the-design/why-hugepages-boost-database-performance/ 部分信息可能已经过时
相关文章 智能推荐
1
为什么数据库会丢失数据
技术科普 深入解析数据库丢失数据的场景与原因,WAL、fsync、缓冲池等机制与数据安全。
2
为什么数据库不应该使用外键
技术科普 深入解析为什么现代互联网应用中不建议使用外键,以及如何替代外键实现数据一致性。
3
为什么 Linux 需要虚拟内存
技术科普 深入解析虚拟内存的设计原理,为什么操作系统需要虚拟内存,页表机制,物理内存与虚拟内存的映射。
4
为什么 Linux 需要 Swapping
技术科普 深入解析 Linux Swapping 机制,为什么需要将内存交换到磁盘,以及 swappiness 的作用。
5
为什么 Linux 默认页大小是 4KB
技术科普 深入解析 Linux 默认选择 4KB 页大小的历史原因和技术权衡。






