目次

環境(問題発生前)

まず、この高額請求が発生する前の稼働状況を説明します。

VPS-Lightsail

AWS LightsailはAmazonが提供するVPS(仮想専用サーバー)サービスです。

  • CPU
  • メモリ
  • SSDストレージ
  • 転送量

がセットになった月額固定料金プランが特徴なので、転送量にほぼ怯えることなく使えるということで愛用していました。

Wasabiクラウドストレージ

Wasabiは非常に安価なGB単価を特徴とするオブジェクトストレージサービスです。AWS S3と互換性のあるAPIを持ち、データ転送量(下り)が無料な点も魅力。大容量データのバックアップやアーカイブ、静的コンテンツ配信等に適しています。(前述した通り、最低保存期間ポリシーという罠が待っていました)

上記サービスの組み合わせイメージ

  • Linux (Ubuntu 20.04)
  • Apache
  • MySQL
  • Ruby
  • PHP

をベースにして、RedmineやBookStack、そしてPiwigoといったWebサービスを稼働。これらWebサービスのデータ(画像データや添付ファイル)の保存先としてWasabiクラウドストレージをs3fsでマウントしていました。

具体的なイメージは以下の通りです。

graph TD subgraph "AWS Lightsail VPS" direction TB OS[Linux OS] WebStack["Webサーバー環境 (Apache, MySQL, PHP/Ruby)"] s3fs["s3fs マウントプロセス"] MySQLDB["ローカルMySQLデータベース"] subgraph "Webアプリケーション" Redmine["Redmine (Ruby)"] BookStack["BookStack (PHP)"] Piwigo["Piwigo (PHP)"] end OS --> WebStack OS --> s3fs WebStack -- データ保存 --> MySQLDB Redmine -- 利用 --> WebStack BookStack -- 利用 --> WebStack Piwigo -- 利用 --> WebStack Redmine -- 添付ファイル保存 --> s3fs BookStack -- 画像/添付ファイル保存 --> s3fs Piwigo -- 写真保存 --> s3fs end subgraph "Wasabi クラウドストレージ" WasabiBucket["Wasabi バケット"] end s3fs -- マウント --> WasabiBucket

VPS変更

しかし、このAWS Ligtsailは円安並びにサービス料の値上げにより、月額2600円ほどから月額4000円強と無視できない値上がりが続きました。また、Ubuntu 20.04のEOLも2025年4月に控えていることから、

  • 国産
  • 円請求のため為替変動に気にする必要がない
  • 月額の最大転送量は劣るものの、転送量超過による追加料金がない
  • しかもNWキャリアが運営するため非常に高速
  • Lightsailと同じように月額固定(正確には従量課金で上限固定)

等を兼ね備えたNTT PCのWeb Arenaへと変更。OSをUbuntu 24.04にすると共に、VPS全体のスペックアップも同時に図りました。

LightsailWeb Arena
メモリ4GB4GB
CPU2vCPU4vCPU
SSD80GB80GB
転送量4TB/月500M/日
月額24 USD1482円(キャンペーンにより897円)

環境(問題発覚時)

こうして、VPSの引っ越しとRedmine/Bookstackの引っ越しが完了。

CPUが 2vCPU→4vCPUへとスペックアップしたことで、長らくやってみたかった

  • Nextcloud
  • Growi

を導入します。(Webアルバムを兼ねるためPiwigoは廃止)この構築時、

  • Nextcloudのデータストレージ
  • Growi(MongoDB)のデータ格納先

それぞれの向き先をWasabiクラウドストレージに設定したことが、本問題の直接的なトリガーとなります。

追加された具体的なイメージは以下の通りです。

graph TD subgraph Wasabi_Storage WasabiBucket end subgraph VPS_WebArena_Indigo MongoDB_Process Growi_App Nextcloud_App s3fs_Process Growi_App --> MongoDB_Process MongoDB_Process -- "データ格納 (問題箇所!)" --> s3fs_Process %% ラベルを修正し""で囲む Nextcloud_App -- "データ格納 (問題箇所!)" --> s3fs_Process %% ラベルを修正し""で囲む end s3fs_Process --> WasabiBucket

問題発覚(までの束の間の快適さ)と忍び寄る亡霊の無視

この、

  • Growiでどこでも高機能なWikiツールが使える
  • Nextcloudにあらゆるデータを格納して好きなタイミングで閲覧できる

という状況は控えめに言って「快適」そのものでした。満足いくWebアプリを自分の手で作り、それが意のままに動く。

ただ、それをあざ笑う「亡霊」は確実に迫っていました。

2024年11月頃、Wasabiクラウドストレージの請求がいつもよりも若干多い請求だったものの、特段気にせず「ちょっと転送量が増えたとかの影響だろう」ぐらいにしか気に留めていなかったのです。

「亡霊」出現。(削除されたストレージ量の発覚)

そして、2024年12月6日、恐ろしい現実が「快適さ」に冷や水を浴びせてきました。

請求額を見て「今回は9.87$」……

その左側にある「TAXES」の項目。更にPDFは次のページもあります。

請求額:$108.57!!!

そして、請求書にある「Timed Deleted Storage」なる謎の文言。

  • 定額であるという安心感
  • 前まで8ドル~12ドルほどだったのに

などから、流石に、今まで気にも留めなかったWasabiクラウドストレージのコンソールに入って、ようやくことの大きさに気づきます。

ダッシュボードにある「削除されたストレージ:21.63TB」。

そして、請求明細を確認。

  • 2024年10月: 18,665 GB-day
  • 2024年11月: 402,930 GB-day

という想像を絶するデータ量を見て「何かの間違い」として、即座にWasabiのカスタマーサポートに

  • この請求額は何かの間違いではないのか
  • その根拠を示していただきたい

と問い合わせをしようとしていたほどです。

Timed Deleted Storageとは?

ですが、その問い合わせの前にChatGPTに訊いてみます。何せ、翌日以降もデータは増え続けているのですから。

質問:

Wasabi cloud storageのMinimum Storage Duration Policyについて

回答:

ユーザーがデータをストレージに保存する際の最小保持期間に関するポリシーです。これは、ユーザーがストレージにデータをアップロードした場合、そのデータは最低90日間は削除できないということを意味します。この期間内にデータを削除すると、削除したデータに対して、最小保持期間を満たすための費用が発生します。

  1. 90日間の保持期間: Wasabiにアップロードしたデータは、最初の90日間は削除しても料金が発生します。
  2. 削除の費用: 90日以内にデータを削除すると、その削除に対して料金がかかることがあります。
  3. 長期間の保存にはコストの影響: データを90日以上保持する場合、その分のストレージコストが発生します。

これを踏まえ、ダッシュボードのグラフを確認します。

「Growiを利用し始めた頃から削除されたストレージ量が増えている」

という明白な事実。ここで、一つの仮説が浮かび、更に質問をしました。

質問:
mongodbを用いたgrowiは、データの削除を頻繁に行うことはありますか? これを導入後、Wasabiクラウドストレージの最低保持期間ポリシーがTimed Deleted Storage (applicable for deleted storage < 90 days 402,930.22 GB-day という恐ろしいデータ量になりました。

回答:
.wtファイルが原因の可能性が高い理由

WiredTigerの特徴
MongoDBはデフォルトでWiredTigerエンジンを使用し、以下のような操作が発生します:

  • 頻繁な読み書きによる .wt ファイルの更新
  • データ削除時に古いデータが削除されても、WiredTiger内部では「ガベージデータ」として保持され続け、再利用可能になるまでストレージに存在する。
  • GROWIの特性
  • リアルタイム編集: GROWIでは頻繁にドキュメントが更新されるため、MongoDBでのデータ更新や削除が多く発生。
  • 履歴機能: ページの履歴保存機能も、ストレージに対して追加的な書き込みを引き起こします。
  • Wasabiの課金ポリシーとの相性
  • MongoDBの .wt ファイルの更新は、「削除」ではなく新しいデータの書き込みとみなされるため、Wasabi上で頻繁に「古いデータ削除」が発生する形になります。
  • Wasabiの最低保持期間(90日)の影響で、削除された .wt ファイルの古いバージョンも課金対象となります。

原因がこれであるとほぼ断定。状況の概略は以下の通りです。

sequenceDiagram
    participant User as ユーザー
    participant GROWI as GROWI
    participant MongoDB as MongoDB
    participant WiredTiger as WiredTiger
    participant Wasabi as Wasabi (ストレージ)

    User->>GROWI: ページを作成/更新 (10~20回/日)
    GROWI->>MongoDB: データ挿入/更新 (テキスト、メタデータ)
    MongoDB->>WiredTiger: データを追記型で保存
    MongoDB->>WiredTiger: インデックスを再生成
    WiredTiger->>WiredTiger: .wtファイルを部分的に書き換え
    WiredTiger->>Wasabi: 書き換えられたファイルをアップロード
    Note over Wasabi: 最小保持ポリシーが適用され、<br>ストレージ容量が膨張

    User->>GROWI: 添付ファイルをアップロード
    GROWI->>Wasabi: ファイルを直接アップロード
    Wasabi->>Wasabi: ファイルを保存 (最小保持ポリシーが適用)
    Note over Wasabi: 添付ファイルは削除しても<br>ポリシーで課金され続ける

    User->>GROWI: 更新されたページを確認
    GROWI->>MongoDB: リアルタイム検索 (インデックス参照)
    MongoDB->>WiredTiger: インデックスにアクセス

快適に使っていたGrowiではありますが、放棄を即断。この間記録していたデータは判明してから取り出す手段はあります。

sudo systemctl stop mongod.service && sudo systemctl disable mongod.service
sudo systemctl stop growi.service && sudo systemctl disable growi.service

として、サービス停止を即断。結果的に、これが、このとき取れる最良の手段でした。

更に問題を確認:Nextcloud

原因がMongoDBであることを確認したものの、依然として「削除されたストレージ量」が増え続けています。ということは、他にも原因があるはず。
そこで、問題を特定するためにWasabiクラウドストレージのコンソールで、バケットログを取り、詳細を知ることにします。

そうして取得されたログを確認。

本件の問題は「削除された」なのですから、「DELETE」の箇所を探してみます。

そして、以下のログを確認。

A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 wasabi_bucket [07/Dec/2024:09:08:08 +0000] xxx.xxx.xxx.xxx A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 732B873ECB2CD0E0:B REST.DELETE.OBJECT hoge%2Ffuga%2Ffiles%2FPhotos%2F24-11-30+10-33-12+3750.jpg.ocTransferId1304092901.part "DELETE /wasabi_bucket/hoge/fuga/files/Photos/24-11-30%2010-33-12%203750.jpg.ocTransferId1304092901.part" 200 - - 98689 20 0 "" "s3fs/1.93 (commit hash unknown; GnuTLS(gcrypt))" -
A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 wasabi_bucket [07/Dec/2024:09:08:11 +0000] xxx.xxx.xxx.xxx A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 66D2BB7EE2397D95:A REST.DELETE.OBJECT hoge%2Ffuga%2Ffiles%2FPhotos%2F24-11-30+11-25-31+3751.jpg.ocTransferId560977963.part "DELETE /wasabi_bucket/hoge/fuga/files/Photos/24-11-30%2011-25-31%203751.jpg.ocTransferId560977963.part" 200 - - 435032 27 0 "" "s3fs/1.93 (commit hash unknown; GnuTLS(gcrypt))" -
A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 wasabi_bucket [07/Dec/2024:09:08:12 +0000] xxx.xxx.xxx.xxx A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 02730C50CB587DCA:A REST.DELETE.OBJECT hoge%2Ffuga%2Ffiles%2FPhotos%2F24-11-30+13-07-26+3752.jpg.ocTransferId1438396366.part "DELETE /wasabi_bucket/hoge/fuga/files/Photos/24-11-30%2013-07-26%203752.jpg.ocTransferId1438396366.part" 200 - - 158612 19 0 "" "s3fs/1.93 (commit hash unknown; GnuTLS(gcrypt))" -
A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 wasabi_bucket [07/Dec/2024:09:08:27 +0000] xxx.xxx.xxx.xxx A25565D26D59120AF42A29C94D9973FC4D36414ED6A9BA752728D0F122DADD90 97B3446816F7804B:A REST.DELETE.OBJECT hoge%2Ffuga%2Ffiles%2FPhotos%2F24-11-30+15-04-53+3753.jpg.ocTransferId957074397.part "DELETE /wasabi_bucket/hoge/fuga/files/Photos/24-11-30%2015-04-53%203753.jpg.ocTransferId957074397.part" 200 - - 335451 24 24 "" "s3fs/1.93 (commit hash unknown; GnuTLS(gcrypt))" -

/hoge/fugaはnextcloudのパス。つまり、Nextcloudの操作やバックグラウンド処理がもう一つの問題として削除されたストレージ量を増やしていると特定。

こちらも放棄を決断します。DBはバックアップを取っているので、これも取り戻すことはできます。

sudo a2disssite nextcloud.conf
sudo systemctl reload apache2.service

として、これも止めました。

対策後に残り続ける「亡霊」との戦い

  • Growi
  • Nextcloud

という、やりたかったものを止めてようやく削除されたストレージ量の増加は止まりました。ですが、依然として21TBという「ちょっとした企業のファイルサーバに匹敵するようなデータ量」は依然として残ります。

ここに、ChatGPTが示した

  1. 90日間の保持期間: Wasabiにアップロードしたデータは、最初の90日間は削除しても料金が発生します。
  2. 削除の費用: 90日以内にデータを削除すると、その削除に対して料金がかかることがあります。
  3. 長期間の保存にはコストの影響: データを90日以上保持する場合、その分のストレージコストが発生します。

が加わります。ここで増加を食い止めたとしても、これらの21TBものファイルは今後90日間は残り続けます。

そこで、この削除されたストレージ量を「亡霊」と定義。(目には見えないのに課金という形で攻撃を加えるとして)

  • ここ(2024年12月8日)から90日後の2025年3月7日には消えるはず。
  • 問題が明らかになったのはその30日前の11月。
  • そして、請求が確定するのは3月の更に1ヶ月後の2025年4月。

ということで、この問題を「150日の亡霊」と名付け、日々、経過を観察することにしました。