Both sides previous revisionPrevious revisionNext revision | Previous revision |
inv:desenvolvemento:amazon_elastic_mapreduce [2015/05/26 10:53] – ismael.rodriguez | inv:desenvolvemento:amazon_elastic_mapreduce [2018/10/03 09:40] (actual) – [Configuración del cluster] diego.cougil |
---|
====== Amazon Elastic MapReduce ====== | ====== Amazon Elastic MapReduce ====== |
Amazon Elastic MapReduce ([[http://aws.amazon.com/elasticmapreduce/|Amazon EMR]]) es un servicio web para la configuración y depliegue de un cluster basado en instancias de máquinas en el servicio Amazon Elastic Compute Cloud ([[http://aws.amazon.com/ec2/|Amazon EC2]]) y que es gestionado mediante [[https://hadoop.apache.org/|Hadoop]]. También se puede ejecutar en Amazon EMR otros marcos de trabajo distribuídos como [[https://spark.apache.org/|Spark]], e interactuar con los datos en otros almacenes de datos como [[http://aws.amazon.com/s3/|Amazon S3]]. | Amazon Elastic MapReduce ([[http://aws.amazon.com/elasticmapreduce/|Amazon EMR]]) es un servicio web para la configuración y despliegue de un cluster basado en instancias de máquinas en el servicio Amazon Elastic Compute Cloud ([[http://aws.amazon.com/ec2/|Amazon EC2]]) y que es gestionado mediante [[https://hadoop.apache.org/|Hadoop]]. También se puede ejecutar en Amazon EMR otros marcos de trabajo distribuidos como [[https://spark.apache.org/|Spark]], e interactuar con los datos en otros almacenes de datos como [[http://aws.amazon.com/s3/|Amazon S3]]. |
| |
===== Creación de un cluster con EMR ===== | ===== Creación de un cluster con EMR ===== |
Un cluster EMR suele tener un ciclo de vida totalmente automatizado y que se establece en el momento de su creación. El proceso general sería: | Un cluster EMR suele tener un ciclo de vida totalmente automatizado y que se establece en el momento de su creación. El proceso general sería: |
* Lanzamiento de las instancias EC2 de las que se compone el cluster | * Lanzamiento de las instancias EC2 de las que se compone el cluster |
* Ejecución de los scripts de instalación, tanto automáticos de amazon (como las imagenes preconfiguradas [[http://aws.amazon.com/es/amazon-linux-ami/|AMI]]) como los añadidos por el usuario en las acciones de inicialización (Bootstrap actions). | * Ejecución de los scripts de instalación, tanto automáticos de amazon (como las imágenes preconfiguradas [[http://aws.amazon.com/es/amazon-linux-ami/|AMI]]) como los añadidos por el usuario en las acciones de inicialización (Bootstrap actions). |
* Trabajos a realizar (Steps) normalmente consistentes en carga de datos de entrada, procesamiento de los mismos, y almacenado de los resultados. | * Trabajos a realizar (Steps) normalmente consistentes en carga de datos de entrada, procesamiento de los mismos, y almacenado de los resultados. |
* Apagado automático del cluster una vez se han terminado todos los steps. | * Apagado automático del cluster una vez se han terminado todos los steps. |
| |
En las siguientes subsecciones se explican todos lo básico para poder lanzar un cluster EMR y analizar los resultados de las ejecuciones. | En las siguientes subsecciones se explica todo lo básico para poder lanzar un cluster EMR y analizar los resultados de las ejecuciones. |
| |
==== Almacenamiento con S3 ==== | ==== Almacenamiento con S3 ==== |
{{ :inv:desenvolvemento:emr_conf.png?nolink&700 |}} | {{ :inv:desenvolvemento:emr_conf.png?nolink&700 |}} |
| |
El siguiente paso es la configuración del software que estará disponible en el cluster. En primer lugar se elige la imagen AMI del linux preconfigurado por amazon (es posible ver que contienen las diferentes [[https://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/ami-versions-supported.html|versiones AMI disponibles]]). Además, es posible añadir software adicional que proporciona Amazon. Es previsible que algunos paquetes de software muy utilizados (como Spark) estean disponibles bajo esta vía en un futuro. | El siguiente paso es la configuración del software que estará disponible en el cluster. En primer lugar se elige la distribución de Hadoop preconfigurada por amazon (versión mayor que emr-4.0.0). Además, es posible añadir software adicional que proporciona Amazon. Es importante que entre este software se encuentre Spark. |
{{ :inv:desenvolvemento:emr_soft.png?nolink&700 |}} | {{ :inv:desenvolvemento:emr.png?nolink&700 |}} |
| |
Una vez configurado el software, se continua con la configuración del hardware. La configuración más típica se compone por un nodo máster donde se lanzarán los trabajos y 2 o más instancias core que harán de workers dentro del cluster hadoop (para realizar, por ejemplo, las tareas de mapper). Dependiendo del tipo de necesidad, amazon pone a disposición varios tipos de [[http://aws.amazon.com/ec2/instance-types/#instance-details|instancias EC2]]. | Es importante configurar Spark para que use todos los recursos disponibles en los nodos. Para ello, una configuración básica para introducir en ''Edit software settings'': |
| <code bash> |
| [{"classification":"spark","properties":{"maximizeResourceAllocation":"true"}},{"classification":"spark-defaults","properties":{"spark.network.timeout":"500s"}}] |
| </code> |
| |
| Una vez configurado el software, se continúa con la configuración del hardware. La configuración más típica se compone por un nodo ''Master'' donde se lanzarán los trabajos y 1 o más instancias ''Core'' que harán de workers dentro del cluster hadoop (para realizar, por ejemplo, las tareas de mapper). Dependiendo del tipo de necesidad, amazon pone a disposición varios tipos de [[http://aws.amazon.com/ec2/instance-types/#instance-details|instancias EC2]]. |
{{ :inv:desenvolvemento:emr_hw.png?nolink&700 |}} | {{ :inv:desenvolvemento:emr_hw.png?nolink&700 |}} |
| |
{{ :inv:desenvolvemento:emr_bootstrap_new.png?nolink&400 |}} | {{ :inv:desenvolvemento:emr_bootstrap_new.png?nolink&400 |}} |
| |
Por último, aunque es posible añadir trabajos una vez desplegado el cluster, el procedimiento habitual y más seguro es añadir los trabajos (Steps) a realizar en el cluster antes de su lanzamiento. | Por último, aunque es posible añadir trabajos una vez desplegado el cluster, el procedimiento habitual y más seguro es añadir los trabajos (''Steps'') a realizar en el cluster antes de su lanzamiento. |
{{ :inv:desenvolvemento:emr_steps.png?nolink&700 |}} | {{ :inv:desenvolvemento:emr_steps.png?nolink&700 |}} |
Por ejemplo, para añadir la ejecución de un archivo ''jar'' de Java mediante Hadoop, es necesario indicar donde está almacenado el programa dentro de un bucket S3 y los argumentos del mismo. La acción a realizar al terminar el trabajo suele ser el apagado del cluster. Sin embargo, si existiesen varios steps, esta acción sería utilizada solo por el último step. | Por ejemplo, para añadir la ejecución de un archivo ''jar'' de Java mediante Hadoop, es necesario indicar donde está almacenado el programa dentro de un bucket S3 y los argumentos del mismo. La acción a realizar al terminar el trabajo suele ser el apagado del cluster. Sin embargo, si existiesen varios steps, esta acción sería utilizada solo por el último step. |
| |
===== Spark sobre EMR ====== | ===== Spark sobre EMR ====== |
Para poder utilizar Spark sobre EMR es necesario seguir una serie de pasos adicionales a lo explicado para desplegar un cluster EMR. En primer lugar es necesario realizar la instalación de Spark sobre el cluster mediante un Bootstrap action. Además, es necesario modificar la forma en que se lanzan los trabajos, ya que deben ser lanzados sobre Spark y no sobre Hadoop. | Desde la versión 4 de la imagen de Hadoop de Amazon (''emr-4.0.0''), Spark está totalmente integrado y solamente es necesario añadir como ''Step'' un ''Spark application''. |
| |
==== Instalar Spark ==== | |
Para instalar Spark se añade una nueva bootstrap action, donde el script a ejecutar es el siguiente (sin argumentos): | |
<code bash> | |
s3://support.elasticmapreduce/spark/install-spark | |
</code> | |
| |
==== Ejecutar un trabajo ==== | ==== Ejecutar un trabajo ==== |
Por defecto, los steps de EMR son ejecutados mediante hadoop. Para evitar esto, amazon proporciona un programa en java para ejecutar scripts fuera de hadoop. De esta forma, para ejecutar un trabajo sobre Spark, las opciones son las siguientes (sustituir los argumentos entre <> por sus valores reales): | Para ejecutar un trabajo sobre Spark, las opciones son las siguientes (sustituir los argumentos entre <> por sus valores reales): |
* **Step type**: Custom JAR | * **Step type**: Spark application |
* **JAR Location**: <code bash>s3://<CLUSTER_REGION>.elasticmapreduce/libs/script-runner/script-runner.jar</code> | * **Deploy mode**: Cluster |
* **Arguments**: <code bash>/home/hadoop/spark/bin/spark-submit --deploy-mode cluster --master yarn-cluster --class <MAIN_CLASS> s3://<BUCKET>/<FILE_JAR> <JAR_OPTIONS></code> | * **Spark-submit options**: ''--class <MainClass>'' |
Los argumentos son: | * **Applicaiton location**: Ruta al archivo en una unidad S3. |
* ''/home/hadoop/spark/bin/spark-submit'' es el script de ejecución de trabajos sobre spark. | * **Arguments**: Argumentos necesarios del programa JAR anterior. |
* ''--deploy-mode cluster'' indica el despliegue de spark en modo cluster, aprovechando todos los nodos configurados en hadoop. | {{ :inv:desenvolvemento:step.png?nolink&700 |}} |
* ''--master yarn-cluster'' lanza spark sobre [[http://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/YARN.html|Apache Hadoop NextGen MapReduce]]. | |
* ''--class <MAIN_CLASS>'' indica cual es la clase ''main'' del programa java. Esto es necesario, ya que un jar almacenado en S3 no hace disponible conocer su clase ''main''. | |
* ''%%s3://<BUCKET>/<FILE_JAR>%%'' es la localización del programa java que realizará el trabajo. | |
* ''<JAR_OPTIONS>'' son los argumentos necesarios del programa java. | |
==== Lectura y escritura en S3 ==== | ==== Lectura y escritura en S3 ==== |
Spark es capaz de leer y escribir mediante el protocolo s3 sin necesidad de realizar cambios. | Spark es capaz de leer y escribir mediante el protocolo s3 sin necesidad de realizar cambios. |
| |
===== Java 8 en EMR ===== | ===== Java 8 en EMR ===== |
La última versión AMI disponible (3.7.0) contiene como versión java 7. Para aquellos que usan java 8 (algo común en este tipo de entorno, por el uso de funciones lambda), pueden instalarlo en el cluster mediante un script ejecutado como bootstrap action. Para ello, solo es necesario almacenar en el contenedor S3 el siguiente script, para luego añadirlo como acción bootstrap a la hora de lanzar un nuevo cluster: | La última versión de EMR (emr-4.0.0) contiene como versión java 7. Para aquellos que usan java 8 (algo común en este tipo de entorno, por el uso de funciones lambda), pueden instalarlo en el cluster mediante un script ejecutado como bootstrap action. Para ello, solo es necesario almacenar en el contenedor S3 el siguiente script (([[https://gist.github.com/ericeijkelenboom/9951500|Bootstrap script for installing Java 8 on an Amazon Elastic MapReduce instance (AMI 3.0.1)]])), para luego añadirlo como acción bootstrap a la hora de lanzar un nuevo cluster: |
<code bash> | <code bash> |
# Check java version | # Check java version |
if [ "$JAVA_VER" -lt 18 ] | if [ "$JAVA_VER" -lt 18 ] |
then | then |
# Download jdk 8 | # Figure out how many versions of Java and javac we currently have |
echo "Downloading and installing jdk 8" | NR_OF_JRE_OPTIONS=$(echo 0 | alternatives --config java 2>/dev/null | grep 'There ' | awk '{print $3}' | tail -1) |
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8-b132/jdk-8-linux-x64.rpm" | NR_OF_SDK_OPTIONS=$(echo 0 | alternatives --config javac 2>/dev/null | grep 'There ' | awk '{print $3}' | tail -1) |
| |
# Silent install | # Silent install javac (includes jre) |
sudo yum -y install jdk-8-linux-x64.rpm | sudo yum -y install java-1.8.0-devel |
| |
# Figure out how many versions of Java we currently have | echo "Found $NR_OF_JRE_OPTIONS existing versions of java. Adding new version." |
NR_OF_OPTIONS=$(echo 0 | alternatives --config java 2>/dev/null | grep 'There ' | awk '{print $3}' | tail -1) | echo "Found $NR_OF_SDK_OPTIONS existing versions of javac. Adding new version." |
| |
echo "Found $NR_OF_OPTIONS existing versions of java. Adding new version." | # Make java 8 the default |
| echo $(($NR_OF_JRE_OPTIONS + 1)) | sudo alternatives --config java |
| echo $(($NR_OF_SDK_OPTIONS + 1)) | sudo alternatives --config javac |
| |
# Make the new java version available via /etc/alternatives | # Fix wrong links |
sudo alternatives --install /usr/bin/java java /usr/java/default/bin/java 1 | sudo rm /etc/alternatives/java_sdk_openjdk;sudo ln -s /usr/lib/jvm/java-1.8.0-openjdk.x86_64 /etc/alternatives/java_sdk_openjdk |
| sudo rm /etc/alternatives/java_sdk_openjdk_exports;sudo ln -s /usr/lib/jvm-exports/java-1.8.0-openjdk.x86_64 /etc/alternatives/java_sdk_openjdk_exports |
# Make java 8 the default | |
echo $(($NR_OF_OPTIONS + 1)) | sudo alternatives --config java | |
| |
# Set some variables | |
export JAVA_HOME=/usr/java/default/bin/java | |
export JRE_HOME=/usr/java/default/jre | |
export PATH=$PATH:/usr/java/default/bin | |
fi | fi |
| |
JAVA_VER=$(java -version 2>&1 | sed 's/java version "\(.*\)\.\(.*\)\..*"/\1\2/; 1q') | JAVA_VER=$(java -version 2>&1 | sed 's/java version "\(.*\)\.\(.*\)\..*"/\1\2/; 1q') |
| |
| echo "" |
echo "Java version is $JAVA_VER!" | echo "Java version is $JAVA_VER!" |
echo "JAVA_HOME: $JAVA_HOME" | echo "JAVA_HOME: $JAVA_HOME" |
echo "PATH: $PATH" | echo "PATH: $PATH" |
</code> | </code> |
| |
===== Enlaces externos ===== | |
* [[https://aws.amazon.com/articles/4926593393724923|Run Spark and Spark SQL on Amazon Elastic MapReduce]] | |