このトピックでは、Deltaテーブルのデータ編成最適化のアーキテクチャについて説明します。
クラスタリング
痛みのポイント
デルタテーブルは、増分データの分レベルのほぼリアルタイムのインポートをサポートします。 デルタテーブルが高トラフィック負荷シナリオで使用される場合、小さな増分ファイルの数が増加する可能性があります。 このため、アクセス負荷が高くなり、ストレージコストが高くなります。 多数の小さなファイルが存在する場合、頻繁なメタデータの更新、データ分析速度の低下、I/O効率の低下など、他の複数の問題が発生します。 これらの問題を解決するには、前述のシナリオで小さなファイルを自動的にマージするクラスタリング操作を実行します。
解決策
MaxComputeのストレージサービスは、小さなファイルをマージするためのクラスタリング操作を実行します。 しかし、クラスタリング操作が実行された後、すべてのデータの中間状態は依然として存在し、変更されないままである。
クラスタリング操作のプロセス
次の図は、クラスタリング操作のプロセスを示しています。
クラスタリングポリシーは、一般的な読み書きビジネスシナリオに基づいて構成できます。 設定後、MaxComputeは、データファイルのサイズや数などの複数の次元に基づいて、階層的な方法で定期的にデータファイルをマージします。 上の図では、レベル0で青色で強調表示されている元のDeltaファイルが、レベル1で黄色で強調表示されている中サイズのDeltaファイルにマージされています。 レベル1の中サイズのデルタファイルの数が指定されたしきい値に達すると、これらのファイルは、レベル2でオレンジ色で強調表示された大きなサイズのデルタファイルにさらにマージされます。
特定のサイズを超えるデータファイルに対して、特別な分離処理が実行されます。 この方法では、これらのDeltaファイルでさらにマージすることはありません。 これは、不必要な読み出し及び書き込み増幅を防止する。 上の図では、バケット3のt8データファイルは他のファイルとマージされていません。 生成時刻が指定された時間範囲内にあるファイルのみを1つのファイルにマージできます。 大きな時間差を有するファイルが1つのファイルにマージされる場合、タイムトラベルクエリまたは増分クエリが実行されるときに、クエリの時間範囲に属さない大量の履歴データが読み取られる可能性がある。 これは、不必要な読み出し増幅を引き起こす。
トランザクションテーブル2.0テーブルのデータは、記憶のためにBucketIndexによって分割される。 この場合、クラスタリング操作は、バケット粒度で同時に実施される。 これにより、ランタイム全体が大幅に削減されます。
クラスタリング操作は、メタサービスと対話して、クラスタリング操作を実行する必要があるテーブルまたはパーティションのリストを取得する必要があります。 インタラクションが完了すると、古いデータファイルと新しいデータファイルに関する情報がメタサービスに渡されます。 メタサービスは、クラスタリング操作のトランザクション競合を検出し、データファイルのメタデータをシームレスに更新し、古いデータファイルを安全に再利用します。
クラスタリング操作は、多数のデータファイルによって引き起こされる読み取りおよび書き込み効率の問題を解決するのに役立ちます。 しかし、クラスタリング操作は、コンピューティングおよびI/Oリソースも消費する。 クラスタリング操作が実行されるたびに、すべてのデータが読み書きされます。 これは、読み出しおよび書き込み増幅を引き起こす。 MaxComputeは、システムステータスに基づいて自動的にクラスタリング操作をトリガーし、クラスタリング操作の効率を高めます。
圧縮
痛みのポイント
デルタテーブルを使用すると、UPDATE型とDELETE型のデータを書き込むことができます。 UPDATEおよびDELETE型の大量のデータがDeltaテーブルに書き込まれると、過剰な冗長中間ステータスデータが生成されます。 これにより、ストレージとコンピューティングコストが増加し、クエリ効率が低下します。 したがって、このシナリオでは、ビジネス要件に基づいてコンパクション操作を使用して、中間ステータスを削除し、パフォーマンスを最適化することをお勧めします。
解決策
MaxComputeのストレージサービスは、データファイルをマージするためのコンパクション操作を実行します。 SQL文を手動で実行して、コンパクション操作をトリガーできます。 また、テーブルプロパティパラメーターを設定して、時間頻度やコミット数などのディメンションに基づいてコンパクション操作を自動的にトリガーすることもできます。 コンパクション操作では、ベースファイルとデルタファイルを含む選択したデータファイルをマージして、UPDATEおよびdeleteタイプのデータの中間ステータスを削除します。 複数行のデータが同じ主キー値を持つ場合、最新のステータスを持つ行のみが保持されます。 このようにして、すべてのデータがINSERT型である新しいベースファイルが生成される。
コンパクション操作のプロセス
次の図は、コンパクション操作のプロセスを示しています。
t1からt3までの時点の間に、いくつかのデルタファイルがバケットに書き込まれた後に、コンパクション動作がトリガされる。 すべてのDeltaファイルは各バケットにマージされます。 次に、新しいベースファイルが各バケットに対して生成される。 t4からt6までの時点の間に、いくつかの新しいデルタファイルがバケットに書き込まれた後に、コンパクション動作が再びトリガされる。 既存のベースファイルと新しいデルタファイルをマージして、新しいベースファイルを生成します。
コンパクション操作は、コンパクション操作が実行されるテーブルまたはパーティションのリストを取得するために、メタサービスと対話する必要もあります。 コンパクション操作とメタサービスとの間の相互作用のプロセスは、クラスタリング操作とメタサービスとの間の相互作用のプロセスと同様である。 インタラクションが完了すると、古いデータファイルと新しいデータファイルに関する情報がメタサービスに渡されます。 メタサービスは、コンパクション操作のトランザクション競合を検出し、データファイルのメタデータをアトミックに更新し、古いデータファイルを再利用します。
コンパクション操作は、中間ステータスを削除することができる。 これにより、コンピューティングコストとストレージコストが削減され、完全なスナップショットクエリの効率が効果的に向上します。 しかし、頻繁なコンパクション操作は、多数のコンピューティングおよびI/Oリソースを必要とし、新しいベースファイルが追加のストレージを占有する可能性があります。 履歴デルタファイルは、タイムトラベルクエリに使用でき、すぐに削除することはできません。 これは、ストレージコストを増加させる。 したがって、ビジネス要件とデータ特性に基づいて、コンパクション操作の頻度を決定する必要があります。 UPDATE型またはDELETE型の大量のデータが存在し、完全なデータが頻繁にクエリされるシナリオでは、コンパクション操作が実行される頻度を増やして、クエリの効率を向上させることができます。
データの再利用
データの履歴ステータスは、タイムトラベルクエリおよび増分クエリが実行されるときにクエリされます。 したがって、データは特定の期間保持されなければならない。 テーブルプロパティパラメーターacid.data.retain.hoursを設定して、履歴データが保持される期間を指定できます。 履歴データが生成された時刻がacid.data.retain.hoursパラメーターで指定された時間範囲より前の場合、システムは自動的にデータを再要求して削除します。 データが削除されると、タイムトラベル機能を使用してデータの履歴ステータスを照会することはできません。 操作ログとデータファイルが再利用されます。
Purgeコマンドは、特別なシナリオで履歴データの強制的な消去を手動でトリガーするのに役立ちます。
新しいDeltaファイルがバケットに継続的に書き込まれる場合、新しいDeltaファイルは以前のDeltaファイルに依存する可能性があるため、Deltaファイルを削除することはできません。 Deltaファイル間の依存関係を削除するには、コンパクション操作またはINSERT OVERWRITE操作を実行します。 コンパクション操作またはINSERT OVERWRITE操作の実行後に生成されるデータファイルは、前のDeltaファイルに依存しません。 タイムトラベル機能を使用してデルタファイルを照会できる期間が経過した後、デルタファイルを削除できます。
ユーザーがコンパクション操作を実行しない極端なシナリオでは、MaxComputeは設定を最適化して、無制限の履歴レコードが生成されないようにします。 バックエンドシステムは、タイムトラベル機能を使用して照会できないベースファイルまたはデルタファイルを定期的に圧縮します。 このようにして、圧縮された履歴データファイルは、期待通りに再利用することができる。