オブジェクトストレージへのエクスポート

達成した目標ごとに JSON オブジェクトを一つ、お客様のバケットへ保存します。BigQuery 以外の各データウェアハウスへの経路です。

1. 埋めるべき不足

これまで、MousePlayer からデータウェアハウスへの経路は Google 向けの一つだけでした。Snowflake、Redshift、ClickHouse を使っていても、三つともオブジェクトストレージを問題なく読めるにもかかわらず、経路がありませんでした。

そこで、各データウェアハウスに個別に書く代わりに、連携ブリッジがオブジェクトストレージへ書き込みます。Snowflake、Redshift、ClickHouse は S3 から、BigQuery は Google Cloud Storage から取り込みます。一つのエクスポートで、すべてに届けられます。

保存先指定方法
Amazon S3Signature Version 4。ホストにバケットを含めます
Cloudflare R2アカウントのエンドポイントに対して Signature Version 4
Google Cloud StorageHMAC キーを使い、S3 互換 API 経由で接続
MinIO、Wasabi、Backblaze B2 など指定したエンドポイントに対して Signature Version 4
Azure Blob Storageコンテナーの SAS リンク。当社側では署名しません

2. Azure が異なる理由と、その利点

Azure Blob は Signature Version 4 を使わず、SharedKey で署名します。別の署名方式を実装することもできましたが、代わりに連携ブリッジは次を受け取ります: コンテナーの SAS リンク 。お客様自身のストレージアカウントで生成する、署名を既に含んだ URL です。

当社側のコードを減らし、お客様が当社に委ねる範囲も減らせます。アカウントキーを当社が見ることはありません。お客様が渡すのは、自分で範囲を決めた、一つのコンテナーへの権限です。有効期限も自分で選び、他に手を加えずいつでも取り消せます。

S3 側でも同じように権限を絞る価値があります。アクセスキーに書き込みを許すのは、 この一つのプレフィックス だけにしてください。次に追加することしかできないキーなら、 mouseplayer/goals/ 漏えいしても、他のバケットは読めません。

3. 目標ごとに一つのオブジェクト。キーは日付

オブジェクトストレージには追記がありません。日次ファイルでは毎回全体を書き直す必要があり、二つの目標が同時に届くと上書きし合ってしまいます。そのため、達成した目標をそれぞれ別のオブジェクトにします。

代わりに小さいオブジェクトが増えますが、キーの構成によって扱えるようにします。

prefix/YYYY/MM/DD/channel/session-goal.json

データウェアハウスは1日分を一つのパーティションとして読み取り、過去分の補完はクエリではなくプレフィックスの走査で行います。日付ではなくプロジェクトで分割したい場合は、プレフィックスにチャネル ID を入れてください。

各オブジェクトは1行の JSON

意図的にインデントしません。オブジェクトを一つずつ開かず、プレフィックス全体を NDJSON として読めるようにするためです。タイムスタンプ、プロジェクト、セッション、顧客 ID、目標、金額、通貨、録画の再生リンクが含まれます。

空の値は0ではなく null

金額のない目標では、次を書き込みます: null。データウェアハウスでは、0にすると実在しない合計に加算されます。「金額が決められていない」と「金額が0」の区別は、エクスポート後も保たれます。

4. 403が返ったら、まず確認してください

拒否された S3 リクエストは、ほとんど何も説明しません。当社のログのエラーメッセージが S3 より詳しいのには理由があります: リージョンが署名に含まれるためです。リージョンの誤りもキーの誤りも同じ403になるため、最初に疑いがちなキーが原因なのは半分だけです。

次の三つを、この順序で確認してください。

  • リージョンは、バケットが示すものと正確に一致させます。R2 と Google Cloud Storage は、 auto を受け付け、確認しません。他はすべて確認します。
  • プレフィックスの権限。 次だけを許可されたキーは、 mouseplayer/ 次に書き込めません: mouseplayer-goals/ 。リソース ARN では、末尾のスラッシュが重要です。
  • エンドポイントは R2 と S3 互換ストレージ用です。次を除いたホスト名を貼り付けます: https://。いずれにせよ当社側で取り除きますが、その後にパスを付けると、別のバケットになってしまいます。

アクセスキー ID は意図的に平文で保存します。設計上、署名付きリクエストのたびに送られるため、暗号化しても保護につながらず、手間だけが増えるからです。シークレットは暗号化し、再表示せず、タスクを運ぶ内部キューにも一切含めません。

記載されている商標はすべて各所有者に帰属します。MousePlayer とこれらのプロバイダーとの間に取引関係はありません。