Cómo comprimimos los mensajes Pub / Sub y más, ahorrando mucho dinero

(29 de diciembre de 2020)

La compresión es un truco que se puede utilizar para resolver una gran cantidad de problemas. A menudo, sus herramientas comprimirán el contenido de forma transparente: la mayoría de los navegadores modernos solicitan una carga útil HTTP comprimida con gzip, y algunos sistemas de archivos se pueden configurar para comprimir bloques sin que el usuario lo pregunte.

Fuera de los casos de uso conocidos, una variedad de oportunidades para mejorar la eficiencia o ahorrar una gran cantidad de dinero al aprovechar la compresión. Es útil estar al tanto de los casos de uso comunes, para que pueda aprovechar estas oportunidades cuando surjan.

Migración de registros

Como ejemplo reciente, mi equipo estaba migrando registros de un clúster de Elasticsearch a otro. Si bien no es del todo Big Data ™, este clúster tenía 10 mil millones de entradas de registro, o unos 60 TB de JSON sin procesar.

Si tiene experiencia en el abordaje de migraciones a gran escala y de larga duración como esta, desea crear un proceso que le permite «guardar el juego» con la mayor frecuencia posible. Esto significa que puede crear y ejecutar un proceso de exportación, manejando cualquier problema que ocurra (¡lo harán, lo prometo!), Luego pasar limpiamente al proceso de importación. Al igual que con las exportaciones, su proceso de importación también se estropeará: por lo que también debería poder volver a ejecutarse fácilmente.

Como se usa en una gran cantidad de sistemas GoCardless, Google Pub / Sub es una solución natural para este problema. El eslogan de marketing de Google incluso suena como si estuviera escrito para describir nuestro proceso ideal y desacoplado:

Pub / Sub es un servicio de mensajería asincrónica que desacopla los servicios que producen eventos de los servicios que procesan eventos.

En Pub / Sub, publica mensajes en temas . Cada tema puede tener muchas suscripciones, de las que los consumidores pueden extraer mensajes . En los términos más simples, la migración:

  1. Exportaría los registros del clúster de origen a un tema de Pub / Sub (por índice)
  2. Configurar las suscripciones de Pub / Sub para retener eventos (establezca retain\_acked\_messages, consulte: Reproducción y purga de mensajes ) para que podamos reproducirlos, si nuestro la importación sale mal
  3. Importa registros extrayendo mensajes de las suscripciones a temas

Entonces, ¿qué tiene esto que ver con la compresión? Como la mayoría de los servicios en la nube, Pub / Sub cobra por el uso, lo que significa que incurriremos en tarifas proporcionales a los datos que enviaremos a través del servicio.

Estos cargos son:

  • $ 40 por TiB entregado, aplicado para publicar y suscribirse
  • Tarifas de red de Google Compute Engine (las ignoraremos, ya que se complican)
  • Almacenamiento de mensajes relacionados con la búsqueda, para retener nuestros mensajes, a $ 0.27 por GiB-mes

En el mejor de los casos, cuando importamos / exportamos con éxito en el primer intento (esto no ocurrirá y no sucedió) Se cobrará 2 x $ 40 x 60TB = $ 4,800 por la entrega de mensajes , ya que se aplicará tanto a la publicación como a la suscripción. Si conservamos nuestros mensajes durante 2 semanas mientras se realiza la migración, se nos cobrará 0.5 x $ 0.27 x 60,000GB = $ 8,100 por el almacenamiento de mensajes .

Esto deja un límite inferior de $ 12,900 para realizar la migración .

Ahora, GoCardless no es pobre. Y como regla general, normalmente desea optimizar las horas de ingeniería sobre el costo de infraestructura.

Pero si puede reducir el costo con un mínimo de esfuerzo, debería hacerlo.

Publicación mensajes comprimidos

Con este fin, hicimos un pequeño cambio en nuestra herramienta de migración (elastic-toolbox) para admitir la compresión de los mensajes que publicamos en Pub / Sub.

Con el manejo de errores eliminado, este es el método de publicación, donde aplicamos compresión después de la serialización:

Aplicando compresión condicionalmente a la carga útil de un mensaje

La compresión en sí es muy simple y casi en su totalidad código de observabilidad:

Implementando la compresión gzip, con observabilidad

Como nuestros ahorros serán proporcionales a nuestra relación de compresión (bytes comprimidos / originales), nos importa mucho cómo Nuestros datos son comprimibles.

Es probable que los registros JSON sean muy comprimibles ya que:

  • Los registros comparten muchas de las claves JSON, que pueden desduplicarse (kubernetes.pod\_name)
  • Los valores de los campos de registro comunes pueden ocurrir con mucha frecuencia (kubernetes.labels.namespace)

Usando el elastic-toolbox para ejecutar una exportación simultánea de tres índices diferentes, podemos usar la elastic\_toolbox\_export\_pubsub\_write\_compression\_ratio métrica de Prometheus (consulte la compress método anterior) para crear un mapa de calor de relaciones de compresión:

Comprimido bytes / bytes originales, siempre 0\%

Este mapa de calor muestra que todos los mensajes comprimidos en como máximo el 30\% del tamaño original . Cuando se mide en todo nuestro corpus de registros, obtenemos un promedio de ~ 12\% de relación de compresión, lo que significa que 1GiB de registros se convierte en solo 120MiB.

Nuestra factura original de $ 12,900 se ha convertido en 12\% x $ 12,900 = $ 1,548.

Esto significa que hemos ahorrado alrededor de $ 11,500.

Explore los datos usted mismo en esta Instantánea de Raintank: compresión de caja de herramientas elástica .

¿Siguiente paso? Aplicar a tiempo completo.

El siguiente paso más obvio fue aplicar esto a nuestra canalización de registros todo el tiempo. Dado que enviamos los registros de contenedores directamente a Pub / Sub y los sacamos de una suscripción a Elasticsearch, podemos escribir fácilmente un filtro fluentd que aplique la misma estrategia de compresión.

Mi colega Ben elaboró ​​un panel de control increíble para realizar un seguimiento de cuánto ahorramos, que resulta ser varios miles al mes :

Ahorros al comprimir registros cuando ingresan a la canalización de registros

¿En qué otro lugar puede ayudar la compresión?

Si trabaja en un entorno en la nube, hay muchas oportunidades para ahorre dinero comprimiendo sus datos.

Más allá de los registros, otro ejemplo de GoCardless es una herramienta llamada draupnir . Este servicio aloja copias de nuestras bases de datos de producción para pruebas de carga y análisis forense (predicción del plan de consultas, etc.). El almacenamiento SSD de Google cuesta $ 187 por TiB / mes, lo que significa que cada copia de nuestro 5TB Postgres cuesta $ 1,000 / mes .

Draupnir puede alojar varias copias a la vez, según los casos de uso. Podemos ahorrar una gran cantidad de dinero habilitando la compresión btrfs para comprimir de forma transparente los bloques del sistema de archivos, lo que nos permite usar ~ 70\% menos de capacidad SSD de lo que podríamos de otra manera.

Y si pensaba que la compresión se limitaba a ahorrar costos, ¡estaría equivocado! Habiendo sufrido micro-interrupciones ocasionales cuando las personas ejecutaban grandes reabastecimientos o construían nuevos índices de bases de datos, resolvimos el problema habilitando la compresión WAL de Postgres (consulte Funciones infrautilizadas de Postgres: compresión WAL , o los Postgres Write Ahead Log docs ).

Las interrupciones fueron causadas por operaciones de base de datos que creaban una gran cantidad de WAL churn, donde la réplica se detendría al escribir el WAL en el disco. Al comprimir la transmisión WAL, redujimos significativamente los picos de E / S, lo que permite que la réplica maneje la transmisión sin problemas .

Hay más ejemplos, pero creo que esto pinta una buena imagen.

¿Cómo te ayuda esto?

La compresión es una compensación, una decisión que tomamos para Cambie la CPU por otro recurso que pueda ser más caro o menos disponible. El valor asignado a la CPU, la memoria o el ancho de banda de la red cambia continuamente, y deberá realizar este cálculo caso por caso.

Esta publicación tenía como objetivo cubrir un escenario en el que el costo de La compresión, tanto en recursos de cómputo como en tiempo de construcción, se vio significativamente superada por los ahorros que supondría. No todas las situaciones tendrán la misma economía, pero se necesitan unos minutos de matemáticas para decidir de cualquier manera.

Espero que este estudio de caso impulse la consideración de la compresión fuera de los casos de uso estándar y aburridos, y ayude para encontrar oportunidades donde pueda aplicarlo a sus propios sistemas.

Discuta esta publicación en Hackernews .

Publicado originalmente en https: // blog .lawrencejones.dev el 29 de diciembre de 2020.