信頼性の高いデータ処理の構築-Google BigQuery内のラムダアーキテクチャ

この記事では、データ処理で混乱を終わらせる方法を共有したいと思います。 私は以前、この混乱とその後の再処理は避けられないと考えていましたが、今ではそれが何であるかを忘れています。 BiqQueryでの実装例を示しますが、トリックは非常に普遍的です。



非常に標準的なデータプロセスがあります。 最も生の形式の生データは、単一のリポジトリ(この場合はBigQuery)に定期的にアップロードされます。 一部のソース(自社のプロダクション)からは1時間ごとにデータが送信され、他のソース(通常はサードパーティのソース)からは毎日データが送信されます。



その後、データはさまざまなユーザーによって使用可能な状態に処理されます。 これらは内部ダッシュボードである場合があります。 パートナーへの報告。 生産に入り、製品の動作に影響する結果。 これらの操作は非常に複雑になる可能性があり、複数のデータソースが含まれます。 しかし、ほとんどの場合、SQL + UDFを使用してBigQuery内でこれを処理します。 結果は、同じ場所の別々のテーブルに保存されます。



この処理を整理する明白な方法は、操作のスケジュールを作成することです。 データが毎日午前1時にロードされる場合、処理を01:05に設定します。 このデータソースが各時間の5分目の領域にロードされる場合、各時間の10分に処理を構成します。 5分間のギャップはユーザーにとって重要ではなく、すべてが機能するはずです。

しかし、世界は残酷です! データは必ずしも時間通りに到着するとは限りません。 または、修理されていなければ、まったく来ません。 1時間ごとのダウンロードが11分に完了し、変換が10分に開始された場合は、ダッシュボードにこのデータが表示されるまでさらに1時間お待ちください。 また、操作で複数のソースを使用する場合、状況はさらに楽しくなります。



さらに、ロードされた生データは常に正しいとは限りません(データは通常常に間違っています!)。 定期的に、データをクリーニングまたはリロードする必要があります。 そして、すべてが修復されるように、正しいパラメーターですべての操作を再開する必要があります。



これはもちろん、生データに関する問題であり、それらを解決する必要があります。 しかし、これは完全に打ち負かすことのできない戦争です。 それでも何かが壊れます。 データソースが内部の場合、開発者は追跡の信頼性ではなく、新しいクールな機能で忙しくなります。 これがサードパーティのデータである場合、通常はパイプです。 少なくとも処理が邪魔にならないようにしたいと思います。生データが修復されるとすぐに、すべての顧客がすぐに正しい結果を見ました。



これは本当に大きな問題です。 そして、他にどのように決定するのですか?



解決策1-問題の詳細を削除する



処理が問題を引き起こす場合、それをしないでください! 処理を行ったり、中間結果を保存したりする必要はありません。 ユーザーが結果を必要とするとすぐに、生データからすべてをその場で計算する必要があります。 BigQueryの速度を考えると、これは非常に現実的です。 特に、データを使用して行うのがGROUP BYの日付とカウント(1)であり、過去14日間のデータのみが必要な場合です。



ほとんどの分析は、このようなクエリで特に機能します。 そのため、このソリューションを積極的に使用しています。 ただし、このアプローチは複雑な変換では機能しません。



1つの問題はコードの複雑さです。 すべての操作を1つのSQLクエリに追加すると、読み取られません。 幸いなことに、これはタイプviewのテーブルを通じて達成されます 。 これらはBigQueryの論理テーブルです。データは格納されませんが、SQLクエリからその場で生成されます。 これにより、コードが大幅に簡素化されます。



しかし、別の問題はパフォーマンスです。 ここではすべてが悪いです。 どんなに高速で安価な最新のデータベースであっても。 1年間の履歴データで複雑な変換を実行すると、時間と費用がかかります。 他のオプションはありません。 この問題により、この戦略はかなりの割合の場合に適用できなくなります。



決定番号2-複雑なシステムを構築する



処理制御システムなしで行う方法がない場合は、このシステムをうまく構築する必要があります。 cronスクリプトの実行スケジュールだけでなく、いつどのような変換を開始するかを決定するデータ読み込み監視システム。 おそらく、 pub / subパターンが非常に適しています。



しかし、問題があります。 複雑なシステムの構築が多かれ少なかれ単純な場合、それを維持してバグをキャッチすることは非常に困難です。 コードが多いほど、問題が多くなります。



幸いなことに、3番目の解決策があります。



ソリューション番号3-ラムダアーキテクチャ! ...まあ、ある種の



Lambdaアーキテクチャは、スケジュールされたリアルタイムのデータ処理を活用する有名なデータ処理アプローチです。





*ロシア語に適切に翻訳する方法がわかりませんが、バッチジョブはバッチジョブですか? 誰が知っている、教えて!



通常、これはすべて複数のソリューションを使用して構築されます。 ただし、BigQueryの内部では基本的に同じトリックを使用します。



そして、これがどのように機能するかです:



スケジュールされた処理(バッチレイヤー)。 毎日、現在のデータを変換し、結果をテーブルに保存するSQLクエリを実行します。 すべてのクエリの構造は次のとおりです。







このクエリの結果はtable_staticに保存されます(上書きします)。 はい。BigQueryでは、このクエリで使用されたテーブルにクエリ結果を保存できます。 結果として、すでに計算済みの古いデータを(再集計しないように)取得し、新しいデータと結合します。 X日は、生データに対するすべての可能な調整を考慮するためにデータを再計算するために選択した期間です。 X日間(ソースに対してどれだけの量か)で、すべての調整が既に行われ、破損したものはすべて修復され、データは変更されないと想定されています。



リアルタイムアクセス(速度層+サービス層)。 これらのタスクは両方とも、単一のSQLクエリに結合されます。







はい、これは同じリクエストです! table_liveという名前のビューとして保存し、すべてのユーザー(ダッシュボード、他のクエリなど)がこのビューから結果を描画します。 BigQueryのビューは論理レベル(データではなくクエリのみ)で保存されるため、アクセスされるたびに、直近のX日間を再計算し、元のデータのすべての変更が結果に反映されます。



どちらの場合もリクエストは同じであるため、実際にはコードの重複を避けるため、(バッチレイヤーからの)毎日のリクエストは次のようになります。



SELECT * FROM table_live
      
      



(および結果をtable_staticに保存します)



このアプローチには、いくつかの重要な利点があります。





PS BigQueryで日付で分割されたテーブルを使用する場合(非常に気に入っています)、これに対する解決策があります。 しかし、これは別の投稿のトピックです。 ヒント-これらのテーブルを操作するための関数は、一部のテーブルが単なる表現である場合、誓いません。



PPS BigQueryのビューがキャッシング(通常のクエリでの動作)をサポートしている場合、それは本当にクールです。 これは本質的にそれらをマテリアライズドビューにします。 そして、このアプローチの有効性はさらに高くなります。 同意する場合- ここにアスタリスクを付けると、この機能をより速く実装できます。



All Articles