容器实战高手课
李程远
eBay 总监级工程师,云平台架构师
4429 人已学习
立即订阅
登录后,你可以任选4讲全文学习
推荐试读
换一换
01 | 认识容器:容器的基本操作和实现原理
07 | Load Average:加了CPU Cgroup限制,为什么我的容器还是很慢?
11 | 容器文件系统:我在容器中读写文件怎么变慢了?
课程目录
已完结/共 31 讲
开篇词 (2讲)
开篇词 | 一个态度两个步骤,成为容器实战高手
01 | 认识容器:容器的基本操作和实现原理
容器进程 (6讲)
02 | 理解进程(1):为什么我在容器中不能kill 1号进程?
03|理解进程(2):为什么我的容器里有这么多僵尸进程?
04 | 理解进程(3):为什么我在容器中的进程被强制杀死了?
05|容器CPU(1):怎么限制容器的CPU使用?
06 | 容器CPU(2):如何正确地拿到容器CPU的开销?
07 | Load Average:加了CPU Cgroup限制,为什么我的容器还是很慢?
容器内存 (3讲)
08 | 容器内存:我的容器为什么被杀了?
09 | Page Cache:为什么我的容器内存使用量总是在临界点?
10 | Swap:容器可以使用Swap空间吗?
容器存储 (4讲)
11 | 容器文件系统:我在容器中读写文件怎么变慢了?
12 | 容器文件Quota:容器为什么把宿主机的磁盘写满了?
13 | 容器磁盘限速:我的容器里磁盘读写为什么不稳定?
14 | 容器中的内存与I/O:容器写文件的延时为什么波动很大?
容器网络 (4讲)
15 | 容器网络:我修改了/proc/sys/net下的参数,为什么在容器中不起效?
16 | 容器网络配置(1):容器网络不通了要怎么调试?
17|容器网络配置(2):容器网络延时要比宿主机上的高吗?
18 | 容器网络配置(3):容器中的网络乱序包怎么这么高?
容器安全 (2讲)
19 | 容器安全(1):我的容器真的需要privileged权限吗?
20 | 容器安全(2):在容器中,我不以root用户来运行程序可以吗?
结束语 (4讲)
结束语 | 跳出舒适区,突破思考的惰性
结课测试|这些容器技术的问题,你都掌握了么?
用户故事 | 莫名:相信坚持的力量,终会厚积薄发
加餐福利 | 课后思考题答案合集
专题加餐 (6讲)
加餐01 | 案例分析:怎么解决海量IPVS规则带来的网络延时抖动问题?
加餐02 | 理解perf:怎么用perf聚焦热点函数?
加餐03 | 理解ftrace(1):怎么应用ftrace查看长延时内核函数?
加餐04 | 理解ftrace(2):怎么理解ftrace背后的技术tracepoint和kprobe?
加餐05 | eBPF:怎么更加深入地查看内核中的函数?
加餐06 | BCC:入门eBPF的前端工具
容器实战高手课
15
15
1.0x
00:00/00:00
登录|注册
开通超级会员可免费学习本课程,还可解锁海量内容免费学特权。

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

你好,我是程远。这一讲,我们继续聊一聊容器中写文件性能波动的问题。
你应该还记得,我们上一讲中讲过 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/1000字
划线
笔记
复制
01 | 认识容器:容器的基本操作和实现原理
07 | Load Average:加了CPU Cgroup限制,为什么我的容器还是很慢?
11 | 容器文件系统:我在容器中读写文件怎么变慢了?
13 | 容器磁盘限速:我的容器里磁盘读写为什么不稳定?
加餐03 | 理解ftrace(1):怎么应用ftrace查看长延时内核函数?
加餐05 | eBPF:怎么更加深入地查看内核中的函数?
开通超级会员免费畅看本课程
开通会员
该文章仅可免费阅读部分内容,如需阅读完整文章,请开通超级会员或单独购买本课程。
登录 后留言

精选留言(9)

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

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

    2020-12-25
    4
  • Helios
    Memory cgroups限制的内存算上了page cache
    2020-12-21
    3
  • 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
    3
  • fuyu
    文章中的工具分析是在宿主机还在容容内?

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

    2020-12-16
    2
  • 良凯尔
    有两个疑问:
    (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
    3
    3
  • 罗峰
    可以这么理解吗,这四个阈值参数是没有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
  • 谢哈哈
    结果应该是一样的,因为使用的是DIO

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

    2020-12-19
    1
收起评论
9
返回
顶部