¿Cómo hacemos que nuestro Impala corra más rápido?
Así que tienes tu Hadoop, terabytes de datos están entrando en él por día, ETLs se hacen 24/7 con Spark, Hive o Dios no lo quiera – Pig. Y entonces, después de que los datos estén en la forma exacta que usted desea (o incluso antes) y todo sea perfecto, los analistas quieren consultarlos. Si eligió Impala para esa misión, este artículo es para usted.
Utilizamos Impala para unos cuantos propósitos:
- Permitir a los analistas consultar nuevos tipos de datos sobre los que los ingenieros de datos no han creado ningún ETL todavía.
- Permitir a los analistas consultar datos cuyo destino final (después del proceso ETL) es HDFS.
- Generación de informes (con nuestras propias herramientas).
- Supervisión de los sistemas de alerta (sobre los nuevos datos que llegan cada hora).
Tenemos decenas de miles de consultas al día, cada consulta escanea de media unos pocos gigabytes de datos y tarda 10 segundos. Nuestro clúster no es enorme en términos de hardware y número de nodos que tenemos. Por no hablar de que tenemos cientos de otros flujos de trabajo (Spark, Pig, Hive) que se ejecutan cada día en el mismo clúster.
En este artículo voy a compartir los conocimientos y conclusiones que hemos aprendido de nuestro proyecto de optimización de Impala.
¿Qué es Impala?
Si no sabes lo que es – lee sobre ello en la Guía de Cloudera Impala, y luego vuelve aquí para lo interesante.
Impala Vs. Otras Soluciones SQL-on-Hadoop
No hay nada que comparar aquí. Hoy en día, Hive es sólo para ETLs y procesamiento por lotes. Tus analistas obtendrán su respuesta mucho más rápido usando Impala, aunque a diferencia de Hive, Impala no tiene tolerancia a fallos. Pero eso está bien para un motor MPP (Massive Parallel Processing).
Impala es más rápido que Hive porque es un motor completamente diferente y Hive está por encima de MapReduce (que es muy lento debido a sus demasiadas operaciones de E/S de disco).
Impala Vs. SparkSQL
Sí, SparkSQL es mucho más rápido que Hive, especialmente si sólo realiza cálculos en memoria, pero Impala sigue siendo más rápido que SparkSQL.
Es más rápido porque Impala es un motor diseñado especialmente para la misión de SQL interactivo sobre HDFS, y tiene conceptos de arquitectura que le ayudan a conseguirlo. Por ejemplo, los demonios ‘always-on’ de Impala están activos y esperando consultas 24/7 – algo que no es parte de SparkSQL. Y algunas razones más como el mecanismo de codegen de Impala, la optimización del formato Parquet, las estadísticas, la caché de metadatos, etc.
El JDBC/ODBC Thrift Server de SparkSQL puede ser un competidor comparable a Impala, pero como no he podido encontrar mucho sobre él en la web – me limitaré a exponerlo aquí y si tienes algún conocimiento y experiencia sobre este tema por favor escribe un post medio sobre él. Yo podría escribir uno en un futuro próximo.
Impala Vs. Presto
Presto es una tecnología muy similar con una arquitectura similar. De acuerdo con casi todos los puntos de referencia en la web – Impala es más rápido que Presto, pero Presto es mucho más enchufable que Impala. Impala se supone que es más rápido cuando necesitas SQL sobre Hadoop, pero si necesitas consultar múltiples fuentes de datos con el mismo motor de consulta – Presto es mejor que Impala. Sólo tienes que ver esta lista de conectores Presto. Impala también puede consultar Amazon S3, Kudu, HBase y eso es básicamente todo.
Para leer más sobre Presto- esta es una revisión completa de PrestoDB que hice.
Mejores prácticas de Impala
Impala se desempeña mejor cuando consulta archivos almacenados como formato Parquet. Toda la tecnología en la que se basa Cloudera Impala proviene del Whitepaper de Google Dremel y en ese paper puedes encontrar el concepto en el que se basa Parquet. Así que recuerda no consultar archivos json, csv o de secuencia – parquet tus archivos antes de dejar que los analistas los consulten.
Trabaja con particiones
Participa tus datos según las consultas de tus analistas. Impala no tiene índices, por lo que es la única manera de reducir la cantidad de datos que se procesan en cada consulta. Utilizamos DT (fecha-hora) como método principal de partición para la mayoría de nuestras tablas. Sobreparticionar puede ser peligroso (siga leyendo para más detalles).
La sentencia REFRESH
La sentencia REFRESH puede ser una operación costosa, especialmente si tiene miles de tablas con datos que se añaden a ellas cada hora. Nosotros ejecutamos más de 10.000 refrescos al día. Estas son mis mejores prácticas para los refrescos:
- Desde Impala 2.7 puedes realizar un refresco en una partición específica, usa eso para hacer la sentencia REFRESH mucho más ligera.
- Arquitectura de tablas calientes & Archivadas – cada tabla tendrá una versión caliente y una versión archivada. La versión caliente mantendrá las últimas 24 horas y un refresco en esa tabla ocurrirá cada hora y será mucho más ligero. Cada día la tabla caliente se fusionará con la tabla archivada y se producirá una actualización más pesada sobre esa tabla. Y por supuesto un VIEW por encima de esas 2 que las une para que los usuarios no se den cuenta de esto.
- No tenga demasiados metadatos (archivos y particiones) por tabla (vea la sección ‘Tamaño óptimo de archivos’).
Calcule las estadísticas
Las estadísticas harán que sus consultas sean mucho más eficientes, especialmente las que involucran más de una tabla (joins). Por lo tanto, debería calcular las estadísticas de todas sus tablas y mantener un flujo de trabajo que las mantenga actualizadas con estadísticas incrementales. Para más detalles técnicos lea sobre Cloudera Impala Table and Column Statistics.
Tamaño óptimo de los archivos – 256MB/Archivo
TL;DR: Asegúrese de no tener demasiados archivos pequeños – perjudicará a su servidor de catálogo, refrescos y rendimiento de las consultas realmente mal.
Nos dimos cuenta de que nuestro servidor de catálogo Impala sigue fallando 4 veces a la semana y que nuestras consultas toman demasiado tiempo. Entonces nos dimos cuenta de que tenemos demasiados archivos y particiones. Estábamos trabajando con particiones DT cada hora, sin importar el tamaño de las particiones.
De esta manera, después de 2 años, teníamos tablas con 17GB de datos y 17.000 particiones – lo que significa que cada partición es aproximadamente 1mb. Teníamos tablas con particiones del tamaño de 50KB. Y por si fuera poco, algunas de esas pequeñas particiones tenían múltiples archivos en ellas.
Al principio pensamos que esta cantidad irrazonable de archivos sólo está causando que nuestros metadatos sean demasiado grandes y por eso los refrescos son tan pesados y el servidor de catálogos se bloquea. Pero luego nos dimos cuenta de que la cantidad de archivos también afecta muy negativamente a nuestro rendimiento de consulta (debido al número de hilos de escáner necesarios para leer tantos archivos de parquet).
¿Qué tan negativamente? Realizamos una prueba en una tabla real de 500MB que tenemos, con 17.280(!) particiones y archivos. Creamos una nueva versión fusionada de esta tabla con sólo 2 archivos, 1 por año. La parte de SCAN HDFS en el resumen de la ejecución de la consulta fue 2.000 veces más rápida. Esa fue la parte en la que entendimos lo mucho que nos están perjudicando nuestros archivos pequeños.
Así que empezamos a gestionar nuestras particiones y a fusionarlas en el tamaño de archivo óptimo que es de unos 256mb.
Las tablas con una partición horaria pasaron a tener particiones diarias, mensuales o anuales. Cada partición tiene sólo 1 archivo (a menos que su tamaño sea > 256mb)
Configurar Coordinadores &Ejecutores por Daemon
Desde Impala 2.9 se puede determinar qué daemons impala son coordinadores y cuáles son ejecutores. Eso es un cambio enorme porque antes de eso – todos los demonios eran coordinadores y ejecutores y la sobrecarga de ser un coordinador consume muchos recursos para los grandes clusters.
Significa, por ejemplo, que cada nodo mantiene toda la caché de metadatos en su RAM. Y si tienes, por ejemplo, 20GB de metadatos y 50 nodos – eso significa un desperdicio de 1TB de RAM sólo porque todos los nodos son también coordinadores!
Prueba cuál es la mejor tasa de coordinadores/ejecutores para ti y úsala. Consejo: empieza con 2 coordinadores por cluster.
Tipos de datos de columnas
Al principio usamos STRING para todas nuestras columnas en todas las tablas. Es una práctica realmente mala que perjudicó mucho el rendimiento. Deberías intentar elegir el tipo más adecuado a la columna de entre todos los tipos de datos que soporta Impala.
Límites de consulta de Impala
Deberías usar el Control de Admisión de Impala para establecer diferentes pools a diferentes grupos de usuarios con el fin de limitar el uso de algunos usuarios a X consultas concurrentes o Y memoria. Pero incluso más que eso – hemos construido nuestro propio sistema para manejar usuarios y consultas problemáticas.
Nuestro sistema muestrea las consultas que se están ejecutando actualmente cada 10 segundos y si una consulta se está ejecutando durante más de 30 minutos – se está matando. Si la misma plantilla de consulta fue matada el 90% de las veces el mes pasado porque tardó más de 30 minutos – nuestro sistema la matará inmediatamente cuando reconozca la plantilla, para proteger nuestra infraestructura.
Matar consultas no es un concepto nuevo – Amazon Athena lo ha hecho antes que nosotros, pero matar consultas sólo por patrón problemático – eso es algo que nadie más hace y es la única manera de manejar miles de analistas hambrientos.
Resumen
Si necesitas dejar que tus analistas realicen consultas SQL ad-hoc e interactivas sobre tu Hadoop – Impala es una gran solución. Deberías leer la Guía de Cloudera Impala para convertirte en un muy buen administrador de Impala y recordar trabajar según las mejores prácticas que expliqué aquí.