热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【云和恩墨】性能优化:Linux环境下合理配置大内存页(HugePage)

原创2016-09-12熊军【云和恩墨】性能优化:Linux环境下合理配置大内存页(HugePage)熊军(老熊)云和恩墨西区总经理OracleACED,ACOUG核心会员PC

原创 2016-09-12 熊军 

【云和恩墨】性能优化:Linux环境下合理配置大内存页(HugePage)  

熊军(老熊)

云和恩墨西区总经理

Oracle ACED,ACOUG核心会员

 


PC Server发展到今天,在性能方面有着长足的进步。64位的CPU在数年前都已经进入到寻常的家用PC之中,更别说是更高端的PC Server;在Intel和AMD两大处理器巨头的努力下,x86 CPU在处理能力上不断提升;同时随着制造工艺的发展,在PC Server上能够安装的内存容量也越来越大,现在随处可见数十G内存的PC Server。正是硬件的发展,使得PC Server的处理能力越来越强大,性能越来越高。而在稳定性方面,搭配PC Server和Linux操作系统,同样能够满重要业务系统所需要的稳定性和可靠性。当然在成本方面,引用一位在行业软件厂商的网友的话来说,“如果不用PC Server改用小型机,那我们赚什么钱啊?”。不管从初期的购买,运行期的能耗和维护成本,PC Server都比相同处理能力的小型机便宜很多。正是在性能和成本这两个重要因素的影响下,运行在PC Server上的数据库越来越多。笔者所服务的一些客户,甚至把高端的PCServer虚拟化成多台机器,在每台虚拟机上跑一套Oracle数据库,这些数据库不乏承载着重要的生产系统。


毫无疑问,在PC Server上运行Oracle数据库,最适合的操作系统无疑是Linux。作为与UNIX极为类似的操作系统,在稳定性、可靠性和性能方面有着与UNIX同样优异的表现。但是Linux在内存分页处理机制上与AIX、HP-UX等操作系统相比有一个明显的缺陷,而这个缺陷在使用较大SGA的Oracle数据库上体现尤为明显,严重时对数据库性能有着显著的负面影响,甚至会导致数据库完全停止响应。而本文就将从一个案例来详述这种缺陷,并使用Linux下的大内存页来解决这一问题。

 

案例的引入


客户的一套系统,出现了严重的性能问题。在问题出现时,系统基本不可使用,应用上所有的业务操作完全失去响应。系统的数据库是运行在RHEL 5.2 (Red Hat Enterprise Linux Server release 5 (Tikanga))下的Oracle 10.2.0.4 Oracle Database,CPU为4颗4核至强处理器(Intel(R) Xeon(R) CPU  E7430  @ 2.13GHz),也就是逻辑CPU为16,内存32GB。故障期间,数据库服务器的CPU长期保持在100%。甚至将应用的所有Weblogic Server都关闭之后,数据库服务器的CPU利用率在数分钟之内都一直是100%,然后逐渐下降,大约需要经过20分钟才会下降到正常的空闲状态,因为这个时候所有的应用都已经关闭,只有非常低的CPU利用率才是正常的状态。据这套系统的数据库维护人员反映,这种情况已经出现多次,就算是重启数据库之后,过不了一两天,这样的故障同样会出现。同时这套系统最近也没做过大的变动。


笔者在接到接到故障报告后,通过SSH连接到数据库数据库都非常慢,需要差不多1分钟才能连接上去。先简单的看一下服务器的性能状况,发展IO极低、内存剩余还比较多,至少还有1GB以上,也没有page in / page out。而最显著的现象就是CPU利用率相当地高,一直保持在100%,同时CPU利用率的SYS部分,均在95%以上。而操作系统运行队列也一直在200以上。服务器内存的使用情况如下:


4749076 kB


从数据可以看到,PageTables内存达到了4637MB。PageTables在字面意思上是指“页面表”。简单地说,就是操作系统内核用于维护进程线性虚拟地址和实际物理内存地址对应关系的表格。


现代计算机对于物理内存,通常是将其以页(Page Frame)为单位进行管理和分配,在 x86处理器架构上,页面大小为4K。运行在操作系统上的进程,可访问的地址空间称为虚地址空间,跟处理器位数有关。对于32位的x86处理器,进程的可访问地址空间为4GB。在操作系统中运行的每一个进程,都有其独立的虚地址空间或线性地址空间,而这个地址空间同样也是按页(Page)进行管理,在Linux中,页大小通常为4KB。进程在访问内存时,由操作系统和硬件配合,负责将进程的虚拟地址转换成为物理地址。两个不同的进程,其相同的虚拟线性地址,指向的物理内存,可能相同,比如共享内存;也可能不同,比如进程的私有内存。


下图是关于虚拟地址和物理内存对应关系的示意图:


假设有两个进程A、B,分别有一个内存指针指向的地址为0x12345(0x表示16进制数),比如一个进程fork或clone出另一个进程,那么这2个进程就会存在指向相同内存地址的指针的情况。进程在访问0x12345这个地址指向的内存时,操作系统将这个地址转换为物理地址,比如A进程为0x23456,B进程为0x34567,二者互不影响。那么这个物理地址是什么时候得来?对于进程私有内存(大部分情况均是如此)来说,是进程在向操作系统请求分配内存时得来。进程向操作系统请求分配内存时,操作系统将空闲的物理内存以Page为单位分配给进程,同时给进程产生一个虚拟线程地址,在虚拟地址和物理内存地址之间建立 映射关系,这个虚拟地址作为结果返回给进程。


Page Table(页表)就是用于操作系统维护进程虚拟地址和物理内存对应关系的数据结构。下图是一个比较简单情况下的Page Table示意图:




下面简单地描述在32位系统下,页大小为4K时,操作系统是如何为进程的虚拟地址和实际物理地址之间进行转换的。

1.   目录表是用于索引页表的数据结构,每个目录项占32位,即4字节,存储一个页表的位置。目录表刚好占用1页内存,即4KB,可以存储1024个目录项,也就是可以存储1024个页表的位置。

2.   页表项(Page Table Entry)大小为4字节,存储一个物理内存页起始地址。每个页表同样占用4K内存,可以存储1024个物理内存页起始地址。由于物理内存页起始地址以4KB为单位对齐,所以32位中,只需要20位来表示地址,其他12位用于其他用途,比如表示这1内存页是只读还是可写等等。

3.   1024个页表,每个页表1024个物理内存页起始地址,合计就是1M个地址,每个地址指向的物理内存页大小为4KB,合计为4GB。

4.   操作系统及硬件将虚拟地址映射为物理地址时,将虚拟地址的31-22这10位用于从目录项中索引到1024个页表中的一个;将虚拟地址的12-21这10位用于从页表中索引到1024个页表项中的一个。从这个索引到的页表项中得到物理内存页的起始地址,然后将虚拟地址的0-11这12位用作4KB内存页中的偏移量。那么物理内存页起始地址加上偏移量就是进程所需要访问的物理内存的地址。


再看看目录表和页表这2种数据结构占用的空间会有多少。目录表固定只有4KB。而页表呢?由于最多有1024个页表,每个页表占用4KB,因此页表最多占用4MB内存。实际上32位Linux中的进程通常不会那么大的页表。进程不可能用完所有的4GB大小地址空间,甚至有1GB虚拟地址空间分给了内核。同时Linux不会为进程一次性建立那么大的页表,只有进程在分配和访问内存时,操作系统才会为进程建立相应地址的映射。


这里只描述了最简单情况下的分页映射。实际上页表目录连同页表一共有四级。同时在32位下启用PAE或64位系统,其页表结构比上面的示意图更复杂。但无论怎么样,最后一级即页表的结构是一致的。在64位系统中,Page Table(页表)中的页表项,与32位相比,大小从32位变为64位。那么这会有多大的影响?假如一个进程,访问的物理内存有1GB,即262144个内存页,在32位系统中,页表需要262144*4/1024/1024=1MB,而在64位系统下,页表占用的空间增加1倍,即为2MB。那再看看对于Linux系统中运行的Oracle数据库,又是怎么样一番情景。本文案例中数据库的SGA大小12GB,如果一个OracleProcess访问到了所有的SGA内存,那么其页表大小会是24MB,这是一个惊人的数字。这里忽略掉PGA,因为平均下来每个进程的PGA不超过2M,与SGA相比实在太小。从AWR报告来看,有300个左右的会话,那么这300个连接的页表会达到7200MB,只不过并不是每个进程都会访问到SGA中所有的内存。而从meminfo查看到的Page Tables大小达到4637MB,这么大的Page Table空间,正是300个会话,SGA大小达到12GB的结果。


系统中显然不会只有Page Table这唯一的内存管理数据结构,还有其他一些数据结构用于管理内存。这些过大的内存管理结构,无疑会大大增加操作系统内核的负担和对CPU的消耗。而在负载变化或其他原因导致内存需求大幅变化,比如多进程同时申请大量的内存,可能引起CPU在短时间内达到高峰,从而引起问题。


使用大内存页来解决问题

虽然没有确实的证据,也没有足够长的时间来收集足够的证据来证明是过大的Page Table导致了问题,那需要面临多次半小时以上的系统不可用故障。但是从目前来看,这是最大的可疑点。因此,决定先使用大内存页来调优系统的内存使用。


大内存页是一种统称,在低版本的Linux中为Large Page,而当前主流的Linux版本中为Huge Page。下面以Huge Page为例来说明Huge Page的优点及如何使用。

使用大内存页有哪些好处:

1.   减少页表(Page Table)大小。每一个Huge Page,对应的是连续的2MB物理内存,这样12GB的物理内存只需要48KB的Page Table,与原来的24MB相比减少很多。

2.   Huge Page内存只能锁定在物理内存中,不能被交换到交换区。这样避免了交换引起的性能影响。

3.   由于页表数量的减少,使得CPU中的TLB(可理解为CPU对页表的CACHE)的命中率大大提高。

4.   针对Huge Page的页表,在各进程之间可以共享,也降低了Page Table的大小。实际上这里可以反映出Linux在分页处理机制上的缺陷。而其他操作系统,比如AIX,对于共享内存段这样的内存,进程共享相同的页表,避免了Linux的这种问题。像笔者维护的一套系统,连接数平常都是5000以上,实例的SGA在60GB左右,要是按Linux的分页处理方式,系统中大部分内存都会被页表给用掉。


那么,怎么样为Oracle启用大内存页(Huge Page)?以下是实施步骤。由于案例中涉及的数据库在过一段时间后将SGA调整为了18G,这里就以18G为例:

1.   检查/proc/meminfo,确认系统支持HugePage:



HugePages Total表示系统中配置的大内存页页面数。HugePages Free表示没有访问过的大内存页面数,这里free容易引起误解,这在稍后有所解释。HugePages Rsvd表示已经分配但是还未使用的页面数。Hugepagesize表示大内存页面大小,这里为2MB,注意在有的内核配置中可能为4MB。


比如HugePages总计11GB,SGA_MAX_SIZE为10GB,SGA_TARGET为8GB。那么数据库启动后,会根据SGA_MAX_SIZE分配HugePage内存,这里为10GB,真正Free的HugePage内存为11-10=1G。但是SGA_TARGET只有8GB,那么会有2GB不会被访问到,则HugePage_Free为2+1=3GB,HugePage_Rsvd内存有2GB。这里实际上可以给其他实例使用的只有1GB,也就是真正意义上的Free只有1GB。

1.   计划要设置的内存页数量。到目前为止,大内存页只能用于共享内存段等少量类型     的内存。一旦将物理内存用作大内存页,那么这些物理内存就不能用作其他用途,比如作为进程的私有内存。因此不能将过多的内存设置为大内存页。我们通常将大内存页用作Oracle数据库的SGA,那么大内存页数量:

HugePages_Total=ceil(SGA_MAX_SIZE/Hugepagesize)+N

比如,为数据库设置的SGA_MAX_SIZE为18GB,那么页面数可以为ceil(18*1024/2)+2=9218。这里加上N,是需要将HugePage内存空间设置得比SGA_MAX_SIZE稍大,通常为1-2即可。我们通过ipcs -m命令查看共享内存段的大小,可以看到共享内存段的大小实际上比SGA_MAX_SIZE约大。如果服务器上有多个Oracle实例,需要为每个实例考虑共享内存段多出的部分,即N值会越大。另外,Oracle数据库要么全部使用大内存页,要么完全不使用大内存页,因此不合适的HugePages_Total将造成内存的浪费。

除了使用SGA_MAX_SIZE计算,也可以通过ipcs -m所获取的共享内存段大小计算出更准确的HugePages_Total。

  HugePages_Total=sum(ceil(share_segment_size/Hugepagesize))


2.   修改/etc/sysctl.conf文件,增加如下行:

vm.nr_hugepages=9218

然后执行sysctl –p命令,使配置生效。

这里vm.nr_hugepages这个参数值为第2步计算出的大内存页数量。然后检查/proc/meminfo,如果HugePages_Total小于设置的数量,那么表明没有足够的连续物理内存用于这些大内存页,需要重启服务器。


3.   在/etc/security/limits.conf文件中增加如下行:

oracle soft memlock 18878464

oracle hard memlock 18878464

这里设定oracle用户可以锁定内存的大小 ,以KB为单位。

然后重新以oracle用户连接到数据库服务器,使用ulimit -a命令,可以看到:

max lockedmemory       (kbytes, -l) 18878464

这里将memlock配置为unlimited也可以。


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


5.   最后启动数据库,检查/proc/meminfo中查看HugePages_Free是否已经减少。如果已经减少,表明已经使用到HugePage Memory。不过查看出故障数据库服务器上的/proc/meminfo时发现,居然没有HugePage相关的信息,sysctl -a查看所有系统参数也没有找到vm.nr_hugepages这个参数。这是由于Linux内核没有编译进HugePage这个特性。我们需要使用其他的内核来启用HugePage。


查看/boot/grub/grub.conf:


发现这个系统使用的内核带有"xen"字样,我们修改这个文件,将default=0改为default=2,或者将前面2种内核用#号屏蔽掉,然后重启数据库服务器,发现新的内核已经支持HugePage。


数据库启用大内存页之后,本文描述的性能问题甚至是在增大了SGA的情况下也没有出现。观察/proc/meminfo数据,PageTables占用的内存一直保持在120M以下,与原来相比,减少了4500MB。据观察,CPU的利用率也较使用HugePages之前有所下降,而系统运行也相当地稳定,至少没有出现因使用HugePage而产生的BUG。


测试表明,对于OLTP系统来说,在运行Oracle数据库的Linux上启用HugePage,数据库处理能力和响应时间均有不同程度的提高,最高甚至可以达到10%以上。


总结

本文以一个案例,介绍了Linux操作系统下大内存页在性能提升方面的作用,以及如何设置相应的参数来启用大内存页。在本文最后,笔者建议在Linux操作系统中运行Oracle数据库时,启用大内存页来避免本文案例遇到的性能问题,或进一步提高系统性能。可以说,HugePage是少数不需要额外代价就能提升性能的特性。另外值得高兴的是,新版本的Linux内核提供了Transparent Huge Pages,以便运行在Linux上的应用能更广泛更方便地使用大内存页,而不仅仅是只有共享内存这类内存才能使用大内存页。对于这一特性引起的变化,让我们拭目以待。

--the end

About Me

 

..........................................................................................................................................................................................................................................................................................................

● 本文来自于微信公众号转载文章,若有侵权,请联系小麦苗及时删除,非常感谢原创作者的无私奉献

● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新

● QQ群:230161599  微信群:私聊

● 原文地址:http://mp.weixin.qq.com/s?__biz=MjM5MDAxOTk2MQ==&mid=2650271630&idx=1&sn=cff27dce68652932016c43c9ba477832&chksm=be487798893ffe8e7ecbf93bda6f2d180d8425d0e12a3091d339cd890e749de2aa51d9f96e65&scene=1&srcid=0912gUd6GpoI9uSUCQCZrXOw#rd

● 小麦苗分享的其它资料:http://blog.itpub.net/26736162/viewspace-1624453/

● 小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● QQ群: 230161599   微信群:私聊

● 联系我请加QQ好友(642808185),注明添加缘由

● 文章内容来源于小麦苗整理的笔记,若有侵权或不当之处还请谅解!

●【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】

..........................................................................................................................................................................................................................................................................................................

手机长按下图识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,免费学习最实用的数据库技术。

 


推荐阅读
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 【重识云原生】第四章云网络4.8.3.2节——Open vSwitch工作原理详解
    2OpenvSwitch架构2.1OVS整体架构ovs-vswitchd:守护程序,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换flow-basedswitchin ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • Linux下安装依赖包版本高解决方法
    本文介绍了在Linux系统下,当已安装的依赖包版本高于需要安装的依赖包版本时,解决方法包括欺骗安装程序和修改相关配置文件等操作。针对不同情况,提供了不同的解决方案。 ... [详细]
author-avatar
远处有个蘑菇丶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有