mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
400 字
1 分钟
为什么 HugePages 可以提升数据库性能
2023-10-25

像 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 # KB
coverage_4k_mb = coverage_4k / 1024 # MB
print(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 HugePages
pages_2m = 64 * 1024 / 2 # 2MB 页
print(f"64GB 内存需要 {pages_2m:,} 个 2MB 页")
# 64GB / 2MB = 32,768 页
# 同样 1024 条 TLB,能覆盖多少内存?
coverage_2m = 1024 * 2 # MB
coverage_2m_gb = coverage_2m / 1024 # GB
print(f"HugePages TLB 覆盖 {coverage_2m_gb} GB 内存")
# vs 4KB: 4MB
# HugePages 覆盖能力提升 512 倍!

3.2 HugePages vs 4KB 对比#

页面大小64GB 内存的页数TLB 覆盖(1024 条)覆盖率提升
4KB16,777,2164 MB1x
2MB32,7682 GB512x
1GB6464 GB16384x

四、数据库的 HugePages 配置#

4.1 PostgreSQL 配置#

# 1. 计算 HugePages 大小
# PostgreSQL shared_buffers = 16GB
# 需要: 16GB / 2MB = 8192 个 2MB 页
# 2. 设置 /etc/sysctl.conf
vm.nr_hugepages = 8192
# 3. 设置 /etc/security/limits.conf
postgres soft memlock unlimited
postgres hard memlock unlimited
# 4. 重启 PostgreSQL
sudo systemctl restart postgresql

4.2 Oracle 配置#

# 1. 计算 HugePages
# SGA = 32GB
# HugePages = 32GB / 2MB = 16384
# 2. 设置 /etc/sysctl.conf
vm.nr_hugepages = 16384
# 3. 设置 /etc/security/limits.conf
oracle soft memlock 33554432
oracle hard memlock 33554432
# 4. 配置 Oracle
# in $ORACLE_HOME/dbs/initORCL.ora
use_large_pages = TRUE

4.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/enabled
echo 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 可以提升数据库性能
https://blog.souloss.com/posts/why-the-design/why-hugepages-boost-database-performance/
作者
Souloss
发布于
2023-10-25
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时