01一緒にビッグデータを学びましょう
Lao Liuが今日共有したのは、ビッグデータHadoopフレームワークの分散コンピューティングMapReduceモジュールです。MapReduceの知識ポイントはたくさんあります。辛抱強く覚えておく必要があります。今回はMapReduceの最初の部分を共有します。今回、Lao Liuは、自習教材に基づいてこれらの知識ポイントを共有しました。1つはビッグデータに関心のある学生を支援することであり、もう1つはビッグデータに関心のある学生を支援することです。
02MapReduceナレッジポイント
ポイント1:MapReduceの概念
MapReduceは、分散コンピューティングフレームワークであり、分割統治法を採用しています。MapReduceは2つの段階で構成されていることが言葉からわかります。
マップステージ(大きなタスクを小さなタスクに分割します)
フェーズを減らす(小さなタスクの結果を要約する)
では、分割統治とは何ですか?
たとえば、複雑で計算量が多く、時間のかかるタスクは、一時的に「ビッグタスク」と呼ばれます。現時点で単一のサーバーを使用して計算できない場合、または計算で短期間で結果が得られない場合。 、大きなタスクは小さなタスクに分割でき、小さなタスクは異なるサーバーで並行して実行でき、最後に各小さなタスクの結果が要約されます。
ポイント2:マップフェーズの概要
mapステージにはキーmap()関数があります。このmap()関数の入力は(k、v)キーと値のペアであり、出力も一連の(k、v)キーと値のペアです。出力はローカルディスクに書き込まれます。
ポイント3:削減フェーズの概要
削減フェーズにはキーreduce()関数があります。このreduce()関数の入力もキーと値のペア(つまり、マップによって出力されるキーと値のペア)であり、出力も一連です。 (k、v)のキーと値のペアの結果。結果は最後にHDFSに書き込まれます。
次のように、ポイント2と3の導入を図に要約します。
ポイント4:MapReduceプログラミング
上記の概念のいくつかを説明した後、Lao Liuは理解しているが、当時は理解していなかったので、資料に記載されているプログラミング例を見て、この例の原理とコードの各行を理解した後、突然悟りを開いて幸せになりました。
MapReduceの単語頻度統計を例として取り上げましょう。英語の冠詞のバッチで、各単語の出現回数の合計を数えます。
MapReduceの単語頻度統計の概略図:
図は少し曖昧です。誰もが見て、最初にマップ側とリデュース側のキーコードを共有し、最後に完全なコードを共有します。
地図側:
String line = value.toString();
//按照\t进行分割,得到当前行所有单词
String[] words = line.split("\t");
for (String word : words) {
//将每个单词word变成键值对形式(word, 1)输出出去
//同样,输出前,要将kout, vout包装成对应的可序列化类型,如String对应Text,int对应IntWritable
context.write(new Text(word), new IntWritable(1));
}
削減側:
//定义变量,用于累计当前单词出现的次数
int sum = 0;
for (IntWritable count : values) {
//从count中获得值,累加到sum中
sum += count.get();
}
//将单词、单词次数,分别作为键值对,输出
context.write(key, new IntWritable(sum));// 输出最终结果
コードに関して、Liuが言いたいのは、MapReduceのすべてのパラメーターを把握する必要があるということです。上記は単なるコアコードです。非常に単純に見えますが、注意深く理解する必要のある詳細やさまざまなパラメータがまだたくさんあります。
次に、このプロセスについて説明しましょう。
マップフェーズでは:
MR入力ファイルにblock1、block2、block3の3つのブロックがあると仮定します。各ブロックは分割に対応し、各分割はマップタスクに対応します。
上の図を見ると、3つのマップタスク(map1、map2、map3)があります。これら3つのタスクのロジックはほぼ同じなので、最初のタスクについて説明します。
map1はblock1のデータを読み取り、block1のデータを一度に1行ずつ読み取り、現在のブロックの先頭に対する現在読み取られている行の先頭のバイトオフセットをkey(0)として使用し、現在のコンテンツを使用します。値としての行。
次に、キーと値のペアがmap()のパラメーターとして渡され、map()が呼び出されます。
map()関数では、さまざまなニーズに応じてコードが記述されます。ワードカウントの場合、現在の値の行の内容がスペースに分割され、Dear、Bear、Riverの3つの単語が取得されます。
各単語をキーと値のペアに変換した後、それを出力してget(Dear、1)|(Bear、1)|(River、1)を取得します。
最終結果は、マップタスクが配置されているノードのローカルディスクに書き込まれます(詳細は多く、知識ポイントのシャッフルが含まれますが、この記事の後半でゆっくりと展開されます)。
ブロックの最初の行のデータが処理された後、2番目の行が処理されます。原理は上記と同じです。マップタスクが現在のブロック内のすべてのデータを処理すると、マップタスクは終了します。
削減フェーズ:
削減タスク(つまり、削減タスク)の数は、自分で作成したプログラムによって指定されます。main()にjob.setNumReduceTasks(4)を記述して、4つの削減タスク(reduce1、reduce2、reduce3、reduce4)を指定します。
各reduceタスクのロジックは類似しているため、最初のreduceタスクを分析に使用します。
map1タスクが完了すると、reduce1はhttpネットワークを介してmap1に接続され、map1の出力結果(デフォルトのハッシュパーティションを使用)のreduce1に属するパーティションのデータがネットワークを介してreduce1の最後まで取得されます。同じことがmap2とmap3に接続されています。結果を取得します。
最終的に、reduce1側は4つの(Dear、1)キーと値のペアを取得します。それらのキーは同じであるため、同じグループにグループ化されます。これらの4つの(Dear、1)キーと値のペアは[Dear、1)に変換されます。 、Iterable(1、1、1、)]、2つのパラメーターとしてreduce()に渡されます。
reduce()では、Dearの総数は4として計算され、(Dear、4)はキーと値のペアとして出力されます。各reduceタスクの最終出力ファイルはHDFSに書き込まれます。シャッフルもここで行われます。
これはおおよそのプロセスです。コードが記述された後、Jarパッケージが生成され、Hadoopクラスターで実行されます。
この例を終えた後、Lao LiuはMapReduceの例がたくさんあると言いました。これはそのうちの1つにすぎません。自分でさらに例を見つけることができます。LaoLiuは引き続きMapReduceプログラミングを共有します:データクリーニング、ユーザーの2つの例の検索。関連するコード、最後にそれを置くと、誰もが行って見ることができます。
ポイント5:シャッフル
これは重要なポイントであり、非常に重要なポイントです。シャフとは、主にマップ側の出力をリデュース側の入力として使用するプロセスを指します。中国語でシャッフルを意味します。
まず、詳細を説明
します。パーティショニングはパーティショナーを使用し、デフォルトのパーティショナーはHashPartitionerであり、コードは次のとおりです。
public class HashPartitioner<K2, V2> implements Partitioner<K2, V2> {
public void configure(JobConf job) {
}
/** Use {@link Object#hashCode()} to partition. */
public int getPartition(K2 key, V2 value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}
次に、特定のプロセスについて話します。
地図側:
1.各マップタスクには対応するリングメモリバッファがあります。出力はkvペアであり、リングバッファに書き込まれます(デフォルトサイズは100Mです)。コンテンツがバッファスペースの80%を占めると、バックグラウンドスレッドはバッファオーバーフローのデータはディスクファイルに書き込まれます。
2.オーバーフロー書き込みプロセス中、マップタスクはリングバッファへのデータの書き込みを続行しますが、書き込み速度がオーバーフロー書き込み速度よりも大きく、最終的に100mがいっぱいになると、マップタスクはリングへのデータの書き込みを一時停止します。 buffer Process;オーバーフロー書き込みのプロセスのみが実行されます;リングバッファ内のすべてのデータがオーバーフローしてディスクに書き込まれるまで、バッファへの書き込みが再開されます。
3.ディスクへのバックグラウンドスレッドオーバーフロー書き込みのプロセスには、いくつかのステップがあります。
①上書きされたkvペアごとに最初のパーティションを作成します。パーティションの数はMRプログラムのreduceタスクの数によって決まります。デフォルトでは、HashPartitionerを使用して、現在のkvペアが属するパーティションを計算します。計算式は(key.hashCode)です。 ()&Integer.MAX_VALUE)%numReduceTasks
②各パーティションで、kvペアのキーに従ってメモリをソートします。
③マップ側のローカルアグリゲーションコンバイナが設定されている場合、各パーティションでソートされたデータが結合されます。
④マップ出力を圧縮する機能を設定すると、上書きされたデータが圧縮されます。
注:並べ替えの2番目のステップでは、Lao Liuが言及せずに多くの資料を読んだため、自分でいくつかの資料を検索しました。この並べ替え操作は、Hadoopのデフォルトの動作に属します。論理的に必要かどうかに関係なく、アプリケーションのデータは並べ替えられます。
ソートには、部分ソート、完全ソート、パーティショナーを使用した完全ソート、補助ソート、二次ソートの5つのカテゴリーがあります。具体的な概念については説明しません。自分で検索してください。
4.データがリングバッファに継続的に書き込まれると、オーバーフロー書き込みが複数回トリガーされ(リングバッファが100mでいっぱいになるたびに)、ローカルディスクは最終的に複数のオーバーフローファイルを生成します。
5.マップタスクが完了する前に、すべてのオーバーフローファイルが1つの大きなオーバーフローファイルにマージされます。これは、パーティション化およびソートされた出力ファイルです。
ここにいくつかの小さな詳細があります、覚えておきましょう:
オーバーフローしたファイルをマージするときに、オーバーフローしたファイルが3つ以上あり、マップ側の結合が設定されている場合、結合操作はマージプロセス中にトリガーされます。
ただし、オーバーフローファイルが2つまたは1つしかない場合、結合操作はトリガーされません(結合操作は本質的に削減であるため、特定のオーバーヘッドがあるJVM仮想マシンを起動する必要があります)
削減側:
1. reduceタスクは、各マップタスクが実行された後、HTTPを介してマップタスク出力で独自のパーティションデータ(多くのkvペア)を取得します。
2.マップ出力データが比較的小さい場合は、最初にそれをreduce jvmメモリに保存します。それ以外の場合は、Reduceディスクに直接書き込みます。
3.メモリバッファがしきい値(デフォルトでは0.66)またはマップ出力数のしきい値(デフォルトでは1000)に達すると、マージがトリガーされ、結果がローカルディスクに書き込まれます。MRプログラミングでcombineが指定されている場合、マージ中にcombine操作が実行されます。
4.オーバーフローによって書き込まれるファイルが増えると、バックグラウンドスレッドはそれらを大きなソート済みファイルにマージします。
5. reduceタスクがすべてのマップタスクをコピーした後、ディスク上のすべてのオーバーフローファイルをマージします
、デフォルトでは、一度に10をマージし、マージの最後のバッチ、データの一部はメモリから、一部はディスク上のファイルから取得されます。
6.「マージ、ソート、およびグループ化の段階」に入ります
7.データセットごとにreduceメソッドを1回呼び出します
8.最終結果はHDFSに書き込まれます
03知識ポイントのまとめ
正直なところ、今日はたくさんの知識があります。初めて学び始めたときは、なかなか理解しづらいことがありましたが、覚えておくと、将来の火花や瞬きを学ぶのにとても役立ちます。このモジュールには多くのコンテンツが含まれています。原則はほぼ同じです。今日共有した内容を覚えておいてください。
最後に言いたいのは、MapReduceのプログラミング例はすべてLao Liuの公開アカウントに掲載されており、興味があればチェックすることができます。
何かお持ちの場合は、公式アカウントに連絡してください。一生懸命働いているLao Liuです。大丈夫です。LaoLiuでビッグデータを学びましょう。