[开源工具] - 容器自动内存调整工具Senpai

Senpai 是一个用于容器应用程序的自动内存大小调整工具。

确定应用程序所需的确切内存量(工作集大小)是一项困难且容易出错的任务。

启动期间使用的库和代码页面会加载到内存中,但之后不会再被触及。此外,Linux 文件系统缓存在需要新数据时才会踢出冷数据。分配的内存并不是所需内存的良好代理。这使得正确配置内存并保持足够的安全余量变得困难:内存不足时,应用程序会在负载高峰期间出现抖动或内存不足被杀死;内存过多,则会浪费昂贵的硬件资源。

Senpai 是一个用户空间工具,用于确定容器化应用程序的实际内存需求。

利用 Linux psi 指标和 cgroup2 内存限制,Senpai 在容器上施加足够的内存压力,以将不必要的冷数据和未使用的内存页面分页出去,从而在不影响正常工作负载性能的情况下释放内存。它动态适应负载高峰和低谷,从而提供应用程序随时间变化的工作集配置文件。

此信息有助于系统操作员消除浪费,预防紧急情况,优化计算网格中的任务放置,并规划长期容量/硬件需求。

一个内核编译任务的峰值内存消耗为 800M:

shell

$ time make -j4 -s
real    3m58.050s
user    13m33.735s
sys     1m30.130s

$ sort -n memory.current-nolimit.log | tail -n 1
803934208

然而,当应用 600M 的内存限制时,任务在相同的时间内完成——可用内存减少了 25%:

shell

# echo 600M > memory.high

$ time make -j4 -s
real    4m0.654s
user    13m28.493s
sys     1m31.509s

$ sort -n memory.current-600M.log | tail -n 1
629116928

显然,完整的 800M 并不是必需的。但是 600M 仍然有未知量的余量——即使是 400M 的限制也不会实质性地影响运行时间:

shell

# echo 400M > memory.high

$ time make -j4 -s
real    4m3.186s
user    13m20.452s
sys     1m31.085s

$ sort -n memory.current-400M.log | tail -n 1
419368960

另一方面,在 300M 时,工作负载难以向前推进并在合理时间内完成:

shell

# echo 300M > memory.high

$ time make -j4 -s
^C
real    9m9.974s
user    10m59.315s
sys     1m16.576s

找到作业性能开始下降的确切临界点是一个繁琐的试错过程。它也只在作业每次运行时都执行固定数量的工作时有效,比如在这个例子中,但这对于许多数据中心服务来说并不成立,这些服务无限期运行并处理高度可变的用户输入。

Senpai 在应用程序运行时确定其内存需求:

shell

# senpai .
2019-08-19 14:26:05 Configuration:
2019-08-19 14:26:05   cgpath = /sys/fs/cgroup/kernelbuild
2019-08-19 14:26:05   min_size = 104857600
2019-08-19 14:26:05   max_size = 107374182400
2019-08-19 14:26:05   interval = 5
2019-08-19 14:26:05   pressure = 1000
2019-08-19 14:26:05   max_probe = 0.01
2019-08-19 14:26:05   max_backoff = 0.1
2019-08-19 14:26:05   log_probe = 1000
2019-08-19 14:26:05   log_backoff = 10
2019-08-19 14:26:05 Resetting limit to memory.current.
2019-08-19 14:26:06 limit=100.00M pressure=0.000000 time_to_probe= 6 total=117669927 delta=0 integral=0
2019-08-19 14:26:07 limit=100.00M pressure=0.000000 time_to_probe= 5 total=117669927 delta=0 integral=0
2019-08-19 14:26:08 limit=100.00M pressure=0.000000 time_to_probe= 4 total=117669927 delta=0 integral=0

$ time make -j4 -s

2019-08-19 14:26:09 limit=100.00M pressure=0.000000 time_to_probe= 3 total=117678359 delta=8432 integral=8432
2019-08-19 14:26:09   backoff: 0.09259305978684715
2019-08-19 14:26:10 limit=109.26M pressure=0.180000 time_to_probe= 5 total=117719536 delta=41177 integral=41177
2019-08-19 14:26:10   backoff: 0.1
2019-08-19 14:26:11 limit=120.18M pressure=0.180000 time_to_probe= 5 total=117768197 delta=48661 integral=48661

...

2019-08-19 14:26:43 limit=340.48M pressure=0.160000 time_to_probe= 5 total=118045638 delta=202 integral=202
2019-08-19 14:26:44 limit=340.48M pressure=0.130000 time_to_probe= 4 total=118045638 delta=0 integral=202
2019-08-19 14:26:45 limit=340.48M pressure=0.130000 time_to_probe= 3 total=118045638 delta=0 integral=202
2019-08-19 14:26:46 limit=340.48M pressure=0.110000 time_to_probe= 2 total=118045638 delta=0 integral=202
2019-08-19 14:26:47 limit=340.48M pressure=0.110000 time_to_probe= 1 total=118045690 delta=52 integral=254
2019-08-19 14:26:48 limit=340.48M pressure=0.090000 time_to_probe= 0 total=118045690 delta=0 integral=254
2019-08-19 14:26:48   probe: -0.001983887611266873
2019-08-19 14:26:49 limit=339.80M pressure=0.090000 time_to_probe= 5 total=118045690 delta=0 integral=0

...

real    4m9.420s
user    13m21.723s
sys     1m33.037s

$ sort -n memory.current-senpai.log | tail -n 1
347762688
  • Linux v4.20 或以上版本
  • 启用 CONFIG_PSI=y
  • python3

相关内容