前言
虚拟化的目的是为了提升硬件的资源利用率,包括CPU,内存、IO等。在各种虚拟化中,都有内存压缩、内存去重等技术。本文通过介绍PowerVM的内存去重技术,有助于读者了解其他虚拟化技术内存区中底层原理。vSphere中的透明页面共享与PowerVM的内存去重技术原理基本是一致的。
名词术语解释
由于 PowerVM 的相关术语较多,并且中英文、以及英文简写夹杂在一起不利于读者理解。因此在文章正文之前,我们先介绍一下文中涉及到的相关术语,统一文中描述方式。为了使描述简介,相关术语将尽量使用英文简写。
Advanced Memory Share:PowerVM 的内存共享技术,文中简称 AMS;
Advanced Memory Share Pool:PowerVM 中的内存共享池,文中简称 AMS Pool;
Advanced Memory Deduplication:PowerVM AMS 中的新技术,用于释放 AMS Pool 中具有相同数据的物理内存页,文中简称 AMD;
Advanced Memory Max Pool size:共享内存池最大值,文中简称:AMS Max Pool size;
Desired processing units : 期望处理单元数;逻辑分区在激活时,尝试获取的 CPU 资源的数量,文中简称 desired CPU;
Desired memory:逻辑分区在激活时,尝试获取的内存资源的数量,文中简称 desired memory;
Hypervisor logical memory map:Hypervisor 逻辑内存表,用于保存逻辑分区内存页与物理页之间的映射关系,文中简称:逻辑内存表;
Hypervisor Deduplication table:重复内存数据删表,用于存放物理内存页的签名;文中简称:Deduplication table;
Micro-partition Uncapped flag:PowerVM 微分区,允许把一个 POWER CPU 划分为最多 10 个逻辑分区,每个分区使用一个 CPU 的 1/10。通过使用不封顶分区 (uncapped partition),它还允许系统的计算能力超过已经分配给分区的标称计算能力。也就是在分区 CPU 资源不足的时候,从 CPU 共享池或者其他途径获取额外的 CPU 资源,文中简称:uncapped 分区。
Micro-partition Uncapped Weight 数值:0-255;表示在 微分区 CPU 处理能力不足的时候,它可以优先获取空闲的 CPU 处理能力的优先级,255 为最高。对于优先级别比较高的微分区,我们通常将其设置成 255,如 VIOS。
文中涉及到了 Coalesce memory 与 Memory Deduplication 两个术语。前者字面意思是将有重复数据的内存页合并,后者字面意思是将有相同数据的内存页释放。实际上两者所指相同,均是 AMD 的重复数据内存页面释放功能。
Advanced Memory Deduplication 介绍
Advanced Memory Share 的原理
由于 AMD 的技术是 AMS 技术的一部分,因此,在介绍 AMD 之前,先介绍一下 AMS 的概念。
在 AMS 技术中,内存池是被多个逻辑分区共享的。每个逻辑分区的都有其 desired memory,但 desired memory 并不一定全部获取。逻辑分区获取物理内存的总量依赖于这个分区的负载大小。
例如,一个分区的负载很低,它使用 desired memory 的一部分就可以完成工作,这时,Hypervisor 将会把这个分区未使用的内存分配给其它运行负载很大,需要更多内存的分区。一个分区启动时,能够获取到的内存资源,处于其设置最小内存和期望内存之前闭区间的数值。
AMS 提高内存利用率的方法是通过降低物理内存的闲置率来实现的。这就要允许共享内存池过度使用。具体而言,就是让所有分区设置的逻辑内存总和大于共享内存池中定义的内存量。
Advanced Memory Deduplication 的原理
在 PowerVM 中,一个逻辑分区的内存并非指物理内存,而是逻辑内存。逻辑分区内存页与物理页之间的映射关系保存在一张表里,称之为 Hypervisor 逻辑内存表。当逻辑分区申请内存页的时候,PowerVM 将逻辑内存页地址转化为物理内存页地址。
Hypervisor 逻辑内存表的优势是可以使一个逻辑分区内一段连续的逻辑内存块不连续的分布在物理内存中,这样,Hypervisor 在管理不同分区的内存时更加高效,分配更加灵活。
在正常的负载下,系统将数据存放在主内存中,并且在需要的时候,从主内存中读取数据。由于负载的特性,相同的数据,尤其是包含代码指令的数据可能被存放在内存中多个内存块中。
AMD 只有在配置了共享内存池时才能生效,一旦 AMD 功能被激活,连接到这个 AMS 的所有分区都将启用 AMD 功能,我们不能只对某几个分区启动这个功能。AMD 通过释放服务器的一个分区内或者分区之间重复内存页,来减少共享内存的过量使用,从而使主内存空间相同内存页面的数量最小化。为了优化内存利用率,AMD 避免在多个不同的物理内存空间之间做数据复制。为了实现这个目的,AMD 合并不同内存页面间相同数据,让数据只存在于一个内存页,然后释放其他具有相同数据的内存页。
例如,在 AMD 功能激活的情况下,当 Hypervisor 发现两个内存页具有相同的数据,重复页面释放的算法将会修改 Hypervisor 逻辑内存地址表,让逻辑分区的两个逻辑内存页都指向一个物理内存页,而另外一个内存页将会被释放。
下图清晰地展示了 AMD 的原理。在三个分区 lpar1,lpar2,lpar3 中均逻辑内存(蓝色所示),这些内存页中所包含相同的数据。通过 AMD 释放 AMS pool 上重复的内存页面并修改逻辑内存表的映射地址,三个逻辑指向 AMS pool 中同一块物理内存。这样,就避免不同的物理内存中出现重复的数据块。
图 1.AMD 原理示意图
PowerVM 中的 Copy-on-Write
在某一时刻,一个逻辑分区在修改一个被合并的内存页面中的数据之前,Hypervisor 需要先对当前 AMS pool 中内存页面做一份拷贝,用于响应逻辑分区的修改请求。然后,逻辑分区修改这份拷贝。最终,被修改了的原内存页面的拷贝将会变成一个普通的内存页面,单独隶属于这个逻辑分区。而其他没有修改内存需求的逻辑分区,仍然指向原内存页面。
这对这个概念,可以举一个形象例子,参照上图进行理解。在服务器上,有三个区 :vioc1,vioc2,vioc3。三个分区上分别有一个逻辑内存页:a,b,c,指向同一个物理内存页 A,A 中的内容是:甲。逻辑内存页 a,b,c 中的内容也是“甲”。
若三个分区均没有修改内存页内容的请求,则状态将会保持下去。在某一时刻,vioc1 对逻辑内存页 a 发出写请求,要将这个页面中的“甲”变成“乙”。此时,Hypervisor 会先对 AMS pool 内存页 A 做一份拷贝,生成一个新的物理内存页 B,Hypervisor 修改逻辑内存表,将 B 指向 vioc1 的逻辑内存页 a;然后告诉 vioc1 可以开始修改数据。vioc1 通过从 a 到 B 的映射关系,将物理内存页中“甲”修改成“乙”。这样,vioc1 对内存的修改就完了。由于,因为 vioc2 和 vioc3 并没有对内存的修改请求,因此这两个分区依然指向物理内存页 A,里面含有内容“甲”。
PowerVM 中的 Deduplication table
为了找到重复的内存页,Hypervisor 需要定期扫描整个物理内存并且对物理内存页面进行比较。当 Hypervisor 扫描物理内存的时候,它将为物理内存创建签名,并且将这些信息保存在 deduplication table 中。
当一个内存页面的签名被 Hypervisor 发现与其他页面的签名相同的时候,Hypervisor 会认为这两个页面可能含有相同的内容。为了稳妥起见,Hypervisor 会对两个内存页面进行全面对比,以确认它们确实含有相同的数据。如果确认两个内存页面内数据完全相同,它们将会被进行重复页面删除处理。也就是说,保留一个内存页面,另外一个内存页面将会被释放。然后,Hypervisor 逻辑内存表将会进行相应的更新,这样,AMD 针对一个内存页面的一个操作就完成了。
整个流程如下图所示:
图 2.AMD 实现方法
Advanced Memory Deduplication 的配置
Advanced Memory Deduplication 的配置要求
PowerVM AMD 的版本需求如下:
图 3.AMD 对软件和硬件版本要求
配置准备
本次配置过程,以 P780 服务器为例,首先登陆到 HMC 上,确认这台 P780 服务器支持 AMD 的功能:
代码语言:javascript复制hscroot@HMC50:~> lssyscfg -r sys -m SVRP7780-06 -F name,capabilities
SVRP7780-06,"active_lpar_mobility_capable,inactive_lpar_mobility_capable,
active_lpar_share_idle_procs_capable,active_mem_dedup_capable,
active_mem_expansion_capable,active_mem_mirroring_hypervisor _capable,
active_mem_sharing_capable,autorecovery_power_on_capable,
bsr_capable,cod_mem_capable,cod_proc_capable,custom_mac_addr_capable,
electronic_err_reporting_capable,firmware_power_saver_capable,
hardware_power_saver_capable,
hardware_discovery_capable,hca_capable,huge_page_mem_capable,lhea_capable,
lpar_affinity_group_capable,lpar_avail_priority_capable,lpar_proc_compat_mode_capable,
lpar_remote_restart_capable,lpar_suspend_capable,os400_lpar_suspend_capable,
micro_lpar_capable,os400_capable,os400_net_install_capable,
redundant_err_path_reporting_capable,shared_eth_failover_capable,
sp_failover_capable,turbocore_capable,vet_activation_capable,
virtual_eth_dlpar_capable,virtual_eth_qos_capable,virtual_fc_capable,
virtual_io_server_capable,virtual_switch_capable,vlan_stat_capable,vtpm_capable
上面粗体字的部分,显示这台 P780 支持 AMD 的功能。
在 ASM 中查看 FRIMWARE 版本,符合要求:
图 4.查看服务器 Firmware 版本
查看 HMC 的版本,符合要求:
hscroot@HMC50:~> lshmc -V
"version= Version: 7
Release: 7.4.0
Service Pack: 1
HMC Build level 20111216.1","base_version=V7R7.3.0
配置过程
首先,在 HMC 上创建一个 VIO 分区:weixinyuvios,并且通过 NIM 的方式,给这个分区安装 VIOS 2.2.1.3 企业版系统。具体的安装步骤,这里不再赘述。
需要注意的是,在创建 VIOS 的 profile 时,为了使 VIOS 能够获取到足够的 CPU 资源,以提供给 AMD 使用,需要进行以下两点配置:
- 将 VIOS 设置成 Uncapped;
- 将 VIOS 的 weght 值设置成 255;
$ ioslevel
2.2.1.3
VIOS 安装完以后,需要配置 AMS 和 AMD:
在 HMC 上,选择“共享内存池管理”
图 5. 配置 AMD 步骤 1
配置 AMS pool 大小为 60G,AMS pool 最大值为 90G;并选中“启动活动内存重复数据删除”,以便启动 AMD 功能。
图 6. 配置 AMD 步骤 2
当然,我们也可以通过 HMC CLI 命令启用 AMD 功能:
chhwres -r mempool -m SVRP7780-06 -o s -a "mem_dedup=1"
接下来,设置调页空间,本服务器只有一个 VIOS:
图 7. 配置 AMD 步骤 3
点击下一步,接下来出现的页面中,点击“选择设备”
图 8. 配置 AMD 步骤 4
点击“刷新”,然后在列出的磁盘设备中选择 hdisk7 作为换页空间:
图 9. 配置 AMD 步骤 5
点击下一步,到图所示,显示出内存池和换页空间的摘要信息。 点击“确定”
图 10. 配置 AMD 步骤 6
这样,共享内存池 AMS 创建完了,AMD 也已经启动。
我们通过 HMC 的命令行也可以产看 AMD 是否已经启用:
hscroot@HMC50:~> lshwres -r mempool -m SVRP7780-06 -F mem_dedup
1
返回值为“1”,表示 AMD 功能已经启用。
接下来,安装 VIOC:weixinyuvioc。具体的安装步骤,不再赘述。
VIOC 安装完毕以后,启用分区系统 AMD 性能监控。
如下图所示,在 HMC 上,选择分区的“属性”,
图 11. 配置 AMD 步骤 7
分别打开 weixinyuvios 和 weixinyuvioc1 处理器选项中的”允许性能信息集合”:
图 12. 配置 AMD 步骤 8
需要指出的是,“允许性能信息集合”的修改并不是动态生效的,需要重启逻辑分区才能生效。 打开此功能后,在 weixinyuvioc1 执行如下命令:
代码语言:javascript复制#lparstat -mpw 1System configuration: lcpu=16 mem=8192MB mpsz=60.00GB iome=77.00MB iomp=9 ent=0.40
physb hpi hpit pmem iomin iomu iomf iohwm iomaf pgcol mpgcol ccol %entc vcsw
----- ----- ----- ----- ------ ------ ------ ------ ----- ------ ------ ---- ----- -----
26.34 0 0 3.47 23.7 11.9 41.3 15.4 0 395.2 517.1 2.0 98.4 3384
24.66 0 0 3.47 23.7 11.8 41.3 15.4 0 395.2 517.1 2.0 98.2 2925
14.01 0 0 3.47 23.7 11.8 41.3 15.4 0 395.2 517.1 2.0 65.4 19468
pgcol
:表示由于启动 AMD,而使分区内逻辑内存内存页合并的总量,以 MB 为单位。
mpgcol
:表示由于启动 AMD,而使共享内存池中内存也合并的总量,以 MB 为单位。
ccol
:AMD 所消耗的 CPU 时间片。
pmem
:表示 Hypervisor 分配给分区的物理内存,以 GB 为单位。
试验中,pgcol,mpgcol 和 ccol 均为 0 的原因是,分区上无负载,仅运行了操作系统。
需要注意的是,VIOC 的 AIX 版本必须达到 AIX 6.1 TL7,否则上面命令的 -p 参数是没有的,如下例:
代码语言:javascript复制# oslevel -s6100-06-01-1043# lparstat -mpw 1lparstat: illegal option -- p
lparstat { -i [-W] | -W | -d |-m [-e [ r | R]] | [-H | -h] | [-c] | [-E [w]]
[Interval [Count]] }
Function: Reports LPAR related information and statistics.
从 AIX6100-06-01-1043 可以直接通过安装 AIX6TL7SP1 的补丁升级到 AIX,无需安装中间补丁。
AMD 效果的衡量标准
AMD 的效率取决于节约的物理内存数量与 AMD 所需要的 CPU 资源的比值。
对于 AMD 的效果,需要关注两个数值:
Pool coalesced memory
Logical partition coalesced memory
Pool coalesced memory
Pool coalesced memory 表示在 AMD 启动期间,所有逻辑分区中合并后的物理内存总量。Pool coalesced memory 是一个全局性的度量,它统计可以访问 AMS pool 的所有逻辑分区。
只有当 AMS pool 中的物理内存页合并时,Pool coalesced memory 的数量才会增加,我们可以将其简单理解成 “AMS pool 中参与合并的物理内存页,在合并后的存页的总量”。
Logical partition coalesced memory
Logical partition coalesced memory 表示已经分配一个逻辑分区或者逻辑分区之间相同内存页合并的物理内存页的总量。我们可以将其简单理解成 “分区内或者分区间参与合并行为的内存页的数量”。在页面合并之前,所有逻辑分区的逻辑内存页面的总和等于对应 AMS poll 中所有物理内存页面的总和。
对于 AMD 而言,即使只有一个逻辑分区在运行,内存页合并也可以发生。Pool coalesced memory 的数值与 Logical partition coalesced memory 的数值没有必然的对应关系,但前者数值要比后者数值大。
为了能够清晰地介绍两个术语的关系,我们以图为例。
在下图中,有三个内存页出现重复数据,红色、绿色和蓝色的页面。然后,AMD 功能将重复数据的内存页进行合并,在共享内存池中只留下三个内存页, 也就是上面提到的 “AMS pool 中参与合并的物理内存页,在合并后的存页的总量”。在页面合并之后,所有逻辑分区逻辑内存页面的总和大于对应 AMS pool 中物理内存页面的总和。
图 13.Pool coalesced memory 与 Logical partition coalesced memory
对于 lpar1,在 AMD 之前,它有 10 个逻辑内存页(8 个绿色的和两个蓝色的),指向 AMS pool 中 10 个物理内存页。通过上面 AMD 技术,Hypervisor 已经将 AMS pool 中物理内存页合并,并且将这 10 个逻辑内粗页面指向 AMS Pool 中的两个物理内存页面。
因此,对于 lpar1 而言,其“分区内或者分区间参与合并行为的内存页的数量”为 10。同理,lpar2 的 Logical partition coalesced memory 为 2;lpar3 为:2;
因此,通过 AMD 技术,真正节省下来的物理内存页面的数量,可以用如下公式进行计算:
Total Memory Savings=(
∑Coalesced )–Pool coalesced
∑ Coalesced 表示:
Logical partition coalesced memory 的总和
Pool coalesced 表示:
Pool coalesced memory
对本例而言:
Total Memory Savings = (10 2 2) - 3 = 11
概念与公式看起来繁琐,其实不难理解:
在页面合并之前(AMD 之前),逻辑分区中总共有 14 个逻辑内存页面(将要参与页面合并的内存页面总数),对应 AMS pool 中 14 个物理内存页面。
在页面合并后,逻辑分区中总共依然有 14 个逻辑内存页面,而 AMS pool 中的物理内存页面减少到 3 个。
因此,通过 AMD,AMS pool 中实际节省出来的物理内存页面的数量是 11.
也就是说,通过 AMD 技术,有 11 个物理内存页面被释放到 AMS pool 中。如果内存页面设置 4K,则有 44K 物理内存被节省了出来。
AMD 的性能相关参数调整
为了使 AMD 性能最优,我们可以调整以下几个参数:
1.deduplication table 大小
2.AMS max pool size 的大小
3.VIOS 上空闲的 CPU 时钟周期
deduplication table 大小
deduplication table 的大小由如下公式决定:
代码语言:javascript复制 deduplication table size = AMS max pool size *deduplication table ratio
通过调整 deduplication table ratio,可以达到调整 deduplication table 的大小的目的。
在 AMS max pool size 不变的情况下,如果 deduplication table 设置的比较大,AMD 将会有更多的内存空间来存放运行 AMD 所需要的必要信息,此时 AMS pool 中的可并的内存页的数量将会增加。反正,若 deduplication table 设置的比较小,AMS pool 中可合并的内存页将会减少。
通过 HMC 的命令,可以查看默认 deduplication table ratio 的数值为 1:1024
代码语言:javascript复制hscroot@HMC50:~> lshwres -r mempool -m SVRP7780-06curr_pool_mem=61440,curr_avail_pool_mem=61100,curr_max_pool_mem=92160,
pend_pool_mem=61440,pend_avail_pool_mem=61100,pend_max_pool_mem=92160,
sys_firmware_pool_mem=263,paging_vios_names=weixinyuvios,paging_vios_ids=1,
mem_dedup=1,dedup_table_ratio=1:1024
查看系统支持的 deduplication table ratio:
代码语言:javascript复制hscroot@HMC50:~> lshwres -r mem -m SVRP7780-06 --level sysconfigurable_sys_mem=1048576,curr_avail_sys_mem=921344,pend_avail_sys_mem=921344,
installed_sys_mem=1048576,max_capacity_sys_mem=deprecated,deconfig_sys_mem=0,
sys_firmware_mem=49408,mem_region_size=256,configurable_num_sys_huge_pages=0,
curr_avail_num_sys_huge_pages=0,pend_avail_num_sys_huge_pages=0,
max_num_sys_huge_pages=60,requested_num_sys_huge_pages=0,huge_page_size=16384,
total_sys_bsr_arrays=256,bsr_array_size=4096,curr_avail_sys_bsr_arrays=256,
max_mem_pools=1,max_paging_vios_per_mem_pool=2,desired_mem_mirroring_mode=none,
pend_mem_mirroring_mode=sys_firmware_only,curr_mem_mirroring_mode=none,
default_hpt_ratios=1:64,"possible_hpt_ratios=1:32,1:64,1:128,1:256,1:512",
default_dedup_table_ratio=1:1024,"possible_dedup_table_ratios=1:256,1:512,1:1024,1:2048,1:4096,1:8192"hscroot@HMC50:~>
deduplication table ratio 的数值可以用如下命令进行修改,我们可以将其改成 1:256:
chhwres -r mempool -m SVRP7780-06 -o s -a "dedup_table_ratio=1:256"
需要注意的是,当 deduplication table ratio 的数值被改变时,所有被合并的内存页将会被拆散成多个含有相同数据的物理内存页(恢复到合并前的状态);在另外一个 deduplication table 被创建后,AMD 将会重新扫描重复数据内存页。
对于本文中的实验而言,AMS max pool size 为 90GB=92160MB,如下图:
图 14. 查看 deduplication table size 的大小
deduplication table size =92160MB*1/1024=90
因此,本实验中,deduplication table 的大小为 90MB。这 90MB 内存是 Hypervisor 从 AMS pool 中获得,为 AMD 保留使用。
AMS max pool size 的大小
AMS max pool size 的大小可以在 HMC 上动态调整的。
如下图,可以根据需要将下图中的 90 改成想要设定的数值,然后确认即可。
图 15. 查看 AMS 的大小
由于 AMS pool 的“最大池大小”修改以后,Hypervisor 所需要的用于 AMS 页面追踪的内存数量也会改变,因此,如果仅出于变更 deduplication table 的大小,则建议通过修改 deduplication table ratio 来实现。
VIOS 上空闲的 CPU 时钟周期
AMD 功能运行所需要的 CPU 时钟周期是通过连接 AMS 的 VIOS 中获取的。因此,VIOS 需要用一些空闲的 CPU 时钟周期提供给 Hypervisor ,以便其进行内存页面合并。
VIOS 上空闲 CPU 时间片的数量,对于 AMD 而言是比较重要的。如果 CPU 时间片不足,将会造成 AMD 在做重复数据内存页面释放的时候比较慢。
通过以下两个手段,可以确保 VIOS 获取足够的 CPU 资源:
- 增加 VIOS 的“期望处理器单元”的数量,一般增加 0.1 个物理 CPU;
- 将 VIOS 设置为 uncapped 分区,并且将其 weight 设置为 255;
图 16. 查看分区概要文件设置
对于本章所讲述的三个数值,我们建议设置如下:
图 17. AMD 性能相关参数推荐值
- deduplication table 采用默认值,1/1024;
- AMS max pool size 需要根据 AMS 的需要来确认;
- VIOS 上的 CPU 资源:在不启用 AMD 时 CPU 需求的基础上的数值增加 0.1 个物理 CPU。并且设置成 uncapped 分区,将 weight 设置成 255。
总结
如本文所讲,AMD 的功能开启和管理是很方便。通过 AMD,可以在 AMS 的基础上,使内存分配的颗粒度变得的更高,更好减少客户 IT 设备的闲置资源,从而降低客户的 IT 成本。在生产环境的实施中,需要认真考量 AMD 相关的性能参数,以便将性能与成本做到平衡。