linux大内存页设置

我的项目现场实践表明,linux的默认内存管理方式是存在问题的,不够智能,多片小的内存页管理带来CPU的高负荷,忙时SYS占用竟然达到了20%甚至30%以上,要知道这个管理开销完全是操作系统层面的,与应用无关,手动改为大内存页管理后,减少了忙时20%以上的CPU开销。这点如果足够智能,完全不需人工介入。也就是说,如果实时观察系统负荷时,发现SYS%这个CPU占用过高,一个可能的原因就是内存管理机制带来的问题,需要手动配置调整大内存页。

实际上,这一点会彻底影响oracle数据库的性能,为此oracle官方也有相应的应对策略。在alertlog有优化建议:
RECOMMENDATION:
Total System Global Area size is 98 GB. For optimal performance,
prior to the next instance restart:
1. Increase the number of unused large pages by
at least 50049 (page size 2048 KB, total size 98 GB) system wide to
get 100% of the System Global Area allocated with large pages
2. Large pages are automatically locked into physical memory.
Increase the per process memlock (soft) limit to at least 98 GB to lock
100% System Global Area's large pages into physical memory
可见,大页会自动锁定到物理内存。

以下是一段详细的描述:

HugePages is crucial for faster Oracle database performance on Linux if you have a large RAM and SGA. If your combined database SGAs is large (like more than 8GB, can even be important for smaller), you will need HugePages configured. Note that the size of the SGA matters. Advantages of HugePages are:

Larger Page Size and Less # of Pages: Default page size is 4K whereas the HugeTLB size is 2048K. That means the system would need to handle 512 times less pages.
Reduced Page Table Walking: Since a HugePage covers greater contiguous virtual address range than a regular sized page, a probability of getting a TLB hit per TLB entry with HugePages are higher than with regular pages. This reduces the number of times page tables are walked to obtain physical address from a virtual address.
Less Overhead for Memory Operations: On virtual memory systems (any modern OS) each memory operation is actually two abstract memory operations. With HugePages, since there are less number of pages to work on, the possible bottleneck on page table access is clearly avoided.
Less Memory Usage: From the Oracle Database perspective, with HugePages, the Linux kernel will use less memory to create pagetables to maintain virtual to physical mappings for SGA address range, in comparison to regular size pages. This makes more memory to be available for process-private computations or PGA usage.
No Swapping: We must avoid swapping to happen on Linux OS at all Document 1295478.1. HugePages are not swappable (whereas regular pages are). Therefore there is no page replacement mechanism overhead. HugePages are universally regarded as pinned.
No 'kswapd' Operations: kswapd will get very busy if there is a very large area to be paged (i.e. 13 million page table entries for 50GB memory) and will use an incredible amount of CPU resource. When HugePages are used, kswapd is not involved in managing them. See also Document 361670.1

以下是一个系统调整以前的情况:

[fss_jk01oracle@~]$ cat /proc/meminfo|grep -i page
AnonPages:       5147628 kB
PageTables:     65664692 kB
AnonHugePages:    946176 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
以上可以看出,PageTables是一个惊人的数值,达到65G大小。
PageTables在字面意思上是指“页面表”。简单地说,就是操作系统内核用于维护进程线性虚拟地址和实际物理内存地址对应关系的表格。“测试表明,对于OLTP系统来说,在运行Oracle数据库的Linux上启用HugePage,数据库处理能力和响应时间均有不同程度的提高,最高甚至可以达到10%以上。可以说,HugePage是少数不需要额外代价就能提升性能的特性。”实际我的实践表明不止10%,甚至达到20%以上!

■■计算HugePages_Total
Oracle数据库要么全部使用大内存页,要么完全不使用大内存页,不合适的HugePages_Total将造成内存的浪费。如下两种方法计算HugePages_Total。

■sga_max_size ---> HugePages_Total
到目前为止,大内存页只能用于共享内存段等少量类型的内存。一旦将物理内存用作大内存页,那么这些物理内存就不能用作其他用途,比如作为进程的私有内存。因此不能将过多的内存设置为大内存页。我们通常将大内存页用作Oracle数据库的SGA,大内存页数量:
HugePages_Total=ceil(SGA_MAX_SIZE/Hugepagesize)+N
这里加上N,是需要将HugePage内存空间设置得比SGA_MAX_SIZE稍大,通常为1-2即可。如果服务器上有多个Oracle实例,需要为每个实例考虑共享内存段多出的部分,即N值会越大。
如下,SGA_MAX_SIZE设置
SYS@jkdb1> show parameter sga
NAME                   TYPE                 VALUE
---------------------- -------------------- -------
lock_sga               boolean              FALSE
pre_page_sga           boolean              FALSE
sga_max_size           big integer          65024M
sga_target             big integer          65024M
HugePages_Total=65024/2+1=32513

■Shared Memory Segments ---> HugePages_Total
通过ipcs -m所获取的共享内存段大小,可计算出更准确的HugePages_Total:
HugePages_Total=sum(ceil(share_segment_size/Hugepagesize))
共享内存段的大小实际上比SGA_MAX_SIZE略大。
[fss_jk01oracle@~]$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 458760     oracle     640        402653184  983
0x00000000 491529     oracle     640        67779952640 983
0xecb7f040 524298     oracle     640        2097152    983
HugePages_Total=192+32320+1=32513

■■修改limits.conf文件
cat >> /etc/security/limits.conf << EOF
oracle soft memlock unlimited
oracle hard memlock unlimited
EOF
这里设定oracle用户可以锁定内存的大小 ,以KB为单位。
Memlock值大于sga没关系的,所以我们能够设置这个值在我们想要的SGA size和物理内存size之间,这个值得单位是kb。
然后重新以oracle用户登陆到数据库服务器,使用ulimit -a命令,可以看到:
max lockedmemory       (kbytes, -l) unlimited
这里将memlock配置为unlimited也可以。

■■修改sysctl.conf文件
■增加如下行
这里vm.nr_hugepages这个参数值为计算出的大内存页数量。
cat >> /etc/sysctl.conf << EOF
vm.nr_hugepages=32513
EOF
■然后使配置生效
sysctl -p
此时系统开始分配使用hugepage,可能需要一段时间。随时观察检查/proc/meminfo,如果HugePages_Total小于设置的数量,表明没有足够的连续物理内存用于这些大内存页,可能需要重启服务器。
cat /proc/meminfo|grep -i page
AnonPages:       2261824 kB
PageTables:      1627476 kB
AnonHugePages:    686080 kB
HugePages_Total:   50049
HugePages_Free:    50049
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

■■确认SGA设置,禁用11G的AMM特性
如果数据库使用MANUAL方式管理SGA,需要改为AUTO方式,即将SGA_TARGET_SIZE设置为大于0的值。对于11g,由于HugePage只能用于共享内存,不能用于PGA,所以不能使用AMM,即不能设置MEMORY_TARGET为大于0,只能分别设置SGA和PGA,SGA只能是AUTO方式管理。

■■最后重新登陆oracle用户,重启数据库
检查/proc/meminfo中查看HugePages_Free是否已经减少。如果已经减少,表明已经使用到HugePage Memory。
此时查看alertlog,可以看到是否启用hugepage,如下:
Thu Sep 28 23:31:13 2017
Starting ORACLE instance (normal)
************************ Large Pages Information *******************
Per process system memlock (soft) limit = UNLIMITED
Total Shared Global Region in Large Pages = 64 GB (100%)
Large Pages used by this instance: 32513 (64 GB)
Large Pages unused system wide = 0 (0 KB)
Large Pages configured system wide = 32513 (64 GB)
Large Page size = 2048 KB
********************************************************************

第二天上午忙时9:52,观察hugepage使用情况,比较理想:
[SYS@jkdb2>]$ cat /proc/meminfo|grep -i page
AnonPages:       3853560 kB
PageTables:       238060 kB
AnonHugePages:    829440 kB
HugePages_Total:   32513
HugePages_Free:     1022
HugePages_Rsvd:     1022
HugePages_Surp:        0
Hugepagesize:       2048 kB

简单来说,配置优化前,CPU需要动态管理的PageTables是一个惊人的数值,达到65G,优化配置后,需维护管理的PageTables仅为200M大小,因此大大减轻了CPU的管理负担。

实际上,目前系统忙时的SYS占用一般在0.1-3%左右。

《linux大内存页设置》有1个想法

  1. 参考其他工具的计算公式,每个共享内存段的数目+1,
    HugePages_Total=192+32320+1=32513 改为:
    HugePages_Total=(192+1)+(32320+1)+(1+1)=32516

发表评论

电子邮件地址不会被公开。 必填项已用*标注