linux大記憶體Hugepages最佳化

shuyingxi發表於2018-02-14

Hugepages是從Linux kernal 2.6後被引入的,其目的是使用更大的memory page size以適應越來越大的系統記憶體。

理論知識:

1、兩者之間有什麼區別

1. Page Table大小

      Page Table是用來存放虛擬記憶體也和實體記憶體頁對應關係的記憶體結構。因為page size較小,所以相應的改記憶體結構也會比較大。

Hugepages的常見page size2M,是4k size500倍,所以可以大大減小page tablesize

我們來看兩個例子:

這是一個沒有配置Hugepage的系統,系統記憶體128Gpagetable大小大約為4G

cat /proc/meminfo
MemTotal: 132086880 kB
PageTables: 4059612 kB

這是配置了Hugepage的系統,系統記憶體96G, PageTable大小僅為78M
MemTotal: 98999880 kB
PageTables: 79916 kB

2.大大提高了CPU cache中存放的page table所覆蓋的記憶體大小從而提高了TLB命中率

      程式的虛擬記憶體地址段先連線到page tables然後再連線到實體記憶體。所以在訪問記憶體時需要先訪問page tables得到虛擬記憶體和實體記憶體的對映關係,然後再訪問實體記憶體。

      CPU cache中有一部分TLBTranslation Lookaside Buffer)用來存放部分page table以提高這種裝換的速度。因為page size變大了,所以同樣大小的TLB,所覆蓋的記憶體大小也變大了。提高了TBL命中率,也就是提高了地址轉換的速度。

3.使用Hugepages的記憶體頁是不會被交換出去的,永遠常駐在記憶體中,所以也減少了記憶體也替換的額外開銷

 

2、資料庫伺服器上使用Hugepages要注意的幾點

1.Hugepages是在分配後就會預留出來的,其大小一定要比伺服器上所有例項的SGA總和要大,差一點都不行。

比如說Hugepages設定為90Goracle SGA91G,那麼oracle在啟動的時候就不會使用到這90GHugepages。這90G就浪費了。所以在設定Hugepages時要計算SGA的大小,後面會給出一個指令碼來計算。

2.其他程式無法使用Hugepages的記憶體,所以不要設定太大,稍稍比SGA大一點保證SGA可以使用到hugepages就好了。

3. PGA不會使用Hugepages的記憶體。所以11gAMM (Automatic Memory Managementmemory_target引數)是不被支援的。而ASMM(Automatic Shared Memory Management, SGA_target引數)是被支援的,這兩個不要搞混淆了。

4.meminfo中和Hugepage相關的有四項(RHEL5

舉例說明:

HugePages_Total: 43000
HugePages_Free: 29493
HugePages_Rsvd: 23550
Hugepagesize: 2048 kB
HugePages_Total為所分配的頁面數目,和Hugepagesize相乘後得到所分配的記憶體大小。43000*2/1024大約為84GB
HugePages_Free為從來沒有被使用過的Hugepages數目。即使oracle sga已經分配了這部分記憶體,但是如果沒有實際寫入,那麼看到的還是Free的。這是很容易誤解的地方
HugePages_Rsvd為已經被分配預留但是還沒有使用的page數目。在Oracle剛剛啟動時,大部分記憶體應該都是Reserved並且Free的,隨著oracle SGA的使用,Reserved和Free都會不斷的降低
HugePages_Free – HugePages_Rsvd 這部分是沒有被使用到的記憶體,如果沒有其他的oracle instance,這部分記憶體也許永遠都不會被使用到,也就是被浪費了。在該系統上有11.5GB的記憶體被浪費了。

Note: RHEL4上的meminfo有所區別,沒有HugePages_Rsvd這一項,並且當oracle instance啟動時,所分配的記憶體就從free list上被移除掉了。也就是啟動後HugePages_Free就是沒有被SGA用到被浪費的記憶體。

 

實戰:

3、設定HugePages步驟:

第一步:設定memlock

/etc/security/limits.conf檔案中新增memlock的限制,注意該值略微小於實際實體記憶體的大小。比如實體記憶體是64GB,可以設定為如下:

*  soft   memlock     60397977

*  hard   memlock    60397977

如果這裡的值超過了SGA的需求也沒有不利的影響。但是其實按我的實驗這個值其實大於SGA小於實體記憶體就可以儘量應該靠近SGA

如果使用了Oracle Linuxoracle?-validated或者Exadata DB compute會自動配置這個引數。

 

第二步驗證memlock使用如下命令檢視引數值  這裡最好是重啟一下伺服器再驗證比較穩妥

$ ulimit -l

60397977

 

第三步11g中禁用AMM    ----注意

如果Oracle11g以後的版本那麼預設建立的例項會使用Automatic Memory Management (AMM)的特性該特性與HugePage不相容。設定HugePage之前需要先禁用AMM。設定初始化引數MEMORY_TARGETMEMORY_MAX_TARGET0即可。使用AMM的情況下,所有的SGA記憶體都是在/dev/shm下分配的,因此在分配SGA時不會使用HugePage。這也是AMMHugePage不相容的原因。

另外:預設情況下ASM instance也是使用AMM的,但因為ASM例項不需要大SGA,所以對ASM例項使用HugePages意義不大。

所以如果我們要使用HugePage那麼就必須先確保沒有設定MEMORY_TARGET/ MEMORY_MAX_TARGET引數。

 

第四步:計算vm.nr_hugepages的建議值

確保所有的資料庫例項都已經啟動,包括ASM例項。使用hugepages_settings.sh指令碼獲取thevm.nr_hugepages核心引數的建議值。

./hugepages_settings.sh          ------指令碼見下面附件

...()

Recommended setting: vm.nr_hugepages = 1496

 

第五步/etc/sysctl.conf檔案中設定vm.nr_hugepages引數

...

vm.nr_hugepages = 1496

 

第六步停止所有例項並重啟伺服器

驗證配置:

在重啟系統之後,確保所有的資料庫例項都已經啟動,使用如下命令檢查HugePage的狀態

      為了確保HugePages配置的有效性HugePages_Free值應該小於HugePages_Total的值並且應該等於HugePages_Rsvd的值。

      正常情況應該只差1-2

例項:機器配置:128G實體記憶體+56GSGA

root># grep HugePages /proc/meminfo
HugePages_Total: 28674
HugePages_Free:    707
HugePages_Rsvd:    706

附計算hugepages指令碼:

#!/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
# 

# Welcome text
echo "
This script is provided by Doc ID 401749.1 from My Oracle Support
() 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 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}'`

# Initialize the counter
NUM_PG=0

# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | awk '{print $5}' | 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


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/438414/viewspace-2151090/,如需轉載,請註明出處,否則將追究法律責任。

相關文章