Share via


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

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

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

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

  • 1 台のコンピューターからリソース (通常は CPU、メモリ、または GPU) を追加または削除することで、垂直スケーリングを行います。 通常、これはワークロードを停止し、より大きなマシンに移動し、再起動することを意味します。 垂直スケーリングの制限: より大きなマシンが存在しないか、次の大きなマシンの価格が非常に高い可能性があります。
  • 分散システムにノードを追加または削除して水平スケーリング: 垂直スケーリングの制限に達すると、水平スケーリングすることが解決策となります: 分散コンピューティングでは、複数のマシン (クラスターと呼ばれる) を持つシステムを使用してワークロードを実行します。 これを可能にするには、Databricks レイクハウス、Apache Spark、Photon のエンジンによってサポートされるように、ワークロードを並列実行用に準備する必要があることを理解することが重要です。 これにより、複数の合理的な価格のマシンを大規模なコンピューティング システムに組み合わせることができます。 より多くのコンピューティング リソースが必要な場合は、水平スケーリングによってクラスターにノードを追加し、不要になったときに削除します。 技術的に制限はありませんが (また、Spark エンジンが負荷の分散の複雑な部分を引き継ぐ)、ノード数が多いと管理の複雑さを増します。
  • 線形スケーラビリティとは、システムにリソースを追加したときに、スループットと使用されるリソースの関係は線形になることを意味します。 これは、並列タスクが独立している場合にのみ可能です。 そうでない場合は、さらに計算するために、1 つのノード セットでの中間結果は、クラスター内の別のノード セットで必要になります。 このノード間のデータ交換には、あるノード セットから別のノード セットにネットワーク経由で結果を転送することが含まれ、これにはかなりの時間がかかります。 一般に、分散コンピューティングでは、データの分散と交換を管理するためのオーバーヘッドが常に発生します。 その結果、分散システムで実行すると、単一ノードで分析できる小規模なデータ セット ワークロードがさらに遅くなる可能性があります。 Databricks Data Intelligence プラットフォームは、ワークロード固有のニーズを満たす柔軟なコンピューティング (単一ノードと分散) を提供します。

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

サーバーレス コンピューティングを使用する

Databricks Data Intelligence プラットフォーム上のサーバーレス コンピューティングでは、コンピューティング レイヤーはお客様の Azure Databricks アカウントで実行されます。 ワークスペース管理者は、インスタント コンピューティングが有効で、Databricks によって管理されるサーバーレス SQL ウェアハウスを作成できます。 サーバーレス SQL ウェアハウスでは、Azure Databricks のお客様のアカウントでホストされているコンピューティング クラスターが使用されます。 通常の Databricks SQL ウェアハウスと同じように Databricks SQL クエリでサーバーレス SQL ウェアハウスを使用します。 サーバーレス コンピューティングは、SQL ウェアハウスの起動時間が非常に速く (10 秒以下)、インフラストラクチャは Databricks によって管理されます。

これにより、生産性が向上します。

  • クラウド管理者が、クォータの調整、ネットワーク資産の作成と保守、請求ソースの結合など、複雑なクラウド環境を管理する必要がなくなりました。
  • ユーザーのクラスター起動の待ち時間がほぼゼロになり、クエリのコンカレンシーが向上するというメリットもあります。
  • クラウド管理者は、低レベルのクラウド コンポーネントを管理する代わりに、より価値の高いプロジェクトに時間を再び集中させることができます。

パフォーマンスのためのワークロードを設計する

データ インジェストとアクセス パターンを理解する

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

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

インジェストとアクセス パターンは、多くの場合、明らかなデータ レイアウトとクラスタリングを指しています。 そうでない場合は、ビジネスにとって何がより重要なものかを決定し、その目標をより適切に解決する方法を考えます。

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

値の取得までの時間は、データを扱う上で重要なディメンションです。 多くのユース ケースは 1 台のマシンに簡単に実装できますが (データが小さく、少数の単純な処理ステップ)、多くの場合、次のようなユース ケースが出てきます。

  • 大規模なデータ セットを処理する必要があります。
  • 複雑なアルゴリズムにより、実行時間が長くなります。
  • 100 回、1000 回と繰り返す必要があります。

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

バッチ タスクと同じ方法で、 構造化ストリーミング は、ストリーミング ジョブをクラスター全体に分散して最適なパフォーマンスを提供します。

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

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

さらに、このプラットフォームには、MLlib と呼ばれる機械学習用の並列アルゴリズムが付属しています。 Horovod Runner など、すぐに活用できるマルチ GPU と分散ディープ ラーニング コンピューティングをサポートします。 「HorovodRunner: Horovod を使用した分散型ディープ ラーニング」を参照してください。 また、このプラットフォームに付属する特定のライブラリは、大量に繰り返されるタスクをすべてのクラスター ノードに分散させて、ほぼ線形的に価値を生み出すまでの時間を短縮するのに役立ちます。 たとえば、ML での並列ハイパーパラメーター最適化の Hyperopt などです。

実行のチェーン全体を分析する

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

  • BI ツール自体。
  • BI ツールと SQL エンジンを接続するコネクタ。
  • BI ツールがクエリを送信する SQL エンジン。

クラス最高のパフォーマンスを発揮するためには、チェーン全体を考慮し、最適なパフォーマンスを発揮するために選択/チューニングする必要があります。

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

Note

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

特にワークロードが線形的にスケーリングされる場合は、大規模なクラスターを計画します。 その場合、ワークロードに大きなクラスターを使用する方が、小さなクラスターを使用するよりもコストが高くつくことはありません。 ただ速くなるだけです。 重要なのは、ワークロードの期間だけクラスターをレンタルすることです。 つまり、2 つのワーカーのクラスターを起動し、1 時間かかる場合は、それらのワーカーに対して 1 時間分の料金を支払うことになります。 同様に、4 つのワーカーのクラスターを起動し、30 分しかかからなかったとしても (線形スケーラビリティが実現されます)、コストは同じです。 コストが非常に柔軟な SLA を備えたプライマリ ドライバーである場合、自動スケーリング クラスターはほとんどの場合、最も安くなりますが、必ずしも最速であるとは限りません。

ネイティブ Spark 機能を使用する

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

理由は、次のとおりです。

  • Python と Spark の間でデータを転送するには、シリアル化が必要となります。 これにより、クエリの速度が大幅に低下します。
  • プラットフォームに既に存在する機能を実装およびテストするための労力が増えます。

ネイティブ関数が欠落しており、Python UDF として実装する必要がある場合は、Pandas UDF を使用します。 Apache Arrow を使用すると、Spark と Python の間でデータの移動が効率的に行われます。

Photon を使用する

Photon は Azure Databricks 上のエンジンであり、データ インジェスト、ETL、ストリーミング、データ サイエンス、対話型クエリなど、データ レイク上で直接、低コストで高速なクエリ パフォーマンスを提供します。 Photon は Apache Spark API と互換性があるため、コードを変更することなく、ロックインされることなく、電源を入れるだけで簡単に使い始めることができます。

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

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

Note

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

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

キャッシュを使用する

Azure Databricks で使用できるキャッシュには、ディスク キャッシュと Spark キャッシュの 2 種類があります。 それぞれの種類には、次の特徴があります。

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

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

  • Spark キャッシュを避ける

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

  • クエリ結果キャッシュ

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

  • Databricks SQL UI キャッシュ

    すべてのクエリとレガシ ダッシュボードのユーザーごとのキャッシュは、Databricks SQL UI になります。

  • プリウォーム クラスター

    Note

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

    クエリとデータ形式に関係なく、クラスター上の最初のクエリは常に後続のクエリよりも遅くなります。 これは、起動し、必要なデータを読み込むすべての異なるサブシステムに関係しています。 これを考慮して、パフォーマンスのベンチマークを行います。 クラスターをすぐに使用できるプールにアタッチすることもできます。 「プール構成リファレンス」を参照してください。

圧縮を使用する

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

自動最適化を使用して、小さなファイルを自動的に圧縮することもできます。 「ファイル サイズのチューニングを検討する」を参照してください。

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

データのスキップ: これを実現するために、Delta テーブルにデータを書き込むと、データ スキップ情報が自動的に収集されます (既定では、Azure Databricks の Delta Lake では、テーブル スキーマで定義された最初の 32 列の統計を収集します)。 Delta Lake on Azure Databricks では、クエリ時にこの情報 (最小および最大の値) を利用してクエリを迅速化します。 「Delta Lake に対するデータのスキップ」を参照してください。

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

動的なファイルの排除:動的なファイルの排除 (DFP) によって、Delta テーブルに対する多くのクエリのパフォーマンスを大幅に向上させることができます。 DFP は、パーティション分割されていないテーブル、またはパーティション分割されていない列の結合に特に効率的です。

過剰なパーティション分割の回避

以前は、パーティション分割がデータをスキップする最も一般的な方法でした。 ただし、パーティション分割は静的であり、ファイル システムの階層としてマニフェストになります。 時間の経過とともにアクセス パターンが変化する場合は、パーティションを簡単に変更する方法はありません。 多くの場合、パーティション分割は過剰なパーティション分割、言い換えると、あまりに小さなファイルであまりに多くのパーティション分割を行うと、クエリのパフォーマンスが低下します。 「パーティション」を参照してください。

それまでの間、パーティション分割よりもはるかに優れた選択肢は Z オーダーです。

ファイル サイズのチューニングを検討する

設定 delta.autoCompactdelta.optimizeWrite によって制御される機能を記述するために、"自動最適化" という用語が使用される場合があります。 この用語は、各設定を個別に記述することを優先して廃止されました。 「データ ファイル サイズを制御するように Delta Lake を構成する」を参照してください。

自動最適化が特に役立つのは、以下のようなシナリオです。

  • 分単位の待機時間が許容されるストリーミングのユース ケース。
  • Delta Lake への書き込みで優先される方法が MERGE INTO である。
  • CREATE TABLE AS SELECT または INSERT INTO は、一般的に使用される操作です。

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

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

    "範囲結合" は、2 つのリレーションが間隔内のポイントまたは間隔の重複条件を使用して結合されるときに実行されます。 Databricks Runtime での範囲結合の最適化のサポートにより、クエリのパフォーマンスを大幅に向上させることができますが、慎重に手動で調整する必要があります。

  • スキュー結合の最適化を検討してください。

    データ スキューは、テーブルのデータがクラスター内のパーティション間で不均等に分散される状態です。 データ スキューは、クエリ (特に結合を含むクエリ) のパフォーマンスを著しくダウングレードする可能性があります。 大きなテーブル間の結合にはデータのシャッフルが必要であり、スキューによってクラスター内の作業の極端な不均衡につながる場合があります。 クエリが非常に少数のタスクを完了してスタックしているように見える場合、データ スキューがクエリに影響を与えている可能性があります。 スキューを改善するために、Delta Lake on Databricks SQL では、クエリのスキュー ヒントを許可します。 Databricks Runtime では、スキュー ヒントからの情報を使用して、データ スキューの影響を受けない、優れたクエリ プランを構築できます。 次の 2 つのオプションがあります。

ANALYZE TABLE を実行してテーブル統計を収集する

ANALYZE TABLE を実行して、クエリ プランナーのテーブル全体の統計を収集します。 「ANALYZE TABLE」を参照してください。

ANALYZE TABLE mytable COMPUTE STATISTICS FOR ALL COLUMNS;

この情報はメタストアに保持され、クエリ オプティマイザーを次の方法でサポートします。

  • 適切な結合の種類の選択。
  • ハッシュ結合で正しいビルド側の選択。
  • 複数方向結合での結合順序の調整。

これは OPTIMIZE と並行して毎日実行する必要があり、テーブル < 5 TB で推奨されます。 唯一の注意点は、ANALYZE TABLE が増分ではないことです。

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

本番データを代表するデータでのテスト

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

リソースのプリウォーミングを考慮する

新しいクラスター上の最初のクエリは、他のすべてのクエリよりも遅くなります。

  • 一般に、クラスター リソースは複数のレイヤーで初期化する必要があります。
  • キャッシュがセットアップの一部である場合、最初の実行によってデータがキャッシュ内にあることを確認し、後続のジョブを高速化します。

リソースのプリウォーミング - リソースの初期化とキャッシュの入力のために特定のクエリを実行する (クラスターの再起動後など) 場合、最初のクエリのパフォーマンスが大幅に向上する可能性があります。 そのため、さまざまなシナリオの動作を理解するには、最初の実行のパフォーマンス (プリウォーミングの有無にかかわらず) とその後の実行をテストします。

ヒント

ダッシュボードの更新などの対話型ワークロードはプリウォーミングの恩恵を大きく受けることができます。 ただし、これは設計による負荷が 1 回だけ実行されるジョブ クラスターには適用されません。

ボトルネックの特定

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

パフォーマンスの監視

オペレーショナル エクセレンス - 監視、アラート、ログ記録を設定する」を参照してください。