実験環境:Red Hat 6.5、Hadoop-2.6.5 JDK1.7.0版
詳細は実験ガイドを参照してください。本書は補助作業用の文書です。詳しいコマンドについては教育実験ガイドを参照してください。
1.Hadoop導入実験
- 準備
- ホスト名を構成する
ホスト名を変更する方法:
仮想マシンの IP アドレスを表示する
各サーバーの /etc/hosts ファイルを変更して、ホスト名構成を追加します。
-
-
- JDKのインストールと設定
-
Red Hat システムの yum を登録する必要があるため、手動でダウンロードします
Jdk のダウンロード バージョンは次のとおりです: jdk-7u67-linux-x64.tar.gz
構成は ./bashrc ファイルに追加されます。
-
-
- Hadoop プログラムを実行するユーザーを作成する
-
Hadoop プログラムを実行するユーザー hadoop をシステムに追加し、そのログイン パスワードを hadoop に変更します。
———————————
Linux では、一般ユーザーにパスワードなしのスーパー権限 sudo を付与します
vim /etc/sudoers
この行を見つけます root ALL=(ALL) ALL
彼の下に xxx ALL=(ALL) ALL を追加します
sudoers は、次の 4 行のいずれかを追加できます。
root ALL=(ALL) ALL
user ALL=(ALL) NOPASSWD: ALL
user ALL=(root) //root ユーザーが所有する権限を付与します
———————————
-
-
- SSH キーレス認証構成を構成する
-
パスワードなしの SSH ログインを実装するには、ホスト上で公開キーと秘密キーのログインを構成する必要があります。この時点で、root アカウントでログインし、各ホストの /etc/ssh/sshd_config ファイルを変更し、RSAAuthentication yes と PubkeyAuthentication yes の前の「#」を削除する必要があります。
作成した Hadoop を使用してシステムに再度ログインし、各ホストで ssh-keygen -t rsa コマンドを実行して、ローカルの公開鍵と秘密鍵のペアを生成します。
3台のスレーブホストで同じ処理を実行する必要があります。次に、scp コマンドを使用して 3 つのスレーブ ホストの公開キーをマスター ホストにコピーします。
このうち、id_rsa.pub の内容は以下の通りで、これはマスターホスト上のユーザー hadoop の公開鍵、slave1.pub、slave2.pub、slave3.pub はそれぞれスレーブホストの公開鍵です。
その後、4 つのホストの公開キーをマスター ホストの認証ファイル[1]に追加すると、次のようになります。
次に、マスター ホスト上のauthorized_keys ファイルを 3 つのスレーブ ホストに scp します。
コマンド scp allowed_keys smile1:/home/hadoop/.ssh/
さらに、関連するディレクトリとファイルの権限を変更する必要があり、各サーバーで以下を実行する必要があります。
ファイアウォールをオフにする
selinux の値を無効に設定します。
-
- Hadoopクラスターのインストール
- マスターにインストールする
- Hadoopクラスターのインストール
ファイル hadoop-2.6.5.tar.gz をマスター ノードにアップロードし、解凍します。
[hadoop@master ~]tar zxvf hadoop-2.6.5.tar.gz
シンボリックリンクを作成する
[hadoop@master ~]ln -s hadoop-2.6.5 hadoop
CCB 設定プロセスでは、hadoop-config ディレクトリを作成し、環境変数を作成します。
[hadoop@master ~]mkdir hadoop-config
[hadoop@master ~]cp hadoop/conf/* ./hadoop-config/
[hadoop@master ~]export HADOOP_CONF_DIR=/home/hadoop/hadoop-config/
環境変数を作成する
etc/hadoop の設定ファイルを変更します。
コアサイト.xml
HDFS-site.xml
マスター
奴隷
-
-
- スレーブホストを変更する
-
構成ファイルとインストール ファイルをマスター ホストにコピーします。
[hadoop@master ~]$ scp -r .bashrc hadoop-config/ hadoop-2.6.5.tar.gz smile1:/home/hadoop/
[hadoop@slave1 ~]# mkdir /var/lib/cassandra/data/hadoop
[hadoop@slave1 ~]# mkdir /var/lib/cassandra/data/hadoop/tmp
[hadoop@slave1 ~]# mkdir /var/lib/cassandra/data/hadoop/data
[hadoop@slave1 ~]# mkdir /var/lib/cassandra/data/hadoop/name
インストールファイルを解凍し、シンボリックリンクを作成します。
tar zxvf hadoop-0.20.2.tar.gz && ln -s hadoop-2.6.5 hadoop
-
- サービスを開始する
サービスを初めて開始する場合は、まず NameNode ノードをフォーマットする必要があります。
[hadoop@master ~]$ hadoop namenode -format
エラーが報告された場合: その理由は、ディレクトリに新しいファイルを作成するのに十分な権限がないためです。次のように入力します。
sudo chmod -R a+w /var/lib/
それでおしまい
jps datanode が起動していない場合:
次に、コマンド ラインを入力します: ${HADOOP_HOME}/sbin/hadoop-daemon.sh start datanode
他のノードも同様の方法で起動します
Hadoop をシャットダウンします: stop-all.sh
ファイルをアップロードする
[hadoop@master ~]$ hadoop fs -put hadoop-config/ config
チェック
Hadoop fs -ls /usr/Hadoop/
サンプルプログラムを実行してみる
[hadoop@master hadoop]hadoop jar hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount /usr/hadoop/config usr/hadoop/results
結果:
…
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています Try_local2077883811_0001_m_000027_0 decomp: 41 len: 45 to MEMORY
19/06/16 21:15:08 情報reduce.InMemoryMapOutput: マップ出力からattempt_local2077883811_0001_m_000027_0の41バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 41、inMemoryMapOutputs.size() -> 11、commitMemory -> 25025、usedMemory -> 25066
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000003_0 decomp: 3942 len: 3946 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000003_0のマップ出力から3942バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 3942、inMemoryMapOutputs.size() -> 12、commitMemory -> 25066、usedMemory -> 29008
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000016_0 decomp: 1723 len: 1727 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000016_0のマップ出力から1723バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 1723、inMemoryMapOutputs.size() -> 13、commitMemory -> 29008、usedMemory -> 30731
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000002_0 decomp: 4795 len: 4799 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000002_0のマップ出力から4795バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 4795、inMemoryMapOutputs.size() -> 14、commitMemory -> 30731、usedMemory -> 35526
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000029_0 decomp: 15 len: 19 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000029_0のマップ出力から15バイトを読み取ります
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 15、inMemoryMapOutputs.size() -> 15、commitMemory -> 35526、usedMemory -> 35541
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000017_0 decomp: 1777 len: 1781 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000017_0のマップ出力から1777バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 1777、inMemoryMapOutputs.size() -> 16、commitMemory -> 35541、usedMemory -> 37318
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000011_0 decomp: 2140 len: 2144 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000011_0のマップ出力から2140バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 2140、inMemoryMapOutputs.size() -> 17、commitMemory -> 37318、usedMemory -> 39458
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000001_0 decomp: 4637 len: 4641 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput: マップ出力からattempt_local2077883811_0001_m_000001_0の4637バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 4637、inMemoryMapOutputs.size() -> 18、commitMemory -> 39458、usedMemory -> 44095
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000025_0 decomp: 938 len: 942 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000025_0のマップ出力から938バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 938、inMemoryMapOutputs.size() -> 19、commitMemory -> 44095、usedMemory -> 45033
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000024_0 decomp: 1019 len: 1023 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000024_0のマップ出力から1019バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 1019、inMemoryMapOutputs.size() -> 20、commitMemory -> 45033、usedMemory -> 46052
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000012_0 decomp: 2144 len: 2148 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000012_0のマップ出力から2144バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 2144、inMemoryMapOutputs.size() -> 21、commitMemory -> 46052、usedMemory -> 48196
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000000_0 decomp: 12150 len: 12154 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000000_0のマップ出力から12150バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 12150、inMemoryMapOutputs.size() -> 22、commitMemory -> 48196、usedMemory -> 60346
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000026_0 decomp: 386 len: 390 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000026_0のマップ出力から386バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 386、inMemoryMapOutputs.size() -> 23、commitMemory -> 60346、usedMemory -> 60732
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000013_0 decomp: 2240 len: 2244 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000013_0のマップ出力から2240バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 2240、inMemoryMapOutputs.size() -> 24、commitMemory -> 60732、usedMemory -> 62972
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000008_0 decomp: 2387 len: 2391 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000008_0のマップ出力から2387バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 2387、inMemoryMapOutputs.size() -> 25、commitMemory -> 62972、usedMemory -> 65359
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000021_0 decomp: 1323 len: 1327 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000021_0のマップ出力から1323バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 1323、inMemoryMapOutputs.size() -> 26、commitMemory -> 65359、usedMemory -> 66682
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000009_0 decomp: 2992 len: 2996 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000009_0のマップ出力から2992バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 2992、inMemoryMapOutputs.size() -> 27、commitMemory -> 66682、usedMemory -> 69674
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000023_0 decomp: 1212 len: 1216 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000023_0のマップ出力から1212バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 1212、inMemoryMapOutputs.size() -> 28、commitMemory -> 69674、usedMemory -> 70886
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000022_0 decomp: 1202 len: 1206 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000022_0のマップ出力から1202バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 1202、inMemoryMapOutputs.size() -> 29、commitMemory -> 70886、usedMemory -> 72088
19/06/16 21:15:08 INFO Reduce.LocalFetcher: localfetcher#1 がマップの出力をシャッフルしようとしています try_local2077883811_0001_m_000010_0 decomp: 2111 len: 2115 を MEMORY に送信します
19/06/16 21:15:08 情報reduce.InMemoryMapOutput:attempt_local2077883811_0001_m_000010_0のマップ出力から2111バイトを読み取りました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: closeInMemoryFile -> サイズのマップ出力: 2111、inMemoryMapOutputs.size() -> 30、commitMemory -> 72088、usedMemory -> 74199
19/06/16 21:15:08 情報reduce.EventFetcher: EventFetcher が中断されました。戻ります
19/06/16 21:15:08 情報mapred.LocalJobRunner: 30 / 30 がコピーされました。
19/06/16 21:15:08 情報reduce.MergeManagerImpl: 30 個のメモリ内マップ出力と 0 個のディスク上のマップ出力を使用して、finalMerge が呼び出されました。
19/06/16 21:15:08 情報mapred.Merger: ソートされた 30 個のセグメントをマージしています
19/06/16 21:15:08 情報mapred.Merger: 最後のマージパスまで、残り 30 セグメントの合計サイズ: 73995 バイト
19/06/16 21:15:08 情報reduce.MergeManagerImpl: メモリ制限の削減を満たすために、30 セグメント、74199 バイトをディスクにマージしました
19/06/16 21:15:08 情報reduce.MergeManagerImpl: ディスクから 74145 バイトの 1 ファイルをマージしています
19/06/16 21:15:08 INFO Reduce.MergeManagerImpl: 0 セグメント、0 バイトをメモリから Reduce にマージします
19/06/16 21:15:08 情報 mapred.Merger: 1 つのソートされたセグメントをマージしています
19/06/16 21:15:08 情報mapred.Merger: 最後のマージパスまで、合計サイズの残り 1 セグメント: 74136 バイト
19/06/16 21:15:08 情報mapred.LocalJobRunner: 30 / 30 がコピーされました。
19/06/16 21:15:08 情報 Configuration.deprecation:mapred.skip.on は非推奨になりました。代わりに、mapreduce.job.skiprecords を使用してください。
19/06/16 21:15:08 INFO mapred.Task: タスク:attempt_local2077883811_0001_r_000000_0 が完了しました。そしてコミット中です
19/06/16 21:15:08 情報mapred.LocalJobRunner: 30 / 30 がコピーされました。
19/06/16 21:15:08 情報mapred.Task: タスクattempt_local2077883811_0001_r_000000_0は現在コミットできます
19/06/16 21:15:08 情報出力.FileOutputCommitter: タスク 'attempt_local2077883811_0001_r_000000_0' の出力を hdfs://master:9000/user/hadoop/usr/hadoop/results/_temporary/0/task_local2077883811_0001_ に保存しましたr_000000
19/06/16 21:15:08 情報mapred.LocalJobRunner: 削減 > 削減
19/06/16 21:15:08 情報mapred.Task: タスク「attempt_local2077883811_0001_r_000000_0」が完了しました。
19/06/16 21:15:08 情報mapred.LocalJobRunner: タスクを終了しています:attempt_local2077883811_0001_r_000000_0
19/06/16 21:15:08 情報mapred.LocalJobRunner: タスク実行プログラムの削減が完了しました。
19/06/16 21:15:09 情報 mapreduce.Job: マップ 100% リデュース 100%
19/06/16 21:15:09 情報 mapreduce.Job: ジョブ job_local2077883811_0001 が正常に完了しました
19/06/16 21:15:09 情報mapreduce.ジョブ: カウンター: 38
ファイル システム カウンター
ファイル: 読み取られたバイト数=10542805
ファイル: 書き込まれたバイト数=19367044
ファイル: 読み取り操作の数 = 0
ファイル: 大規模な読み取り操作の数 = 0
ファイル: 書き込み操作の数 = 0
HDFS: 読み取られたバイト数=1847773
HDFS: 書き込まれたバイト数 = 36492
HDFS: 読み取り操作の数 = 1117
HDFS: 大規模な読み取り操作の数 = 0
HDFS: 書き込み操作の数 = 33
Map-Reduce フレームワーク
マップ入力レコード=2087
マップ出力レコード=7887
マップ出力バイト数=105178
マップ出力の実体化バイト数=74319
入力分割バイト数=3547
入力レコードを結合=7887
出力レコードを結合=3940
入力グループを減らす=1570
シャッフルバイトを減らす=74319
入力レコードの削減=3940
出力レコードを削減=1570
流出した記録=7880
シャッフルされたマップ = 30
失敗したシャッフル数=0
結合されたマップの出力 = 30
GC 経過時間 (ミリ秒)=1088
CPU 消費時間 (ミリ秒)=0
物理メモリ (バイト) スナップショット = 0
仮想メモリ (バイト) スナップショット = 0
コミットされたヒープの合計使用量 (バイト)=4331405312
シャッフルエラー
BAD_ID=0
接続=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
ファイル入力フォーマットカウンター
読み取りバイト数=77522
ファイル出力フォーマットカウンター
書き込まれたバイト数=36492
part-r-00000 ファイルの内容をオンラインで表示する
hadoop fs -cat /user/hadoop/results/part-r-00000
結果は次のとおりです
…
ジャワ3
Javadoc 1
ジョブ6
ジョブ 10
仕事、1
仕事。2
jsvc2
jvm3
jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext 1
jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 1
jvm.period=10 1
jvm.servers=localhost:8649 1
キー10
鍵。1
key="容量" 1
key="ユーザー制限" 1
キー1
キーストア9
2を読む
1を殺す
キロ2
kms-監査1
言語 24
最後の1
法律24
葉2
レベル6
レベル2
図書館1
ライセンス12
ライセンス 12
3のような
制限1
制限 24
ライン1
リンク1
リスト44
場所2
ログ14
log4j.additivity.kms-audit=false 1
log4j.additivity.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=false 1
log4j.additivity.org.apache.hadoop.mapred.AuditLogger=false 1
log4j.additivity.org.apache.hadoop.mapred.JobInProgress$Jobsummary=false 1
log4j.additivity.org.apache.hadoop.yarn.server.resourcemanager.RMAppManager$Applicationsummary=false 1
log4j.appender.DRFA.DatePattern=.yyyy-MM-dd 1
log4j.appender.DRFA.File=${hadoop.log.dir}/${hadoop.log.file} 1
log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout 1
log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender 1
log4j.appender.DRFAS.DatePattern=.yyyy-MM-dd 1
log4j.appender.DRFAS.File=${hadoop.log.dir}/${hadoop.security.log.file} 1
log4j.appender.DRFAS.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.DRFAS.layout=org.apache.log4j.PatternLayout 1
log4j.appender.DRFAS=org.apache.log4j.DailyRollingFileAppender 1
log4j.appender.EventCounter=org.apache.hadoop.log.metrics.EventCounter 1
log4j.appender.JSA.File=${hadoop.log.dir}/${hadoop.mapreduce.jobsummary.log.file} 1
log4j.appender.JSA.MaxBackupIndex=${hadoop.mapreduce.jobsummary.log.maxbackupindex} 1
log4j.appender.JSA.MaxFileSize=${hadoop.mapreduce.jobsummary.log.maxfilesize} 1
log4j.appender.JSA.layout.ConversionPattern=%d{yy/MM/dd 1
log4j.appender.JSA.layout=org.apache.log4j.PatternLayout 1
log4j.appender.JSA=org.apache.log4j.RollingFileAppender 1
log4j.appender.MRAUDIT.File=${hadoop.log.dir}/mapred-audit.log 1
log4j.appender.MRAUDIT.MaxBackupIndex=${mapred.audit.log.maxbackupindex} 1
log4j.appender.MRAUDIT.MaxFileSize=${mapred.audit.log.maxfilesize} 1
log4j.appender.MRAUDIT.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.MRAUDIT.layout=org.apache.log4j.PatternLayout 1
log4j.appender.MRAUDIT=org.apache.log4j.RollingFileAppender 1
log4j.appender.NullAppender=org.apache.log4j.varia.NullAppender 1
log4j.appender.RFA.File=${hadoop.log.dir}/${hadoop.log.file} 1
log4j.appender.RFA.MaxBackupIndex=${hadoop.log.maxbackupindex} 1
log4j.appender.RFA.MaxFileSize=${hadoop.log.maxfilesize} 1
log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.RFA.layout=org.apache.log4j.PatternLayout 1
log4j.appender.RFA=org.apache.log4j.RollingFileAppender 1
log4j.appender.RFAAUDIT.File=${hadoop.log.dir}/hdfs-audit.log 1
log4j.appender.RFAAUDIT.MaxBackupIndex=${hdfs.audit.log.maxbackupindex} 1
log4j.appender.RFAAUDIT.MaxFileSize=${hdfs.audit.log.maxfilesize} 1
log4j.appender.RFAAUDIT.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.RFAAUDIT.layout=org.apache.log4j.PatternLayout 1
log4j.appender.RFAAUDIT=org.apache.log4j.RollingFileAppender 1
log4j.appender.RFAS.File=${hadoop.log.dir}/${hadoop.security.log.file} 1
log4j.appender.RFAS.MaxBackupIndex=${hadoop.security.log.maxbackupindex} 1
log4j.appender.RFAS.MaxFileSize=${hadoop.security.log.maxfilesize} 1
log4j.appender.RFAS.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.RFAS.layout=org.apache.log4j.PatternLayout 1
log4j.appender.RFAS=org.apache.log4j.RollingFileAppender 1
log4j.appender.RMSUMMARY.File=${hadoop.log.dir}/${yarn.server.resourcemanager.appsummary.log.file} 1
log4j.appender.RMSUMMARY.MaxBackupIndex=20 1
log4j.appender.RMSUMMARY.MaxFileSize=256MB 1
log4j.appender.RMSUMMARY.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.RMSUMMARY.layout=org.apache.log4j.PatternLayout 1
log4j.appender.RMSUMMARY=org.apache.log4j.RollingFileAppender 1
log4j.appender.TLA.isCleanup=${hadoop.tasklog.iscleanup} 1
log4j.appender.TLA.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.TLA.layout=org.apache.log4j.PatternLayout 1
log4j.appender.TLA.taskId=${hadoop.tasklog.taskid} 1
log4j.appender.TLA.totalLogFileSize=${hadoop.tasklog.totalLogFileSize} 1
log4j.appender.TLA=org.apache.hadoop.mapred.TaskLogAppender 1
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd 1
log4j.appender.console.layout=org.apache.log4j.PatternLayout 1
log4j.appender.console.target=System.err 1
log4j.appender.console=org.apache.log4j.ConsoleAppender 1
log4j.appender.httpfs.Append=true 1
log4j.appender.httpfs.DatePattern='.'yyyy-MM-dd 1
log4j.appender.httpfs.File=${httpfs.log.dir}/httpfs.log 1
log4j.appender.httpfs.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.httpfs.layout=org.apache.log4j.PatternLayout 1
log4j.appender.httpfs=org.apache.log4j.DailyRollingFileAppender 1
log4j.appender.httpfsaudit.Append=true 1
log4j.appender.httpfsaudit.DatePattern='.'yyyy-MM-dd 1
log4j.appender.httpfsaudit.File=${httpfs.log.dir}/httpfs-audit.log 1
log4j.appender.httpfsaudit.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.httpfsaudit.layout=org.apache.log4j.PatternLayout 1
log4j.appender.httpfsaudit=org.apache.log4j.DailyRollingFileAppender 1
log4j.appender.kms-audit.Append=true 1
log4j.appender.kms-audit.DatePattern='.'yyyy-MM-dd 1
log4j.appender.kms-audit.File=${kms.log.dir}/kms-audit.log 1
log4j.appender.kms-audit.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.kms-audit.layout=org.apache.log4j.PatternLayout 1
log4j.appender.kms-audit=org.apache.log4j.DailyRollingFileAppender 1
log4j.appender.kms.Append=true 1
log4j.appender.kms.DatePattern='.'yyyy-MM-dd 1
log4j.appender.kms.File=${kms.log.dir}/kms.log 1
log4j.appender.kms.layout.ConversionPattern=%d{ISO8601} 1
log4j.appender.kms.layout=org.apache.log4j.PatternLayout 1
log4j.appender.kms=org.apache.log4j.DailyRollingFileAppender 1
log4j.category.SecurityLogger=${hadoop.security.logger} 1
log4j.logger.com.amazonaws.http.AmazonHttpClient=エラー1
log4j.logger.com.amazonaws=エラー1
log4j.logger.com.sun.jersey.server.wadl.generators.WadlGeneratorJAXBGrammarGenerator=OFF 1
log4j.logger.httpfsaudit=情報、1
log4j.logger.kms-audit=情報、1
log4j.logger.org.apache.hadoop.conf.Configuration.deprecation=警告 1
log4j.logger.org.apache.hadoop.conf=エラー1
log4j.logger.org.apache.hadoop.fs.http.server=情報、1
log4j.logger.org.apache.hadoop.fs.s3a.S3AFileSystem=警告 1
log4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=${hdfs.audit.logger} 1
log4j.logger.org.apache.hadoop.lib=情報、1
log4j.logger.org.apache.hadoop.mapred.AuditLogger=${mapred.audit.logger} 1
log4j.logger.org.apache.hadoop.mapred.JobInProgress$Jobsummary=${hadoop.mapreduce.jobsummary.logger} 1
log4j.logger.org.apache.hadoop.yarn.server.resourcemanager.RMAppManager$Applicationsummary=${yarn.server.resourcemanager.appsummary.logger} 1
log4j.logger.org.apache.hadoop=情報 1
log4j.logger.org.jets3t.service.impl.rest.httpclient.RestS3Service=エラー 1
log4j.rootLogger=${hadoop.root.logger}, 1
log4j.rootLogger=ALL、1
log4j.threshold=ALL 1
ロガー2
ロガー。1
ロギング 4
ログ2
ログ。</description> 1
ループ1
管理1
マネージャー3
マップ2
マッピング1
マッピング]※1
マッピング1
マッピング。1
マップレッド1
Mapred.audit.log.maxbackupindex=20 1
mapred.audit.log.maxfilesize=256MB 1
mapred.audit.logger=情報,NullAppender 1
mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext 1
mapred.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 1
mapred.class=org.apache.hadoop.metrics.spi.NullContext 1
マップレッド.期間=10 1
Mapred.servers=localhost:8649 1
マップリデュース.cluster.acls.enabled 3
マップリデュース.クラスター.管理者 2
マップ1
マスター1
マスター1
match="構成"> 1
資料3
最大3
最大4
5月52日
18を意味します
メッセージ1
メッセージ2
metadata 1
メソッド="html" /> 1
メトリクス 3
深夜1時
かもしれない1
ミリ秒。4
min.user.id=1000#防止 1
逃した 1
変更されました。1
1を変更する
1を修正中
もっと見る 12
@mradmin1
ミリ秒)1
多次元1
倍数4
必須 1
名前3
名前。1
name="{name}"><xsl:value-of 1
名前ノード 1
namenode-metrics.out 1
ネームノード。2
名前ノード。</description> 1
ネームノード: 1
名前。19
ネスト 1
新しい2
いいえ4
ノード2
ノード。2
非特権2
通常1
51ではない
ヌル5
6番
数字の3
24を取得
138件中
オフ4
30日に
1 15
1:2
9だけ
手術。3
オペレーション8
オペレーション。9
機会1
オプション 6
オプション。2
オプション 11
オプション。2
または71
普通の1
org.apache.hadoop.metrics2 1
その他1
他の。6
その他2
オーバーライドされた 4
オーバーライド5
4をオーバーライドします
所有者1
所有。12
パッケージ情報.java 1
パラメータ4
親1
パート2
パスワード3
パス2
保留中 1
1あたり
パーセント1
パーセンテージ 1
期間1
期間、1
権限 24
3を選んだ
ピッド3
1位
1をください
ポリシー3
ポート5
ポート2
ポート。2
可能性2
優先 3
接頭語。1
現在、1
プリンシパル4
主要。1
印刷済み 1
優先順位。1
優先度 1
特権2
特典1
特権。1
プロパティ 7
物件11
プロトコル6
プロトコル、2
プロトコル。2
3を提供します
q1. 1
q2 2
q2. 1
押しつぶされた 1
クエリ1
キュー12
列)。1
キュー、1
列。10
尾9
尾1
尾。3
ラック1
ラックローカル 1
回復。1
2を減らす
リフレッシュ2
12について
リロード2
リモート2
3を表す
必須 29
解決2
リソース2
応答。2
復元1
1を取得します
1を返す
2を返しました
ローリング 1
ロールオーバーキー1
ルート2
ルートロガー 1
rpc.class=org.apache.hadoop.metrics.ganglia.GangliaContext 1
rpc.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 1
rpc.class=org.apache.hadoop.metrics.spi.NullContext 1
rpc.period=10 1
rpc.servers=ローカルホスト:8649 1
10を実行します
ランニング3
ランニング、1
ランニング。1
3を実行します
ランタイム2
同じ1
サンプル1
サンプリング2
スケール3
スケジュール1
スケジューラー。1
スケジューラ、1
スケジュール2
二次1
秒1
秒)。2
秘密3
安全な7
セキュリティ1
セグメント1
select="説明"/></td> 1
select="名前"/></a></td> 1
選択="プロパティ"> 1
select="値"/></td> 1
1を送信します
送信1
別冊2
別れた20
別れた。1
サーバー3
サービス2
サービスレベル2
セット60
設定してください。」1
セット2
設定7
セットアップ1
重大度1
6 すべきです
サイン1
署名2
似たような3
シングル1
シンク1
サイト固有 4
サイズ1
スレーブ1 1
スレーブ2 1
スレーブ3 1
それで3
ソフトリンク 1
ソフトウェア 24
いくつか2
時々1
ソース2
スペース1
スペース)、2
スペース1
スペシャル19
特定の 33
仕様。1
指定13
指定、3
指定。6
1を指定する
3を指定してください
2を指定
分割1
スタンバイ1
スタート3
始めました2
開始3
状態4
状態1
ステータス2
止まった、1
ストア1
保存2
保管されています。7
文字列3
文字列、1
提出物1
提出2
提出中 1
そんな1
概要 5
スーパーユーザー 1
サポート2
サポート1
サポート1
サポートパース1
抑制1
シンボリックリンク 2
構文 1
構文: 1
システム3
タグ1
タグ3
ターゲット1
タスク2
タスクトラッカー。1
テンプレート 1
一時的2
1よりも
その19
370
彼ら1
それから8
そこ2
したがって3
これ 78
スレッド1
時間4
タイムライン 2
タイムスタンプ。1
163まで
トップ1
渋滞。1
転送4
真実。3
ターン1
二。3
タイプ1
タイプ、1
type="text/xsl" 6
通常は1
u:%user:%user 1
ug.class=org.apache.hadoop.metrics.ganglia.GangliaContext 1
ug.class=org.apache.hadoop.metrics.ganglia.GangliaContext31 1
ug.class=org.apache.hadoop.metrics.spi.NullContext 1
ウギ.ピリオド=10 1
ug.servers=localhost:8649 1
コメントなし1
84歳未満
設定を解除1
アップ2
更新1
使い方2
30を使用
使用、2
使用。4
中古 36
使用済み。3
ユーザー 48
ユーザー。2
ユーザー1、ユーザー2 2
ユーザー?1
ユーザー 27
ユーザー、ホイール」。18
2を使用します
14を使用して
値45
値 = "20" /> 1
値="30" /> 1
値4
変数4
変数4
バージョン1
バージョン = "1.0" 5
バージョン="1.0"> 1
バージョン="1.0"?> 7
3経由
ビュー、1
閲覧1
1個付き
1が欲しい
警告。1
9時
ここで4
どの7
一方1
誰6
23
窓1
窓、1
59と
4以内
1なし
仕事12
執筆、24
書かれた2
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 1
糸.nodemanager.linux-container-executor.group 1
yarn.nodemanager.linux-container-executor.group=#configured 1
糸.server.resourcemanager.appsummary.log.file 1
yarn.server.resourcemanager.appsummary.log.file=rm-appsummary.log 1
糸.server.resourcemanager.appsummary.logger 2
yarn.server.resourcemanager.appsummary.logger=${hadoop.root.logger} 1
あなた28
結果をローカルにダウンロードします。
hadoop fs -get /user/hadoop/usr/hadoop/results count-results
ls
ローカルにダウンロードした後に確認し、成功した場合は
さて、実験は終わりました。
2.MapReduceプログラミング実験
実験目標
MapReduce の仕組みを理解する
基本的な MapReduce プログラミング方法をマスターする
Eclipse で MapReduce プログラミングを学ぶ
MapReduce プログラムの設計、実装、実行方法を学びます
実験内容
備考: バージョンの理由により、教育実験ガイドの内容は比較的古いです。現在、Hadoopコンテンツはバージョン2.xおよび3.xに達しています。実験ガイドのHadoop-0.20バージョンでは、多くのクラス、メソッド、およびAPIが実験は教育実験指導書を参考にしながら以下の手順で行います。
サンプル プログラム WordCount は、テキスト ファイルのバッチ内の単語の頻度をカウントするために使用されます。完全なコードは、Hadoop インストール パッケージ (src/examples ディレクトリ内) で入手できます。(Hadoop2.xのバージョンが変わったので見つかりません)
WordCount コード:
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class WordCount {
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer
extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length < 2) {
System.err.println("Usage: wordcount <in> [<in>...] <out>");
System.exit(2);
}
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
for (int i = 0; i < otherArgs.length - 1; ++i) {
FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
}
FileOutputFormat.setOutputPath(job,
new Path(otherArgs[otherArgs.length - 1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
-
- Eclipse のインストールと構成
- Hadoop Eclipse プラグインをインストールする
ここでは hadoop-eclipse-plugin-2.7.3.jar パッケージを使用し、コンパイルされた hadoop-eclipse-plugin 関連の jar パッケージを Eclipse インストール ディレクトリのプラグインにコピーします。エクリプスを再起動します。メニューバーの「Windows」→「環境設定」をクリックすると、プラグインが正常にインストールされると下図が表示されますので、赤丸内のhadoopインストールディレクトリを選択してください。
点击Windows –> ビューの表示 –> その他 –> 地図/場所の縮小。
下の [Map/Redure Locations] ウィンドウをクリックし、空白スペースで [New Hadoop location] を右クリックします。または、右側にあるプラス記号の付いた小さな青い象をクリックします。関連情報を入力します。
情報を設定する方法は、以下の図を参照してください。
-
- Eclipse環境での開発とデバッグ
Hadoop 並列プログラムの開発とデバッグは、Eclipse 環境で簡単に実行できます。IBM MapReduce Tools for Eclipse を使用することをお勧めします。この Eclipse プラグインを使用すると、Hadoop 並列プログラムの開発およびデプロイのプロセスを簡素化できます。このプラグインに基づいて、Eclipse で Hadoop MapReduce アプリケーションを作成し、JAR ファイルにパッケージ化できる MapReduce フレームワークに基づくクラス開発用のいくつかのウィザードを提供し、Hadoop MapReduce アプリケーションを Hadoop サーバー (両方ともローカル) にデプロイできます。およびリモート) )、特別なパースペクティブを通じて、Hadoop サーバー、Hadoop 分散ファイル システム (DFS)、および現在実行中のタスクのステータスを表示できます。
MapReduce ツールは、IBM alpha Works Web サイト、またはこの記事のダウンロード リストからダウンロードできます。ダウンロードした圧縮パッケージを Eclipse インストール ディレクトリに解凍し、Eclipse を再起動して使用します。Eclipse メイン メニューで [Windows]、[設定] の順にクリックし、左側の [Hadoop ホーム ディレクトリ] を選択して Hadoop ホーム ディレクトリを設定します。
構成が完了したので、Eclipse でサンプルを実行します。
ファイル—> プロジェクト、マップ/リデュース プロジェクトを選択し、プロジェクト名 WordCount などを入力します。
WordCount コードを記述します。
WordCount.java をクリックして右クリックし、「実行」->「実行構成」をクリックして、実行パラメーターを構成します。パラメーターは次のとおりです。 hdfs://localhost:9000/user/hadoop/input hdfs://localhost:9000/user/hadoop/出力は、それぞれ入力と出力に対応します。
実行後、結果を確認します。
方法 1: コマンドを使用してターミナルで表示する
方法 2: Eclipse で直接表示し、[DFS の場所] をダブルクリックしてpart-r00000 を開き、結果を表示します。
-
- WordCount プログラムの改善
WordCount プログラムにいくつかの改善を加えてみましょう。目標は次のとおりです。
- オリジナルの WordCount プログラムでは単語をスペースで区切るだけで、さまざまな句読点や単語が混在していましたが、改良されたプログラムでは単語を正しく切り出すことができ、単語の大文字と小文字は区別されません。
- 最終結果では、単語は頻度の降順に並べ替えられます。
WordCount の降順出力コード:
package desc;
/**
* WordCount
* 统计输入文件各个单词出现频率
* 统计的时候对于“停词”(从文本文件读入)将不参与统计
* 最后按统计的词频从高到底输出
*
* 特别主import某个类的时候,确定你是要用哪个包所属的该类
*
* */
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.map.InverseMapper;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
public class WordCount {
/**
* Map: 将输入的文本数据转换为<word-1>的键值对
* */
public static class WordCountMap extends Mapper<LongWritable, Text, Text, IntWritable> {
String regex = "[.,\"!--;:?'\\]]"; //remove all punctuation
Text word = new Text();
final static IntWritable one = new IntWritable(1);
HashSet<String> stopWordSet = new HashSet<String>();
/**
* 将停词从文件读到hashSet中
* */
private void parseStopWordFile(String path){
try {
String word = null;
BufferedReader reader = new BufferedReader(new FileReader(path));
while((word = reader.readLine()) != null){
stopWordSet.add(word);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 完成map初始化工作
* 主要是读取停词文件
* */
public void setup(Context context) {
Configuration patternsFiles = null;
{
patternsFiles = context.getConfiguration();
}
if(patternsFiles == null){
System.out.println("have no stopfile\n");
return;
}
//read stop-words into HashSet
for (Entry<String, String> patternsFile : patternsFiles) {
parseStopWordFile(patternsFile.toString());
}
}
/**
* map
* */
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String s = null;
String line = value.toString().toLowerCase();
line = line.replaceAll(regex, " "); //remove all punctuation
//split all words of line
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
s = tokenizer.nextToken();
if(!stopWordSet.contains(s)){
word.set(s);
context.write(word, one);
}
}
}
}
/**
* Reduce: add all word-counts for a key
* */
public static class WordCountReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
int min_num = 0;
/**
* minimum showing words
* */
public void setup(Context context) {
min_num = Integer.parseInt(context.getConfiguration().get("min_num"));
System.out.println(min_num);
}
/**
* reduce
* */
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
if(sum < min_num) return;
context.write(key, new IntWritable(sum));
}
}
/**
* IntWritable comparator
* */
private static class IntWritableDecreasingComparator extends IntWritable.Comparator {
public int compare(WritableComparable a, WritableComparable b) {
return -super.compare(a, b);
}
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return -super.compare(b1, s1, l1, b2, s2, l2);
}
}
/**
* main: run two job
* */
public static void main(String[] args){
boolean exit = false;
String skipfile = null; //stop-file path
int min_num = 0;
String tempDir = "wordcount-temp-" + Integer.toString(new Random().nextInt(Integer.MAX_VALUE));
Configuration conf = new Configuration();
//获取停词文件的路径,并放到DistributedCache中
for(int i=0;i<args.length;i++)
{
if("-skip".equals(args[i]))
{
DistributedCache.addCacheFile(new Path(args[++i]).toUri(), conf);
System.out.println(args[i]);
}
}
//获取要展示的最小词频
for(int i=0;i<args.length;i++)
{
if("-greater".equals(args[i])){
min_num = Integer.parseInt(args[++i]);
System.out.println(args[i]);
}
}
//将最小词频值放到Configuration中共享
conf.set("min_num", String.valueOf(min_num)); //set global parameter
try{
/**
* run first-round to count
* */
Job job = new Job(conf, "jiq-wordcountjob-1");
job.setJarByClass(WordCount.class);
//set format of input-output
job.setInputFormatClass(TextInputFormat.class);
job.setOutputFormatClass(SequenceFileOutputFormat.class);
//set class of output's key-value of MAP
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//set mapper and reducer
job.setMapperClass(WordCountMap.class);
job.setReducerClass(WordCountReduce.class);
//set path of input-output
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(tempDir));
if(job.waitForCompletion(true)){
/**
* run two-round to sort
* */
//Configuration conf2 = new Configuration();
Job job2 = new Job(conf, "jiq-wordcountjob-2");
job2.setJarByClass(WordCount.class);
//set format of input-output
job2.setInputFormatClass(SequenceFileInputFormat.class);
job2.setOutputFormatClass(TextOutputFormat.class);
//set class of output's key-value
job2.setOutputKeyClass(IntWritable.class);
job2.setOutputValueClass(Text.class);
//set mapper and reducer
//InverseMapper作用是实现map()之后的数据对的key和value交换
//将Reducer的个数限定为1, 最终输出的结果文件就是一个
/**
* 注意,这里将reduce的数目设置为1个,有很大的文章。
* 因为hadoop无法进行键的全局排序,只能做一个reduce内部
* 的本地排序。 所以我们要想有一个按照键的全局的排序。
* 最直接的方法就是设置reduce只有一个。
*/
job2.setMapperClass(InverseMapper.class);
job2.setNumReduceTasks(1); //only one reducer
//set path of input-output
FileInputFormat.addInputPath(job2, new Path(tempDir));
FileOutputFormat.setOutputPath(job2, new Path(args[1]));
/**
* Hadoop 默认对 IntWritable 按升序排序,而我们需要的是按降序排列。
* 因此我们实现了一个 IntWritableDecreasingComparator 类,
* 并指定使用这个自定义的 Comparator 类对输出结果中的 key (词频)进行排序
* */
job2.setSortComparatorClass(IntWritableDecreasingComparator.class);
exit = job2.waitForCompletion(true);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
//delete tempt dir
FileSystem.get(conf).deleteOnExit(new Path(tempDir));
if(exit) System.exit(1);
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
操作結果:
これまでに、実験 1 と実験 2 が完了しました。
ありがとう:
[1] https://blog.csdn.net/u010223431/article/details/51191978
[2] https://blog.csdn.net/xingyyn78/article/details/81085100
[3] https://blog.csdn.net/abcjennifer/article/details/22393197
[4] https://www.cnblogs.com/StevenSun1991/p/6931500.html
[5] https://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop2/index.html