本文主要介绍如何在Linux操作系统的实例中配置透明大页内存。
关于透明大页
Transparent Huge Pages (THP)是一种 Linux 内存管理系统,它通过使用更大的内存页面来减少在具有大量内存的机器上进行转换后备缓冲区 (TLB) 查找的开销。
使用透明大页的优点
通过THP可以减少TLB miss和缺页中断,可以提升性能。例如:
应用程序需要2MB的内存,如果操作系统以4KB作为分页的单位,则需要512个页面,进而在TLB中需要512个表项,同时也需要512个页表项,操作系统需要经历至少512次TLB Miss和512次缺页中断才能将2MB应用程序空间全部映射到物理内存。
而当操作系统采用2MB作为分页的基本单位时,只需要1次TLB Miss和1次缺页中断,就可以为该应用程序空间建立虚拟映射,并在运行过程中无需再经历TLB Miss和缺页中断(假设未发生TLB项替换和 Swap)。
使用透明大页的缺点
- 内部碎片。例如给需要1个字节数据的应用程序分配了2MB的大页内存,会导致出现内部碎片。
- 缺页处理延迟增高。尽管透明大页减少了缺页的次数,但更大的页面需要更长的时间从磁盘传输,从而导致缺页处理延迟增高。同时,清零大页也需要更长的时间。
- 内存路径加锁带来的访存性能下降。在khugepaged扫描进程内存,并将4kB页面合并为大页的这个过程中,对于操作的内存的各种分配活动都需要各种内存锁,直接影响程序的内存访问性能。并且,这个过程对于应用是透明的,在应用层面不可控制,对于专门为4kB内存页优化的程序来说,可能会造成随机的性能下降现象。
- 后台任务占用系统资源。当系统没有足够的连续内存时,会触发内存压缩和内存回收,导致系统性能下降。
操作场景
透明大页对系统性能的影响需要分场景看待,您可以根据实际场景选择是否启用THP。
SPECjbbⓇ场景
在如标准性能评估组织的 (Standard Performance Evaluation Corporation,简称SPEC) 的Java服务器性能测试(JAVA server Business Benchmark,简称SPECjbb)场景,应用程序需要使用大量内存,使用更大的page粒度映射内存以增加TLB中的命中率是有意义的,对于内存密集型工作负载,启用THP可能会产生可观的性能收益。
数据库场景
由于数据库往往具有稀疏而不是连续的内存访问模式,因此在启用THP的情况下,其工作负载通常表现不佳。例如在Linux上运行MongoDB时,应禁用THP以获得最佳性能。
操作步骤
开启/关闭透明大页
cat /sys/kernel/mm/transparent_hugepage/enabled
-
- [always] madvise never:表示已启用透明大页。
- always [madvise] never:只能通过madvise()系统调用在MADV_HUGEPAGE的内存区域使用透明大页。
- always madvise [never]:表示已禁用透明大页。
注意
本方式配置无需重启实例,但仅在本次系统运行期间有效,重启后配置将失效。
- 当系统启动至内核选择界面时,按↑或↓键选择目标内核。
-
- 将光标定位至Linux内核参数行,添加transparent_hugepage=always、transparent_hugepage=madvise或transparent_hugepage=never参数,如下图所示。
-
- 进入操作系统后,可执行步骤2命令查看配置是否生效。
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/enabled
- 指定只能通过madvise()系统调用在MADV_HUGEPAGE的内存区域使用透明大页
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
注意
本方式配置永久有效,但需重启实例使配置生效。
sudo vim /etc/default/grub
- 按i键进入编辑模式,在GRUB_CMDLINE_LINUX后添加透明大页参数transparent_hugepage。若已有该参数,请按需调整其参数值。
说明
请将never替换为所需的参数值。取值:
- madvise:只能通过madvise()系统调用在MADV_HUGEPAGE的内存区域使用透明大页。
transparent_hugepage=never
-
- 按esc键退出编辑模式,输入:wq按回车键,保存并退出文件。
说明
请将never替换为所需的参数值。取值:
- madvise:只能通过madvise()系统调用在MADV_HUGEPAGE的内存区域使用透明大页。
sudo grubby --args="transparent_hugepage=never" --update-kernel="/boot/vmlinuz-$(uname -r)"
查看透明大页使用情况
cat /proc/meminfo | grep AnonHugePages
AnonHugePages: 819200 kB
cat /proc/[pid]/smaps | grep AnonHugePages
透明大页碎片整理配置
您可以通过如下方式配置透明大页碎片整理功能,当无法分配透明大页时,系统将自动完成相应操作整理大页碎片。
- 当无法分配透明大页时,暂停分配透明大页,并直接回收页面和压缩内存以立即分配透明大页。
echo always >/sys/kernel/mm/transparent_hugepage/defrag
- 当无法分配透明大页时,转而分配4kB普通页,同时在后台唤醒kswapd以回收页面并唤醒kcompactd以压缩内存,以便khugepaged在连续内存可用的时候合成透明大页。
echo defer >/sys/kernel/mm/transparent_hugepage/defrag
- 当无法分配透明大页时,仅对通过madvise()系统调用在MADV_HUGEPAGE的内存区域分配透明大页的采用always方式,其他区域分配4kB普通页。
echo madvise >/sys/kernel/mm/transparent_hugepage/defrag
- 当无法分配透明大页时,对于通过madvise()系统调用在MADV_HUGEPAGE的内存区域分配透明大页的采用always方式,其他区域采用defer方式。
echo defer+madvise >/sys/kernel/mm/transparent_hugepage/defrag
echo never >/sys/kernel/mm/transparent_hugepage/defrag
Khugepaged配置
khugepaged是透明大页的守护进程,它的主要功能是定时唤醒,根据配置尝试将4k的普通page转成2M等大页,减少TLB压力,提高内存使用效率。但khugepaged在处理过程中需要使用各种内存锁,在一定程度上会影响系统性能。您可以根据实际需求配置khugepaged。
- 执行如下命令,禁用khugepaged碎片整理。
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
- 执行如下命令,启用khugepaged碎片整理。
echo 1 >/sys/kernel/mm/transparent_hugepage/khugepaged/defrag
- 执行如下命令,设置khugepaged每次扫描4096页(默认也是4096页)。
echo 4096 > /sys/kernel/mm/transparent_hugepage/khugepaged/pages_to_scan
- 执行如下命令,设置khugepaged每次唤醒的时间间隔为10000ms(默认也是10000ms)。
echo 10000 > /sys/kernel/mm/transparent_hugepage/khugepaged/scan_sleep_millisecs
- 执行如下命令,设置khugepaged分配大页失败后的等待时间为60000ms,防止短时间重复失败(默认也是60000ms)。
echo 60000 > /sys/kernel/mm/transparent_hugepage/khugepaged/alloc_sleep_millisecs
- 如果系统出现严重卡顿并且khugepaged使用率高达100%,您可以执行如下命令,禁用khugepaged。
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag
相关文档