HugePage介绍
Linux操作系统以页为单位管理内存,无论是将磁盘中的数据加载到内存中,还是将内存中的数据写回磁盘。当前大部分系统默认的页大小为4096 byte 即4K。1MB内存等于256 页;1GB内存等于256000页。也可以支持大页。
在大量内存访问场景下,可以通过使用大页面来获得性能改进,同时大页内存可以减少页的交换,从而减少了磁盘I/O操作。CPU拥有内置的内存管理单元,包含这些页面的列表,每个页面通过页表条目引用,页面大小和条数不同,CPU需要处理工作负载不同。当内存越来越大的时,CPU需要管理这些内存页的成本也就越高,这样会对操作系统的性能产生影响。
- 减少页面表遍历:由于HugePage比常规大小的页面覆盖了更大的连续虚拟地址范围,因此使用HugePage获得每个TLB条目的TLB命中率高于使用常规页面。这减少了页面表从虚拟地址获取物理地址的次数。
- 内存操作开销较小:在虚拟内存系统(任何现代操作系统)上,每个内存操作实际上是两个抽象的内存操作。使用HugePages,由于可处理的页面数量较少,因此可以很好地避免页面表访问方面可能出现的瓶颈。
- 内存使用更少:从数据库的角度来看,与常规大小的页面相比,使用HugePages,Linux内核将使用更少的内存来创建页面表,以维护内存地址范围的虚拟到物理映射。
在Linux中大页分为两种:Huge pages( 标准大页 ) 和 Transparent Huge pages( 透明大页 )。
1.HugePages
HugePages是从Linux Kernel2.6 后被引入的,目的是通过使用大页内存来取代传统的4kb内存页, 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能。
Huge pages有两种格式大小:2MB 和1GB ,默认的2MB页大小。
- 2MB页块大小适合用于GB大小的内存。
- 1GB页块大小适合用于TB 级别的内。
2.Transparent HugePages
Transparent Huge Pages缩写THP,这个是RHEL6引入的一个功能,在Linux6上透明大页是默认启用的。
由于Hugepages很难手动管理,而且通常需要对代码进行重大的更改才能有效的使用,因此RHEL6开始引入了Transparent Huge Pages,THP是一个抽象层,能够自动创建、管理和使用传统大页。具了解THP目前只能映射异步内存区域,比如堆和栈空间。
3.HugePages优缺点
优点:
- 无需交换。也就是说不存在swap换入换出问题。
- 减少TLB条数,释放压力,所管理的虚拟地址数量更少,可以包含更多的地址空间,寻址能力更强。
- 降低page table负载。
- 提高内存的整体性能。
缺点: - 一次性分配,如果没有手动介入,那么永远不会释放。
- HugePage与传统4KB页使用内存不同,两者不能一起使用。
4.大页配置
在Linux的内核默认启用了大页面功能。查看如下:
shell> grep -i huge /proc/meminfo
AnonHugePages: 413696 kB ----->>返回值不为0,表示开启了THP
ShmemHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
检查当前的transparent_hugepage开启配置:
#大页是否开启:always:开启 never:禁用 madvise:表示只在MADV_HUGEPAGE标志的VMA中使用
shell> cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
#大页碎片整理defer是否开启
shell> cat /sys/kernel/mm/transparent_hugepage/defrag
always defer defer+madvise [madvise] never
#关闭大页方法
shell> echo never > /sys/kernel/mm/transparent_hugepage/enabled
shell> echo never > /sys/kernel/mm/transparent_hugepage/defrag
#重新失效,所以开机时设置never到rc.local中
shell> echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.d/rc.local
shell> echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
#授予执行权限
shell> chmod +x /etc/rc.d/rc.local
MySQL中大页设置
在MySQL中启用大页(Huge Pages)可以提高性能,还可以减少内存的使用。大页能够减少操作系统的页表,由此可减轻CPU负担和内存空间,从而减少了内存管理开销。在MySQL中,InnoDB可以使用大页面为其缓冲池和额外的内存池分配内存。
1.首先要在my.cnf配置文件,开启大页支持
[mysqld]
large-pages=ON
2.确保innodb_buffer_pool_chunk_size设置为大于Hugepagesize。默认值为128M。
3.保证操作系统大页缓存数量。InnoDB缓冲池的大小除以大页面大小(InnoDB_buffer_pool_size/Hugepagesize)。如:innodb_buffer_pool_size的默认值(128MB),并使用从/proc/meminfo(2MB)获得的Hugepagesize值,这是128MB/2MB=64,即确定所需的大页数64(称这个值为P)。
需要在操作系统/etc/sysctl.conf,并添加此处显示的行,其中P是在上一步中获得的大页面数:
#添加大页数量
shell> vim /etc/sysctl.conf
vm.nr_huge_pages=64
#载入sysctl配置文件
shell> sysctl -p
备注:nr_hugepages:表示池中大于HugePages数量。剩余HugePages的最大数量由nr_overcommit_hugepages 控制。
到此MySQL大页配置完成。
使用建议
在MySQL使用场景中,是否需要开启HugePages配置。大页虽然有优点,但又可能带来不确定的缺点。如:软件本身也对这方面的支持,虚拟化的融入,更难控制大页的处理。因此需要对使用大页的应用,进行压测,来判断是否受益于页。
可以是使用perf进行大页统计和分析:
#每秒钟输出一次dTLB读取大页情况CTRL-C退出
shell> perf stat -e dTLB-loads,dTLB-load-misses,dTLB-stores,dTLB-store-misses -a -I 1000
# time counts unit events
1.001030174 1,404,619,363 dTLB-loads [100.00%]
1.001030174 8,371,328 dTLB-load-misses [100.00%]
1.001030174 8,172,342 dTLB-stores [100.00%]
1.001030174 624,246 dTLB-store-misses
# 查看指定进程的dTLB读取大页情况
shell> perf stat -e dTLB-loads,dTLB-load-misses,dTLB-stores,dTLB-store-misses -a -p 248777
Performance counter stats for process id '248777':
1,579,026,997 dTLB-loads
8,628,213 dTLB-load-misses # 0.55% of all dTLB cache hits
773,612,816 dTLB-stores
681,404 dTLB-store-misses
7.571849344 seconds time elapsed
# 每秒钟输出一次iTLB未命中率情况
shell> perf stat -e iTLB-load,iTLB-load-misses -a -I 1000
# time counts unit events
1.000715912 624,176,335 iTLB-load [100.00%]
1.000715912 8,200,197 iTLB-load-misses
# 查看指定进程的iTLB情况
shell> perf stat -e iTLB-load,iTLB-load-misses -a -p 248777
Performance counter stats for process id '248777':
1,609,612,422 iTLB-load [100.00%]
9,912,523 iTLB-load-misses #0.06% of all iTLB cache hits
2.004872274 seconds time elapsed
总结
启用大页需要硬件和操作系统的支持,并且需要对系统进行适当的配置。目前MySQL使用中,大页没有明显的受益,建议不要开启大页。因为大页的操作往往受许多因素的影响(底层操作系统协调,MySQL内部对大页数据的读取和处理等)。综上所述,建议关闭大页,避免其带来的不确定性,如需要,就进行一系列基准测试,以确保大页功能对MySQL的性能有积极的影响。