A system enables the host to detect and reclaim idle memory inside guests, overcoming virtualization isolation to improve memory utilization.
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 2 个月前 | ||
| 1 个月前 | ||
| 8 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 8 个月前 | ||
| 1 个月前 |
Memlink
介绍
在云场景,随着主机上的内存容量越来越多,内存所占的整机成本持续走高(超过50%),并且大部分主机内存的整体利用率较低,所以需要技术手段能够提升主机的内存利用率。在单机视角下,最大的挑战是如何充分回收虚拟机内部的空闲内存。由于虚拟化的隔离属性,Host是无法感知到Guest内部的内存语义(包括空闲、使用等),所以当前云场景上虚拟机的内存都是预占的,例如当前4U8G虚拟机在创建的时候就需要占用8G的大页内存,并且在运行过程中,一直都是占用8G的大页内存,即使虚拟机内部实际使用可能远低于8G。
Memlink 提供两大核心子系统:
- Balloon 子系统:通过 virtio-balloon 设备感知 Guest 内部的内存使用情况,并自动回收空闲内存,提升 Host 内存利用率。
- Page Score 子系统:通过 etmem 内核接口扫描虚拟机进程的页面访问热度,生成页面访问评分(page score),并通过 TCP 服务对外提供查询接口,为页面迁移、内存压缩等内存优化策略提供决策依据。
仅支持 aarch64 架构。
软件架构
src/
├── main.c # 主入口,初始化各子系统并进入主循环
├── memlinkd.conf # 配置文件
├── memlinkd.service # systemd 服务文件
├── CMakeLists.txt # CMake 构建脚本
├── balloon/ # Balloon 子系统
│ └── balloon.c/h # Balloon 核心逻辑和驱动
├── page_score/ # Page Score 子系统
│ └── page_score.c/h # Page Score VM 管理(页面扫描、评分查询)
├── sdk/ # 对外 SDK
│ ├── memlink_sdk.c/h # 客户端 SDK 库(libmemlink_sdk.so)
│ └── memlink_example.c # SDK 示例工具
├── util/ # 工具模块
│ ├── config.c/h # 配置文件解析
│ ├── server.c/h # Unix域套接字查询服务(单线程)
│ ├── vm_manager.c/h # VM 生命周期管理器
│ ├── libvirt_helper.c/h # libvirt 事件监听封装
│ ├── etmem_scan_helper.c/h # etmem 内核接口封装(idle page 扫描)
│ ├── log.c/h # 日志模块
│ └── util.c/h # 通用工具
└── sysmonitor/
└── memlinkd-daemon # sysmonitor 守护配置
安装教程
- 进入项目目录
- 安装构建依赖:
yum-builddep memlinkd.spec - 将源码打包:
tar jcvf memlinkd.tar.bz2 --exclude=.git src - 将打包文档放到 rpm 构建目录下(如目录不存在需自行创建):
cp memlinkd.tar.bz2 /root/rpmbuild/SOURCES/ - 执行构建:
rpmbuild -ba memlinkd.spec - 安装 memlink:
cd /root/rpmbuild/RPMS/aarch64/ && rpm -ivh memlinkd-* - 安装后构建产物:
/usr/sbin/memlinkd— 主服务程序/etc/memlinkd.conf— 配置文件libmemlink_sdk.so— SDK 共享库memlink_example— SDK 示例工具
软件依赖
- libvirt / libvirt-devel
- libboundscheck
- systemd-units
- gnutls / gnutls-devel
- cmake
- CUnit-devel(测试)
使用说明
配置文件
memlink 的配置文件位于 /etc/memlinkd.conf,所有参数说明如下:
Balloon 子系统参数
| 参数 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|
balloon_enable |
0 / 1 | 1 | 是否启用 balloon 子系统 |
balloon_target_used_percent |
[120, 10000] | 130 | 利用虚拟机 used 内存计算出单虚拟机应该保留的内存量。例如配置为 130(即 1.3 倍),虚拟机规格=8G,used=4G,则 target=4G * 1.3 = 5.2G,即最多可回收 8G - 5.2G = 2.8G。 |
balloon_target_max_total_percent |
[0, 100] | 50 | 保留给虚拟机的内存量百分比下限。例如配置为 50%,虚拟机规格=10G,则最少保留 10G * 50% = 5G,即最多回收 5G。 |
Page Score 子系统参数
| 参数 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|
page_score_enable |
0 / 1 | 1 | 是否启用 page score 子系统 |
page_score_poll_cycle_sec |
[1, 3600] | 10 | page score 页面扫描周期(秒) |
其他参数
| 参数 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|
host_info_poll_time |
[100, 6000] | 1000 | 主机和虚拟机信息轮询周期(毫秒) |
init_sem_wait_timeout |
[10000, 3600000] | 600000 | 初始化信号量等待超时时间(毫秒) |
配置文件示例
balloon_enable=1
balloon_target_used_percent = 130
balloon_target_max_total_percent = 50
page_score_enable=0
page_score_poll_cycle_sec=30
运行 memlinkd
- 启动 memlinkd:
systemctl start memlinkd - 虚拟机内存 balloon 的设置需在虚拟机的 XML 配置文件中添加 balloon 设备,在启动虚拟机时添加如下字段:
<domain type='kvm' id='1'>
<memoryBacking>
<hugepages>
<page size='2' unit='MiB'/>
</hugepages>
<allocation mode="hugepage-ondemand"/>
</memoryBacking>
......
<devices>
......
<memballoon model='virtio'>
<stats period='5'/>
</memballoon>
</devices>
</domain>
Page Score 查询接口
memlinkd 启动后会开启 Unix 域套接字服务(路径 /var/run/memlinkd.sock),对外提供页面评分查询能力。支持两种请求:
查询页面访问评分(reqid: 1)
- 协议:Unix 域套接字文本协议,请求格式为
<reqid> <pid> <addr>\n - 示例:
1 12345 7f000000 - 响应:
OK <score>或ERR <message> - 用途:查询指定 QEMU 进程的指定虚拟地址页面的访问热度评分(0-65535,值越大表示访问越频繁)
查询并清零访问计数(reqid: 2)
- 协议:Unix 域套接字文本协议,请求格式为
<reqid> <pid>\n - 示例:
2 12345 - 响应:
OK <count>或ERR <message> - 用途:查询指定 QEMU 进程自上轮查询以来的总页面访问次数,查询后自动清零
SDK 使用
memlink 提供 C 语言 SDK(libmemlink_sdk.so),封装了 Unix 域套接字查询协议,方便外部程序集成。
SDK API
// 查询页面访问评分
int QueryPageScore(uint64_t addr, int pid, uint64_t *score);
// 查询并清零页面访问计数
int QueryAndClearPageAccessedCount(int pid, uint64_t *accessed_count);
SDK 示例工具
memlink_example 是 SDK 的命令行示例工具:
# 查询页面评分
memlink_example -p 12345 -a 7f000000
# 查询总访问计数
memlink_example -p 12345 -c
集成测试
cd tests/integration/
./test_memlinkd.sh
测试脚本会自动检查 memlinkd 二进制文件、配置文件、libvirtd 状态以及运行中的虚拟机状态。