2012-07-22 10 views
8

Tengo la siguiente situaciónHadoop: trabajo se ejecuta bien en conjunto más pequeño de datos, pero falla con gran conjunto de datos

tengo 3 máquinas se agrupan con los siguientes confirguration.

Master

Usage of /: 91.4% of 74.41GB 
MemTotal:  16557308 kB 
MemFree:   723736 kB 

Slave 01

Usage of /: 52.9% of 29.76GB 
MemTotal:  16466220 kB 
MemFree:   5320860 kB 

Slave 02

Usage of /: 19.0% of 19.84GB 
MemTotal:  16466220 kB 
MemFree:   6173564 kB 

hadoop/conf/núcleo-site.xml

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> 

<!-- Put site-specific property overrides in this file. --> 

<configuration> 
<property> 
    <name>hadoop.tmp.dir</name> 
    <value>/work/app/hadoop/tmp</value> 
    <description>A base for other temporary directories.</description> 
</property> 

<property> 
    <name>fs.default.name</name> 
    <value>hdfs://master:54310</value> 
    <description>The name of the default file system. A URI whose 
    scheme and authority determine the FileSystem implementation. The 
    uri's scheme determines the config property (fs.SCHEME.impl) naming 
    the FileSystem implementation class. The uri's authority is used to 
    determine the host, port, etc. for a filesystem.</description> 
</property> 
<property> 
    <name>dfs.datanode.max.xcievers</name> 
    <value>4096</value> 
</property> 
</configuration> 

hadoop/conf/mapred-site.xml

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> 

<!-- Put site-specific property overrides in this file. --> 

<configuration> 
<property> 
    <name>mapred.job.tracker</name> 
    <value>master:54311</value> 
    <description>The host and port that the MapReduce job tracker runs 
    at. If "local", then jobs are run in-process as a single map 
    and reduce task. 
    </description> 
</property> 

<property> 
    <name>mapred.reduce.tasks</name> 
    <value>1</value> 
</property> 

<property> 
    <name>mapred.map.tasks</name> 
    <value>100</value> 
</property> 

<property> 
    <name>mapred.task.timeout</name> 
    <value>0</value> 
</property> 

<property> 
    <name>mapred.child.java.opts</name> 
    <value>-Xmx512m</value> 
</property> 
</configuration> 

hadoop/conf/hdfs-site.xml

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> 

<!-- Put site-specific property overrides in this file. --> 

<configuration> 
<property> 
    <name>dfs.replication</name> 
    <value>3</value> 
    <description>Default block replication. 
    The actual number of replications can be specified when the file is created. 
    The default is used if replication is not specified in create time. 
    </description> 
</property> 
<property> 
    <name>dfs.datanode.socket.write.timeout</name> 
    <value>0</value> 
</property> 
</configuration> 
  • tengo más de 2 millones de documentos XML (cada tamaño del documento ~ 400 KB)
  • map tareas abre cada uno de estos XMLs y emiten como JSON
  • reduce tarea se hace cada uno de estos JSON como cadena, se aplica la transformación y la emite
  • no. de map tareas - 100
  • no. de reduce tareas - 01
  • Todo el trabajo se ejecuta bien cuando number of documents = 10,000
  • cuando number of documents = 278262, el trabajo falla y veo varios problemas de la siguiente manera

En WebUI

en el esclavo-01 , slave-02

java.lang.Throwable: Child Error 
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271) 
Caused by: java.io.IOException: Task process exit with nonzero status of 255. 
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:258) 

El maestro

java.lang.RuntimeException: java.io.IOException: Spill failed 
    at org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:325) 
    at org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:545) 
    at org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:132) 
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:57) 
    at org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:36) 
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:436) 
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:372) 
    at org.apache.hadoop.mapred.Child$4.run(Child.java:261) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at javax.security.auth.Subject.doAs(Subject.java:396) 
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1059) 
    at org.apache.hadoop.mapred.Child.main(Child.java:255) 
Caused by: java.io.IOException: Spill failed 
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1029) 
    at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:592) 
    at org.apache.hadoop.streaming.PipeMapRed$MROutputThread.run(PipeMapRed.java:381) 
Caused by: org.apache.hadoop.util.DiskChecker$DiskErrorException: Could not find any valid local directory for output/spill1.out 
    at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:381) 
    at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:146) 
    at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:127) 
    at org.apache.hadoop.mapred.MapOutputFile.getSpillFileForWrite(MapOutputFile.java:121) 
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.sortAndSpill(MapTask.java:1392) 
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.access$1800(MapTask.java:853) 
    at org.apache.hadoop.mapred.MapTask$MapOutputBuffer$SpillThread.run(MapTask.java:1344) 

java.lang.Throwable: Child Error 
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271) 
Caused by: java.io.IOException: Creation of /work/app/hadoop/tmp/mapred/local/userlogs/job_201207220051_0001/attempt_201207220051_0001_m_000004_2 failed. 
    at org.apache.hadoop.mapred.TaskLog.createTaskAttemptLogDir(TaskLog.java:102) 
    at org.apache.hadoop.mapred.DefaultTaskController.createLogDir(DefaultTaskController.java:71) 
    at org.apache.hadoop.mapred.TaskRunner.prepareLogFiles(TaskRunner.java:316) 
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:228) 

------- 
java.lang.Throwable: Child Error 
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271) 
Caused by: java.io.IOException: Creation of /work/app/hadoop/tmp/mapred/local/userlogs/job_201207220051_0001/attempt_201207220051_0001_m_000004_2.cleanup failed. 
    at org.apache.hadoop.mapred.TaskLog.createTaskAttemptLogDir(TaskLog.java:102) 
    at org.apache.hadoop.mapred.DefaultTaskController.createLogDir(DefaultTaskController.java:71) 
    at org.apache.hadoop.mapred.TaskRunner.prepareLogFiles(TaskRunner.java:316) 
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:228) 

Cuando voy y comprobar los registros en slaves, esto es lo que encontré en hadoop-hduser-datanode-hadoop-01.log

2012-07-22 09:26:52,795 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Receiving block blk_-5384386931827098009_1010 src: /10.0.0.81:51402 dest: /10.0.0.82:50010 
2012-07-22 09:26:52,800 WARN org.apache.hadoop.hdfs.server.datanode.DataNode: IOException in BlockReceiver constructor. Cause is 
2012-07-22 09:26:52,800 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: writeBlock blk_-5384386931827098009_1010 received exception java.io.IOException: Unexpected problem in creating temporary file for blk_-5384386931827098009_1010. File /work/app/hadoop/tmp/dfs/data/tmp/blk_-5384386931827098009 should not be present, but is. 
2012-07-22 09:26:52,800 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: DatanodeRegistration(10.0.0.82:50010, storageID=DS-735951984-127.0.1.1-50010-1342943517618, infoPort=50075, ipcPort=50020):DataXceiver 
java.io.IOException: Unexpected problem in creating temporary file for blk_-5384386931827098009_1010. File /work/app/hadoop/tmp/dfs/data/tmp/blk_-5384386931827098009 should not be present, but is. 
     at org.apache.hadoop.hdfs.server.datanode.FSDataset$FSVolume.createTmpFile(FSDataset.java:426) 
     at org.apache.hadoop.hdfs.server.datanode.FSDataset$FSVolume.createTmpFile(FSDataset.java:404) 
     at org.apache.hadoop.hdfs.server.datanode.FSDataset.createTmpFile(FSDataset.java:1249) 
     at org.apache.hadoop.hdfs.server.datanode.FSDataset.writeToBlock(FSDataset.java:1138) 
     at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.<init>(BlockReceiver.java:99) 
     at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:299) 
     at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:107) 
     at java.lang.Thread.run(Thread.java:662) 

Por favor, me ayudan a entender lo que es que yo Qué hacer para resolver este problema?

+0

Veo que nunca encontró una respuesta. ¿Intentó combinar sus registros con menos archivos grandes? –

Respuesta

14

Como tiene más de un reductor, sus cartógrafos escribirán salidas en el disco local de sus esclavos (en lugar de en HDFS). Para ser más precisos, los mapeadores no escriben en el disco local de inmediato. En cambio, almacenan en búfer la salida en la memoria hasta que alcanza un umbral (consulte la configuración de configuración "io.sort.mb"). Este proceso se llama derrame. Creo que el problema es que cuando Hadoop intenta derramarse en el disco, tus esclavos no tienen suficiente espacio en disco para contener todos los datos generados por tus mapeadores.

Mencionó que cada asignador produce una cadena json. Asumiendo que es ~ 100KB por documento (quizás incluso más grande que esto), sería 278,262 x 100KB = ~ 28GB y sus dos esclavos tienen aproximadamente 15GB de espacio libre cada uno.

La forma más fácil, creo, es comprimir la salida inmediata de creadores de mapas usando los siguientes dos ajustes de configuración:

<property> 
    <name> mapreduce.map.output.compress</name> 
    <value>true</value> 
</property> 
<property> 
    <name>mapreduce.map.output.compress.codec</name> 
    <value>org.apache.hadoop.io.compress.GzipCodec</value> 
</property> 

Dado que sus datos están todos los datos/texto JSON, creo que se beneficiarán de cualquier Algoritmo de compresión soportado por Hadoop.

Como un FYI, si el tamaño de su documento crece mucho más allá de 2 mil, debería considerar agregar más memoria a su maestro. Como regla general, cada archivo/directorio/bloque ocupa alrededor de 150 bytes (o 300 MB por 1 millón de archivos). En realidad, sin embargo, reservaría 1GB por 1 millón de archivos.

0

me encontré con el mismo problema (en Mac OS X) y se solucionaron mediante el establecimiento de los siguientes valores en site.xml mapred

<name>mapred.child.ulimit</name> 
<value>unlimited</value> 

entonces dejé de los servicios de Hadoop bin/stop-all.sh, eliminado el directorio/usr/local/tmp/carpeta, formateado el namenode bin/hadoop namenode -format e inició los servicios de hadoop bin/start-all.sh

Cuestiones relacionadas