Aprovechando la publicación de la última release de Apache Druid en la que se incluyen numerosas mejoras, vamos a hablar en este artículo acerca de cómo realizar una instalación Serverless en el entorno de la nube pública con AWS.

¿Qué es Apache Druid?

Apache Druid es una base de datos de alto rendimiento en tiempo real, está orientada a columnas y se trata de un sistema distribuido que se compone de varios servicios. Es un nuevo tipo de base de datos que combina ideas de bases de datos analíticas/OLAP, bases de datos de series temporales y sistemas de búsqueda para permitir nuevos casos de uso en arquitecturas de streaming. Proporciona consultas analíticas rápidas, en alta concurrencia, sobre datos de eventos. Puede ingerir instantáneamente datos de flujo y proporcionar consultas de subsegundo. Además se integra de forma nativa con buses de mensajes (Kafka, AWS Kinesis, etc.) y datalakes (HDFS, AWS S3, etc.).

Como curiosidad, el nombre Druid viene de los juegos de rol, en muchos de ellos existe un personaje que puede cambiar su forma y se escogió este nombre para reflejar el hecho de que la arquitectura del sistema puede cambiar para resolver diferentes tipos de problemas de datos.

¿Cómo desplegar Apache Druid en AWS?

Haciendo uso de infraestructura como código, podemos servirnos de CloudFormation o Terraform para llevar a cabo el despliegue de todos los recursos que componen Druid. La arquitectura de la que se compone Druid es la siguiente:

 

Para desplegar la infraestructura de Druid en AWS, se presenta la siguiente arquitectura con diferentes servicios gestionados por AWS:

Como se muestra en el diagrama de la arquitectura, Druid tiene varios tipos de procesos, que se describen brevemente a continuación:

  • Coordinator: Este proceso se encarga de coordinar los procesos históricos. Son responsables de asignar segmentos a servidores específicos, y de asegurar que los segmentos estén bien balanceados en los nodos Historical.
  • Overlord: Vigilan los procesos MiddleManager y controlan la ingesta de datos en Druid. Son responsables de asignar las tareas de ingesta a los MiddleManagers y de coordinar la publicación de segmentos.
  • Broker: Reciben consultas de clientes externos y las reenvían. Cuando los Brokers reciben los resultados de esas subconsultas, fusionan los resultados y los devuelven. Los usuarios finales normalmente consultan a los Brokers.
  • Router: El router ejecuta la Consola de Druid, es la interfaz de administración para fuentes de datos, segmentos, tareas y procesos de datos. El usuario también puede ejecutar consultas SQL y nativas dentro de la consola. Es el proceso al que añadiremos un ALB para poder acceder a su interfaz web.
  • Historical: Son los responsables del almacenamiento y la consulta de datos. Los procesos históricos descargan segmentos del Deep Storage y responden a las consultas sobre esos segmentos.
  • MiddleManager: Gestionan la ingesta de nuevos datos en el cluster. Se encargan de leer de fuentes de datos externas y de publicar nuevos segmentos.

Estos procesos pueden ser ejecutados en contenedores, con Fargate, asignando a los servicios la cantidad de CPU y RAM deseada. El servicio Historical es recomendable hacer uso de contenedores EC2 en máquinas con SSD en instancias i3, optimizadas para grandes cargas de trabajo de transacciones. Para desarrollar el Dockerfile con el que construir la imagen de docker que se subirá a ECR, en la documentación de Druid podemos ver la recomendación de organización de ficheros por servicios y la configuración a definir en cada proceso, en github se pueden encontrar varios ejemplos.

Por otro lado, Druid cuenta con tres dependencias externas:

  • ZooKeeper: Se utiliza para el descubrimiento de servicios internos, la coordinación y la elección de líderes.
  • Metadata storage: Contiene los metadatos de sistema compartidos, como la información sobre el uso de los segmentos y la información sobre las tareas. Se puede utilizar aurora serverless con MySQL.
  • Deep Storage: Se trata de un almacenamiento de archivos compartidos accesibles por cada servicio de Druid. Se utiliza para almacenar cualquier dato que haya sido ingestado en el sistema y es compatible con S3.

¿Qué resultados se obtienen con esta arquitectura?

Contando con los servicios replicados en HA, no perderemos información ya que, aunque se caiga uno de los servicios, hay otro disponible y Fargate levantará de nuevo el contenedor por lo que en un breve periodo de tiempo contará de nuevo con la instancia. Para los nodos del servicio Historical, se recomiendan instancias con SSD ya que ofrecen una gran velocidad de lectura por lo que la obtención de los resultados de las queries será en pocos segundos.

Por otro lado, si nuestra ingesta de datos proviene de un bus en stream como Apache Kafka, en caso de caída de la tarea que gestiona la lectura de datos, Druid volverá a conectarse en el punto en el que se encontraba antes del fallo por lo que no hay pérdida de información, para este punto es aconsejable una buena configuración de las políticas de retención de los tópicos de Apache Kafka.

¿Qué mejoras se pueden realizar?

Finalmente contamos con una base de datos timeseries estable, tolerante a fallos y preparada para realizar ingestas en tiempo real. Como posible mejora, se puede realizar el despliegue en EKS en lugar de ECS obteniendo aún mejores tiempos de escalado.

Author

  • Luis Gomez

    Cloud Engineer en Keepler. "I love technology, teamwork and constant learning. In recent years I have worked with both physical and virtualized infrastructures, currently I work with public clouds in order to take advantage of their full potential."