🪣

Google Cloud Storageで大量のオブジェクトを操作する方法

2024/12/16に公開

はじめに

こんにちは D2Cエンジニアの羽原です。
Google Cloud Storageの管理において、大量のオブジェクトの削除・クラス変更において
発生したいくつかの課題とその課題を解消をする方法について共有できればと思います。
記事の構成としては、

  • Google Cloud Storage(GCS)をマルチリージョンバケットで、オブジェクトクラスを変更する際の注意点
  • 大量のオブジェクトの処理を行う際のベストプラクティス
    の2点で構成されています

GCSマルチリージョンバケットでオブジェクトクラスを変更する際の注意点

経緯

  • あるプロジェクトでデータを蓄積していたGCSのコストが高額であった
  • バケットがマルチリージョンバケットで構成されたたためストレージ料金も高額であった
    2024/12GCS料金
    リージョン Standard Storage(GB 単位/月) Nearline Storage(GB 単位/月) Coldline Storage(GB 単位/月) Archive Storage(GB 単位/月)
    東京(asia-northeast1) $0.023 $0.016 $0.006 $0.0025
    アジア(アジア マルチリージョン) $0.026 $0.015 $0.00875 $0.0030
  • 今後もデータを保存する方針だが、取り出し操作や削除を頻繁に行う予定がないため、ストレージクラスをStandard StorageからArchive Storageに変更することでコスト削減を計画した
  • ストレージクラスを変更する際のコストは、ClassAオペレーションにあたるstorage.*.updateが発生すると試算し実施を行った
  • 対象バケット全体の容量とオブジェクト数
    • 容量:100TB オーダー
    • オブジェクト数:100万オブジェクト オーダー

問題発生

  • ある日課金料をなんとなく確認したところ
    課金グラフ
    料金が跳ね上がってる!!
  • GCSに関する部分(青色)が跳ね上がっていたため、内容を確認
  • 跳ね上がりの料金区分Network Data Transfer GCP Replication within Asiaであった
    • ある程度の料金跳ね上がりは理解していたが、大幅に大きい点とネットワーク料金であったため確認することに

結論

  • GCSにて既存オブジェクトのストレージクラスを変更する際、内部処理ではobject.rewiriteの操作が発生する。
  • 発生する料金は
    • Class Aオペレーション
    • マルチリージョンバケットでrewrite処理を行うと、各地のリージョンに再度データを転送するのでNetwork Data Transfer GCP Replication within Asiaも発生するとのこと
  • Network Data Transfer GCP Replication within Asiaの料金は$0.08/GBと高め

となりました。以上から

  • マルチリージョンバケットのオブジェクト操作においては、ネットワーク転送量がかかる可能性のある操作がある
  • ネットワーク転送量は高めなので、そこも試算に入れて検討しよう

と認識いただければと思います。

大量のオブジェクトの処理を行う際のベストプラクティス

経緯

  • 引き続きオブジェクトの整理作業を行う際、gcloudコマンドで実施していた
    • 実施作業していたコンピュートがプロジェクト内に立ち上げたGCE(e2-small構成)
  • 実行スクリプトは以下の通り
gcloud storage objects update gs://hoge-bucket/dir/** --storage-class=archive
  • 進捗の確認のためGCEに接続するとマシンに繋がらない!
    • モニタリングを確認すると、CPUが100%に張りついたうえでにOpsAgentが落ちている状態だった
  • 原因分析の結果gcloudコマンドで大量のオブジェクトを変換したことにより
    • タスクがスタック→CPU張り付き→VMへログイン処理も受け付けない状態に陥る
  • 検証環境で実施した際には、オブジェクト数が少なくタスクがスタックすることが少なかったが、本番環境ではオブジェクト数が多くタスクがスタックした
    • スペックの高いマシンでも実施したが、タスクがスタックして実行完了できませんでした

結論

オブジェクトのライフサイクル管理を使おう!
https://cloud.google.com/storage/docs/lifecycle?hl=ja

  • ライフサイクルを利用することで以下アクションが設定できる
    • Delete(削除操作)
    • SetStorageClass(ストレージクラスの変更操作)
    • AbortIncompleteMultipartUpload(不完全なマルチパートアップロードの中止)
  • SetStorageClassを実施すればストレージクラスが変更可能であった
  • 削除タイミングと処理期間について
    • ageが1dayであれば、オブジェクトが保存された日から1日以上経過すると順次処理が行われる
    • 今回の場合、(100万オブジェクト オーダー)処理完了まで3日かかった

その後

  • 費用削減の観点で、GCSに保存したデータは特定期間(1日)で削除する方針となった
  • terraformでGCSを構築していたため、ライフルサイクルを以下のように定義し設定
resource "google_storage_bucket" "hoge" {
  name          = "hoge-bucket-${var.env}"
  location      = "ASIA-NORTHEAST1"
  storage_class = "STANDARD"
  lifecycle_rule {
    condition {
      age = 1
    }
    action {
      type = "Delete"
    }
  }
  versioning {
    enabled = false
  }
}

まとめ

  • マルチリージョンバケットでのオブジェクト操作では、ネットワーク通信料が加算されるので注意しましょう
  • 大量のオブジェクトを削除・クラス変更をする場合は、ライフサイクルを利用しよう

GCSを普段から活用されているかたは、当たり前の内容が多いと思いますが、
初めて大規模なデータを操作する方には参考になる内容かなと思っております。
活用いただければ幸いです。

[補足]Amazon Web Service(AWS)では

  • AWS S3にも、同様のライフサイクル設定が存在します

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/object-lifecycle-mgmt.html

設定の詳細についてはAmazon Web Serviceのドキュメントをご覧下さい

D2C m-tech

Discussion