今天無意見看到演演算法同學寫的一個 docker run
命令用到了 --shm-size
引數。沒錯,接著他想將這些容器跑到 K8s 裡,於是我就得開始思考 --shm-size
在 K8s 裡對應的特性是什麼了。
我猜 K8s 裡會有優雅的方式來實現一樣的目的,最終我也找到了那個優雅的方法。不過這個過程還是稍稍坎坷,我在在網上看一圈,找到的前2種方案都有點「醜陋」,但是給人一種「只能這樣」的錯覺。最後看到第三條路的時候,我不禁拍了一下大腿:「我X!太帥了!」。於是乎,我想讓你們也拍一下大腿,然後就有了此文。行,且往下看。
Linux 裡有一個 /dev/shm
目錄,shm 代表共用記憶體(Shared Memory)。如果這是你第一次聽說 shm,可能會有點疑惑:「這東西到底是記憶體還是磁碟」。其實 /dev/shm
是一個臨時檔案系統,讓你用操作磁碟中的檔案一樣的方式來將讀寫記憶體。換言之,你可以用檔案讀寫的語法來操作「/dev/shm/a.txt」,但是這個檔案本質是存在記憶體裡的,所以讀寫速度會非常快。
有了 /dev/shm
,你就可以讓一個程序非常高效地存取一些臨時檔案,或者讓多個程序非常高效的「共用記憶體」。這種「程序間快速共用記憶體」的能力對於很多機器學習框架來說非常有用。
順口提一下,可能大夥平時接觸最多的程序間通訊(IPC)方式是 Socket 和 RPC,這類走網路通訊的方式可以實現跨主機的 IPC,應用場景更廣。不過上帝給你開了一扇門,就不會多給你開一堆窗,Socket 和 RPC 的通訊效率肯定就沒有「共用記憶體」來得快了。(可能你心裡在想 http 協定,沒錯,http 用的更多,但是一般 http 不被歸入程序間通訊方式。)
在 Linux 系統中,/dev/shm
的大小一般為實體記憶體的一半。Docker 在啟動容器的時候,預設給容器設定的 /dev/shm
大小是 64M。(你品,你細品,是不是自定義容器內 shm 大小的需求就產生了?)
Docker 在 shm 大小的設定上提供了兩種支援:
docker run
支援通過 --shm-size=1g
這種方式指定一個容器的 shm 大小;daemon.json
中可以通過 "shared-memory-size": "1G"
設定指定容器啟動的預設 shm 大小。不難猜到,--shm-size
引數的優先順序會比 shared-memory-size
設定高。
/dev/shm
大小K8s 裡沒有原生提供啥直觀的 shm 設定方式。但是為了讓應用能夠嚐到「共用記憶體」的滋味,YAML 工程師還是得給出方案。
Sao 操作來了,因為 Docker 支援 shared-memory-size
設定,所以直接修改節點的 daemon.json
設定,那不就讓所有 Pod 都能夠用起來更大的 share memory 了?
我就不演示了。反正基本滿足需求,但是冥冥之中又讓你覺得哪裡不太對勁,總之吧,不優雅。
不就是讓 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 上看到了第三種玩法。
且看這段設定:
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
。
散了吧,總結啥。大週五的,早點回家。