tutorial - mapreduce java example
Especificar límites de memoria con hadoop (1)
Estoy tratando de ejecutar un trabajo de alta memoria en un clúster de Hadoop (0.20.203). Modifiqué mapred-site.xml para aplicar algunos límites de memoria.
<property>
<name>mapred.cluster.max.map.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapred.cluster.max.reduce.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapred.cluster.map.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>mapred.cluster.reduce.memory.mb</name>
<value>2048</value>
</property>
En mi trabajo, estoy especificando cuánta memoria necesitaré. Desafortunadamente, aunque estoy ejecutando mi proceso con -Xmx2g
(el trabajo funcionará bien con esta cantidad de memoria como una aplicación de consola) necesito solicitar mucha más memoria para mi mapeador (como una subversión, ¿por qué es esto?) O es asesinado.
val conf = new Configuration()
conf.set("mapred.child.java.opts", "-Xms256m -Xmx2g -XX:+UseSerialGC");
conf.set("mapred.job.map.memory.mb", "4096");
conf.set("mapred.job.reduce.memory.mb", "1024");
El reductor apenas necesita memoria ya que estoy realizando un reductor de identidad.
class IdentityReducer[K, V] extends Reducer[K, V, K, V] {
override def reduce(key: K,
values: java.lang.Iterable[V],
context:Reducer[K,V,K,V]#Context) {
for (v <- values) {
context write (key, v)
}
}
}
Sin embargo, el reductor sigue usando mucha memoria. ¿Es posible darle al reductor diferentes argumentos de JVM que el asignador? Hadoop mata el reductor y afirma que está utilizando 3960 MB de memoria. Y los reductores terminan fallando el trabajo. ¿Cómo es esto posible?
TaskTree [pid=10282,tipID=attempt_201111041418_0005_r_000000_0] is running beyond memory-limits.
Current usage : 4152717312bytes.
Limit : 1073741824bytes.
Killing task.
ACTUALIZACIÓN: incluso cuando especifico un trabajo de transmisión con cat
como mapeador y uniq
como reductor y -Xms512M -Xmx1g -XX:+UseSerialGC
mis tareas toman más de 2g de memoria virtual! Esto parece extravagante a 4 veces el tamaño máximo de almacenamiento dinámico.
TaskTree [pid=3101,tipID=attempt_201111041418_0112_m_000000_0] is running beyond memory-limits.
Current usage : 2186784768bytes.
Limit : 2147483648bytes.
Killing task.
Actualización: la versión original de JIRA para cambiar el formato de configuración para el uso de memoria menciona específicamente que los usuarios de Java están más interesados en la memoria física para evitar la manipulación excesiva. Creo que esto es exactamente lo que quiero: no quiero que un nodo haga girar un mapper si no hay memoria física disponible. Sin embargo, todas estas opciones parecen haberse implementado como restricciones de memoria virtual, que son difíciles de administrar.
Verifica tu ulimit. De Cloudera , en la versión 0.20.2, pero probablemente se aplique un problema similar para versiones posteriores:
... si establece mapred.child.ulimit, es importante que sea más de dos veces el valor de tamaño de montón establecido en mapred.child.java.opts. Por ejemplo, si configura un montón de 1G, establezca mapred.child.ulimit en 2.5GB. Ahora se garantiza que los procesos hijo se bifurcarán al menos una vez, y el tenedor requiere momentáneamente el doble de sobrecarga en la memoria virtual.
También es posible que establecer mapred.child.java.opts programáticamente sea "demasiado tarde"; es posible que desee verificar que realmente esté entrando en vigor, y ponerlo en su mapred-site.xml si no es así.