冪等性とデータパイプラインの障害防止対策
冪等性とデータパイプラインの障害防止対策
冪等(べきとう)性は、データ統合の障害によって引き起こされうる最悪の結果から、どのように私たちを守ってくれるのでしょうか。
2021年1月22日
冪等性は、データ同期に失敗した際、重複データの生成を防止する性質を持ちます。データウェアハウスでは、効率化のため、個別ではなくバッチでレコードを読み込みます。これは、進捗の記録についても、個別のレコードではなくバッチで行われることを意味します。データ統合の同期が中断された際、障害の発生時点で処理されていたレコードを正確に特定できないという事態も頻繁に発生します。そのような場合は、同期を再開するためにデータパイプラインを最新のバッチの先頭から開始する必要があります。つまり、すでに処理された一部のデータを再度処理しなければならないのです。
不具合のある同期を冪等性なしで再開する場合の課題
データウェアハウスに同期させるデータのバッチが4つあるとします。最初のバッチは同期が終了し、2つ目のバッチも同期(緑色のバー)が途中まで進んでいます。現在、進捗を追跡するカーソル(赤矢印)は、最初のバッチの終了位置にあります。
最初のバッチの全レコード(「foo」、「bar」、「baz」、「qux」、「corge」)と、2つ目のバッチの一部(「grault」、「garply」、「waldo」)がすでに読み込まれています。
ここで同期が中断されました。
同期が再開されると、データパイプラインはカーソル部分を参照し、最初のバッチは同期が完了していること、そして2番目のバッチは完了していないことを認識します。こうして2つ目のバッチからやり直しとなります。
2つ目のバッチの同期が終了すると、カーソルは2つ目のバッチの最後に移動します。
2つ目のバッチから過去に同期されたレコード(ここでは「grault」、「garply」、「waldo」)は、デスティネーション(宛先)に再度読み込まれます(赤い行)。ここで、冪等性がなければレコードは重複してしまいます。
一方、冪等性があれば、すべての一意のレコードが適切に識別され、重複することはありません。
障害には、「ハード」な障害と「ソフト」な障害があります。 上の図はハードな障害の例です。例外の発生によりプログラムが終了したため、カーソルで示された場所からシステムが再開されます。
「ソフト」な障害とは、データ同期に失敗するのではなく、破損したデータがデスティネーションに読み込まれてしまうため、より重大です。ソフトな障害では、人間が介入して徹底的な調査を行い、カーソルの位置を過去にさかのぼって特定しなければなりません。冪等性がなければ、再度同期された範囲内の正しいレコードの重複はもちろんのこと、破損したレコードの正しい値と誤った値の両方が同時にデスティネーションに存在する結果にもなりかねません。
データ統合の障害はどこで発生するのか
障害は、現代のデータスタックでは以下の3つの段階のいずれにおいても発生する可能性があります。
-
ソース:データソースが予期せず使用不能となり、同期が中断されます。
-
パイプライン:パイプライン自体に不具合が発生し、動作を停止する場合もあります。
-
デスティネーション:データウェアハウスへのクエリ(処理要求)に失敗すると、アップグレードや移行と同様、同期が中断される場合があります。
これらの障害に共通するのは、上記のように、すでに読み込み済みのデータ値がデスティネーションに再度読み込まれることで、値の重複や矛盾が発生する可能性があるという点です。
ソースの障害
ソースが、一時的または恒久的に利用できなくなることがあります。一時的な障害は、ネットワークやクエリの障害に起因している場合もあります。恒久的な障害はフェイルオーバーを引き起こす可能性があります。フェイルオーバーとは、あるリソースが予期せず完全に利用できなくなることで、そのリソースがセカンダリのバックアップコピーに切り替えられることを指します。パイプラインがバックアップリソースに切り替えられると、すでにフェッチされていたレコードの一部が再度フェッチされることがあります。
パイプラインの障害
最も多いのがパイプラインの障害です。一般的に、パイプラインの障害の原因としては以下が考えられます。
-
インフラの停止(サーバーのダウンなど)
-
認証情報の誤りや不足
-
リソースの制限(メモリリークなど)
-
ソフトウェアのバグ
データパイプライン、特に従来のETLフローを運用した経験があれば、現場では障害が日常的に発生していることがわかるでしょう。よりシンプルで耐久性の高いELTパイプラインでも、一定のペースで停止が発生します。
デスティネーションの障害と移行
クエリの障害により、デスティネーションで同期が障害する場合もあります。ノードが混雑していたり、ダウンタイムが予定されていたりすると、リソースの制約が原因でクエリの障害につながります。
さらに、組織は定期的にアップグレードを行ったり、あるデスティネーションから別のデスティネーションに移行させたりもします。このプロセスでは、通常古いデスティネーションへのデータパイプラインを維持し、新しいデスティネーションの設定中も運用できるようにしておきます。この新しいデスティネーションには、古いデスティネーションのデータのコピーが追加されますが、更新内容が失われることを防ぐには、同じレコードの一部がデスティネーションに再度読み込まれるように、カーソルを巻き戻す必要があります。
冪等性は自己修正を可能にする
上記の各障害に共通するのは、復旧には、ある程度前のカーソルまでさかのぼり、一定数のレコードをデスティネーションに再度読み込ませる必要があるということです。冪等性がなければ、この再読み込みによりレコードが重複し、データリポジトリの整合性が損なわれてしまいます。このようなデータの整合性の問題を解決するためには、通常、人為的な介入が必要です。
冪等性と、レコードを一意に識別する能力があれば、重複やそれに伴う下流の問題は発生しません。ソース、パイプライン、デスティネーションの障害を回避することはできません。ただし、冪等性を持つデータパイプラインであれば基本的に自己修正を行うため、人間の手でデータの整合性を確認する作業はほぼ不要となります。