第 7 章 KSM
共享内存的概念在现代操作系统中很常见。例如,当程序首次启动时,它会与父程序共享其所有内存。当子程序尝试修改此内存时,内核会分配一个新的内存区域,复制原始内容并允许程序修改这个新区域。这被称为 write(写时)的 copy。
KSM 是一种新的 Linux 功能,以相反地使用此概念。KSM 使内核能够检查两个或多个已运行程序并比较它们的内存。如果任何内存区域或页面相同,则 KSM 会将多个相同内存页减至单个页面。然后,这个页会在 write 上标记为副本。如果 guest 虚拟机修改了页面的内容,则会为该 guest 虚拟机创建一个新页面。
这对于使用 KVM 进行虚拟化非常有用。当客户机虚拟机启动时,它只会从父
qemu-kvm
进程中继承内存。客户机虚拟机运行后,可以在客户机运行相同操作系统或应用程序时,客户机虚拟机操作系统镜像的内容可以共享。
注意
页面重复数据删除技术(由 KSM 实施也使用)可能会引入侧信道,这些通道可能会用于泄漏多个客户机中的信息。如果出现这种情况,可以基于每个虚拟机禁用 KSM。
KSM 提供增强的内存速度和利用率。通过 KSM,通用进程数据存储在缓存或主内存中。这可减少 KVM 客户机的缓存丢失,从而可提高某些应用程序和操作系统的性能。其次,共享内存可减少客户机的总内存用量,从而可以增加密度并增加资源的利用率。
注意
从 Red Hat Enterprise Linux 6.5 开始,KSM 是 NUMA 感知功能。这样,它在合并页面时可以考虑 NUMA 本地性,从而避免与将页面移动到远程节点中的页面相关的性能下降。红帽建议在使用 KSM 时避免多节点内存合并。如果使用 KSM,将
/sys/kernel/mm/ksm/merge_across_nodes
可调项改为 0
,以避免在 NUMA 节点间合并页面。内核内存核算统计最终可在大量跨节点合并后相互冲突。因此,numad 在 KSM 守护进程合并大量内存后可能会变得混乱。如果您的系统有大量可用内存,可以通过关闭和禁用 KSM 守护进程来获得更高的性能。有关 NUMA 的更多信息,请参阅 Red Hat Enterprise Linux 性能调优指南。
Red Hat Enterprise Linux 使用两种单独的方法来控制 KSM:
ksm
服务启动并停止 KSM 内核线程。ksmtuned
服务控制并调整ksm
,动态管理同一页面合并。ksmtuned
服务启动ksm
,并在不需要内存共享时停止ksm
服务。ksmtuned
服务必须使用retune
参数告知在创建或销毁新客户机时运行。
这两个服务都使用标准服务管理工具进行控制。
KSM 服务
ksm
服务包含在 qemu-kvm 软件包中。在 Red Hat Enterprise Linux 6 中默认禁用 KSM。但是,当使用 Red Hat Enterprise Linux 6 作为 KVM 主机物理机器时,它可能会被 ksm/ksmtuned
服务打开。
如果没有启动
ksm
服务,则 KSM 仅共享 2000 个页面。这个默认值较低,并提供有限的内存保存优势。
启动
ksm
服务后,KSM 将最多共享主机物理机器系统主内存的一半。启动 ksm
服务,使 KSM 能够共享更多内存。
# service ksm start Starting ksm: [ OK ]
ksm
服务可以添加到默认启动序列中。使用 chkconfig 命令使 ksm
服务持久。
# chkconfig ksm on
KSM 调整服务
ksmtuned
服务没有任何选项。ksmtuned
服务循环并调整 ksm
。当客户机虚拟机被创建或销毁时,libvirt 会通知 ksmtuned
服务。
# service ksmtuned start Starting ksmtuned: [ OK ]
可以使用
retune
参数调整 ksmtuned
服务。retune
参数指示 ksmtuned
手动运行调整功能。
在更改文件中的参数前,需要说明几个术语:
thres
- 激活阈值,单位为字节。当把thres
值添加到所有qemu-kvm
进程 RSZ 超过总系统内存时,会触发 KSM 周期。这个参数在KSM_THRES_COEF
中定义的百分比的 kbytes 中相同。
/etc/ksmtuned.conf
文件是 ksmtuned
服务的配置文件。以下文件输出是默认的 ksmtuned.conf
文件。
# Configuration file for ksmtuned. # How long ksmtuned should sleep between tuning adjustments # KSM_MONITOR_INTERVAL=60 # Millisecond sleep between ksm scans for 16Gb server. # Smaller servers sleep more, bigger sleep less. # KSM_SLEEP_MSEC=10 # KSM_NPAGES_BOOST is added to thenpages
value, whenfree memory
is less thanthres
. # KSM_NPAGES_BOOST=300 # KSM_NPAGES_DECAY Value given is subtracted to thenpages
value, whenfree memory
is greater thanthres
. # KSM_NPAGES_DECAY=-50 # KSM_NPAGES_MIN is the lower limit for thenpages
value. # KSM_NPAGES_MIN=64 # KSM_NAGES_MAX is the upper limit for thenpages
value. # KSM_NPAGES_MAX=1250 # KSM_TRES_COEF - is the RAM percentage to be calculated in parameterthres
. # KSM_THRES_COEF=20 # KSM_THRES_CONST - If this is a low memory system, and thethres
value is less thanKSM_THRES_CONST
, then resetthres
value toKSM_THRES_CONST
value. # KSM_THRES_CONST=2048 # uncomment the following to enable ksmtuned debug information # LOGFILE=/var/log/ksmtuned # DEBUG=1
KSM 变量和监控
KSM 将监控数据存储在 /sys/kernel/mm/ksm/
目录中。这个目录中的文件由内核更新,是 KSM 使用和统计数据的准确记录。
以下列表中的变量也是
/etc/ksmtuned.conf
文件中的可配置变量,如下所示。
/sys/kernel/mm/ksm/
文件
- full_scans
- 完整扫描运行.
- pages_shared
- 共享的总页面。
- pages_sharing
- 现已共享的页面.
- pages_to_scan
- 页面未扫描。
- pages_unshared
- 页面不再共享。
- pages_volatile
- 易失性页面的数量。
- run
- KSM 进程是否在运行。
- sleep_millisecs
- sleep 毫秒.
如果
DEBUG=1
行添加到 /etc/ksmtuned.conf
文件中,则 KSM 调整活动将存储在 /var/log/ksmtuned
日志文件中。日志文件位置可使用 LOGFILE
参数更改。不建议更改日志文件位置,可能需要特殊配置 SELinux 设置。
取消激活 KSM
KSM 具有性能开销,对于某些环境或主机物理机器系统来说可能太大。
通过停止
ksmtuned
和 ksm
服务可停用 KSM。停止服务会停用 KSM,但重启后不会保留。
# service ksmtuned stop Stopping ksmtuned: [ OK ] # service ksm stop Stopping ksm: [ OK ]
使用 chkconfig 命令永久取消激活 KSM。要关闭服务,请运行以下命令:
# chkconfig ksm off # chkconfig ksmtuned off
重要
确保交换大小足以用于提交的 RAM,即使是 KSM。KSM 可减少相同或类似虚拟机的 RAM 使用量。可能会在没有足够 swap 空间的情况下使用 KSM 过量使用客户机,但不建议使用,因为客户机虚拟机内存使用可能会导致页面变得不共享。