- El futuro de los servicios de datos en la nube tiene una estructura de "gran escala y multi-tenant"
- La razón por la que servicios SaaS de primer nivel como S3 ofrecen simplicidad, confiabilidad, durabilidad, escalabilidad y bajo costo es que las tecnologías de estos servicios fueron diseñadas estructuralmente para proporcionar esas cualidades
- Proveer servicios a los clientes a través de grandes pools de recursos garantiza eficiencia y confiabilidad a escala
[Definición de un sistema multi-tenant serverless]
Definición de "Multi-Tenancy"
- Multi-tenant se trata de compartir recursos mediante la colocación conjunta de cargas de trabajo sobre hardware compartido
- Construir un sistema en la nube significa que varios tenants reciben servicio desde instancias de cómputo compartidas (por ejemplo, Amazon EC2 o Google Compute) o servicios PaaS compartidos (por ejemplo, almacenamiento de objetos en la nube)
- Se define multi-tenant como "proveer servicio a varios tenants sobre recursos compartidos (como servidores virtualizados, discos y servicios base de PaaS)"
- Se pueden usar varios modelos de recursos compartidos, y algunos sistemas combinan múltiples modelos a lo largo de sus componentes
- Proceso compartido: el mismo proceso de software atiende a varios tenants. El aislamiento de datos y seguridad es lógico
- Contenedores: se ejecuta un nodo de tenant único y se empaquetan varios contenedores por host. Generalmente esto se hace con Kubernetes, donde un nodo específico de K8s puede alojar pods de muchos tenants
- Virtualización: se ejecuta un nodo de tenant único en una VM (por ejemplo, QEMU) o microVM (por ejemplo, Firecracker) y se empaquetan varias VM por host. Kubernetes también puede usarse con VM a través de Kata Containers
- También existe un método de aislamiento de V8 donde los tenants pueden compartir el mismo proceso de V8 usando contextos ligeros separados, pero aún no lo he visto en sistemas de datos
Definición de serverless
- El cliente no elige el tipo de servidor ni selecciona explícitamente el hardware
- Estos sistemas dependen de cierto nivel de elasticidad y movilidad para manejar la demanda de todas las cargas de trabajo sin que el cliente tenga que ajustar explícitamente el tamaño del hardware
- Elasticidad: capacidad del servicio para escalar hacia arriba o hacia abajo según las necesidades de la carga de trabajo
- Movilidad: capacidad del servicio para mover y balancear internamente las cargas de trabajo con el fin de cumplir requisitos de rendimiento y estabilidad
- El modelo serverless usa facturación basada en consumo, algo cada vez más importante para los clientes
- Muchos clientes no quieren hacer compromisos grandes por adelantado y prefieren simplemente pagar por lo que usan
- La facturación basada en consumo tiene muchas variantes que cambian bastante según la carga de trabajo y la implementación subyacente del sistema
- Pagar por (millón de) operaciones
- Pagar por el uso de CPU y memoria de la carga de trabajo
- Pagar por GB de almacenamiento
- Pagar por unidades virtuales de rendimiento/capacidad relacionadas con los recursos y la tasa de trabajo (por ejemplo, RCU/WCU de DynamoDB)
- Modelos híbridos donde el cliente paga por cierta capacidad base y luego paga por el uso adicional ("paga una base y cubre los picos")
[Retos comunes]
Trabajar dentro de las restricciones impuestas por la carga de trabajo
- Muchas de las restricciones impuestas por la carga de trabajo de un sistema de datos dado son impulsores clave de la arquitectura subyacente
- Requisitos de latencia/disponibilidad
- Requisitos de consistencia
- Correlaciones/dependencias entre solicitudes y datos
- Patrones de acceso secuencial frente a acceso aleatorio
- Variedad del trabajo realizado por solicitud
- Tamaño de los datos
- Protocolos orientados a sesión frente a orientados a solicitud, mecanismos push frente a pull
- Intensidad computacional del trabajo
- Requisitos más relajados de latencia y consistencia le dan al ingeniero más libertad
- Un buen ejemplo es aprovechar el bajo costo y la alta durabilidad del almacenamiento de objetos en la nube, ya que en sistemas de baja latencia hay restricciones para introducir componentes con latencia alta
- Los sistemas eventually consistent pueden evitar este dilema escribiendo datos de forma asíncrona al almacenamiento de objetos sin incluirlo en la ruta crítica sincrónica de datos
- Los sistemas de baja latencia y consistencia fuerte no cuentan con esa carta de escape
- Cuando se combinan restricciones como la baja latencia, la localidad espacial y temporal de la carga de trabajo puede influir en las decisiones de arquitectura
- Por ejemplo, en cargas de trabajo caracterizadas por escaneos secuenciales, conviene mantener juntos rangos contiguos de datos para lograr escaneos rápidos y eficientes desde disco
- Dividir esos rangos en subrangos más pequeños ayuda a manejar hotspots, pero ambos objetivos entran en conflicto, así que hay que encontrar un equilibrio
- Los patrones de acceso aleatorio con poca correlación entre solicitudes individuales pueden aprovechar un espacio de direcciones plano que se distribuya de forma uniforme y fina entre muchos servidores
- Los protocolos orientados a sesión que establecen conexiones persistentes suelen ser más difíciles que los protocolos orientados a solicitud, donde cada solicitud es independiente de la anterior
- Las conexiones persistentes pueden requerir connection pooling, y alteraciones como rolling nodes y balanceo de datos pueden tener efectos visibles externamente para el cliente
- Hay sistemas con APIs de almacenamiento simples, como el almacenamiento de objetos o la API de Kafka, y también sistemas intensivos en cómputo, como las bases de datos SQL
- Esto lleva al tema de la previsibilidad y variabilidad del trabajo necesario para procesar cada solicitud
- Un ejemplo extremo es una API de streaming de datos como Kafka, que solo necesita recuperar bloques consecutivos de registros, mientras que en el otro extremo está SQL, donde el trabajo puede variar mucho entre consultas
Aislamiento entre tenants
- Compartir recursos mejora la utilización del hardware, pero puede provocar contención de recursos, donde la carga de trabajo de un tenant afecta a otros tenants
- En un sistema multi-tenant, debe garantizarse que los tenants atendidos sobre recursos de hardware compartidos reciban un servicio como si estuvieran en un servicio dedicado propio
Separación entre almacenamiento y cómputo
- La separación entre almacenamiento y cómputo es un principio central de diseño que todos los sistemas analizados implementan en algún grado
- Las tendencias de hardware están haciendo que esta separación sea cada vez más viable, en parte porque la red ya no es el cuello de botella que era antes
- Aunque el throughput de red ha aumentado, siguen existiendo nuevos retos en esta separación, sobre todo porque el almacenamiento de objetos en la nube ocupa un lugar prioritario
- El almacenamiento de objetos en la nube sigue teniendo una latencia relativamente alta, pero ofrece gran durabilidad y bajo costo
- Sin embargo, puede ser difícil introducirlo en cargas de trabajo que normalmente requieren baja latencia, como las bases de datos OLTP
- Además, el modelo económico del almacenamiento de objetos en la nube juega en contra de los diseños que dependen de muchos objetos pequeños, ya que obliga a acumular datos en objetos más grandes con menos solicitudes, lo que complica aún más la vida de los sistemas de baja latencia
- Los ingenieros pueden incluir almacenamiento de objetos en sistemas de baja latencia y compensar su latencia colocando frente a él una caché de escritura duradera y tolerante a fallas, junto con una caché de lectura predictiva
- Esta caché de escritura duradera es básicamente un clúster de servidores que implementa un protocolo de replicación y escribe datos en almacenamiento en bloque
- En segundo plano, el clúster sube los datos de forma asíncrona al almacenamiento de objetos siguiendo un patrón económico de escritura de menos archivos pero más grandes
- La caché de escritura tolerante a fallas soporta bien escrituras de baja latencia
- Lo que puede ser problemático en esta arquitectura es la caché de lectura
- Las cargas de trabajo secuenciales, como el event streaming, son simples y muy efectivas
- Mientras el aggregate prefetching logre seguir la demanda, las lecturas siempre deberían llegar a la caché de lectura local
- Las bases de datos enfrentan un problema más difícil por los patrones de acceso aleatorio difíciles de predecir, aunque los table scans todavía pueden beneficiarse del read-ahead
- Implementar una caché de escritura distribuida y tolerante a fallas mediante un protocolo de replicación no es algo tan sencillo, y en un entorno multi-AZ pueden aparecer otros costos, como cargos por tráfico entre AZ
- Pero por ahora no hay alternativa para sistemas de baja latencia que quieran usar almacenamiento de objetos barato y duradero como almacén de datos principal
- Otros sistemas de baja latencia deberían evitar por completo el uso de almacenamiento de objetos en la nube y priorizar, ante todo, una latencia baja y predecible
- El almacenamiento en la nube se usa ampliamente, pero no es universal debido a los compromisos de latencia
Gestión del calor
- La gestión del calor consiste en distribuir la carga de la forma más uniforme posible entre varios nodos de almacenamiento para evitar hotspots que puedan causar problemas de rendimiento visibles externamente, como picos de latencia o una caída en las operaciones por segundo
- También podría llamarse balanceo de carga, aunque normalmente el término load balancer se usa para nodos stateless
- En sistemas stateful pueden surgir hotspots donde objetos con mucha demanda quedan agrupados en un nodo de almacenamiento específico, causando contención
- Un load balancer puede distribuir uniformemente la carga entre un conjunto de nodos stateless con estrategias simples como aleatorio, least connections o alguna variación de FIFO, pero los sistemas stateful deben enrutar las solicitudes a los nodos según dónde estén los datos
- Mover datos para redistribuir la carga suele llamarse rebalancing
- Un problema aún más complejo es que la distribución de carga puede cambiar con el tiempo
- La distribución de datos se vuelve un proceso dinámico que debe manejar desde picos de corto plazo que afectan pequeños subconjuntos de datos hasta cambios de carga mayores provocados por patrones diarios o eventos estacionales que aparecen en varios tenants
- Los conjuntos de datos grandes, como bases de datos masivas o event streams de alto throughput, deben particionarse para distribuir la carga de manera efectiva
- El rebalancing pasa a ser rebalancing de shards, y el sistema también puede dividir o fusionar shards a medida que cambia la distribución de carga
- Sin embargo, pueden existir tensiones contrapuestas relacionadas con la cantidad y tamaño de los shards, como la localidad de datos
- Por un lado, cuanta más co-ubicación de datos haya, más eficiente será la recuperación
- Por otro lado, el costo de trabajos computacionales que deben leer desde demasiados shards puede superar el beneficio de distribuir la carga entre más servidores
- La gestión del calor también puede ser necesaria en sistemas single-tenant, por lo que no es un problema exclusivo de multi-tenant
- Pero en sistemas de datos MT, la gestión del calor se vuelve aún más importante para evitar que los tenants experimenten variaciones en la calidad del servicio
Lograr una alta utilización de recursos
- Una de las motivaciones principales para implementar una arquitectura serverless multi-tenant es ofrecer un mejor desempeño económico mediante un uso más eficiente de los recursos de hardware subyacentes
- Aumentar la utilización de recursos mediante resource pooling es lo más importante, pero lograrlo con aislamiento entre tenants y rendimiento predecible es un reto difícil
Cold start
- Los sistemas serverless que reducen los recursos a cero por tenant pueden enfrentar el problema del cold start cuando un tenant reanuda su carga de trabajo
- El cold start ha sido un foco desde el inicio de serverless, y también puede afectar a algunos sistemas de datos serverless
- En algunos sistemas no ocurre en absoluto, mientras que en otros es algo prácticamente inevitable debido a la arquitectura y a una oferta de producto con scale-to-zero
- En todos los casos que he visto, el problema del cold start es una decisión de producto, y el nivel de reducción de recursos puede variar según el plan y el esquema de precios
- En última instancia, clientes y proveedores pueden elegir el trade-off que mejor se ajuste a sus necesidades
Sistemas analizados
- Grupo 1 - APIs de almacenamiento (compute-light)
- Amazon DynamoDB (capítulo 1)
- Kora - motor serverless de Kafka dentro de Confluent Cloud (capítulo 2)
- Backblaze B2 (planeado)
- Grupo 2 - Bases de datos SQL OLTP (compute-heavy)
- Neon - PostgreSQL serverless (capítulo 3)
- Arquitectura multi-tenant serverless de CockroachDB (en progreso)
- Planetscale (planeado)
- Grupo 3 - Bases de datos SQL OLAP y data warehouses (compute-heavy)
- Google BigQuery (planeado)
- ClickHouse Cloud (en progreso)
- Este trabajo seguirá avanzando, pero hay una publicación de "conclusión" prevista para enero/febrero de 2024
Aún no hay comentarios.