Ond*_*ček 5 linux memory docker
我正用这个问题把头撞在墙上。我们正在并行运行许多容器,它们正在运行简单的文件系统操作或简单的linux命令,并且其中某些在某些情况下会因内存分配问题而失败,Docker容器会出现OOMKiled。
我相信它与特定命令无关。tail不是唯一失败的命令,我们也遇到过cp或gzip。
我们已经缩小了问题的范围,并创建了一个脚本,当参数根据底层系统进行相应调整后,几乎可以肯定会失败。
https://github.com/keboola/processor-oom-test
具有默认设置的脚本会生成具有100M行(〜2.5GB)的随机CSV,将其复制20次,然后运行20个运行中的容器tail -n +2 ...。在m5.2xlarge具有1TB SSD 的AWS EC2实例上,某些容器被OOMKilled(某些容器具有不同的错误)。进程因各种错误而终止:
/code/tail.sh: line 2: 10 Killed tail -n +2 '/data/source.csv' > '/data/destination.csv'
tail: error reading '/data/source.csv': Cannot allocate memory
tail: write error
Run Code Online (Sandbox Code Playgroud)
(最后一个不是OOMKilled)
我不知道该tail消耗任何内存。如果可以同时工作的容器数量足够少,则可以轻松使用64MB的内存。对于更大数量的容器,即使256MB内存也不够用。我一直在观察htop,docker stats还没有看到内存消耗的任何峰值。
我们已经尝试过的事情
其中一些只提供了部分帮助。调整内存限制或容器数量会使它每次都再次崩溃。我们有一个带有1GB内存的容器,tail使用OOMKilled可以在大型文件崩溃时简单地运行。
关于几个月前我尝试过的内容-https: //500.keboola.com/cp-in-docker-cannot-allocate-memory-1a5f57113dc4。而--memory-swap原来只仅仅是一个局部的帮助。
有什么建议么?我不是Linux专家,所以我可能缺少一些重要的东西。任何帮助或建议,我们将不胜感激。
小智 5
似乎您对“写入缓存大小”有问题。
当您想要向磁盘写入某些内容时,它不会直接写入,而是存储在写入缓存中(称为 dirty_pages)。这是因为所有进程都不需要等到获得写入磁盘的权限并继续工作。但是,当进程长时间没有获得在磁盘上写入的权限时,它的写入缓冲区开始增长,直到达到为容器定义的内存限制。然后它被docker杀死了。
有一个名为的守护进程pdflush负责刷新缓存并将这些 dirty_pages 写入磁盘。我认为您肯定正在寻找参数vm.dirty_bytes和vm.dirty_background_bytes。这两个参数在这里有很好的描述vm.dirty_ratio 和 vm.dirty_background_ratio? 之间的区别?。
例如,如果您正在使用内存限制--memory=128M,并且您的容器一次仅运行一个进程,则您的内存vm.dirty_bytes不应超过 128M(以字节为单位)。vm.dirty_background_ratio(可以选择设置比率[总内存的%]或确切的字节数)取决于同时运行的容器数量。该值对您来说并不那么重要,您可以将其设置为 10 到 15 之间的某个值。
要设置这些变量,请使用sysctl -w. 对于你的情况应该是:
sysctl -w vm.dirty_bytes=134217728
sysctl -w vm.dirty_background_ratio=15
Run Code Online (Sandbox Code Playgroud)
希望它会有所帮助!