Linux内存管理-之-KSM功能介绍
作者:快盘下载 人气:目录
- 前言
- 1. 概述
- 1.1 使用 madvise 控制 KSM
- 1.1 KSM 守护进程 sysfs 接口
- 2.KSM技术应用场景
- 3. KSM技术实践
- 3.1 查看KSM运行情况
- 3.2 KSM设置
- 3.3 对vm的设置
前言
KSM(Kernel Samepage Merging)
共享内存的概念在现代操作系统中很常用了;比如;一个程序启动时会与父进程共用它的全部内存。当其中一个进程发生变化时;就会触发写时复制;把原来的内容写入到新的内存页中;再进行修改。这时其他的未改动的页面仍然是共享的。在执行完exec之后所有的页面不再共享;父子进程各有各的物理页。
共享内存是进程间通信的一种手段;多个进程的地址空间共享同一块物理内存;共享内存的进程在进行修改之后同样也会修改物理内存。
当linux启用了KSM之后;KSM会检查多个运行中的进程;并比对它们的内存。如果任何区域或者分页是一样的;KSM就会毫不犹豫地合并他们成一个分页。 那么新分页也是被标记成copy on write。如果VM要修改内存的话;那么linux就会分配新的内存给这个VM。
1. 概述
KSM 是一种节省内存的重复数据删除功能;由 CONFIG_KSM=y 启用;在 2.6.32 中添加到 Linux 内核中。
KSM 最初是为与 KVM;在那里称为内核共享内存;一起使用而开发的;通过共享它们之间的公共数据;将更多虚拟机放入物理内存中。但它对于生成相同数据的许多实例的任何应用程序都非常有用。
KSM 守护进程 ksmd 会定期扫描那些已注册的用户内存区域;寻找可以被单个写保护页面(fork过后的父子进程页面只读)替换的相同内容页面;如果进程稍后想要更新其内容;则会自动复制该页面;。 KSM 守护进程在单次扫描中扫描的页面数量和两次扫描之间的时间使用sysfs 接口配置
KSM 只合并匿名;私有;页面;从不合并页面缓存;文件;页面。KSM 的合并页面最初被锁定在内核内存中;但现在可以像其他用户页面一样换出;但当它们换回时共享被破坏;ksmd 必须重新发现它们的身份并再次合并;。
1.1 使用 madvise 控制 KSM
通过使用 madvise(2) 系统调用;KSM 仅在应用程序建议作为合并候选对象的地址空间区域上运行;
int madvise(addr, length, MADV_MERGEABLE)
该应用程序可能会调用
int madvise(addr, length, MADV_UNMERGEABLE)
取消该建议并恢复未共享的页面;因此 KSM 取消合并它在该范围内合并的任何内容。注意;这个取消合并的调用可能会突然需要比可用内存更多的内存 - 可能会因 EAGAIN 而失败;但更有可能引起 Out-Of-Memory 杀手。
如果 KSM 未配置到正在运行的内核中;则 madvise MADV_MERGEABLE 和 MADV_UNMERGEABLE 只会以 EINVAL 失败。如果正在运行的内核是用 CONFIG_KSM=y 构建的;那么这些调用通常会成功;即使 KSM 守护进程当前没有运行;只要 KSM 守护进程启动;MADV_MERGEABLE 仍然会注册范围;即使该范围不能包含 KSM 可以实际合并的任何页面;即使MADV_UNMERGEABLE应用于一个从来没有MADV_MERGEABLE的范围。
如果必须将内存区域拆分为至少一个新的 MADV_MERGEABLE 或 MADV_UNMERGEABLE 区域;则如果进程超出vm.max_map_count;则 madvise 可能会返回 ENOMEM 。
与其他 madvise 调用一样;它们旨在用于用户地址空间的映射区域;如果指定的范围包含未映射的间隙;尽管在中间映射区域上工作;;它们将报告 ENOMEM;如果没有足够的内存;则可能会失败并显示 EAGAIN内部结构。
应用程序在使用 MADV_MERGEABLE 时应考虑周到;将其使用限制在可能受益的领域。KSM 的扫描可能会使用大量处理能力;因此某些安装会禁用 KSM。
1.1 KSM 守护进程 sysfs 接口
KSM 守护进程由 中的 sysfs 文件控制/sys/kernel/mm/ksm/;所有人都可以读取;但只能由 root 用户写入;
- pages_to_scan
在 ksmd 进入睡眠状态之前要扫描多少页;例如。echo 100 > /sys/kernel/mm/ksm/pages_to_scan默认值;100;选择用于演示目的;
- sleep_millisecs
下一次扫描前 ksmd 应该休眠多少毫秒;例如 echo 20 > /sys/kernel/mm/ksm/sleep_millisecs默认值;20;选择用于演示目的;
- merge_across_nodes
指定是否可以合并来自不同 NUMA 节点的页面。当设置为 0 时;ksm 仅合并物理上驻留在同一 NUMA 节点的内存区域中的页面。这为访问共享页面带来了更低的延迟。具有更多节点且 NUMA 距离较远的系统可能会受益于设置 0 的较低延迟。需要最小化内存使用量的较小系统可能会受益于设置 1;默认值;的更大共享。
在决定使用哪种设置之前;您可能希望比较系统在每种设置下的性能。merge_across_nodes只有在系统中没有ksm共享页面时才能更改设置;将run 2设置为先取消合并页面;更改后merge_across_nodes设置为1 ;根据新设置重新合并 。默认值;1;在早期版本中跨节点合并;
- run
设置为 0 以停止 ksmd 运行但保留合并页面;
设置为 1 以运行 ksmd 例如;echo 1 > /sys/kernel/mm/ksm/run
设置为 2 以停止 ksmd 并取消合并当前合并的所有页面;但保留已注册的可合并区域以供下次运行。默认值;0;必须更改为 1 才能激活 KSM;除非禁用 CONFIG_SYSFS;
- use_zero_pages
指定是否应特别处理空页;即仅包含零的已分配页;。当设置为 1 时;空页将与内核零页合并;而不是像通常那样相互合并。这可以提高具有彩色零页的架构的性能;具体取决于工作负载。启用此设置时应小心;因为它可能会降低某些工作负载的 KSM 性能;例如;如果要合并的候选页面的校验和与空页面的校验和匹配。此设置可随时更改;仅对更改后合并的页面有效。默认值;0;早期版本中的正常 KSM 行为;
- max_page_sharing
每个 KSM 页面允许的最大共享。这会强制执行重复数据删除限制;以避免涉及遍历共享 KSM 页面的虚拟映射的虚拟内存操作的高延迟。最小值为 2;因为新创建的 KSM 页面将至少有两个共享者。该值越高;KSM 合并内存的速度越快;重复数据删除因子越高;但最坏情况下虚拟映射遍历对于任何给定 KSM 页面的速度可能越慢。减慢这种遍历意味着在交换、压缩、NUMA 平衡和页面迁移期间发生的某些虚拟内存操作会有更高的延迟;从而降低这些虚拟内存操作的调用者的响应能力。
- stable_node_chains_prune_millisecs
指定 KSM 检查达到重复数据删除限制的页面元数据以获取陈旧信息的频率。较小的毫秒值将释放具有较低延迟的 KSM 元数据;但它们会使 ksmd 在扫描期间使用更多 CPU。如果还没有一个 KSM 页面达到max_page_sharing;那就是一个错误。
KSM 和 MADV_MERGEABLE 的有效性显示在/sys/kernel/mm/ksm/;
-
pages_shared
正在使用多少共享页面
-
pages_sharing
还有多少网站正在共享它们;即节省了多少
-
pages_unshared
有多少页面是唯一但反复检查合并的
-
pages_volatile
有多少页面变化太快而无法放在树中
-
全扫描
已扫描所有可合并区域的次数
-
stable_node_chains
达到max_page_sharing限制的 KSM 页面数
-
stable_node_dups
重复的 KSM 页面数
较高的pages_sharingto比率pages_shared表示良好的共享;但较高的pages_unsharedto比率pages_sharing 表示浪费了精力。 pages_volatile包含几种不同类型的活动;但高比例也表明 madvise MADV_MERGEABLE 使用不当。
最大可能pages_sharing/pages_shared比率受max_page_sharing可调参数限制 。要增加比例max_page_sharing必须相应增加。
2.KSM技术应用场景
这里主要阐述在KVM上的应用
优点;
a. 一个VM启动;则只继承了父进程;qemu-kvm;的内存。一台VM的内存;可以让相同操作系统或者运行相同应用的VM共享。
b. 当开启了KSM;常用的进程数据存在缓存和主内存中。这样可以减少VM的缓存未命中;同时也提高了VM性能。
c. 共享内存降低了VM的总体内存使用率;从而允许更高的密度和更大的资源利用率。
当然每种技术都有局限性的;不同场景下;它的缺点也暴露无疑。
a.
利用KSM使内存超用。这会导致消耗一定的计算资源用于内存扫描;加重了CPU的消耗。内存超用;使得频繁地使用swap交互;导致VM性能下降。b. KSM使用了边通道;side channels;;可能存在泄露客户信息的潜在风险。为此就要考虑在VM上关闭KSM。
所以总结一下应用的场景;
a. 生产环境慎用;应急时可开启。
b. 测试环境建议使用。
c. 桌面虚拟化环境建议使用;但要注意内存使用情况。
3. KSM技术实践
Linux的2.6.32 内核中新增了 KSM(Kernel Samepage Merging;;在CentOS 6和Fedora 16中;KSM默认是打开的。而debian和ubuntu默认是没有这个服务的。 KSM通过两个服务;ksmd和ksmtuned实现;管理员应该判断他们的环境并决定保持KSM处于运行状态还是关闭它。
对centos6系统来说;在没有开启KSM时就能够满足虚拟机的内存需求;那么最好关闭KSM。关闭的方法如下;
chkconfig ksmd off
chkconfig ksmtuned off
service ksmd off
service ksmtuned off
而ubuntu默认没有KSM服务; 如果需要使用则安装ksmtuned服务
sudo apt-get install ksmtuned
service ksmtuned start
3.1 查看KSM运行情况
在/sys/kernel/mm/ksm目录下
pages_to_scan ; ksmd睡眠前需要扫描多少分页;默认是100;。
sleep_millisecs ;文件定义执行另一次页面扫描前 ksmd 休眠的毫秒数。
max_kernel_pages ;文件定义 ksmd可以使用的最大页面数;默认值是可用内存的 25%但可以写入一个 0 来指定为无限;。
pages_to_scan ;文件定义一次给定扫描中可以扫描的页面数。任何用户都可以查看。这些文件;但是用户必须拥有根权限才能修改它们。
full_scans ;文件表明已经执行的全区域扫描的次数。
pages_shared;KSM 正在使用的不可交换的内核页面的数量。
pages_sharing ;一个内存存储指示。 多少节点被共享并且多少被保存。
pages_unshared ;为合并而重复检查的惟一页面的数量。
pages_volatile;频繁改变的页面的数量。
max_page_sharing : 每个分页能运行共享的次数。
merge_across_nodes;
是否指定多个numa节点的内存进行合并。
run ;设置ksm属性的状态。
use_zero_pages ;是否合并空白分页;默认关闭。;零页合并功能在Linux较高版本才支持;
3.2 KSM设置
即然上面对KSM的作用进行了了解;那么如何在使用KSM时进行调优呢?
KSM的参数可以在/etc/ksmtuned.conf文件中调整。其默认参数如下;
以下是对于该参数的具体解释;
KSM_MONITOR_INTERVAL表示ksm每次内存扫描的时间;
KSM_SLEEP_MSEC表示每次扫描休息的间隔时间(最小值为10);KSM扫描会占用一些CPU的开销;所以当KVM虚拟机数量或者应用软件较少时可以调整KSM_SLEEP_MSEC至一个较大的值;反之则设置较小的值;同时当Hypervisor里面的虚拟机的内存调优到达一个稳定状态;也可以根据情况把这个参数调小节省CPU的开销;KSM_THRES_COEF表示临界值系数;
KSM_THRES_CONST表示临界值常量;
KSM_NPAGES_BOOST表示内存页合并增加数量;
KSM_NPAGES_DECAY表示内存页合并减少数量;
KSM_NPAGES_MIN表示内存页合并最小值;
KSM_NPAGES_MAX表示内存页合并最大值;
LOGFILE表示ksmtuned的日志存放路径;建议使用默认路径;
DEBUG取消注释才生效;建议使用默认值;
3.3 对vm的设置
在kvm环境中;可以选择VM是否允许内存合并。
为了保护客户的信息不泄露;一般我们还是会关闭KSM。步骤很简单,修改VM的xml;
<memoryBacking>
<nosharepages/>
</memoryBacking>
加载全部内容