これは、Wano Group Advent Calendar 2024の14日目の記事です。
13日目は、私@kotobuki5991の、URLのヒストリーを保持しつつ、1ページで複数の検索を走らせるために頑張った話です。
概要
弊社では、カラオケやミュージックビデオの配信ができるサービスVideo Kicksを開発・運営しています。
配信のためには、配信ストアに対して動画ファイルや楽曲のメタ情報(タイトルやアーティスト名など)を納品する必要があります。
今回は、納品に使用しているSFTPサーバーで発生したエラーと、その解消のために実施したことを書いていきます。
SFTPサーバーの構成
Lightsailインスタンス上のDockerコンテナ内でmount-s3を実行し、S3にアップロードされた納品ファイルをマウントしています。
配信ストアはS3に直接アクセスすることなく、mount-s3によりマウントされたファイルをDLします。
SFTPサーバーを構成する他の方法としては、AWS Transfer Familyなどが挙げられます。
しかし、コスト面を考慮し、本構成が採用となりました。
マウントが切れる問題
このSFTPサーバーを運用する中で、ある日ファイルのマウントが切れてしまう問題が起こりました。
動作確認したところ、以下のようなエラーが発生しています。
エラーのタイミング的に、数十GB程度の大量DLリクエスト時に発生すると思われます。
sftp> ls
remote readdir("/"): Failure
また、調査中に以下のログを発見しました。
mount-s3プロセスがOOMによりkillされていることが分かります。
# dmesg | tail -n 50
[22051422.570373] Memory cgroup out of memory: Killed process 1234567 (mount-s3) total-vm:1900108kB, anon-rss:1022488kB, file-rss:1548kB, shmem-rss:0kB, UID:0 pgtables:2216kB oom_score_adj:0
対応策
以下の3つの対応を実施しました。
- S3側で過去ファイルをマウント対象外の場所に移動
- mount-s3のバージョン更新
- swap領域の確保
1. S3側で過去ファイルをマウント対象外の場所に移動
マウント対象を減らすため、不要なS3オブジェクトをマウント対象外の場所に移動しました。
2. mount-s3のバージョン更新
以下のissueで話されていますが、mount-s3のバージョンが1.10以下の場合
メモリ使用量が多くなってしまうバグがあるようです。
使用しているmount-s3のバージョンは、1.5.0
でした。
こちらは、最新バージョンに更新しておきます。
3. swap領域の確保
swap領域とは、物理メモリが不足したときに使用されます。
ハードドライブ上に存在しているため、物理メモリに比べて処理速度が落ちます。一方、メモリ不足を一時的に補うことができるためOOM回避につながります。(積極的に利用するものではないですが)
詳細な設定項目については後述します。
Dockerfile
ここでは、再度docker buildし直すことで、mount-s3最新版を取得します。
# DebianベースのDockerイメージを指定
FROM debian:latest AS builder
# 必要なパッケージをインストール
RUN apt-get update && \
apt-get install -y --no-install-recommends wget gnupg && \
rm -rf /var/lib/apt/lists/*
# MP_ARCHを取得
RUN wget -q --no-check-certificate "https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb" && \
wget -q --no-check-certificate "https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.deb.asc" && \
wget -q --no-check-certificate https://s3.amazonaws.com/mountpoint-s3-release/public_keys/KEYS
# Import the key and validate it has the fingerprint we expect
RUN gpg --import KEYS && \
(gpg --fingerprint mountpoint-s3@amazon.com | grep "673F E406 1506 BB46 9A0E F857 BE39 7A52 B086 DA5A")
# Verify the downloaded binary
RUN gpg --verify mount-s3.deb.asc
# 新しいコンテナに依存関係を最小限にしてRPMをインストール
FROM atmoz/sftp:debian
COPY --from=builder /mount-s3.deb /mount-s3.deb
# 必要なパッケージをインストール
RUN apt-get update && \
apt-get install -y less vim curl unzip sudo && \
apt-get install -y --no-install-recommends ./mount-s3.deb fuse && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* mount-s3.deb
# aws cli v2 のインストール
# https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-linux.html
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
sudo ./aws/install
RUN echo "user_allow_other" >> /etc/fuse.conf
docker-compose.yml
このファイルでswap領域に関する設定を実施します。
メモリ不足の時、不足したメモリを回収するためには2パターンの方法があります。
- anonymousページをswapに逃す
- fileページ(ファイルシステムのキャッシュなど)を捨てる
docker-compose.ymlに定義されているmem_swapinessという項目(0〜100で設定)は、メモリ回収をanonymousページの回収寄りにするのかあるいはfileページ寄りにするのかの重み付けをすることができます。
ただし、その重み付けは、システム側で定義されているvm.swappiness(0〜200。デフォルトは60であることが多い)と併せて判断されるようです。
つまり、mem_swappinessを100にしても、100%swapのみが使用されるということにはなりません。
また、HDDはswap利用時のコストが高いため、swappinessを低くした方が速度を確保できます。
一方でLightsailのストレージにも利用されるSSDの場合は1と2のコストは同程度です。したがって、ある程度高い値を設定することでOOM回避に役立つと思います。
参考:
services:
sftp_mountpoint:
image: sftp-mountpoint_sftp
build:
context: docker
dockerfile: Dockerfile
privileged: true
stdin_open: true
deploy:
resources:
limits:
cpus: '0.5' # コンテナに割り当てるCPUの数を0.5に制限します。
memory: 1.5g # コンテナの最大メモリ使用量を1.5GBに制限します。
reservations:
cpus: '0.25' # コンテナが保証される最低CPU使用量を0.25に設定します。
memory: 20m # コンテナが保証される最低メモリ使用量を20MBに設定します。
memswap_limit: 2g # メモリ+スワップの合計使用量を2GBに制限します。物理メモリとスワップの合計(memoryが1.5gなのでswapは0.5gとなる)
mem_swappiness: 100 # スワップ使用の優先度を最大にします。(0-100の範囲; デフォルト値はシステムに依存しますが、一般的には60)
cap_add:
- mknod
- SYS_ADMIN
devices:
- /dev/fuse
volumes:
# 省略
tty: true
# ${変数:?err} は、 変数 が設定されていないか、環境変数の値が空の場合、 err を含むエラーメッセージと共に終了する
command: sftp-user:${SFTP_PASS}:${PORT}
とりあえず解決!
DLテストを実施
全体でメモリは500M前後使用しており、mem_swappiness: 100でもswapは使用されていないようでした。
おそらく、mount-s3のバージョン更新によりメモリを食い潰す問題が解決したためswapを使用する状況にならなかったと思われます。
htopコマンド結果
人材募集
弊社グループでは一緒に働くメンバーを募集中です、ご応募お待ちしています!