侧边栏壁纸
博主头像
与晚风述往事博主等级

万般皆下品,唯有读书高。

  • 累计撰写 149 篇文章
  • 累计创建 29 个标签
  • 累计收到 19 条评论

目 录CONTENT

文章目录

使用HugePage优化内存

与晚风述往事
2022-06-08 / 0 评论 / 0 点赞 / 390 阅读 / 2,186 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-06-11,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

介绍

在Linux中,内存并不是我们想象的是一个整体,而是以一个个的页组成的,每个页的默认大小都是4KB。Linux是怎么管理这些页的呢?

Linux将内存以虚拟地址和物理地址分割开,物理地址是数据在内存中的真实地址,虚拟地址可以理解为指向真实地址的一个链接,虚拟地址和物理地址的映射关系保存在PageTables(页表)中。内存中的每个页在PageTables中都会有一条映射条目,内存越大,内存中的页也就越多,而页表的占用也就越大。

CPU在接收到访问内存的需求时,会先在页表中查询映射规则,这个查询的过程,被称为MMU。由于将虚拟地址转换为物理地址的开销较大,就又在MMU中引入了新的单元,它就是TLB(Translation Lookaside Buffer)。

TLB的作用是缓存虚拟地址和物理地址的转换关系,有了TLB单元后,MMU就有了一点变化。在CPU接收到访问内存的需求时,会先访问TLB缓存,如果在TLB缓存中找到了转换关系,就直接使用TLB中,快速访问到物理地址,这被称为TLB命中;反之,则会进行虚拟地址和物理地址的转换,在转换完成后,将其加入到TLB缓存中,这也被称为TLB未命中。如果在这个过程中,TLB缓存满了,也会有算法来决定哪条转换关系失效。

对于早期的时候内存都比较小,例如KB、MB或GB来说,PageTables不会很大,管理起来不会有很大的性能问题,但现在服务器动辄几十上百GB内存的服务器来说,4KB的内存页,PageTables会很大,可能会带来延迟问题。对此,Linux引入了HugePage,它是从Kernel 2.6开始就被广泛使用了。

HugePage是传统4KB页的替代方案,它能让Linux在内存中使用更大的页。在CentOS上,有2MB和1GB的可选项,默认情况下会使用2MB的页。如果要调整页的大小,则需要修改内核启动参数。通常情况下2MB已经足够满足服务器的需求,如果你的服务器内存在1TB以上,则建议使用1GB的内存页。

在Oracle数据库中使用HugePage后,会有以下好处:

  • 使用HugePage后,Oracle的SGA就不再会用到SWAP,这就避免了因频繁切换SWAP所带来的性能问题。
  • 减少TLB的负担,TLB是MMU中的一个单元,其作用主要是缓存虚拟地址和物理地址的转换关系。如果在查询时能在TLB中命中,就可以避免去查页表。
  • 减少PageTable占用空间,在配置HugePage后,PageTable的占用空间会有明显的降低。例如我在测试某台服务器时发现不使用HugePage时,PageTable大小344M左右;使用HugePage后,PageTable大小为50M。
  • 加快PageTable检索,PageTable的总大小降低后,检索PageTable时自然会更快。
  • 提升内存性能,Page的数量减少,大小增加,这就减少了管理过程中的复杂性,进而提升内存性能。

方案

1、备份limits.conf文件

在修改/etc/security/limits.conf文件之前,先备份它,预防出现问题后能够快速定位问题。

[root@rac-1 ~]# cp /etc/security/limits.conf /etc/security/limits.conf.20220607

2、修改limits.conf文件

备份好后,就可以编辑/etc/security/limits.conf文件了。

[root@rac-1 ~]# vim /etc/security/limits.conf

在最下面新增以下内容,然后保存并退出。

oracle  soft   memlock  unlimited
oracle  hard   memlock  unlimited

3、备份sysctl.conf文件

同理,在修改/etc/sysctl.conf文件时,先创建一个备份,以防万一。

[root@rac-1 ~]# cp /etc/sysctl.conf /etc/sysctl.conf.20220607

4、脚本计算hugepage合理值

使用Oracle提供的脚本来计算hugepage的合理值大小。注意,在使用脚本前,必须保证当前服务器的数据库实例已启动,因为脚本会根据SGA的大小去评估大页的数量。例如SGA大小是1G的话,则建议值会比1G多一点点。

新增hugepages_settings.sh脚本

[root@rac-1 ~]# vim hugepages_settings.sh

在脚本中新增以下内容,然后保存并退出。

#!/bin/bash
#
# hugepages_settings.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
# on Oracle Linux
#
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter it
# is an Oracle RDBMS shared memory segment or not.
#
# This script is provided by Doc ID 401749.1 from My Oracle Support 
# http://support.oracle.com

# Welcome text
echo "
This script is provided by Doc ID 401749.1 from My Oracle Support 
(http://support.oracle.com) where it is intended to compute values for 
the recommended HugePages/HugeTLB configuration for the current shared 
memory segments on Oracle Linux. Before proceeding with the execution please note following:
 * For ASM instance, it needs to configure ASMM instead of AMM.
 * The 'pga_aggregate_target' is outside the SGA and 
   you should accommodate this while calculating SGA size.
 * In case you changes the DB SGA size, 
   as the new SGA will not fit in the previous HugePages configuration, 
   it had better disable the whole HugePages, 
   start the DB with new SGA size and run the script again.
And make sure that:
 * Oracle Database instance(s) are up and running
 * Oracle Database 11g Automatic Memory Management (AMM) is not setup 
   (See Doc ID 749851.1)
 * The shared memory segments can be listed by command:
     # ipcs -m


Press Enter to proceed..."

read

# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`

# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
if [ -z "$HPG_SZ" ];then
    echo "The hugepages may not be supported in the system where the script is being executed."
    exit 1
fi

# Initialize the counter
NUM_PG=0

# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | cut -c44-300 | awk '{print $1}' | grep "[0-9][0-9]*"`
do
    MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
    if [ $MIN_PG -gt 0 ]; then
        NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q`
    fi
done

RES_BYTES=`echo "$NUM_PG * $HPG_SZ * 1024" | bc -q`

# An SGA less than 100MB does not make sense
# Bail out if that is the case
if [ $RES_BYTES -lt 100000000 ]; then
    echo "***********"
    echo "** ERROR **"
    echo "***********"
    echo "Sorry! There are not enough total of shared memory segments allocated for 
HugePages configuration. HugePages can only be used for shared memory segments 
that you can list by command:

    # ipcs -m

of a size that can match an Oracle Database SGA. Please make sure that:
 * Oracle Database instance is up and running 
 * Oracle Database 11g Automatic Memory Management (AMM) is not configured"
    exit 1
fi

# Finish with results
case $KERN in
    '2.2') echo "Kernel version $KERN is not supported. Exiting." ;;
    '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`;
           echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
    '2.6') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '3.8') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '3.10') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '4.1') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
esac

# End

授权脚本可执行权限

[root@rac-1 ~]# chmod +x hugepages_settings.sh

执行脚本

[root@rac-1 ~]# ./hugepages_settings.sh

image-1654572051934
如图所示,得到当前建议值为580。默认情况下,大页为2M,因此它给的建议值是580*2M,也就是1160MB,我的实例配置的SGA内存是1136M,可以看到Oracle建议值也就比SGA大了24M。

5、修改sysctl.conf文件

得到建议值后,将参数添加到/etc/sysctl.conf即可。

[root@rac-1 ~]# vim /etc/sysctl.conf

在文件最下面新增参数,然后保存并退出。

vm.nr_hugepages = 580

生效参数

[root@rac-1 ~]# sysctl -p

6、重启服务器并验证

配置好后,我们重启下服务器,然后验证大页是否启用。

重启服务器

[root@rac-1 ~]# reboot

验证

[root@rac-1 ~]# cat /proc/meminfo | grep Huge

image-1654573247909
说明:

  • HugePages_Total 系统内核已分配的大页总页数。
  • HugePages_Free 系统内核剩余未使用的页数。
  • HugePages_Rsvd 程序已申请的页数(程序已申请的页数,此时还未发生实际的读写需求,内存可能只分配了部分)。
  • HugePages_Surp 超过系统内核常驻页的数目。
  • Hugepagesize 页的大小,默认是2MB。

观察HugePages_Total和HugePages_Free这两个值是否一致,越接近则说明大页没有被使用。通常情况下HugePages_Free会明显比HugePages_Total要低。

0

评论区