0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(続)S3にアップロード

Last updated at Posted at 2024-07-31

FileMakerのオブジェクトをS3にアップロードするのその後だが、アップロードに時間がかかるので(10,000件で4時間)速くなる方法がないかAIに聞いたらxargsを使うとコマンドを並列処理できるらしい。以下がそのコード。

upload_objects_to_s3.sh
#!/bin/bash

# 言語環境をen_US.UTF-8に設定
export LC_ALL=en_US.UTF-8

# cronで実行に必要
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
export PATH

# ログファイルのパス
LOG_FILE="/Users/iwaninc/Documents/tmp/upload_script.log"

# 停止ファイルのパス
STOP_FILE="/Users/iwaninc/Documents/tmp/stop_upload_script"

# ロックファイルのパス
LOCK_FILE="/Users/iwaninc/Documents/tmp/upload_script.lock"

# ロックファイルのチェックと作成
if [ -e "$LOCK_FILE" ]; then
    echo "$(date) Another instance is already running. Exiting." >> "$LOG_FILE"
    exit 1
else
    touch "$LOCK_FILE"
fi

# 終了時にロックファイルを削除する関数
cleanup() {
    rm -f "$LOCK_FILE"
    echo "$(date) Script finished, lock file removed." >> "$LOG_FILE"
}

# スクリプト終了時にcleanup関数を呼び出す
trap cleanup EXIT

# グローバル変数で停止フラグを設定
stop_flag=0

# シグナルハンドラ
trap 'stop_flag=1; echo "$(date) Received stop signal. Stopping gracefully..." >> "$LOG_FILE"' SIGINT SIGTERM

# 停止ファイルをチェックする関数
check_stop_file() {
    if [ -f "$STOP_FILE" ]; then
        echo "$(date) Stop file detected. Stopping process..." >> "$LOG_FILE"
        stop_flag=1
        rm -f "$STOP_FILE"  # 停止ファイルを削除
    fi
}

echo "$(date) Start..." >> "$LOG_FILE"

# アップロード先のS3バケット名
S3_BUCKET="<バケット名>"

# ディレクトリとプレフィックスの配列
DIRECTORIES=("/Users/iwaninc/Documents/object" "/Users/iwaninc/Documents/object2" "/Users/iwaninc/Documents/object3")
PREFIXES=("<プレフィックス1>" "<プレフィックス2>" "<プレフィックス3>")

# 並列処理の数(同時にアップロードするファイルの数)
PARALLEL_JOBS=10

upload_and_delete() {
    local file="$1"
    local bucket="$2"
    local prefix="$3"
    local filename=$(basename "$file")

    # 停止フラグをチェック
    if [ $stop_flag -eq 1 ]; then
        echo "$(date) Stopping process for file: $file" >> "$LOG_FILE"
        return
    fi

    if aws s3 cp "$file" "s3://$bucket/$prefix/$filename" --quiet; then
        echo "$(date) Uploaded: $file" >> "$LOG_FILE"
        rm "$file"
        echo "$(date) Deleted local file: $file" >> "$LOG_FILE"
    else
        echo "$(date) Upload failed: $file" >> "$LOG_FILE"
    fi
}

export -f upload_and_delete
export stop_flag
export LOG_FILE

for i in "${!DIRECTORIES[@]}"; do
    # 停止フラグをチェック
    check_stop_file
    if [ $stop_flag -eq 1 ]; then
        echo "$(date) Stopping process before processing directory: ${DIRECTORIES[$i]}" >> "$LOG_FILE"
        break
    fi

    DIR="${DIRECTORIES[$i]}"
    PREFIX="${PREFIXES[$i]}"
    
    echo "$(date) Processing directory: $DIR" >> "$LOG_FILE"
    
    # 並列処理でファイルをアップロード
    find "$DIR" -type f -print0 | xargs -0 -P "$PARALLEL_JOBS" -I {} bash -c '
        if [ $stop_flag -eq 0 ]; then
            upload_and_delete "{}" "$0" "$1"
        fi
    ' "$S3_BUCKET" "$PREFIX"
    
    echo "$(date) Finished processing directory: $DIR" >> "$LOG_FILE"
done

echo "$(date) Upload and deletion completed or stopped." >> "$LOG_FILE"

4時間以上かかっていたのが30分ほどになり10倍くらい速くなった。並列数はPARALLEL_JOBSで調整できるがMac Studio (M1 Max メモリ64GB)で60で実行するとCPUモニタはこんな感じになる(黒い部分が全くない)。

処理が終わるとこんな感じ。

がんばっていただいてました。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?