6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wano GroupAdvent Calendar 2024

Day 14

SFTPサーバーのMountpoint for Amazon S3によるマウントが切れる問題

Last updated at Posted at 2024-12-13

これは、Wano Group Advent Calendar 2024の14日目の記事です。
13日目は、私@kotobuki5991の、URLのヒストリーを保持しつつ、1ページで複数の検索を走らせるために頑張った話です。

概要

弊社では、カラオケやミュージックビデオの配信ができるサービスVideo Kicksを開発・運営しています。

配信のためには、配信ストアに対して動画ファイルや楽曲のメタ情報(タイトルやアーティスト名など)を納品する必要があります。

今回は、納品に使用しているSFTPサーバーで発生したエラーと、その解消のために実施したことを書いていきます。

SFTPサーバーの構成

Lightsailインスタンス上のDockerコンテナ内でmount-s3を実行し、S3にアップロードされた納品ファイルをマウントしています。
配信ストアはS3に直接アクセスすることなく、mount-s3によりマウントされたファイルをDLします。

スクリーンショット 2024-12-12 9.25.07.png

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つの対応を実施しました。

  1. S3側で過去ファイルをマウント対象外の場所に移動
  2. mount-s3のバージョン更新
  3. 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パターンの方法があります。

  1. anonymousページをswapに逃す
  2. 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回避に役立つと思います。

参考:

docker-compose.yml

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コマンド結果

スクリーンショット 2024-12-12 22.03.17.png

人材募集

弊社グループでは一緒に働くメンバーを募集中です、ご応募お待ちしています!

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?