🕌

PythonでDocker上のソケットバッファについて観察する

に公開

はじめに

普段、ソケット通信を使っていて1クライアントあたりのリソースの消費と、同時接続数の限界はどこなんだろう?と疑問に思い、実験してみました。
シナリオとしては、YoutubeやTVでの紹介など何かを契機にたくさんのアクセスが生じた場合を想定します。
本記事ではコードは公開せず、その現象を観測する実験手法と結果を共有します。あくまで参考としてご覧いただきたく、よろしくお願いします。

マシンスペック

MacBook Air M2 arm64

準備

Dockerファイルの作成

# Dockerfile
FROM python:3.11-slim

# procps: freeコマンドなど、メモリやプロセス情報を確認するツール群
RUN apt-get update && apt-get install -y procps iproute2

WORKDIR /app

ファイルの作成

今回は、サーバ用ファイル(server.py)・クライアント用ファイル(client.py)・メモリ監視shell(monitor.sh)・結果可視化用のpython(visualize_monitor.py)ファイルを準備します。
※今回は、ソースコードは公開しません。

Dockerビルド・接続

terminalのメインプロセスで実施(モニタリング)

docker build -t memory-test .
# RAMは256に制限
docker run --rm -it --name mem-test --memory=256m -v "$PWD":/app memory-test bash
chmod +x monitor.sh
./monitor.sh

terminalの別プロセスで実施1つ目(サーバ)

docker exec -it mem-test bash
python3 server.py

terminalの別プロセスで実施2つ目

docker exec -it mem-test bash
# 過剰かもしれないが50_000クライアントで一気に接続
python3 client.py 50000

結果

ローカルのterminalで下記コマンドを実施して、結果をローカルにコピーします。

docker cp mem-test:/app/memory.log .

ログを確認

head memory_and_connections.log 
timestamp,mem_available_kb,tcp_connections
1752479295,7415328,1
1752479296,7414956,1
1752479297,7413672,1
1752479298,7413448,1
1752479299,7403620,1
1752479300,7403620,1
1752479301,7403628,1
1752479302,7187292,14971
1752479303,7188076,23051

上手に取れている様です。

グラフに描画

データを可視化して傾向を探ります。

python3 visualize_monitor.py


RAMは今回はローカルのリソースも含んでいるため、256より大きいのですが接続数は5万を前にして、RAMの枯渇で接続を開放している様に伺えます。
該当箇所をログの生データの方で確認してみます。

timestamp,mem_available_kb,tcp_connections
...
1752479301,7403628,1
1752479302,7187292,14971
...
1752479320,7141060,49423
1752479321,7178116,1

上記は接続開始時と接続開放時のRAMの残容量と接続数です。
今回の結果では接続前は7400MB、開放時は7140MBでRAMが枯渇したため、すべてのクライアントの接続を開放したことが伺えます。
厳密ではないですが、1クライアントあたりのRAMの消費を算出すると、1接続あたりのRAMの消費量は5.31MBという値になりました。
しかし、Linuxカーネルドキュメントから1接続に対して5.31MBもバッファを食うことは考えづらく、python実行時のRAMの消費も考えらます。cgroup上限+Pythonヒープ領域の確保により、マシンのリソースが枯渇してメモリの開放が走ったと考えられます。
⚠️ この実験では/proc/meminfoのMemAvailableを使用しているため、Pythonヒープ・TCP バッファ・ページキャッシュなどが混在した全体的な傾向値です。

まとめ

今回は、Pythonのソケット通信で消費されるRAMの容量とその限界を実験してみました。
皆様の学習の補助になれば幸いです。

Discussion