Redshift para entregar nuestros datos – Parte 2

Cómo usamos y abusamos de Redshift para entregar nuestros datos

En la primera Parte 1, describimos nuestra tubería de ingesta de datos de Analytics, con BigQuery como nuestro almacén de datos. Sin embargo, tener nuestros eventos analíticos en BigQuery no es suficiente. Lo más importante es que los datos deben ser enviados a nuestros usuarios finales .

En este artículo, detallaremos:
  • ¿Por qué elegimos Redshift para almacenar nuestros almacenes de datos,
  • Cómo encaja en nuestra capa de servicio,
  • Aprendizaje clave y consejos de optimización para aprovechar al máximo,
  • Flujos de trabajo de orquestación,
  • Cómo nuestras aplicaciones de visualización de datos ( Chartio , aplicaciones web) se benefician de estos datos.

Los datos están en BigQuery, ¿ahora qué?

Volver a donde nos detuvimos en el articulo anterior. Nuestros datos se almacenan en formatos brutos y agregados en BigQuery. Nuestros analistas de datos pueden consultarlos directamente con fines de exploración o depuración, pero SQL tiene su límite. Ahí es donde un código Scala toma el control de nuestra arquitectura, en un componente que llamamos el Servicio de Análisis .


Visión general del servicio de analytics
Visión general del servicio de analytics

El Servicio de análisis es una pieza bastante central que realiza algunas operaciones y lógica empresarial que sería demasiado compleja para modelar como SQL.

También agrega datos de BigQuery junto con otras fuentes de datos para enriquecerlos. Para ser más específicos, estas operaciones implican:
  • Derechos de acceso , para que los usuarios solo obtengan datos para los que están autorizados a ver,
  • Hidratación de datos a partir de tablas de dimensiones (nuestra principal base de datos de negocios),
  • Cálculo avanzado de métricas financieras que incluye tasas de cambio y reglas de negocios,
  • Gestión de zonas horarias : almacenamos datos en UTC pero permitimos que los usuarios soliciten datos en cualquier zona horaria,
  • Mantener un registro de qué datos están disponibles o no y advertir a los usuarios que están obteniendo informes que incluyen datos parcialmente disponibles,
  • Desencadena trabajos posteriores cuando hay datos disponibles (incluidos los mercados de datos).
El servicio de análisis atiende dos casos de uso bastante diferentes con el mismo código e infraestructura:
  • Informes de hoja de cálculo (xlsx, csv)  : pueden generarse a pedido o programarse. Se utilizan mucho para seguir métricas de negocios específicas a diario.
  • Generación del mercado de  datos: los almacenes de datos son vistas personalizadas de los datos y se utilizan para crear paneles de control, servir como back-end para las aplicaciones web, etc. Los almacenes de datos pueden configurarse para que se ejecuten cada hora (por ejemplo, a ~ 08: 30). para el período de 07:00 a 07:59) o diario (por ejemplo, en ~ 00: 30, generar data mart para el día anterior).

Debido a la latencia incompresible de BigQuery y al procesamiento adicional involucrado para aplicar las reglas de negocios, los informes de hoja de cálculo pueden demorar de 10 segundos a unas pocas horas en calcularse. Todo depende del período solicitado y de la complejidad de las reglas comerciales implícitas en los datos solicitados.

Técnicamente, descargamos el procesamiento de grandes informes como trabajos Spark para aislar cada proceso. Los almacenes de datos suelen ser más grandes que los informes de hojas de cálculo y requieren más tiempo para procesarlos.

¿Por qué Redshift?

Antes de poner Redshift en su lugar, el Servicio de análisis procesó los informes de hojas de cálculo y los resultados de SQL que se cargaron en una base de datos de Infobright Enterprise Edition ( IEE ) *.

* IEE es una bifurcación propietaria de MySQL, modificada para análisis (orientada a columnas). Aunque estaba bien usar IEE para servir paneles conChartio (la aplicación de visualización SaaS, que utilizamos internamente para Business Intelligence), estábamos llegando a sus límites, en términos de precios y escalabilidad.

También teníamos otras necesidades de visualización de datos dentro de las aplicaciones web recién creadas. En estas aplicaciones.

Los usuarios pueden explorar sus datos (por ejemplo, un editor puede ver sus ingresos, con muchos desgloses: por hora, por dispositivo, por sitio web, etc.). El bajo tiempo de respuesta es un requisito ya que los usuarios esperan una experiencia interactiva. Establecemos el requisito de que cualquier tablero de mandos se cargue en 1s para estas IU.

Teniendo en cuenta estos dos casos de uso (Chartio para uso interno y aplicaciones web para clientes), consideramos varias opciones:

Opción 1: BigQuery en todas partes

Inicialmente, pensamos que podíamos manejar todo esto con BigQuery, cargando los resultados del Servicio de Análisis de nuevo en BigQuery (en lugar de IEE). Pero haciendo esto nos topamos con algunas limitaciones:

  • La latencia mínima de BigQuery es de alrededor de 5 s. Eso podría haber funcionado para Chartio y su sistema de caché incorporado, pero es mucho más alto de lo que es aceptable para una aplicación web.
  • Ya nos estábamos acercando al número máximo de consultas simultáneas en BigQuery (Google permite hasta 50 de forma predeterminada) sin que ninguna aplicación de visualización de datos lo use directamente. Con el desarrollo de más y más aplicaciones web, sabíamos que no se escalaría.

Opción 2: mantener los almacenes de datos en IEE para Chartio y considerar soluciones de almacenamiento en caché para aplicaciones web

Para solucionar los problemas de latencia y concurrencia de BigQuery, naturalmente, buscamos soluciones de almacenamiento en caché y tiendas de valor clave de referencia. Los candidatos preseleccionados fueron DynamoDB y BigTable .

Ambos ofrecen un gran rendimiento de lectura, pero el desafío está en el lado de escritura . Con BigQuery como la fuente de datos principal, una falla de caché costaría demasiado , por lo tanto, la necesidad de pre-computar y cargar todo en un caché. Esta solución agregaría mucho trabajo de antemano y no nos ayudaría a alejarnos de IEE.

redshift - Una comparación simplista de los candidatos
Una comparación simplista de los candidatos basada en evaluaciones subjetivas . Mayor es mejor.

Como la invalidación del caché es una de las dos cosas difíciles en la informática, pasamos mucho tiempo evaluando alternativas. Una proposición fuera de la caja era Redshift .

No fue intuitivo, pero llegamos a un punto en el que consideramos que era un candidato serio para resolver dos problemas a la vez.

Opción 3: La opción contraintuitiva de Redshift

Redshift fue una elección natural para reemplazar IEE (los productos son similares en el papel) y sirven como una fuente de datos para los paneles de control internos de Chartio.

¿Pero Redshift podría ser una alternativa seria a los almacenes de Key-Value de baja latencia para las necesidades de nuestras aplicaciones web?

Redshift podría, de hecho, ayudar a reducir la carga de BigQuery proveniente de Chartio, y también tuvimos la tentación de que se ajustara a las necesidades de nuestras aplicaciones web. De esta manera, podríamos mutualizar el esfuerzo de implementación.

Esta solución para aplicaciones web nos sedujo de inmediato, ya que ofrece dos grandes ventajas :
  • La modelación de datos sería la misma que la de datos para Chartio. La mayor diferencia sería el alcance de cada data mart. Si bien usamos algunos mercados de datos grandes para alimentar todos los paneles de Chartio, cada caso de uso específico de aplicaciones web podría requerir un centro de datos dedicado, de modo que esté optimizado para ello. El hecho de que el servicio de análisis ya sea capaz de generar estos mercados de datos facilita la implementación.
  • Redshift ofrecería más flexibilidad para las aplicaciones web ya que SQL simplifica (mucho) la manipulación de datos. Esto es especialmente cierto porque decidimos manejar la restricción de múltiples inquilinos en el tiempo de alcance, es decir, tener un “caché” por aplicación, en lugar de por aplicación / usuario. No buscamos esto último ya que la cardinalidad (número de usuarios / “vistas” filtradas por derechos) es alta. Además, tener SQL en el lado del consumidor también facilitaría la migración futura a otro proveedor / base de datos, ya que no tendríamos que volver a escribir todas las consultas de la aplicación web o del panel de control.

Sin embargo, la escala de nuestros almacenes de datos se encuentra entre lo que el mundo de SQL puede manejar y el Big Data real.

Tenemos tablas de unos pocos miles de millones de filas y hasta 600 GB de datos por tabla. Es suficiente para que las bases de datos clásicas empiecen a luchar, pero es el extremo inferior del espectro para Redshift.

Todavía teníamos las mismas dos preocupaciones, sin embargo:
  • ¿Redshift podría lograr una latencia lo suficientemente baja como para servir aplicaciones web interactivas?
  • ¿ Sería suficiente el límite de concurrencia de consultas para nuestros casos de uso? Las aplicaciones web que estábamos construyendo eran aplicaciones avanzadas de back-office, y no previmos más de unos pocos miles de usuarios activos diarios.

Preocupación # 1 latencia de consulta

Sorprendentemente, encontramos poca información sobre el desempeño de Redshift en conjuntos de datos relativamente pequeños. Todos los puntos de referencia disponibles en ese momento se centraron en los casos de uso de Big Data. Naturalmente, involucraron grandes grupos que serían excesivos y económicamente difíciles para nuestro caso de uso. Estos puntos de referencia estaban probando Redshift para consultas grandes que tomaron de 10 a 30 segundos.

Sin experiencia de primera mano con pequeños grupos y pequeñas consultas optimizadas, fuimos incapaces de saber si Redshift podría realizar tiempos de respuesta por debajo de un segundo para nuestros conjuntos de datos.

La experiencia ahora nos dice que es posible servir una aplicación con paneles de instrumentos complejos para unos pocos usuarios simultáneos y mantener la latencia por debajo de 500 ms , que es:

  • Satisfacer para una aplicación de negocios con carga asíncrona,
  • Impresionante para una mesa con 8 mil millones de filas.
Aquí hay algunas prácticas y optimizaciones que seguimos para lograr este nivel de rendimiento:
  • Cada aplicación utiliza un clúster dedicado Redshift ,
  • Cada sección de la aplicación obtiene un data mart dedicado , adaptado a la necesidad de esta sección,
  • Al conocer de antemano todas las consultas que realizamos en un data mart, podemos elegir la mejor clave de clasificación que funcionará mejor con esas consultas,
  • La ordenación ( ORDER BY) es una operación costosa para Redshift. Logramos un mejor rendimiento al permitir que la aplicación clasificara los datos una vez que se extrajeron de Redshift.
redshift - Duración de la consulta de desplazamiento al rojo (p90)
Duración de la consulta de desplazamiento al rojo (p90)

Preocupación de la consulta # 2

Antes de dar un paso hacia lo desconocido, preguntamos por personas que ya habían intentado conectar Redshift a una aplicación orientada al usuario. Todos nos advirtieron y señalaron las limitaciones de concurrencia de Redshift . Las limitaciones de las consultas simultáneas son similares o peores que las de BigQuery ( máximo de 50 espacios, se recomiendan 15 ).

Continuamos de todos modos . Fue una elección arriesgada , pero apostamos por Redshift porque:
  • Nuestras aplicaciones son esencialmente oficinas con un número limitado de usuarios . Además, una visita típica no implica muchas consultas, por lo que pensamos que tendríamos un margen para el futuro.
  • Nuestras aplicaciones no interfieren entre sí, por lo tanto, al tener un clúster por aplicación, podríamos aislar la carga y multiplicar el número total de espacios disponibles para consultas simultáneas. Nuestra estrategia es utilizar varios grupos pequeños y baratos de Redshift. Esta escala horizontal, en número de grupos más que en número de nodos, es posible gracias al precio de entrada de Redshift: 180 $ / mes para un grupo (a pedido) y tan bajo como $ 70 / mes (3 años por adelantado). También vale la pena mencionar que el modo de clúster incluye un nodo líder que es gratuito. Con la diferencia de precios, podemos permitirnos funcionalmente tener un grupo para cada caso de uso, ya que los almacenes de datos se adaptan para que sean autosuficientes (no es JOINnecesario realizar ninguna operación). Utilizamos Terraform para describir nuestra infraestructura, que ayuda a reducir la fricción y la entropía al crear nuevos grupos.
  • De todos modos, invertir en Redshift todavía era útil para nuestro caso de uso de Chartio para reemplazar IEE.

Aproveche al máximo Redshift – Un viaje de optimización

A diferencia de BigQuery, Redshift requiere una gran cantidad de optimizaciones manuales para rendir al máximo. AWS administra el hardware y la agrupación en clústeres, pero aún es responsable de muchas opciones de base de datos heredadas de Postgres .

La mayor parte de la optimización se realiza a nivel de tabla con muchas opciones para elegir (tipo de columna y codificación, claves de clasificación, clave principal y externa, etc.), así como operaciones de mantenimiento (vacío, reindexación de vacío, análisis).

La documentación de Redshift ofrece una buena visión general de las mejores prácticas ( aquí , aquí , aquí y aquí ). También puede encontrar algunos consejos de ajuste excelentes en este artículo . Esto es lo que funciona para nosotros:

Dimensionamiento

Es lo primero que debe hacer al crear un clúster. Usamos las instancias más pequeñas de SSD ( dc2.large) y hasta la fecha tenemos 5 grupos de Redshift (de 3 a 18 dc2.largenodos cada uno). También tenemos un clúster de “archivo” para almacenar datos fríos, que usamos para copias de seguridad y consultas ad hoc (4 ds2.xlargeinstancias de HDD). Es realmente fácil cambiar el tamaño de un clúster , por lo que no es necesario realizar una planificación de capacidad compleja aquí.

Codificación de columnas

La compresión es lo primero y más importante sobre el rendimiento, pero reducir la huella de la tabla siempre es bienvenido. Todo lo que necesita saber acerca de la codificación está en la documentación . Después de ejecutar algunos puntos de referencia en nuestros datos, la mejor configuración para nosotros es:

  • DELTA32Kpara las BIGINTmétricas,
  • LZOpara las NUMERICmétricas, en general, LZOofrece el mejor compromiso entre el rendimiento de las consultas y la compresión en nuestra experiencia,
  • BYTEDICTpara las dimensiones donde sabemos que la cardinalidad es <255. Es un 3% más rápida y un 18% más comprimida en comparación con TEXT255(codificación de compresión alt para diccionarios). BYTEDICTSoporta todos los tipos mientras que TEXT255solo soporta VARCHAR.
  • LZO para otras dimensiones,
  • Sin compresión para ninguna columna en el sortkey.
redshift - Ejemplo de tabla con codificación de columnas
Ejemplo de tabla con codificación de columnas

En este ejemplo, usamos la BYTEDICTcodificación para la columna del dispositivo porque sabemos que la cardinalidad es 4 (móvil, escritorio, televisión, tableta), pero usamos LZOpara el navegador porque hay una infinidad de agentes virtuales.

También hemos comparado algoritmos de propósito general LZOZSTANDARD. Aunque ZSTANDARDsiempre ofrece la mejor relación de compresión, compromete el rendimiento de las consultas. Terminamos nunca usándolo debido a nuestro enfoque en el rendimiento de las consultas.

En este punto de referencia, la DELTAcodificación tiene un rendimiento de lectura aún mejor, pero no es compatible ni está adaptada a todos los tipos de datos.

Redshift - Performance and compression benchmark (greater is better)
Este gráfico es específico para nuestro contexto, y solo con fines ilustrativos. Da una idea aproximada de los resultados de nuestras primeras pruebas comparativas que comparan los algoritmos de compresión. El eje x es un índice del tiempo de respuesta de la consulta.

Claves de clasificación

Las claves de clasificación son como índices, es la palanca de rendimiento más importante. Hay dos tipos de claves de clasificación :

  • Compuesto: estos son los más eficientes, pero restringen la forma en que debe consultar los datos. sort key(hour, ad_id)estará activo cuando discrimines hourhourad_idno ad_idsolo.
  • Intercalado: estas claves de clasificación permiten consultar columnas en cualquier orden, pero comprometen el rendimiento de lectura y aumentan considerablemente la duración del vacío .

Vacíos y analytics

Redshift no clasifica los datos en la inserción ni mueve los datos durante las eliminaciones. Los vacíos son operaciones de mantenimiento que desfragmentarán y clasificarán las tablas. Es obligatorio mantener un rendimiento óptimo.

Las 3 operaciones más importantes son:
  • Vacío: ordenar los datos y desfragmentar las partes eliminadas. Lo ejecutamos una vez al día y toma aproximadamente 1 hora para una tabla con 3 mil millones de filas (200 GB). Realizamos vacíos con un umbral del 100% para tener un rendimiento de lectura óptimo,
  • Reindexación al vacío: operación específica necesaria cuando se utilizan claves de clasificación intercaladas. Esta operación es muy costosa (alrededor de 3 a 5 veces más que las aspiradoras), por lo que puede valer la pena considerar una copia profunda .
  • Analizar: actualiza las estadísticas de la tabla que utiliza el planificador de consultas. Una operación relativamente barata.

La programación de vacíos es complicada ya que estos son procesos largos de uso intensivo de E / S y están limitados a una sola operación de vacío concurrente por grupo.

Las operaciones de Reindex al vacío son tan exigentes que no podemos realizarlas en todas las mesas todos los días, llevaría más de 24 horas procesarlas.

Vale la pena mencionar que durante los vacíos nuestros clústeres se desempeñan en aproximadamente un tercio de sus capacidades nominales (lo que puede estar relacionado con el hecho de que usamos clústeres pequeños).

Al principio, intentamos aspirar después de cada carga de datos (cada hora), para maximizar el rendimiento. No resultó ser una buena idea, los servidores tardaban la mayor parte del tiempo en realizar estas costosas operaciones, y la reducción del rendimiento durante el día sin vacío es insignificante.

 En su lugar, ejecutamos una secuencia de comandos personalizada cada nocheque recorre todas las tablas del clúster y realiza estas operaciones de mantenimiento.

Colas y prioridades

Redshift tiene mecanismos avanzados para administrar los SLA entre usuarios, pero por el momento mantuvimos todas las configuraciones predeterminadas. El hecho de que tengamos un grupo por caso de uso simplifica esta parte.

Hemos habilitado la aceleración de consultas cortas para un clúster que tiene muchas consultas simultáneas (la de Chartio). Analiza automáticamente las consultas y asigna las más cortas a una cola dedicada. Funcionó muy bien para reducir el impacto en el rendimiento de consultas más grandes.

Reserva de instancia

Como muchos recursos de AWS , las instancias de Redshift son elegibles para los mecanismos de reserva . Reservar instancias es una tarea tediosa pero necesaria para reducir su factura. Afortunadamente, los almacenes de datos caen en el tipo permanente de instancias, por lo que es relativamente fácil pronosticar el uso mínimo.

Aprendizajes clave trabajando con Redshift

  • A pesar de que la infraestructura subyacente de Redshift está gestionada por AWS, se necesita mucho trabajo para optimizarla y operarla. Para darle una idea, pasamos más tiempo operando 100s de GB en Redshift que en 100Q de TB en BigQuery,
  • Añadiendo más nodos se necesitan cuando las tablas se hacen más grandes y / o más con la consulta de tráfico, pero no tiene por qué aumentar el rendimiento de mesas pequeñas (durante nuestros puntos de referencia, que no vi mucha diferencia cuando se compara largefrente a 8xlargecasos),
  • El límite de consultas simultáneas (valor predeterminado 15, máx. 50) puede ser un problema para las aplicaciones interactivas orientadas al usuario,
  • La carga de datos es rápida, pero tienes que pasar por S3 y usar el COPYcomando,
  • Redshift se basa en PostgreSQL 8: la administración de derechos deacceso de usuarios y grupos es una molestia . Incluso lo más básico, como dar a un usuario acceso de solo lectura a todas las tablas, implica muchas operaciones tediosas. En realidad, nos desalentó a que nuestros analistas de datos tuvieran acceso directo a SQL: preferimos BigQuery para eso.

La evolución de Redshift

Redshift es un producto en evolución. Este artículo refleja principalmente Redshift a principios de 2017. Algunas características y simplificaciones se lanzan regularmente.

  • Desde enero de 2019 (versión de corrimiento al rojo 1.0.5671), ANALYSEVACUUM DELETElas operaciones se realizan de forma automática para usted en el fondo. Podemos esperar que el otro, más complejo VACUUMy las VACUUM REINDEXoperaciones se vuelvan innecesarias también.
  • En noviembre de 2018, Redshift introdujo una nueva forma de agregar o eliminar nodos más rápido. Solo está disponible si duplica o divide por dos el número de nodos, pero toma minutos en lugar de horas.
  • En re: Invent 2018 , Redshift anunció una función de escalado simultáneo que ayudaría con las ráfagas de actividad del usuario. Esto debería estar disponible en la primera mitad de 2019.

Orquestación y programación.

Cada paso de nuestro proceso, desde la ingestión del flujo de datos hasta el procesamiento de data mart en Redshift, debe estar bien organizado. Usamos buenos viejos Jenkins y jobHistory(una herramienta interna) para lograrlo.

redshift - Jenkins y jobHistory
Jenkins y jobHistory

La mayoría de nuestros trabajos procesan un flujo de datos de solo escritura sin fin. La unidad base de tiempo es una hora y jobHistoryactúa como un cronometrador para todos nuestros trabajos.

Básicamente, cada trabajo tendrá que procesar 24 de estos trozos todos los días. Para cada trabajo, jobHistorysabe qué parte se ha procesado y cuál no. También mantiene un gráfico de dependencia de los trabajos, de modo que cada trabajo exitoso puede desencadenar operaciones posteriores.

Para cada trabajo, Jenkins sondea jobHistorycada pocos minutos y solicita fechas para procesar. La mayoría de las veces no hay nada que hacer y una vez por hora se activa el procesamiento de esta parte.

redshift - JobHistory UI
JobHistory UI, las horas grises son fragmentos que se procesarán una vez que se procesen las dependencias principales

Probamos alternativas más avanzadas a jobHistory, como Cloud Composer(basado en Apache Airflow ), pero no se ajustó a nuestras necesidades y carecía de madurez en ese momento.

Jenkins, jobHistorylos ingredientes son simples.

 La clave para la confiabilidad de la cadena reside en algunas buenas prácticas :
  • Todos los trabajos están diseñados para ser idempotentes, por lo que puede ejecutarlos y volver a ejecutarlos con confianza (por ejemplo, cuando fallan o cuando ocurren eventos tardíos para una parte que ya se procesó).
  • Escribir datos con operaciones atómicas ayuda a lograr la idempotencia. Ejemplo de la vida real: un trabajo de Jenkins A se encarga de crear la tabla A delegando el proceso a BigQuery. Digamos que la consulta lleva más tiempo de lo habitual y el trabajo de Jenkins termina con un tiempo de espera. En este punto, no sabemos si la consulta tuvo éxito. Podemos volver a ejecutar el trabajo A con el mismo parámetro, el trabajo buscará primero una tablaA . Debido a que la salida de BigQuery es atómica, si la tabla está presente, no hay nada que hacer.
  • Escribir datos usando mecanismos de inserción (insertar o actualizar) es otra forma de ser idempotente.
  • Confíe en los datos en bruto más que en los metadatos de mantenimiento. Con el ejemplo anterior, para obtener la última tabla procesada, puede confiar en un conjunto de metadatos para el trabajo A, o puede verificar directamente si existe una tablaA . No siempre es factible (por ejemplo, por razones de rendimiento), pero elimina los problemas potenciales causados ​​por las discrepancias entre los datos y los metadatos.

Conclusión

Dos años después de nuestras primeras pruebas, Redshift se ha convertido en una pieza central de nuestra pila de Analytics : una base de datos para resolver todas nuestras diversas necesidades de visualización de datos, desde la exploración de datos de autoservicio en Chartio hasta aplicaciones con restricciones de latencia.

Tiene una interfaz SQL simple con buen rendimiento y escalabilidad a un precio razonable. Incluso si nuestro caso de uso híbrido es exótico , la latencia es aceptable para las interfaces de usuario web y aún nos encontramos bajo los límites de concurrencia.

No podríamos pensar en una mejor manera de mostrar nuestros resultados que una descripción general rápida o nuestras aplicaciones de visualización de datos:

Aquí está una de nuestras aplicaciones web:
Redshift4 - app web
Redshift4 - app web
Tablero de control de Chartio (ejemplo):
Redshift5 - Tablero de control de Chartio

Si te gusto este artículo también puedes leer otros dos temas interesantes en nuestra sección de Analytics.

Gracias por leer y yo estoy esperando para escuchar sus preguntas:)
Esté atento y Feliz Analytics!.

PD Si quiere aprender más sobre el mundo de Analytics, también puede seguirnos en Instagram , encuéntreme en linkedin  o en Facebook. Me encantaría saber que te sumes!.

Dejá un comentario