合 Linux 标准大页和透明大页
Linux 标准大页和透明大页简介
HugePages是Linux内核的一个特性,它允许更大的页面管理内存,以替代4KB的页面大小。
操作系统把逻辑地址映射成物理地址时,需要把映射关系也存储到一块内存中,这部分内容就是页表(PageTables)。操作系统虚拟内存到物理内存的映射表,就被称为页表。计算机内存是通过表映射(页表)的方式进行内存寻址。CPU 拥有内置的内存管理单元,包含这些页面的列表,每个页面通过页表条目引用。当内存越来越大的时候, CPU 需要管理这些内存页的成本也就越高,这样会对操作系统的性能产生影响。
在64位机器上,目前系统默认内存以4KB为一个页,作为内存寻址的最小单元,随着内存和进程数的不断增大,页表的大小将会不断增大。内存是以块即页的方式进行管理的,当前大部分系统默认的页大小为 4096 bytes 即 4K 。 1MB 内存等于 256 页; 1GB 内存等于 256000 页。
1 2 | [lhrxxt@dbaup ~]$ getconf PAGESIZE 4096 |
在Linux操作系统中,即使是同一块共享内存,每个进程中的逻辑地址也是不相同的,因此不同进程中的映射表项也不相同。在64位的机器上,每个4k页需要占用大约8字节的内存,一台48GB内存的机器,如果分配了24GB的共享内存,则每个进程的页表大小为24GB/4K*8=48MB
;如果连接上500个进程,那么页表的大小将是500*48MB=24GB
。这会立刻把机器上的所有内存吃光【可以得到,大约1G的共享内存,若有一个进程连接,则页表大小大约为2MB】。当然,并不是每个新连接一连接上来就会分配48MB,而是当进程需要建立逻辑地址和物理地址之间的映射关系时才会分配,所以,进程占用的页表空间是缓慢增加的,但最终还是会占用很大的页表内存。
页表是必须装在内存的,而且是在CPU内存,太大就会发生大量miss,内存寻址性能就会下降。
要查看是否存在大页表的问题,可以使用如下的命令来检查页表的大小:
1 2 | [root@lhrdb ~]# cat /proc/meminfo | grep PageTables PageTables: 1932200 kB |
如果发现页表的大小不是几十兆,而是达到了1GB以上,就说明数据库存在此问题。有的数据库系统可以达到50GB的页表,严重浪费内存。基于共享内存的多进程架构的程序都会存在此问题。
Huge Page就是为了解决这个问题,它使用2MB的大页代替传统小页4KB来管理内存,这样页表大小就可以控制的很小,进而全部装在CPU内存,防止出现miss。在 Linux 中,大页分为两种:一是静态大页面(Static Huge Pages,SHP)也称为标准大页,二是透明大页面(Transparent Huge Pages,THP)。从它们的名字就可以看出,SHP是静态的,而THP是动态的。由于THP是在运行期做分配和管理,因此会有一定程度的延迟,对于内存密集型的应用(例如数据库类)十分不利,必须关闭它。
标准大页(Huge Pages)
Huge pages 是从 Linux Kernel 2.6 后被引入的,目的是通过使用大页内存来取代传统的 4kb 内存页面, 以适应越来越大的系统内存,让操作系统可以支持现代硬件架构的大页面容量功能。
Huge pages 有两种格式大小: 2MB 和 1GB , 2MB 页块大小适合用于 GB 大小的内存, 1GB 页块大小适合用于 TB 级别的内存; 2MB 是默认的页大小。
标准大页的页面大小:
1 2 | [root@docker35 ~]# grep Hugepagesize /proc/meminfo Hugepagesize: 2048 kB |
使用Huge pages优点
- 适合大内存或内存密集型应用(例如数据库)的调优。
- 减小页表尺寸(避免页表过大),降低查找缓存(TLB,Translation Lookaside Buffer)的cache-miss,加速VM内存转换。
- 可以使花费在内存管理上的 CPU 时间更少,从而提高性能。
使用Huge pages缺点
当然使用 Huge pages 也会存在某些缺点:
第一, 首先开启该功能需要进行额外设置,不同的数据库配置方法不同。
第二, 大页内存一旦设置,内存就实际分配出去了,也会一直驻留在内存中,不会被交换出去。若数据库没有使用这部分大页,那么相当于这部分大页内存是白白浪费掉的,因为它不会给文件系统缓存使用,也不能给其它不使用大页内存的程序使用。
透明大页 (Transparent Huge Pages)
Transparent Huge Pages 缩写 THP ,这个是 RHEL 6 开始引入的一个功能,在 Linux6 上透明大页是默认启用的。
由于 Huge pages 很难手动管理,而且通常需要对代码进行重大的更改才能有效的使用,因此 RHEL 6 开始引入了 Transparent Huge Pages ( THP ), THP 是一个抽象层,能够自动创建、管理和使用传统大页。
THP 为系统管理员和开发人员减少了很多使用传统大页的复杂性 , 因为 THP 的目标是改进性能 , 因此其它开发人员 ( 来自社区和红帽 ) 已在各种系统、配置、应用程序和负载中对 THP 进行了测试和优化。这样可让 THP 的默认设置改进大多数系统配置性能。但是 , 不建议对数据库工作负载使用 THP (Oracle、MySQL、PostgreSQL、MongoDB均建议关闭THP),因为THP在运行时动态分配内存,而运行时的内存分配会有延迟,对于数据库的管理来说并不友好,会导致数据库性能抖动,所以建议关闭THP。
这两者最大的区别在于 : 标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。
THP存在的问题
注:Transparent Huge Pages在32位的RHEL 6中是不支持的。
Transparent Huge Pages (THP) is a Linux memory management system that reduces the overhead of Translation Lookaside Buffer (TLB) lookups on machines with large amounts of memory by using larger memory pages.
However, database workloads often perform poorly with THP,because they tend to have sparse rather than contiguous memory access patterns.
You should disable THP on Linux machines to ensure best performance。
如何关闭 THP?(禁用透明大页)
检查当前的transparent_hugepage状态(以下为开启状态):
1 2 3 4 | [lhrxxt@dbaup ~]$ cat /sys/kernel/mm/transparent_hugepage/defrag [always] madvise never [lhrxxt@dbaup ~]$ cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never |
使用命令查看时,如果输出结果为 [always] 表示透明大页启用了,[never] 表示透明大页禁用。
透明大页关闭方法有两种,一种是通过命令关闭,一种通过修改grub开机引导文件关闭:
支持Markdown