LINUX HUGEPAGES在大内存数据库中的应用


背景介绍
随着X86服务器被越来越多的客户所接受,LINUX操作系统也越来越多的被作为主流的数据库服务器操作系统,我们都知道在现今的IT行业中,内存已经相对越来越廉价,一般的普通的X86服务器内存动辄百G甚至T级别,随着硬件的不断升级,相应的,软件的配置也要发生相对变化,从最简单的理解,操作系统从原先的管理百G以下的内存,到现在的管理T级别的内存,如果没有相应的管理方法,相应的管理效率肯定会降低。 

LINUX操作系统进程是通过虚拟地址对内存进行访问,而CPU必须把它转换成实际的物理内存地址才能真正访问内存。而CPU通过缓存最近的虚拟内存地址和物理内存地址的映射关系来提高访问效率,并且保存在一个由CPU维护的映射表中。为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。我们都知道,在传统的LINUX内存管理模式中,内存都是以页的形式进行分配的,默认每个内存页大小为4K。这就产生了一个问题,在原先的百G左右的内存下,可能整个映射表还在可控范围内,而当内存增加到T级别后,内存页依旧是4K大小,这就会导致整个映射表变得非常庞大,导致CPU的检索效率大大降低。而HUGEPAGES就是在这样一个环境下产生。

概念普及

hugepage是在Linux2.6内核中被引入的,提供4k的pagesize和比较大的pagesize的选择。huge page 的大小取决于所使用的操作系统的内核版本以及不同的硬件平台
可以使用$grep Hugepagesize /proc/meminfo来查看huge page 的大小,对于较大的系统内存以及sga,使用hugepage可以极大程度的提高Oracle数据库性能

注意点:

Hugepage虽然是一个比较好的选择方案,但仍然需要注意以下几点:

1. HugePages 在操作系统启动后,如果没有管理员的介入,是不会释放和改变的,是属于一种常驻内存

2. HugePages 也不会被交换.也就是没有换入换出过程(page-in/page-out)。HugePages一直被pin在内存中,这就要求我们不能把HugePages设置过大。

3. 由于AMM(Automatic Memory Management)特性与Hugepages不兼容,如果希望使用HugePages需要禁用AMM特性。、

4. Hugepages是在分配后就会预留出来的,其大小一定要比服务器上所有实例的SGA总和要大,如果比SGA小,oracle SGA将无法使用Hugepages,例如当我们设置SGA为40G而设置Hugepages为30G那么oracle将无法使用这30G的内存,所以这也是相对比较危险的一点,可能在前期配置中没有问题,但是后期人为的调整了SGA大小,将SGA的大小超过了Hugepages的大小,那么就会导致致命的错误,最糟糕的结果就是由于oracle无法得到内存而宕掉。

操作过程

以下讲解如何配置Hugepages过程以RHEL6.2环境为模板,配置过程也可以参见MOS文档:HugePages on Oracle Linux 64-bit (文档 ID 361468.1)

[root@rehl6 ~]# more /etc/redhat-release

Red Hat Enterprise Linux Server release 6.2 (Santiago)

[root@rehl6 ~]# uname -a

Linux rehl6 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux


Step 1:查看当前系统是否配值HugePages

下面的查询中HugePages相关的几个值都为0,表明当前未配值HugePages

[root@rehl6 ~]# grep Huge /proc/meminfo

AnonHugePages:   1142784 kB

HugePages_Total:       0

HugePages_Free:        0

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB

我们来详细解释一下一上4个参数值的意思:

HugePages_Total为所分配的页面总数目,该值和Hugepagesize相乘后得到所分配的内存大小。

HugePages_Free为从来没有被使用过的Hugepages数目。即使oraclesga已经分配了这部分内存,但是如果没有实际写入,那么看到的还是Free的。这是很容易误解的地方

HugePages_Rsvd为已经被分配预留但是还没有使用的page数目。在Oracle刚刚启动时,大部分内存应该都是Reserved并且Free的,随着oracleSGA的使用,Reserved和Free都会不断的降低

HugePages_Free减去HugePages_Rsvd 这部分是没有被使用到的内存,如果没有其他的oracleinstance,这部分内存也许永远都不会被使用到,也就是被浪费了。

Step 2:修改用户的memlock限制

通过修改/etc/security/limits.conf 配值文件来实现

  该参数的值通常配值位略小于当前的已安装系统内存,如当前你的系统内存为30G,可以做如下设置

  *   soft   memlock    30000000

  *   hard   memlock    30000000

  上述的设置单位为kb,不会降低系统性能。至少也要配值为略大于系统上所有SGA的总和。

  退出重新登录并使用ulimit -l 来校验该设置

 

Step 3:禁用AMM(Oracle 11g)

如果当前的Oracle 版本为10g,可以跳过此步骤。

如果当前的Oracle 版本为11g,由于AMM(Automatic Memory Management)特性与Hugepages不兼容,需要禁用AMM。

ALTER SYSTEM RESET memory_target SCOPE=SPFILE;

ALTER SYSTEM RESET memory_max_target SCOPE=SPFILE;

ALTER SYSTEM SET sga_target=g SCOPE=SPFILE;

ALTER SYSTEM SET pga_aggregate_target=g SCOPE=SPFILE;

SHUTDOWN IMMEDIATE;

STARTUP;

实践证明,在MOS文档中提供的以上方法是不行的,对于重新设置memory_target需要通过导出参数文件删除memory_target及memory_max_target并设置相关的SGA值重新创建spfile才可以。

Step 4:计算vm.nr_hugepages 值

简单的计算方法如下:(只做系统估计)

简单的计算原理是total SGA_MAX_SIZE(多个instance的总和)/hugepagesize + N

N为少量内存盈余,一般多出100就足够了。如果主机内存128GB,计划70GB用于SGA共享内存,则大内存页需70×1024/2=35840

使用Oracle 提供的脚本hugepages_settings.sh的脚本来计算vm.nr_hugepages的值(这个值设置的是hugepage momory 的大小)

  在执行脚本之前确保所有的Oracle 实例已启动以及ASM也启动(存在的情形下)

  $ ./hugepages_settings.sh

该文档脚本可以参看MOS文档(Shell Script to Calculate Values Recommended Linux HugePages / HugeTLB Configuration (文档 ID 401749.1)),附录一提供摘录

 

Step 5:设置vm.nr_hugepages参数

编辑/etc/sysctl.conf 来设置vm.nr_hugepages参数

  $ sysctl -w vm.nr_hugepages = 1496(该值为上述脚本获得的值,vm.nr_hugepages指明了内存页数) 

  $ sysctl -p

 

Step 6 重启主机验证

HugePages相关参数的值会随着当前服务器上的实例的停止与启动而动态发生变化

  通常情况下,HugePages_Free的值应当小于HugePages_Total的值,在HugePages被使用时HugePages_Rsvd值应当为非零值。

  $ grep Huge /proc/meminfo

  HugePages_Total:   131

  HugePages_Free:     20

  HugePages_Rsvd:     20

  Hugepagesize:     2048 kB

 

  如下面的情形,当服务器上仅有的一个实例被关闭后,HugePages_Rsvd的值为零。且HugePages_Free等于HugePages_Total

  $ grep Huge /proc/meminfo

  HugePages_Total:   131

  HugePages_Free:    131

  HugePages_Rsvd:      0

  Hugepagesize:     2048 kB  

 

附录一:

hugepages_settings.sh

#!/bin/bash

#

# hugepages_settings.sh

#

# Linux bash script to compute values for the

# recommended HugePages/HugeTLB configuration

#

# 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. 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.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" ;;

     *) echo "Unrecognized kernel version $KERN. Exiting." ;;

esac

 

# End

 ---------------------------------------------------------------------------------------------------

原博客地址:http://blog.itpub.net/23732248/
原作者:应以峰 (frank-ying)
----------------------------------------------------------------------------------------------------

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23732248/viewspace-1449366/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23732248/viewspace-1449366/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值