MapReduce運転問題記録


構成の問題


1.ローカルでのみ実行可能


具体的な問題


hadoop jarでjarパッケージをコミットしますが、ローカルでLocal_を実行するしかありません.job.

解決策


hadoop配備パッケージ下/etc/hadoop/yarn.xml構成エラー.次の構成が欠けています.追加すればいいです.

       mapreduce.framework.name
       yarn
    

2.メモリオーバーフロー


具体的な問題


メモリが制限を超え、containerがkillされ、タスクが失敗しました.異常は以下の通りで、ブログ『Container is running beyond virtual memory limits...』でこの問題について明確に説明しています.
Container [pid=100156,containerID=container_1513249052998_0001_02_000001] is running beyond virtual memory limits. 
Current usage: 114.4 MB of 1 GB physical memory used;
 2.2 GB of 2.1 GB virtual memory used. Killing container.

上記の情報では,1 GBの物理メモリが割り当てられ,114.4 MBを占有し,制限を超えていない.1 GBは、デフォルトで割り当てられている物理メモリサイズです.この値はmapreduceによるはずです.map.memory.mbとmapreduce.reduce.memory.mb決定.この値はContainerのメモリ上限を設定します.このパラメータはNodeManagerによって読み込まれ、制御されます.Containerのメモリサイズがこのパラメータ値を超えると、NodeManagerはkillを担当してContainerを削除します.
2.1 GBの仮想メモリが割り当てられており、2.2 GBの占有量が制限を超えています.2.1 GBはデフォルトで割り当てられた仮想メモリサイズです.この値は実際にはデフォルトの物理メモリサイズとyarnによって設定.nodemanager.vmem-pmem-ratio決定.yarn.nodemanager.vmem-pmem-ratioは、仮想メモリと物理メモリの割合を表し、デフォルトは2.1です.

解決策


方法1:仮想メモリのチェックを解除します.yarn-site.xmlファイルに以下の設定を追加しますが、この方法は危険で、クラスタが崩壊する可能性があります.

  yarn.nodemanager.vmem-check-enabled
  false
  Whether virtual memory limits will be enforced for containers.


方法2:mapred-site.xmlファイルに設定を追加し、デフォルトの物理メモリサイズ(mapreduce.map.memory.mbとmapreduce.reduce.memory.mb)を大きくします.この値はyarnを超えることはできません.scheduler.maximum-allocation-mb(yarn-site.xmlで設定可能)のサイズ.yarn-site.xmlファイルに設定を追加し、仮想メモリ/物理メモリの割合(yarn.nodemanager.vmem-pmem-ratio)を大きくします.
結局、私はmapred-siteにいます.xmlファイルには物理メモリが増大する、mapreduceも増加する.map.java.optsとmapreduce.reduce.java.optsの設定.「mapreduce on yarn単純メモリ割り当て解釈」には、以下のようにクリアされた解釈があります.
mapタスクを例にとると、Containerはスクリプトファイルを実行していますが、スクリプトファイルではJavaのサブプロセスが実行されます.このサブプロセスは本当のMapTask、mapreduceです.map.java.optsとは、実はJVM仮想マシンを起動する際に、仮想マシンの起動パラメータに渡されるもので、デフォルト値-Xmx 200 mは、このJavaプログラムで使用できる最大スタックメモリ数を表し、このサイズを超えると、JVMはOut of Memory異常を投げ出し、プロセスを終了します.

  mapreduce.map.memory.mb
  2048


  mapreduce.map.java.opts
  -Xmx1024M


  mapreduce.reduce.memory.mb
  3072


  mapreduce.reduce.java.opts
  -Xmx2560M


3.JobHistory設定異常によるException from container-launch


###具体的な問題この問題は『hadoopエラープロンプトexitCode:1 due to:Exception from container-launch』に詳細な記録があります.
Exit code: 1  
Stack trace: ExitCodeException exitCode=1:   
        at org.apache.hadoop.util.Shell.runCommand(Shell.java:538)  
        at org.apache.hadoop.util.Shell.run(Shell.java:455)  
        at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:702)  
        at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:196)  
        at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:299)  
        at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:81)  
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)  
        at java.util.concurrent.FutureTask.run(FutureTask.java:166)  
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)  
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)  
        at java.lang.Thread.run(Thread.java:722)  
Container exited with a non-zero exit code 1  

解決策


この問題はjobhistory設定異常によるものです.$HADOOP_でHOME/etc/hadoop/mapred-site.xmlファイルで次のパラメータ設定エラーが見つかりました.エラーの原因はhostnameがプライマリノードのアドレスに変更されていないことであり,構成内容が直接コピーされているため,現在のクラスタの状況に従って変更されていない.

        mapreduce.jobhistory.address
        hostname:10020
    
    
        mapreduce.jobhistory.webapp.address
        hostname:19888
    

コード問題


1.シーケンス化と逆シーケンス化の問題


MR二次ソートアルゴリズムを作成し、実行後にエラーを報告し、以下に示す.問題はソートに使用されるクラスInPairです.
2018-06-09 10:14:04,168 INFO [org.apache.hadoop.mapred.MapTask] - Ignoring exception during close for org.apache.hadoop.mapred.MapTask$NewOutputCollector@1c994c51
java.lang.RuntimeException: java.io.EOFException
	at org.apache.hadoop.io.WritableComparator.compare(WritableComparator.java:165)
	at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.compare(MapTask.java:1268)
	at org.apache.hadoop.util.QuickSort.sortInternal(QuickSort.java:74)
	at org.apache.hadoop.util.QuickSort.sort(QuickSort.java:63)
	at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1600)
	at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.flush(MapTask.java:1489)
	at org.apache.hadoop.mapred.MapTask$NewOutputCollector.close(MapTask.java:723)
	at org.apache.hadoop.mapred.MapTask.closeQuietly(MapTask.java:2019)
	at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:797)
	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
	at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException
	at java.io.DataInputStream.readInt(DataInputStream.java:392)
	at hadoop.mapred.basic.IntPair.readFields(IntPair.java:39)
	at org.apache.hadoop.io.WritableComparator.compare(WritableComparator.java:158)
	... 15 more

InPairクラスはWritableComparableを継承している.その重荷重のreadFields方法とwrite方法は対応しなければならない.コードを見ると、writeメソッド内でout.write(second)と誤記されていることがわかります.これをout.writeInt(second)に変更すればよい.
 @Override
    public void readFields(DataInput in) throws IOException {
        first = in.readInt();
        second = in.readInt();
    }

    @Override
    public void write(DataOutput out) throws IOException {
        out.writeInt(first);
        out.write(second);  // out.writeInt(second);
    }

2.Keyクラス未定義compareToメソッド


mysqlにデータをインポートするコードを作成し、タイムズエラーを実行します.次のようになります.
2018-06-09 10:24:36,600 WARN [org.apache.hadoop.mapred.MapTask] - Unable to initialize MapOutputCollector org.apache.hadoop.mapred.MapTask$MapOutputBuffer
java.lang.ClassCastException: class hadoop.mapred.mysql.tbl.StudentinfoRecord
	at java.lang.Class.asSubclass(Class.java:3404)
	at org.apache.hadoop.mapred.JobConf.getOutputKeyComparator(JobConf.java:887)
	at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.init(MapTask.java:1004)
	at org.apache.hadoop.mapred.MapTask.createSortingCollector(MapTask.java:402)
	at org.apache.hadoop.mapred.MapTask.access$100(MapTask.java:81)
	at org.apache.hadoop.mapred.MapTask$NewOutputCollector.(MapTask.java:698)
	at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:770)
	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
	at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

異常表示StudentinfoRecordはClassCastException、つまりクラス変換異常を出しています.StudentinfoRecordはmysqlテーブルを記述するクラスです.私のmapメソッドではcontext.write(stuRecord,NullWritable.get()は、keyとして出力します.MRはkeyのデータのみmysqlテーブルにインポートするためです.MRはMap出力データをkeyでソートするので、Mapのkeyクラスはソート可能である必要があります.ソート可能にするには、次の2つの方法があります.
  • WritableComparatorクラスを継承し、keyのソートクラスKeyComparatorを定義し、次の方法でMR jobに構成します.
  • job.setSortComparatorClass(KeyComparator.Class)
    

    2.ソート・クラスが定義されていない場合、KeyクラスはWritable Comparableインタフェースを実装し、comparareToメソッドを実装する必要があります.MapTask$MapOutputBufferが初期化されると、getOutputKeyComparatorによってソートクラスオブジェクトが取得され、先にgetソートクラスが存在せず、ソートクラスが存在しない場合は、KeyクラスをWritableComparableサブクラスに変換してソートクラスが取得されます.
    public RawComparator getOutputKeyComparator() {
            Class theClass = this.getClass("mapreduce.job.output.key.comparator.class", (Class)null, RawComparator.class);
            return (RawComparator)(theClass != null?(RawComparator)ReflectionUtils.newInstance(theClass, this):WritableComparator.get(this.getMapOutputKeyClass().asSubclass(WritableComparable.class), this));
        }
    

    キークラスがWritableComparableインタフェースを実装していないため、上記の2点が満たされない場合、asSubClassはクラス変換異常を発生します.comparetoメソッドがないため、次のような異常が相次いで発生します.解決策は:1)KeyクラスがWritableComparableインタフェースを実現し、CompareToメソッドを再ロードすることである.2)ソートクラスを定義します.
    java.lang.Exception: java.io.IOException: Initialization of all the collectors failed. Error in last collector was :class hadoop.mapred.mysql.tbl.StudentinfoRecord
    	at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462)
    	at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:522)
    Caused by: java.io.IOException: Initialization of all the collectors failed. Error in last collector was :class hadoop.mapred.mysql.tbl.StudentinfoRecord
    	at org.apache.hadoop.mapred.MapTask.createSortingCollector(MapTask.java:415)
    	at org.apache.hadoop.mapred.MapTask.access$100(MapTask.java:81)
    	at org.apache.hadoop.mapred.MapTask$NewOutputCollector.(MapTask.java:698)
    	at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:770)
    	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
    	at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243)
    	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    	at java.lang.Thread.run(Thread.java:745)
    Caused by: java.lang.ClassCastException: class hadoop.mapred.mysql.tbl.StudentinfoRecord
    	at java.lang.Class.asSubclass(Class.java:3404)
    	at org.apache.hadoop.mapred.JobConf.getOutputKeyComparator(JobConf.java:887)
    	at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.init(MapTask.java:1004)
    	at org.apache.hadoop.mapred.MapTask.createSortingCollector(MapTask.java:402)
    	... 10 more