zoukankan      html  css  js  c++  java
  • 透明大页

    透明大页介绍

    Transparent Huge Pages的一些官方介绍资料:

    Transparent Huge Pages (THP) are enabled by default in RHEL 6 for all applications. The kernel attempts to allocate hugepages whenever possible and any Linux process will receive 2MB pages if the mmap region is 2MB naturally aligned. The main kernel address space itself is mapped with hugepages, reducing TLB pressure from kernel code. For general information on Hugepages, see: What are Huge Pages and what are the advantages of using them?

    The kernel will always attempt to satisfy a memory allocation using hugepages. If no hugepages are available (due to non availability of physically continuous memory for example) the kernel will fall back to the regular 4KB pages. THP are also swappable (unlike hugetlbfs). This is achieved by breaking the huge page to smaller 4KB pages, which are then swapped out normally.

    But to use hugepages effectively, the kernel must find physically continuous areas of memory big enough to satisfy the request, and also properly aligned. For this, a khugepaged kernel thread has been added. This thread will occasionally attempt to substitute smaller pages being used currently with a hugepage allocation, thus maximizing THP usage.

    In userland, no modifications to the applications are necessary (hence transparent). But there are ways to optimize its use. For applications that want to use hugepages, use of posix_memalign() can also help ensure that large allocations are aligned to huge page (2MB) boundaries.

    Also, THP is only enabled for anonymous memory regions. There are plans to add support for tmpfs and page cache. THP tunables are found in the /sys tree under /sys/kernel/mm/redhat_transparent_hugepage.

    查看是否启用透明大页

    1:命令cat /sys/kernel/mm/redhat_transparent_hugepage/enabled 该命令适用于Red Hat Enterprise Linux系统

    [root@getlnx06 ~]# more /etc/issue
     
    Red Hat Enterprise Linux Server release 6.6 (Santiago)
     
    Kernel 
     on an m
     
    [root@getlnx06 ~]# cat /sys/kernel/mm/redhat_transparent_hugepage/enabled
     
    [always] madvise never

    2:命令cat /sys/kernel/mm/transparent_hugepage/enabled 该命令适用于其它Linux系统

    [root@getlnx06 ~]# cat /sys/kernel/mm/transparent_hugepage/enabled
     
    always madvise [never]
     
    [root@getlnx06 ~]# 

    使用命令查看时,如果输出结果为[always]表示透明大页启用了。[never]表示透明大页禁用、[madvise]表示(只在MADV_HUGEPAGE标志的VMA中使用THP

    3:如何HugePages_Total返回0,也意味着标准大页禁用了(注意传统/标准大页和透明大页的区别)

       透明大页(THP)管理和标准/传统大页(HP)管理都是操作系统为了减少页表转换消耗的资源而发布的新特性,虽然ORACLE建议利用大页机制来提高数据库的性能,但是ORACLE却同时建议关闭透明大页管理。这二者的区别在于大页的分配机制,标准大页管理是预分配的方式,而透明大页管理则是动态分配的方式。

    [root@getlnx06 ~]# grep -i HugePages_Total /proc/meminfo 
     
    HugePages_Total: 0

    4:cat /proc/sys/vm/nr_hugepages返回0也意味着传统大页禁用了(传统大页和透明大页)。

    [root@getlnx06 ~]# cat /proc/sys/vm/nr_hugepages 
     
    0

    禁用、启用透明大页功能

    方法1:设置/etc/grub.conf文件,在系统启动是禁用。

    [root@getlnx06 ~]# vi /etc/grub.conf
    # grub.conf generated by anaconda
    #
    # Note that you do not have to rerun grub after making changes to this file
    # NOTICE:  You have a /boot partition.  This means that
    #          all kernel and initrd paths are relative to /boot/, eg.
    #          root (hd0,0)
    #          kernel /vmlinuz-version ro root=/dev/mapper/VolGroup--LogVol0-LogVol01
    #          initrd /initrd-[generic-]version.img
    #boot=/dev/sda
    default=0
    timeout=5
    splashimage=(hd0,0)/grub/splash.xpm.gz
    hiddenmenu
    title Red Hat Enterprise Linux 6 (2.6.32-504.el6.x86_64)
            root (hd0,0)
            kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=/dev/mapper/VolGroup--LogVol0-LogVol01 rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup-LogVol0/LogVol01 rd_LVM_LV=VolGroup-LogVol0/LogVol00  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
            initrd /initramfs-2.6.32-504.el6.x86_64.img
    transparent_hugepage=never

    方法2:设置/etc/rc.local文件

    [root@getlnx06 ~]# vi /etc/rc.local
    #!/bin/sh
    #
    # This script will be executed *after* all the other init scripts.
    # You can put your own initialization stuff in here if you don't
    # want to do the full Sys V style init stuff.
     
    touch /var/lock/subsys/local
     
    if test -f /sys/kernel/mm/redhat_transparent_hugepage/enabled; then
       echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
    fi

    使用上面的配置后必须重启操作系统才能生效,你也可以运行下面命令不用重启操作系统。

    You must reboot your system for the setting to take effect, or run the following two echo lines to proceed with the install without rebooting:

    [root@getlnx06 ~]# echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
    [root@getlnx06 ~]# cat /sys/kernel/mm/redhat_transparent_hugepage/enabled
    always madvise [never]
    [root@getlnx06 ~]# 

    小知识点:

    1:从RedHat 6, OEL 6, SLES 11 and UEK2 kernels 开始,系统缺省会启用 Transparent HugePages :用来提高内存管理的性能透明大页(Transparent HugePages )和之前版本中的大页功能上类似。主要的区别是:Transparent HugePages 可以实时配置,不需要重启才能生效配置;

    2:Transparent Huge Pages在32位的RHEL 6中是不支持的。

    Transparent Huge Pages are not available on the 32-bit version of RHEL 6.

    3: ORACLE官方不建议我们使用RedHat 6, OEL 6, SLES 11 and UEK2 kernels 时的开启透明大页(Transparent HugePages ), 因为透明大页(Transparent HugePages ) 存在一些问题:

            1.在RAC环境下 透明大页(Transparent HugePages )会导致异常节点重启,和性能问题;

            2.在单机环境中,透明大页(Transparent HugePages ) 也会导致一些异常的性能问题;

    Transparent HugePages memory is enabled by default with Red Hat Enterprise Linux 6, SUSE Linux Enterprise Server 11, and Oracle Linux 6 with earlier releases of Oracle Linux Unbreakable Enterprise Kernel 2 (UEK2) kernels. Transparent HugePages memory is disabled in later releases of Oracle Linux UEK2 kernels.Transparent HugePages can cause memory allocation delays during runtime. To avoid performance issues, Oracle recommends that you disable Transparent HugePages on all Oracle Database servers. Oracle recommends that you instead use standard HugePages for enhanced performance.Transparent HugePages memory differs from standard HugePages memory because the kernel khugepaged thread allocates memory dynamically during runtime. Standard HugePages memory is pre-allocated at startup, and does not change during runtime.

    Starting with RedHat 6, OEL 6, SLES 11 and UEK2 kernels, Transparent HugePages are implemented and enabled (default) in an attempt to improve the memory management. Transparent HugePages are similar to the HugePages that have been available in previous Linux releases. The main difference is that the Transparent HugePages are set up dynamically at run time by the khugepaged thread in kernel while the regular HugePages had to be preallocated at the boot up time. Because Transparent HugePages are known to cause unexpected node reboots and performance problems with RAC, Oracle strongly advises to disable the use of Transparent HugePages. In addition, Transparent Hugepages may cause problems even in a single-instance database environment with unexpected performance problems or delays. As such, Oracle recommends disabling Transparent HugePages on all Database servers running Oracle.

    4:安装Vertica Analytic Database时也必须关闭透明大页功能。

    参考资料:

    https://access.redhat.com/solutions/46111

    http://www.soso.io/article/65143.html

    https://developers.redhat.com/blog/2014/03/10/examining-huge-pages-or-transparent-huge-pages-performance/

     https://blog.nelhage.com/post/transparent-hugepages

    Check THP usage per process

    Run the following command to monitor which processes are using THP:

    # grep -e AnonHugePages  /proc/*/smaps | awk  '{ if($2>4) print $0} ' |  awk -F "/"  '{print $0; system("ps -fp " $3)} '


    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     

    https://fangpeishi.com/transparent-hungepages_zh.html -》

    禁用透明大页

    tl;dr(长话短说)

    “透明大页(Transparent Hugepages)”是一个Linux 内核特性,它通过提高处理器的内存映射硬件的使用效率(译注:降低TLB Miss 和page fault,提高TLB 的命中率,这部分基础知识可以翻下操作系统书)来获取更好的性能。在绝大多数Linux 发行版中它是被默认启用的(“enabled=always”)。

    透明大页能让一些应用程序的性能提高一点点(最好的情况大约是10%,一般在0~3%),但是它会造成很明显的性能问题(参考:1.mongodb,2.oracle, 3.splunk), 甚至会造成严重的内存泄漏(参考:1.digitalocean,2.golang/go).

    为了避免这些问题,你应该将运行的服务器设置成enabled=madvise

    echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
    

    并在服务器的内核命令行上设置transparent_hugepage=madvise(例如在/etc/default/grub 中设置)。

    这样修改之后,应用程序能通过透明大页提升性能,也能避免上述问题(译注:设置成madvise,应用程序通过设置MADV_HUGEPAGE标志就能分配到大页,不需要的程序则不受影响)。

    继续阅读了解更多细节。

    什么是透明大页?

    什么是大页?

    数十年来,处理器和操作系统之间通过使用虚拟内存,在应用程序可见的内存空间(“虚拟内存空间(virtual address space)”)和底层的物理内存之间设置了间接层。间接层不仅保护了应用程序互相不受影响,还有许多强大的特性。

    非常多的 x86 处理器都是通过一个叫页表(page table)的方案实现虚拟内存,这个方案会在内存中存一个非常大的映射表(实际上一个深度不同的树结构,不过也可以看作是一个稀疏表)。传统上,x86 处理器中一份页表条目对应一份4KB 的内存“页”。

    虽然页表都是存在内存里,但是处理器会缓存一部分页表条目到处理器的寄存器上,它被称为TLB 。查看我笔记本上的cpuid(1)(译注:Linux tool to dump x86 CPUID information about the CPU(s))发现最低等级的TLB 只包含64个条目,每个条目对应一份4KB 的数据页。现在是2017年,64*4KB 只有四分之一兆字节,远小于目前使用的大多数应用程序的工作内存。这种大小不匹配的情况意味着占用大量内存的应用程序会周期性的遇到TLB 不命中的情况,从而需要花费很高的代价访问主内存,只为得到具体的内存地址(译注:TLB Miss 之后需要访问内存中的页表,从而得到具体内存地址)。

    为了改进TLB 的效率,x86 及其他处理器长期以来都支持创建“大页(huge pages)”,大页的页表条目能映射一大段的物理内存地址。根据操作系统的配置不同,大多数最近的芯片能够映射2MB,4MB,甚至1GB 的内存页。使用大页意味着TLB 存着更多的数据,对某些特定的任务来说效率更高。

    什么是透明大页?

    存在各种页表管理方式,这意味着操作系统需要决定如何映射地址空间和物理内存。由于应用程序的内存管理接口(例如mmap(2))一直都是基于最小的 4KB 页,所以内核映射数据必须以4KB 为单位。最简单和最灵活的(就已支持的内存布局而言)方案是只采用4KB 的页,应用程序映射内存无法使用大页。长期以来,这是内核最通用的内存管理策略。

    对于需要大量内存并对性能敏感的应用程序(例如某些特定数据库或者科学计算程序),内核引入hugetlbfs 特性,该特性允许系统管理员通过配置让特定的应用程序使用大页。

    透明大页(简称“THP”),正如其名,旨在自动为应用程序提供大页支持,不需要特殊配置(译注:透明大页的透明,类似透明代理的透明)。透明大页通过在后台扫描(使用khugepaged 内核线程)内存映射,尝试找到或者创建(通过移动相邻的内存)总共2MB 的连续4KB 映射,用一个大页来替换这一段内存映射。

    有什么问题?

    透明大页运行良好时,特定的测试场景下,可以带来大约10% 的性能提升。然而,它也会造成至少两种非常严重的故障:

    内存泄漏

    THP 倾向于创建2MB 的内存映射。然而,这样做太贪心,即使必要的情况下,也不愿意把它们拆分回去。如果一个应用程序映射了一大段内存但是只访问前面几个字节,传统上只会消耗一个4KB 的物理内存页。THP 开启的情况下,khugepaged会将4KB 页扩张到2MB,内存占用量增大512倍(这份Bug 报告 中的例子更糟糕,甚至超过512 倍!)。

    这种情况不是假设;Go 语言的GC 就有一个明确的解决方法,Digital Ocean 也记录了它们是如何处理Redis,THP 和jemalloc遇到的问题。

    (译注:据说3.10 内核透明零页有泄漏问题,内核只释放2MB 中第一个4KB 的页面,剩余的页面泄漏)

    卡顿和高CPU 使用率

    应用程序都是分配相对静态的内存,稳定的状态下,khugepaged 的工作量是最小的。但是如果存在频繁映射内存的情况,或者存在生命周期很短的进程,khugepaged 会进行大量的拆分/合并内存区域的工作,毫无意义,存活时间很短。这会引起很高的CPU 使用率,以及较长的卡顿,因为内核被迫得先把2MB 的页拆分成4KB 的页,才能执行原本在单页上效率很高的操作。

    因为这些原因,启用了THP 之后,好几个应用程序都观察到30% 的性能下降,甚至更糟。

    现在怎么办?

    THP 作者们事先意识到了透明大页可能有潜在的问题(尽管如今看来,他们低估了问题的严重性),所以他们选择通过 /sys/kernel/mm/transparent_hugepage/enabled 系统文件配置透明大页。

    更重要的是,他们为透明大页实现了一种可选择的模式。将/sys/kernel/mm/transparent_hugepage/enabled 设置为madvisekhugepaged默认情况下不会处理内存,除非应用程序使用madvise 系统调用,给特定范围的内存进行THP 处理。

    由于在大多数情况下,只有少数特定的应用程序能通过透明大页显著提升性能,所以这是一个两全其美的选项。这些少数的应用程序可以选择使用madvise,其余的应用程序不受影响。

    所以,我建议每个用户都把透明大页配置成madvise,如文章开头tl;dr所说的。同时我也希望说服主流的发行版默认禁用透明大页,让更多的系统管理员和开发者避免踩这些坑。

     
     
     
  • 相关阅读:
    UVa 12174 (滑动窗口) Shuffle
    UVa 1607 (二分) Gates
    CodeForces ZeptoLab Code Rush 2015
    HDU 1525 (博弈) Euclid's Game
    HDU 2147 (博弈) kiki's game
    UVa 11093 Just Finish it up
    UVa 10954 (Huffman 优先队列) Add All
    CodeForces Round #298 Div.2
    UVa 12627 (递归 计数 找规律) Erratic Expansion
    UVa 714 (二分) Copying Books
  • 原文地址:https://www.cnblogs.com/DataArt/p/10061579.html
Copyright © 2011-2022 走看看