パフォーマンス効率のベストプラクティス

この記事では、次のセクションに示すアーキテクチャの原則別に整理された 、パフォーマンス効率のベスト プラクティスについて説明します。

1. 垂直スケーリング、水平スケーリング、線形スケーラビリティ

ベスト プラクティスに入る前に、分散コンピューティングの概念 (水平スケーリング、垂直スケーリング、線形スケーラビリティ) をいくつか見てみましょう。

  • 垂直スケーリング: 単一のマシンからリソース (通常は CPU、メモリ、GPU) を追加または削除することで、垂直にスケーリングします。 これは通常、ワークロードを停止し、より大きなマシンに移動して再起動することを意味します。 垂直スケーリングには限界があり、より大きなマシンがなかったり、次に大きなマシンの価格が法外に高かったりすることがあります。

  • 水平スケーリング: 分散システムにノードを追加または削除することで、水平方向にスケーリングします。 垂直スケーリングの限界に達した場合、ソリューションは水平スケーリングです。分散コンピューティングでは、複数のマシン (クラスターと呼ばれる) を備えたシステムを使用してワークロードを実行します。 これを可能にするには、Databricks Data Intelligence Platform、Apache Spark、および Photon のエンジンでサポートされているように、ワークロードを並列実行用に準備する必要があることを理解することが重要です。 これにより、複数の安価なマシンを組み合わせて、より大きなコンピューティングシステムにすることができます。 より多くのコンピュートリソースが必要な場合は、水平スケーリングによってクラスターにノードが追加され、不要になったら削除されます。 技術的には制限はありませんが (Spark エンジンが負荷分散の複雑な部分を実行します)、ノードの数が多くなると管理の複雑さが増します。

  • 線形スケーラビリティ。つまり、システムにリソースを追加しても、スループットと使用されるリソースの関係は線形になります。 これは、並列タスクが独立している場合にのみ可能です。 そうでない場合、あるノード セットの中間結果は、さらなる計算のためにクラスター内の別のノード セットで必要になります。 このノード間のデータ交換には、あるノードセットから別のノードセットへのネットワーク経由の転送が含まれますが、これにはかなりの時間がかかります。 一般に、分散コンピューティングには、データの配布と交換を管理するためのオーバーヘッドがあります。 その結果、単一ノードで分析できる小さなデータ セットのワークロードは、分散システムで実行するとさらに遅くなる可能性があります。 Databricks データ インテリジェンス プラットフォームは、ワークロードの固有のニーズを満たす柔軟なコンピューティング (単一ノードおよび分散) を提供します。

2. サーバーレスアーキテクチャを使用する

サーバレス コンピュートを使用する

Data Intelligence Platform 上の サーバレス コンピュート を使用すると、コンピュート レイヤーは顧客の DatabricksDatabricksアカウントで実行されます。サービスはフルマネージドであり、 Databricksによって継続的に強化されています。 顧客は使用した分だけ支払うことになるため、生産性が向上します。

  • クラウド管理者は、クォータの調整、ネットワーク リソースの作成と維持、課金ソースへの接続など、複雑なクラウド環境を管理する必要がなくなります。 低レベルのクラウド コンポーネントを管理する代わりに、より価値の高いプロジェクトに時間を集中できます。

  • ユーザーは、クラスターの起動待ち時間がほぼゼロになり、クエリの同時実行性が向上するというメリットを享受できます。

、 ワークロード用の サーバーレスDatabricks SQLウェアハウス SQLSQLを提供します。ワークスペース管理者は、即時コンピュートが可能で によって管理されるサーバーレス ウェアハウスを作成できます。Databricks元の Databricks SQL ウェアハウスで通常使用するのと同じように、Databricks SQL クエリで使用します。 サーバレス コンピュートはSQLウェアハウスにとって非常に高速な起動時間を特徴としており、インフラストラクチャはDatabricksによって管理および最適化されています。

3. パフォーマンスを考慮したワークロードの設計

データ取り込みとアクセスパターンを理解する

パフォーマンスの観点から見ると、"集計とポイント アクセス" や "スキャンと検索" などのデータ アクセス パターンは、データ サイズに応じて動作が異なります。 大きなファイルはスキャンクエリに対してより効率的であり、特定の行を見つけるために読み取る必要のあるデータが少なくて済むため、小さなファイルは検索に適しています。

インジェスト パターンでは、DML ステートメントを使用するのが一般的です。 DML ステートメントは、データがクラスター化され、データのセクションを簡単に分離できる場合に最もパフォーマンスが高くなります。 取り込み中はデータをクラスター化し、分離可能に保つことが重要です: 自然な時間の並べ替え順序を維持し、取り込みターゲット テーブルにできるだけ多くのフィルターを適用することを検討してください。 追加のみのインジェスト ワークロードと上書きインジェスト ワークロードの場合は、比較的安価な操作であるため、考慮することはあまりありません。

取り込みとアクセスのパターンは、多くの場合、明らかなデータ レイアウトとクラスタリングを示します。 そうでない場合は、ビジネスにとって何がより重要かを決定し、その目標をより適切に達成する方法に焦点を当てます。

有益な場合は並列計算を使用する

価値実現までの時間は、データを扱う際の重要なディメンションです。 多くのユースケースは単一のマシンで簡単に実装できますが (データが少なく、計算ステップが少なくて単純)、大規模なデータ セットを処理する必要があるユースケースや、複雑なアルゴリズムのために実行時間が長いユースケース、または何百回、何千回も繰り返す必要があるユースケースも数多くあります。

Databricks プラットフォームのクラスター環境は、これらのワークロードを効率的に分散するのに最適な環境です。 クラスターのすべてのノードにわたって SQL クエリを自動的に並列化し、同じことを実行するためのPythonおよびScala用のライブラリを提供します。 内部的には、Apache Spark エンジンと Photon エンジンがクエリを分析し、並列実行の最適な方法を決定し、分散実行を回復力のある方法で管理します。

バッチタスクと同様に、構造化ストリーミングは ストリーミング ジョブをクラスター全体に分散して、最高のパフォーマンスを実現します。

並列コンピューティングを使用する最も簡単な方法の 1 つは、Delta Live Tablesを使用することです。 ジョブのタスクと依存関係をSQLまたはPythonで宣言すると、 Delta Live Tables実行計画、効率的なインフラストラクチャのセットアップ、ジョブの実行、モニタリングを処理します。

データサイエンティストにとって、 pandas はPythonプログラミング言語用の使いやすいデータ構造とデータ分析ツールを提供するPythonパッケージです。 ただし、Pandasはビッグデータにスケールアウトしません。 Spark 上の Pandas API は、Apache Spark で動作する pandas と同等の APIs を提供することで、このギャップを埋めます。

さらに、このプラットフォームには、標準の機械学習ライブラリMLlibの並列化された機械学習アルゴリズムが付属しています。 すぐに使用できるマルチGPUの使用をサポートしています。 ディープラーニングは、 Horovod RunnerDeepSpeed Distributor 、またはTorchDistributorを使用して並列化することもできます。

実行チェーン全体を分析

ほとんどのパイプラインや消費パターンには、システムのチェーンが関係しています。 たとえば、BI ツールの場合、パフォーマンスはいくつかの要因によって影響を受けます。

  • BI ツール自体。

  • BI ツールと SQL エンジンを接続するコネクタ。

  • BI ツールがクエリを送信する SQL エンジン。

クラス最高のパフォーマンスを得るには、チェーン全体を考慮し、最高のパフォーマンスが得られるように選択/調整する必要があります。

より大きなクラスターを優先する

特にワークロードが直線的に拡張される場合は、より大きなクラスターを計画します。 この場合、ワークロードに対して大規模なクラスターを使用することは、小規模なクラスターを使用することよりもコストが高くなることはありません。 ただ、その方が速いのです。 重要なのは、ワークロードの期間中、クラスターをレンタルすることです。 したがって、ワーカー クラスターを 2 つ起動して 1 時間かかる場合は、ワーカーに対して 1 時間分の料金を支払うことになります。 同様に、4 つのワーカー クラスターを起動するのに 30 分しかかからない場合 (ここで線形スケーラビリティが役立ちます)、コストは同じになります。 コストが主な要因であり、非常に柔軟なSLAである場合、オートスケール クラスターは通常最も安価ですが、必ずしも最速であるとは限りません。

サーバレス コンピュートでは、クラスターを自動的に管理するため、大規模なクラスターを優先する必要はありません。

ネイティブの Spark 操作を使用する

ユーザー定義関数 (UDF) は、Spark SQL の機能を拡張する優れた方法です。 ただし、ネイティブ関数が存在する場合は、Python または Scala UDF を使用しないでください。

理由:

  • Python と Spark 間でデータを転送するにはシリアル化が必要です。 これにより、クエリが大幅に遅くなります。

  • プラットフォームに既に存在する機能を実装してテストする労力の増加。

ネイティブ関数が欠落していて、Python UDF として実装する必要がある場合は、 Pandas UDF を使用します。 Apache Arrowは 、データがSparkとPythonの間を効率的に行き来することを保証します。

ネイティブ・プラットフォーム・エンジンの使用

Photon はDatabricksのエンジンで、データ取り込み、ETL、ストリーミング、データサイエンス、インタラクティブクエリーなど、高速なクエリーパフォーマンスを低コストでデータレイク上で直接提供します。 PhotonはApache Spark APIsと互換性があるため、コードの変更やロックインなしで、電源を入れるのと同じくらい簡単に開始できます。

Photon は、既存の SQL および DataFrame API 呼び出しをより高速に実行し、ワークロードあたりの総コストを削減する高性能ランタイムの一部です。 Photon は、Databricks SQL ウェアハウスでデフォルトで使用されます。

ハードウェアとワークロードの種類を理解する

すべてのクラウド VM が同じように作成されるわけではありません。 クラウド プロバイダーが提供するさまざまなマシン ファミリは、それぞれが異なっており、重要な点があります。 RAMとコアという明らかな違いと、プロセッサの種類と世代、ネットワーク帯域幅の保証、ローカルの高速ストレージとローカルディスクとリモートディスクの微妙な違いがあります。 「スポット」市場にも違いがあります。 ワークロードに最適な VM の種類を決定する前に、これらを理解する必要があります。

serverless コンピュートではクラスターが自動的に管理されるため、これは必要ありません。

キャッシュを使用する

キャッシュは、頻繁にアクセスされるデータをより高速なメディアに保存し、元のデータソースにアクセスする場合と比較して、データの取得に必要な時間を短縮します。 これにより、レイテンシーが短縮され、応答時間が短縮され、アプリケーションの全体的なパフォーマンスとユーザーエクスペリエンスが大幅に向上します。 キャッシュは、元のデータソースへのリクエスト数を最小限に抑えることで、ネットワーク トラフィックとデータ転送コストを削減するのに役立ちます。 この効率性の向上は、外部APIsや従量課金制のデータベースに依存するアプリケーションにとって特に有益です。 これにより、システム全体に負荷をより均等に分散し、ボトルネックや潜在的なダウンタイムを防ぐことができます。

Databricks ではいくつかの種類のキャッシュが利用できます。 各タイプの特徴は次のとおりです。

  • ディスクキャッシュを使用

    ディスク キャッシュ(旧称「 Deltaキャッシュ」) は、仮想マシンのローカル ディスク ( SSDなど) にリモート データのコピーを保存します。 さまざまなクエリのパフォーマンスを向上させることができますが、任意のサブクエリの結果を格納するために使用することはできません。 ディスクキャッシュは、データファイルが作成または削除されたことを自動的に検出し、それに応じてその内容を更新します。 ディスク キャッシュを使用するための推奨される (そして最も簡単な) 方法は、クラスターを構成するときに SSD ボリュームを持つワーカー タイプを選択することです。 このようなワーカーは有効化され、ディスク キャッシュ用に構成されます。

  • Spark キャッシュを避ける

    Spark キャッシュ( .persist().unpersist()を使用) には、サブクエリ データの結果と、Parquet 以外の形式 (CSV、JSON、ORC など) で保存されたデータを保存できます。 ただし、クエリの間違った場所で使用すると、すべてのメモリが消費され、クエリの速度が大幅に低下する可能性があります。 経験則として、どのような影響があるか正確にわからない限り、 Spark キャッシュは避けてください

  • クエリー 結果キャッシュ

    ウェアハウスを介したすべての クエリのクエリ結果をクラスターごとにキャッシュします 。SQLクエリ結果のキャッシュを活用するには、たとえば = NOW()などの述語を使用しない決定論的クエリに重点を置きます。 クエリが決定論的であり、基になるデータがDelta形式で変更されていない場合、 SQLウェアハウスはクエリ結果キャッシュから直接結果を返します。

  • Databricks SQL UI キャッシュDatabricks SQL UIのすべてのクエリと従来のダッシュボードの結果のユーザーごとのキャッシュ。

圧縮を使用する

Databricks 上の Delta Lake を使用すると、テーブルからのクエリの読み取り速度が向上します。 1 つの方法は、小さなファイルを大きなファイルに結合することです。 OPTIMIZE コマンドを実行すると、圧縮がトリガーされます。 「データファイルのレイアウトを最適化する」を参照してください。

Delta Lake には、書き込みおよび OPTIMIZE 操作のターゲット ファイル サイズを自動的に構成するためのオプションが用意されています。 Databricks はこれらの設定の多くを自動的に調整し、適切なサイズのファイルを求めてテーブルのパフォーマンスを自動的に向上させる機能を有効にします。

  • 自動コンパクトは、 Delta テーブル パーティション内の小さなファイルを結合して、小さなファイルの問題を自動的に軽減します。 自動圧縮は、テーブルへの書き込みが成功した後に行われ、書き込みを実行したクラスター上で同期的に実行されます。 自動圧縮は、以前に圧縮されていないファイルのみを圧縮します。

  • 最適化された書き込みにより 、データが書き込まれるときのファイルサイズが改善され、テーブルに対する後続の読み取りに役立ちます。 最適化された書き込みは、各パーティションに書き込まれる小さなファイルの数を減らすため、パーティション テーブルに対して最も効果的です。

詳細については、 「Delta Lake を構成してデータ ファイル サイズを制御する」を参照してください。

データのスキップを使用する

データのスキップは、クエリ条件を満たさないデータをスキップすることで、クエリのパフォーマンスを大幅に向上させることができます。 これにより、読み取りと処理が必要なデータの量が減り、クエリの実行時間が短縮されます。

これを実現するために、Delta テーブルにデータを書き込むときに、データ スキップ情報が自動的に収集されます (デフォルトでは、Databricks 上の Delta Lake は、テーブル スキーマで定義されている最初の 32 列の統計を収集します)。 Databricks 上の Delta Lake は、クエリ時にこの情報 (最小値と最大値) を使用して、より高速なクエリを提供します。 Delta Lake のデータスキップを参照してください。

最良の結果を得るには、関連する情報を同じファイル セット内に配置するための手法であるZ-Ordering使用します。 この共存性は、Databricks では Delta Lake のデータ スキップ アルゴリズムによって自動的に使用されます。 この動作により、Delta Lake が読み取る必要があるデータの量が大幅に削減されます。

または、データ レイアウトの決定を簡素化し、クエリ パフォーマンスを最適化する、新しいリキッド クラスタリングを使用します。 時間の経過とともに、パーティショニングとZ-Orderingが置き換えられます。 Databricks 、すべての新しいデルタ テーブルにリキッド クラスタリングを推奨しています。 リキッドクラスタリングは、既存のデータを書き換えることなくクラスタリング キーを再定義する柔軟性を提供し、時間の経過とともに分析ニーズに合わせてデータ レイアウトを進化させることができます。 Databricks 、すべての新しいデルタ テーブルにリキッド クラスタリングを推奨しています。

リキッドクラスタリングは、以下の特性を持つテーブルに最適です。

  • カーディナリティの高い列でフィルター処理されます。

  • データ分布が著しく歪んでいる。

  • これは急速に成長し、メンテナンスとチューニングの労力を必要とします。

  • 並列書き込み要求あり。

  • 時間の経過とともに変化するアクセス パターン。

  • 一般的なパーティション キーでは、テーブルのパーティションが多すぎたり少なすぎたりする可能性があります。

詳細とテクニックについては、「Databricks、Spark、Delta Lake ワークロードを最適化するための包括的なガイド」を参照してください。

過剰なパーティション分割を避ける

以前は、 パーティション分割 がデータをスキップする最も一般的な方法でした。 ただし、パーティション分割は静的であり、ファイルシステム階層として現れます。 アクセスパターンは時間の経過とともに変化するため、パーティションを変更する簡単な方法はありません。 多くの場合、パーティション分割は過剰なパーティション分割、つまり、小さすぎるファイルを含むパーティションが多すぎて、クエリのパフォーマンスが低下します。

Databricks では、サイズが 1 TB 未満のテーブルをパーティション分割しないこと、および各パーティションのデータが少なくとも 1 GB になると予想される場合にのみ列ごとにパーティション分割することをお勧めします。

その間、パーティショニングよりも優れた選択肢はZ-Orderingまたは新しいリキッドクラスタリング(上記を参照) です。

結合パフォーマンスの最適化

  • 範囲結合の最適化を検討してください。

    範囲結合は、2 つのリレーションが間隔内の点または間隔のオーバーラップ条件を使用して結合されるときに発生します。 Databricks Runtime の範囲結合最適化サポートにより、クエリ パフォーマンスが大幅に向上しますが、慎重な手動チューニングが必要です。

  • アダプティブ クエリ実行を使用します。

    アダプティブ クエリ実行 (AQE) は、クエリの実行中に発生するクエリの再最適化です。 4つの主要な機能があります。

    • ソート・マージ結合をブロードキャスト・ハッシュ結合に動的に変更します。

    • シャッフル交換後にパーティションを動的に結合します。

    • ソートマージ結合とシャッフルハッシュ結合のスキューを動的に処理します。

    • 空のリレーションを動的に検出して伝播します。

    AQE を有効にしておくことをお勧めします。 さまざまな機能を 個別に構成できます

詳細については、Databricks、Spark、Delta Lake ワークロードを最適化するための包括的なガイドを参照してください。

テーブルの分析を実行してテーブル統計を収集する

`ANALYZE TABLE`ステートメントは、指定されたスキーマ内のテーブルに関する統計を収集します。 これらの統計は、 クエリ オプティマイザー によって、最適なクエリ プランの生成、正しい結合の種類の選択、ハッシュ結合での正しいビルド側の選択、または多方向結合での結合順序の調整に使用されます。

これらのクエリ最適化を適切に活用するには、 ANALYZE TABLEコマンドを定期的に実行する必要があります (1 日に 1 回、またはデータが 10% 以上変化したとき、どちらか早い方)。

4. 開発範囲内でパフォーマンステストを実行する

本番運用データを表すデータのテスト

本番運用データ(読み取り専用)または同様のデータに対してパフォーマンス テストを実行します。 同様のデータを使用する場合、ボリューム、ファイル レイアウト、データ スキューなどの特性は本番運用データと類似している必要があります。これは、パフォーマンスに大きな影響を与えるためです。

予熱リソースを検討する

クエリとデータ形式に関係なく、クラスター上の最初のクエリは常に後続のクエリよりも遅くなります。 これは、すべての異なるサブシステムが起動し、必要なすべてのデータを読み取っているためです。 事前ウォーミングは、パフォーマンステストの結果に大きな影響を与えます。

  • クラスターを事前ウォームアップ: クラスター リソースは複数のレイヤーで初期化する必要があります。 クラスターを事前にウォームアップすることが可能です。Databricksプールは、アイドル状態ですぐに使用できるインスタンスのセットです。 これらのアイドル インスタンスを使用してクラスター ノードを作成すると、クラスターの起動時間とオートスケール時間が短縮されます。

  • キャッシュの事前ウォームアップ: キャッシュがセットアップの一部である場合、最初の実行でデータがキャッシュ内にあることが保証され、後続のジョブが高速化されます。 特定のクエリを実行してキャッシュを初期化することにより、キャッシュを事前ウォームアップできます (たとえば、クラスターの再起動後)。 これにより、最初のいくつかのクエリのパフォーマンスが大幅に向上します。

そのため、さまざまなシナリオの動作を理解するには、事前ウォームアップの有無にかかわらず、最初の実行と後続の実行のパフォーマンスをテストします。

ボトルネックを特定する

ボトルネックとは、本番運用中に負荷が増加すると全体的なパフォーマンスが低下する可能性があるワークロード内の領域です。 設計時にこれらを特定し、より高いワークロードに対してテストすることで、本番運用でワークロードを安定させることができます。

5. パフォーマンスを監視する

クエリのパフォーマンスを監視する

クエリ パフォーマンスを監視すると、さまざまなクエリによってリソースがどのように使用されているかを理解するのに役立ちます。 実行速度が遅いクエリを特定して、システムのパフォーマンスのボトルネックを特定できます。 また、システム リソースを大量に消費し、不安定性やダウンタイムにつながる可能性のあるクエリを特定することもできます。 この情報は、リソースの割り当てを最適化し、無駄を減らし、リソースが効率的に使用されていることを確認するのに役立ちます。

Databricks Data Intelligence Platform にはさまざまな モニタリング 機能があり ( 「Operational Excellence - モニタリング、アラート、ログの設定」を参照)、その一部はパフォーマンス モニタリングに使用できます。

  • クエリ プロファイル: クエリ プロファイル 機能を使用して、クエリ実行中のパフォーマンスのボトルネックをトラブルシューティングします。 各クエリ タスクと、費やされた時間、処理された行数、使用されたメモリなどの関連メトリックの視覚化を提供します。

  • SQLウェアハウスモニタリング: ライブ統計、ピーククエリ数チャート、稼働中のクラスターチャート、クエリ履歴テーブルを表示して、 SQLウェアハウスを監視します。

ストリーミングワークロードを監視する

ストリーミング モニタリングを使用すると、データを分析し、問題が発生したときにそれを検出できるため、システムのパフォーマンスと動作に関するリアルタイム 知見が得られます。 ストリーミング データを分析することで、傾向、パターン、最適化の機会を特定できます。 これにより、システムを微調整し、リソースの使用率を向上させ、コストを削減することができます。

ストリーミング Spark UIクエリの場合は、 の組み込み 構造化ストリーミング モニタリング を使用するか、Apache Spark ストリーミング クエリ リスナー インターフェイスを使用してメトリックを外部のサービスにプッシュします。

ジョブのパフォーマンスを監視する

ジョブ モニタリングは、障害、遅延、パフォーマンスのボトルネックなど、 Databricksジョブの問題を特定して対処するのに役立ちます。 ジョブ モニタリングは、ジョブ のパフォーマンスに関する知見を提供し、リソースの使用率を最適化し、無駄を減らし、全体的な効率を向上させることを可能にします。