Sparkは0から1まで学習します(11)-Sparkはデータの偏りを解決します

1. HiveETLを使用してデータを前処理します

1.1ソリューションのアプリケーションシナリオ

データスキューの原因がHiveテーブルの場合。Hiveテーブルのデータは均一ではなく(たとえば、キーは100万データに対応し、他のキーは10個のデータに対応します)、ビジネスシナリオでは、Hiveテーブルで特定の分析操作を実行するためにSparkを頻繁に使用する必要があるため、使用に適しています。この技術的な解決策。

1.2スキーム実現のアイデア

この時点で、データをHiveで前処理できるかどうか(つまり、データがHive ETLでキーによって事前に集計されるか、他のテーブルと事前に結合されるか)を評価できます。その後、Sparkジョブの対象となるデータは元のデータではありません。ハイブテーブルですが、前処理されたハイブテーブルです。現時点では、データと事前集計または結合操作のため、Sparkジョブでこのような操作を実行するために元のシャッフル演算子を使用する必要はありません。

1.3スキーム実現の原則

このソリューションは、Sparkでのシャッフル演算子の実行を完全に回避するため、根本原因からのデータスキューの問題を解決します。データスキューの問題はまったくありません。しかし、ここでは、このアプローチが永続的な解決策ではなく一時的な解決策であることも思い出してください。データ自体に偏在の問題があるため、Hive ETLでグループ化や結合などのシャッフル操作を実行すると、データスキューが発生し、HiveETLの速度が非常に遅くなる可能性があります。Sparkプログラムでのデータスキューを回避するために、データスキューの発生をHiveETLに進めるだけです。

2.スキューの原因となるいくつかのキーをフィルタリングします

2.1アプリケーションシナリオ

傾きの原因となるキーが少なく、計算自体への影響が大きくないことがわかった場合、このスキームは非常に適しています。たとえば、キーの99%は10個のデータに対応しますが、100万個のデータに対応するキーは1つだけであるため、データの偏りが生じます。

2.2スキーム実現のアイデア

大量のデータを含むいくつかのキーがジョブの実行と計算結果にとって特に重要でないと判断した場合は、いくつかのキーを削除するだけで済みます。たとえば、Spark SQLでは、where句を使用してこれらのキーを削除したり、SparkCoreのRDDでフィルター演算子を実行してこれらのキーを削除したりできます。番号が最も大きいキーを動的に判別し、ジョブが実行されるたびにフィルタリングする必要がある場合は、サンプル演算子を使用してRDDをサンプリングし、各キーの番号を計算して、番号が最も大きいキーを除外できます。

2.3スキーム実現の原則

データスキューの原因となるキーが除外された後、これらのキーは計算に参加せず、データスキューを引き起こすことは当然不可能です。

3.シャッフル操作の並列処理を改善します

3.1スキーム実現のアイデア

RDDでシャッフル演算子を実行するときは、シャッフル演算子の実行時にシャッフル読み取りタスクの数を設定するreduceByKey(1000)などのパラメータをシャッフル演算子に渡します。groupbyやjoinなどのSparkSQLのシャッフルステートメントの場合、パラメータを設定する必要があります。つまりspark.sql.shuffle.partitions、このパラメータはシャッフル読み取りタスクの並列処理を表します。デフォルト値は200で、多くのシナリオでは少し小さすぎます。

3.2スキーム実現の原則

シャッフル読み取りタスクの数を増やすと、タスクに最初に割り当てられた複数のキーを複数のタスクに割り当てることができるため、各タスクで処理できるデータが以前より少なくなります。たとえば、元々5つの異なるキーがあり、各キーが10個のデータに対応し、これらの5つのキーがすべてタスクに割り当てられている場合、このタスクは50個のデータを処理します。シャッフル読み取りタスクが追加された後、各タスクにキーが割り当てられます。つまり、各タスクは10個のデータを処理するため、当然、各タスクの実行時間は短くなります。

4.二重集計

4.1アプリケーションシナリオ

このスキームは、RDDでreduceByKeyなどの集約シャッフル演算子を実行する場合、または集約をグループ化するためにSparkSQLでgroupbyステートメントを使用する場合に適しています。

4.2スキーム実現のアイデア

このスキームの中心的な実現アイデアは、2段階の集計を実行することです。

初めては部分的な集約です:

最初に各キーにランダムな番号(10以内のランダム番号など)を配置します。その後、同じキーが異なります。たとえば、(hello、1)(hello、1)(hello、1)(hello、1)は(1_hello、1)(1_hello、1)(2_hello、1)(2_hello、1)になります。次に、ランダムな番号のデータに対してreduceByKeyなどの集計操作を実行して部分集計を実行すると、部分集計の結果は(1_hello、2)(2_hello、2)になります。

2回目はグローバルアグリゲーションです。

次に、各キーのプレフィックスを削除すると、(hello、2)(hello、2)になり、グローバル集計操作を再度実行して、最終結果(hello、4)を取得します。

4.3スキーム実現の原則

元の同じキーにランダムなプレフィックスを追加することで、複数の異なるキーになり、1つのタスクで元々処理されたデータを複数のタスクに分散して部分的に集約できるため、1つのタスクによる過剰なデータ処理の問題が解決されます。問題。次に、ランダムプレフィックスを削除し、グローバル集計を再度実行して、最終結果を取得します。

[外部リンクの画像転送に失敗しました。ソースサイトにアンチホットリンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-BB9Tof6K-1602580670499)(E:\ maven \ big-data-cloud \ spark \ spark_double_groupby.png)]

データクリーニングを引き起こすキーがRDDにあり、同時に他のキーがある場合、通常、最初にデータがサンプリングされ、次に傾斜したキーが検出され、次に元のRDDがフィルターを使用して分離されて2つのRDDが分離されます。傾斜キーで構成されるRDD1、1つは他のキーで構成されるRDD2です。次に、RDD1を使用して、マルチパーティションおよびマルチタスク計算用のランダムプレフィックスを追加し、別のRDD2用の通常の集計計算を行い、最後に結果を結合します。

5.リデュース結合をマップ結合に変換します

BroadCast +フィルター(またはマップ)

5.1スキームの適用シナリオ

RDDで結合操作を使用する場合、またはSpark SQLで結合ステートメントを使用する場合で、結合操作でRDDまたはテーブルのデータ量が比較的少ない場合(数百Mまたは1つまたは2つのGなど)、このソリューションの方が適しています。

5.2スキーム実現のアイデア

結合操作に結合演算子を使用しないでください。ただし、ブロードキャスト変数とマップ演算子を使用して結合操作を実装することで、シャッフル操作を完全に回避し、データスキューの発生と発生を完全に回避します。小さい方のRDDのデータは、収集演算子を介してドライバ側のメモリに直接プルされ、ブロードキャスト変数が作成されます。マップ演算子は、別のRDDでは実行されません。演算子関数で、Broadcast変数から小さいRDDの完全なデータを取得し、接続キーに従って現在のRDDの各データと比較します。接続キーが同じである場合は、2つのRDDのデータを必要な方法で使用します。それらを接続します。

5.3スキーム実現の原則

通常の結合はシャッフルプロセスを経て、一度シャッフルすると、同じキーのデータをシャッフル読み取りタスクにプルしてから結合するのと同じです。今回はリデュース結合です。ただし、RDDが比較的小さく、ブロードキャストスモールRDDフルデータ+マップ演算子を使用して、結合と同じ効果、つまりマップ結合を実現できる場合、シャッフル操作は発生せず、データスキューも発生しません。 。

6.チルトキーとスプリットジョイン操作のサンプル

6.1アプリケーションシナリオ

2つのRDD / Hiveテーブルが結合されている場合、データ量が比較的多く、「Resolution Five」を採用できない場合は、この時点で2つのRDD / Hiveテーブルのキー分布を確認できます。データスキューが発生する場合は、一方のRDD / Hiveテーブルのいくつかのキーのデータ量が大きすぎて、もう一方のRDD / Hiveテーブルのすべてのキーがより均等に分散されているため、このソリューションはより多くなります。適切です。

6.2スキーム実現のアイデア

データ量が多すぎるいくつかのキーを含むRDDの場合、サンプルオペレーターを使用してサンプルをサンプリングし、各キーの数をカウントして、データ量が最も多いキーを計算します。次に、これらのキーに対応するデータが元のRDDから分離されて、個別のRDDが形成され、各キーの前にn内のランダムな番号が付けられ、ほとんどの歪んだキーが別のキーを形成することはありません。 RDD。次に、結合する必要のある別のRDDで、ページは傾斜キーに対応するデータを除外して単一のRDDを形成し、各データをn個のデータに展開します。これらのn個のデータは順番に0〜nに近くなります。プレフィックス。傾きを引き起こさないほとんどのキーは、別のRDDも形成します。ランダムなプレフィックスを持つ独立したRDDと、n倍に拡張された別の独立したRDDの結合について説明します。このとき、元の同じキーをn個の部分に分割し、結合のために複数のタスクに分散できます。他の2つの通常のRDDは、通常どおり結合できます。最後に、2つの結合の結果がユニオン演算子を使用して結合され、これが最終的な結合結果になります。

ここに写真の説明を挿入

7.ランダムプレフィックスと拡張RDDを使用して結合します

7.1ソリューションのアプリケーションシナリオ

RDD内のキーの数が多いと、結合操作中にデータスキューが発生する場合、キーを分割しても意味がありません。現時点では、最後の解決策は問題の解決にのみ使用できます。

7.2スキーム実現のアイデア

このソリューションの実装方法は、基本的に「ソリューション6」に似ています。まず、RDD / Hiveテーブルのデータ分布を確認し、データスキューの原因となるRDD / Hiveテーブルを見つけます。たとえば、10,000個を超えるデータに対応する複数のキーがあります。 。次に、n内にランダムなプレフィックスを付けて各データをRDDに配置します。同時に、別の通常のRDDの容量を拡張し、各データをn個のデータに拡張し、拡張された各データの前に0〜nのプレフィックスを付けます。最後に、処理された2つのRDDを結合します。

ここに写真の説明を挿入

おすすめ

転載: blog.csdn.net/dwjf321/article/details/109056363