K8s 里如何优雅地使用 /dev/shm 实现容器间共享内存
1. 从 docker run 的 --shm-size 参数聊起
今天无意见看到算法同学写的一个 docker run
命令用到了 --shm-size
参数。没错,接着他想将这些容器跑到 K8s 里,于是我就得开始思考 --shm-size
在 K8s 里对应的特性是什么了。
我猜 K8s 里会有优雅的方式来实现一样的目的,最终我也找到了那个优雅的方法。不过这个过程还是稍稍坎坷,我在在网上看一圈,找到的前2种方案都有点“丑陋”,但是给人一种“只能这样”的错觉。最后看到第三条路的时候,我不禁拍了一下大腿:“我X!太帅了!”。于是乎,我想让你们也拍一下大腿,然后就有了此文。行,且往下看。
2. Linux 里的 /dev/shm
Linux 里有一个 /dev/shm
目录,shm 代表共享内存(Shared Memory)。如果这是你第一次听说 shm,可能会有点疑惑:“这东西到底是内存还是磁盘”。其实 /dev/shm
是一个临时文件系统,让你用操作磁盘中的文件一样的方式来将读写内存。换言之,你可以用文件读写的语法来操作“/dev/shm/a.txt”,但是这个文件本质是存在内存里的,所以读写速度会非常快。
有了 /dev/shm
,你就可以让一个进程非常高效地存取一些临时文件,或者让多个进程非常高效的“共享内存”。这种“进程间快速共享内存”的能力对于很多机器学习框架来说非常有用。
顺口提一下,可能大伙平时接触最多的进程间通信(IPC)方式是 Socket 和 RPC,这类走网络通信的方式可以实现跨主机的 IPC,应用场景更广。不过上帝给你开了一扇门,就不会多给你开一堆窗,Socket 和 RPC 的通信效率肯定就没有“共享内存”来得快了。(可能你心里在想 http 协议,没错,http 用的更多,但是一般 http 不被归入进程间通信方式。)
3. Docker 对共享内存的支持
在 Linux 系统中,/dev/shm
的大小一般为物理内存的一半。Docker 在启动容器的时候,默认给容器设置的 /dev/shm
大小是 64M。(你品,你细品,是不是自定义容器内 shm 大小的需求就产生了?)
Docker 在 shm 大小的配置上提供了两种支持:
docker run
支持通过--shm-size=1g
这种方式指定一个容器的 shm 大小;- Docker 配置
daemon.json
中可以通过"shared-memory-size": "1G"
配置指定容器启动的默认 shm 大小。
不难猜到,--shm-size
参数的优先级会比 shared-memory-size
配置高。
4. K8s 里如何设置 /dev/shm
大小
K8s 里没有原生提供啥直观的 shm 配置方式。但是为了让应用能够尝到“共享内存”的滋味,YAML 工程师还是得给出方案。
4.1 方案一:修改节点的 Docker 配置
Sao 操作来了,因为 Docker 支持 shared-memory-size
配置,所以直接修改节点的 daemon.json
配置,那不就让所有 Pod 都能够用起来更大的 share memory 了?
我就不演示了。反正基本满足需求,但是冥冥之中又让你觉得哪里不太对劲,总之吧,不优雅。
4.2 方案二:通过 Volume 挂载一个大目录到 Pod 的 /dev/shm
不就是让 Pod 内的 /dev/shm
大一点嘛,那就挂卷呀:
apiVersion: v1
kind: Pod
metadata:
name: shared-memory-pod
spec:
containers:
- name: mycontainer
image: your_image_name
volumeMounts:
- name: shared-memory-volume
mountPath: /dev/shm
volumes:
- name: shared-memory-volume
emptyDir: {}
如果用 PVC 的方式,后端存储系统支持限定卷大小的话,这里就能精准分配 shm 的大小了。总之,业务能跑起来。(你是不是已经忍不住要开喷了?忍忍。我知道,这种方式通过磁盘上的文件来实现“共享内存”,功能走通了,性能不达标。)
到这一步,我以为“方案一”挺合理的,改改 Docker 的启动参数,似乎影响不大,没啥大坏处,妥。
不过更进一步,K8s 真的不支持配置 shm?这个需求听起来合理呀,为什么没有被实现呢?继续搜一搜,我在 stackoverflow 上看到了第三种玩法。
4.3 方案三:用 K8s 的方式共享内存
且看这段配置:
apiVersion: v1
kind: Pod
metadata:
name: shared-memory-pod
spec:
volumes:
- name: dshm
emptyDir:
medium: Memory
sizeLimit: "1Gi"
containers:
- name: mycontainer
image: your_image_name
volumeMounts:
- name: dshm
mountPath: /dev/shm
行吧,破案了。之前我也不知道 emptyDir 可以配置 medium: Memory
。
5. 总结
散了吧,总结啥。大周五的,早点回家。
K8s 里如何优雅地使用 /dev/shm 实现容器间共享内存的更多相关文章
- oracle对/dev/shm的使用
查看共享内存打开的文件数 [root@db2 ~]# lsof -n | grep /dev/shm | wc -l 34693 共享内存中总共文件数 [root@db2 ~]# ls -l /dev ...
- 浅析/dev/shm
一,/dev/shm 概念 /dev/shm 是一个tmpfs文件系统,临时文件系统,是基于内存的文件系统,也就是说/dev/shm中的文件是直接写入内存的,而不占用硬盘空间. 在Centos和Red ...
- linux概念之/dev/shm
Linux默认(CentOS)/dev/shm分区的大小是系统物理内存的50%, 虽说使用/dev/shm对文件操作的效率会高很多,但是目前各发行软件中却很少有使用它的(除了前面提到的Oracle), ...
- 用linux服务器下的/dev/shm/来释放磁盘的压力
巧用linux服务器下的/dev/shm/来释放磁盘的压力 浏览:646 | 更新:2013-06-18 18:08 | 标签: 磁盘 tmpfs是Linux/Unix系统上的一种基于内存的文件系统. ...
- /dev/shm(转)
引用网上:/dev/shm首先可以看出来/dev/shm是一个设备文件, 可以把/dev/shm看作是系统内存的入口, 可以把它看做是一块物理存储设备,一个tmp filesystem, 你可以通过这 ...
- /dev/shm 引起的内存统计问题
最近,有个同事问我,怎么准确地描述linux系统到底还有多少内存可供我使用.这里不扯内存碎片问题,就说剩余总量. 如下: cat /proc/meminfo MemTotal: 263796812 k ...
- linux下的/dev/shm/ 以及与swap目录的区别【转】
/dev/shm 概念 首先可以看出来/dev/shm是一个设备文件, 可以把/dev/shm看作是系统内存的入口, 可以把它看做是一块物理存储设备,一个tmp filesystem, 你可以通过这个 ...
- linux下的/dev/shm/及对Oracle 的影响
一./dev/shm/介绍: /dev/shm/是linux下一个非常有用的目录,因为这个目录不在硬盘上,而是在内存里.因此在linux下,就不需要大费周折去建ramdisk,直接使用/dev/shm ...
- C扩展 从共享内存shm到memcache外部内存
引言 - ipc - shm 共享内存 本文会通过案例了解ipc 的共享内存机制使用, 后面会讲解C 如何使用外部内存服务memcached. 好先开始了解 linux 共享内存机制. 推荐先参看下面 ...
- 进程间通信之信号量、消息队列、共享内存(system v的shm和mmap)+信号signal
进程间通信方式有:System v unix提供3种进程间通信IPC:信号量.消息队列.共享内存.此外,传统方法:信号.管道.socket套接字. [注意上述6种方式只能用户层进程间通信.内核内部有类 ...
随机推荐
- [Love] VSCODE 调试 LOVE 引擎游戏
VSCODE调试LOVE引擎游戏 安装插件 配置插件 按 CTRL + SHIFT + P,打开Preferences: Open User Settings (JSON),为settings.jso ...
- 一个.NET 7 + DDD + CQRS +React+Vite的实战项目
项目简介 基于SignalR实现聊天通信,支持横向扩展,可支撑上万用户同时在线聊天 后端架构 后端技术栈采用 .NET 7 PostgreSQL (业务数据库) Redis(用于存放热点数据,和支持S ...
- MySQL数据库触发器讲解 [创建/删除/查询/select into]
刚学习实例完mysql触发器, 前来分享学习经验. 菜鸟装逼, 老鸟勿喷 先来认识一下有关触发器的一些关键词. 在使用触发器时, 这些关键词将被用到, 请记下它们的模样和用途(意思) cre ...
- 图解Spark排序算子sortBy的核心源码
原创/朱季谦 一.案例说明 以前刚开始学习Spark的时候,在练习排序算子sortBy的时候,曾发现一个有趣的现象是,在使用排序算子sortBy后直接打印的话,发现打印的结果是乱序的,并没有出现完整排 ...
- @Validated指定校验顺序
在Java中,使用@NotNull注解时,可以指定多个参数的顺序.为了指定顺序,你可以使用@GroupSequence注解. 首先,为每个需要校验的参数定义一个接口,并在接口上添加@GroupSequ ...
- 「atcoder - 214G」Three Permutations
la traduction. link. 如果我们对于每一个 \(k\in[0,n]\) 找到所有满足存在 \(k\) 个 \(i\) 使得 \(r_i=p_i\) 或 \(r_i=q_i\) 条件的 ...
- 解决CentOS 7出现docker-compose: command not found
解决CentOS 7出现docker-compose: command not found 1. 安装docker-compose 既然使用了docker-compose那自然得安装了 在GitHub ...
- 【开源】给ChatGLM写个,Java对接的SDK
作者:小傅哥 - 百度搜 小傅哥bugstack 博客:bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 大家好,我是技术UP主小傅哥. 清华大学计算机系的超大规模训练模型 Cha ...
- 文心一言 VS 讯飞星火 VS chatgpt (118)-- 算法导论10.3 3题
三.用go语言,在ALLOCATE-OBJECT和 FREE-OBJECT过程的实现中,为什么不需要设置或重置对象的 prev 属性呢? 文心一言: 在 Go 语言中,ALLOCATE-OBJECT ...
- java值传递机制
目录 1. 基本数据类型 2. 引用数据类型 3. 总结 1. 基本数据类型 public class ValueTransferTest { public static void main(Stri ...