容器实战高手课
李程远
eBay 总监级工程师,云平台架构师
24647 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 31 讲
容器实战高手课
15
15
1.0x
00:00/00:00
登录|注册

14 | 容器中的内存与I/O:容器写文件的延时为什么波动很大?

dirty_expire_centisecs
dirty_writeback_centisecs
dirty_bytes
dirty_ratio
dirty_background_bytes
dirty_background_ratio
解决思路
Page Cache和内存限制的关系
Dirty Pages回收机制
定位耗时高的函数
使用perf和ftrace工具进行分析
实验验证
相关内核参数
Dirty Pages写入到磁盘的时机
在虚拟机和容器中运行比较
设计小程序模拟现象
思考题
重点总结
调试问题
时间波动是因为Dirty Pages的影响么?
问题再现
Buffered I/O
Direct I/O
Buffered I/O在容器中的性能波动问题
Linux中的两种I/O模式
容器写文件的延时为什么波动很大

该思维导图由 AI 生成,仅供参考

你好,我是程远。这一讲,我们继续聊一聊容器中写文件性能波动的问题。
你应该还记得,我们上一讲中讲过 Linux 中的两种 I/O 模式,Direct I/O 和 Buffered I/O。
对于 Linux 的系统调用 write() 来说,Buffered I/O 是缺省模式,使用起来比较方便,而且从用户角度看,在大多数的应用场景下,用 Buffered I/O 的 write() 函数调用返回要快一些。所以,Buffered I/O 在程序中使用得更普遍一些。
当使用 Buffered I/O 的应用程序从虚拟机迁移到容器,这时我们就会发现多了 Memory Cgroup 的限制之后,write() 写相同大小的数据块花费的时间,延时波动会比较大。
这是怎么回事呢?接下来我们就带着问题开始今天的学习。

问题再现

我们可以先动手写一个小程序,用来模拟刚刚说的现象。
这个小程序我们这样来设计:从一个文件中每次读取一个 64KB 大小的数据块,然后写到一个新文件中,它可以不断读写 10GB 大小的数据。同时我们在这个小程序中做个记录,记录写每个 64KB 的数据块需要花费的时间。
我们可以先在虚拟机里直接运行,虚拟机里内存大小是大于 10GB 的。接着,我们把这个程序放到容器中运行,因为这个程序本身并不需要很多的内存,我们给它做了一个 Memory Cgroup 的内存限制,设置为 1GB。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文讨论了容器中使用Buffered I/O进行文件写入时的延时波动问题。作者通过实验观察到在容器中写入数据块的时间会时不时地增高到200us,而在虚拟机中则比较平稳。文章分析了可能的原因,包括dirty pages的影响和相关内核参数的作用,并验证了时间波动并非由于强制将dirty page写入磁盘引起。最后,文章提出了使用perf和ftrace工具对容器中写数据块的进程进行profile和调试的思路,并给出了具体的操作步骤。通过分析和实验,读者可以了解容器中写文件延时波动的原因,并学习使用工具进行调试和定位问题的方法。文章重点强调了在对容器做Memory Cgroup限制内存大小时,需要考虑容器中程序I/O的量,合理预留足够的内存作为Buffered I/O的Page Cache。总体而言,本文提供了深入的技术分析和解决问题的思路,对于容器中文件写入延时波动问题的理解和解决具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《容器实战高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(10)

  • 最新
  • 精选
  • 姜姜
    dirty_background_ratio/dirty_background_bytes: 当dirty pages超过设置值时,系统才主动开始将脏页刷到磁盘。 dirty_ratio/dirty_bytes: 当dirty pages超过该设置值时,系统会将当前所有dirty pages 全部写入到磁盘,这个过程会阻塞write()调用。 请问老师: 关于dirty_background_ratio/dirty_background_bytes,在刷脏页到磁盘的过程中,是否也会阻塞当前的write()调用呢?还是由另一个后台线程执行刷盘的工作?是每隔一段时间刷一次吗?还是一直刷到dirty pages小于dirty_background_ratio/dirty_background_bytes了才停止? 课后思考题: 因为开启了"-direct=1",采用非 buffered I/O 文件读写的方式,所以过程中不会产生脏页,但是I/O的性能会下降。

    作者回复: @姜姜 好问题! 如果dirty page的数目超过dirty_background_ratio/dirty_background_bytes对应的页面数,会有一个kernel thread把dirty page写入磁盘,这样不会阻塞当前的write()。这个kernel thread会一直刷到dirty pages小于dirty_background_ratio/dirty_background_bytes对应的页面才停止工作。

    2020-12-18
    15
  • 您好老师,想请教一下,perf能观察到哪个函数占用的cpu时间比较多,为什么还需要用ftrace来观察函数调用的时间呢; 另外ftrace统计的时间,是指cpu时间,还是墙上时间呢?

    作者回复: @威 很好的问题。 perf看到的函数占比是采样比例,有可能是函数调用的次数多。而ftrace可以看到单个函数的调用时间。 这里的时间值是wall-clock time

    2020-12-25
    8
  • 良凯尔
    有两个疑问: (1)节点可用内存是指这个节点的内存总量吗,还是剩余可分配量 (2)容器里的这个比值A,是等于 dirty pages 的内存 / 节点可用内存 *100%吗,还是说等于 dirty pages 的内存 / 容器可用内存 *100%。 (3)当节点上和容器里的/proc/sys/vm dirty page 相关内核参数配置了不同的值,会以哪个值为准呢

    作者回复: (1) 这里的可用内存可以理解为"free" 命令输出的"available" 内存。 (2) 是等于 dirty pages 的内存 / 节点可用内存 *100% (3) /proc/sys/vm/dirty_*, 在容器和宿主机上是一样的,这个值没有namespace.

    2020-12-16
    4
    7
  • Geek8819
    12G,ratio 20%,1GB内存的这个case,我理解是,该case,即便是性能低,但是也没使用超过了dirty page的上限,为了说明dirty_ratio的设置不是性能低的原因 "然后再记录一下容器程序里每写入 64KB 数据块的时间,这时候,我们就会看到,时不时一次写入的时间就会达到 9ms,这已经远远高于我们之前看到的 200us 了。因此,我们知道了这个时间的波动,并不是强制把 dirty page 写入到磁盘引起的。" 对于这一段话不是很懂,和上面的12G,ratio 20% 的例子有何关系呢? 如果是控制变量法,感觉不太合理啊,dirty_page的使用量没超过上限的话,不影响,但是超过了设置的上限,就一定不影响吗?这个case是不是应该保持dirty_bytes的数量很大?

    作者回复: @Geek8819 这个例子中后来是把dirty_bytes值设置小了,让它对write()操作产生了影响。只是这个影响产生的9ms等待时间要远远高于我们之前看到的200us。这样只是说明,200us的延时不是dirty_bytes的配置引起的。 echo 8192 > /proc/sys/vm/dirty_bytes echo 4096 > /proc/sys/vm/dirty_background_bytes

    2020-12-18
    3
    5
  • fuyu
    文章中的工具分析是在宿主机还在容容内?

    作者回复: 你指的是ftrace和perf? 在宿主机上运行的。

    2020-12-16
    2
    2
  • 谢哈哈
    结果应该是一样的,因为使用的是DIO

    作者回复: 有测试数据吗? :-)

    2020-12-19
    1
  • Helios
    Memory cgroups限制的内存算上了page cache
    2020-12-21
    3
  • 北国骑士
    在调用do_try_to_free_pages回收内存的时候,如果page是脏页,应该是会刷脏页的,为啥不把do_try_to_free_pages里面的操作进一步截图分析出来?可能就是刷脏引起的呢,另外,如果 不是刷脏页引起的,为啥不分析下 do_try_to_free_pages 耗时高的原理是什么呢,里面到底进行了什么操作导致耗时长呢?感觉分析得不彻底啊。另外,对于定位不是刷脏页引起的例子也不是太懂,感觉不是太合理。
    2022-06-15
    1
    2
  • 罗峰
    可以这么理解吗,这四个阈值参数是没有namespace的,所以容器和宿主机都是一样的值。但是统计容器的内存脏页比例是使用k8s的request memory limit。那么假如没有设置limit,那比例应该怎么算呢?按照宿主机的内存来算吗
    2021-08-24
  • 多选参数
    老师,这里有个问题,就是 dirty 相关的参数也会限制容器里的吗?比如我 dirty_background_ratio 是 10%,容器的 memory 限制是 1GB,那么容器里的 dirty page 到达 1GB*10% 之后,内核 flush 也会把 dirty pages 写入磁盘吗?还是说 dirty 相关的参数只限制全部的内存使用?
    2021-08-12
收起评论
显示
设置
留言
10
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部