👬

べき等性パターン(#2 内容・IDで重複排除)

2021/05/22に公開

https://zenn.dev/notrogue/articles/85083dcf1c4c16
の続きです

概要

データが重複すること自体は許容し、使う側で対応するパターンです。
データの内容や適当なID等で重複かを判断し、SQLやETL/ELTで排除するイメージです。

どんな時に使えるの

アプリケーションコードやSQLで頑張れば良いので、広範囲で使えます。
(性能やこれがベストな選択肢かどうかば別の話)

例 BigQueryのStreaming Insert:

BigQueryの書き込みには大きく三つの方法があります(※)が、Streaming Insertは仕様としてデータが重複する可能性があります

その対応としては、

  • 「insertId」を指定し、BigQuery側で重複排除
    • ただしベストエフォート
    • ちなみに、insertIdを指定すると遅くなるらしい
  • 重複を含めて格納し、SQL側で重複を排除する
    • Google Cloudの人によるクエリの
    • 重複が致命的に重複な場合

といった、中身・IDによる重複排除が考えられます。

ファイルからLOADStorage Write APIStreaming Insert

注意点

仕様の周知

「重複します」を、データの仕様として利用者に周知する必要があります。
データカタログや仕様書・社内Wiki等で記載する他、重複が致命的な場合は、ビューやマテリアライズド・ビューで重複を排除して提供するのもありかもしれません。

重複とは何か

便利なパターンですが、なにを「重複」と判断・排除するかを注意して考える必要があります。

例えば、Pub/SubのデータをBigQuery(Streaming Insert)に入れる場合、処理するプログラムで

  1. Pub/Subから受け取る
  2. 各データにUUID等を付与
  3. それで重複排除.

としてしまうと、同じデータに複数のUUIDが付与され、データが重複する可能性が残ります(Pub/SubはAt Least Onceなため、1の時点で重複している可能性がある)。

また、「中身が同じだから重複」かどうかは、扱うデータや処理の流れに依存して決まります。
例えば、ログを扱う場合、同じログメッセージがあったとしても、

  • 途中の経路(Pub/SubやStreaming Insert)で重複した
  • 元から同じメッセージのログが複数あった(特にログが日時を含まない場合や、精度が低い場合)

のどちらの可能性もありえるため、重複排除してよいかは、格納したログデータを何に使うかに依存するでしょう。

Discussion