1 为什么要开启大页
内存表映射优化
操作系统的虚拟内存管理,我们所看到的任何地址都是虚拟地址,而页表维护了虚拟内存地址到实际物理内存地址的映射关系。页面越大,页面的数量就越少,映射表就越小,映射速度就越快。
使用hugepage可以减少页表大小。
操作系统使用TLB来加速这个映射过程,如果物理地址在TLB中命中,直接转换为物理地址,只访问一次内存地址。否则扫描页表查找地址,然后映射条目到TLB,然后再转换为物理地址,这样就有两次内存访问。最差的是页表中也没有,需要从磁盘写到页表,那么这样效率会更慢。
因为TLB只能保存几千个条目,为了提高性能,有两个办法:
- 增加TLB的大小,成本太高
- 增加内存页面的大小,比如如果TLB只能对应256个页表项,页面大小为1GB,那么TLB就能映射到256G的内存空间
2 具体步骤
2.1 查看Linux的Huge pages页大小
grep Hugepage /proc/meminfo
在Linux系统中,Huge Pages的默认大小通常是2MB,这是系统在未经过任何额外配置时默认支持的大页大小。
如果需要使用更大的页面(如1GB),则需要在系统启动时通过 GRUB 配置 明确设置。例如,可以在 /etc/default/grub 文件中添加以下参数来启用1GB的大页内存:
vi /etc/default/grub
GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=1"
然后通过 grub2-mkconfig 命令更新 GRUB 配置并重启系统。
2.2 计算需要的大页数量
假设我们的内存有512GB,shared_buffer设置为128GB,如何计算需要的大页数量?
方法一:使用PG的内置工具
从PG15开始,可以通过以下命令直接计算所需的大页数量
su - postgres
/usr/pgsql-15/bin/postgres --shared-buffers=20GB -D $PGDATA -C shared_memory_size_in_huge_pages
假设输出为 10475,则表示需要 10475 个大页。这种方法考虑了所有相关因素,是最精确的。
方法二:手动验证
shared_buffer设置为128GB,128GB/2MB=65535
取一个比65535略大的值,比如67537,这种方法不精确,若系统提示分配失败,则调小重试
2.3 设置大页数量
设置linux的Huge Pages个数,立即生效,但这是临时的,系统重启后会失效
sysctl -w vm.nr_hugepages=67537
永久设置需要编辑文件 /etc/sysctl.conf,在末尾添加以下内容
vm.nr_hugepages = 67537
配置生效
sysctl -p
打开数据库的大页参数
vi /$PGDATA/postgresql.conf
huge_pages = on # on, off, or try
# 设置为try的话,会先尝试huge page,如果启动时无法锁定给定数目的大页,则不会使用huge page
重启数据库之后,查看当前的大页配置
cat /proc/meminfo |grep -i huge
AnonHugePages: 6144 kB
HugePages_Total: 67537 ## 设置的HUGE PAGE
HugePages_Free: 66117 ## 这个是当前剩余的,但是实际上真正可用的并没有这么多,因为被PG锁定了65708个大页
HugePages_Rsvd: 65708 ## 启动PG时申请的HUGE PAGE
HugePages_Surp: 0
Hugepagesize: 2048 kB ## 当前大页2M
执行一些查询之后,会发现Free变小了,这是因为被数据库用掉了。
Comments NOTHING