29 puntos por xguru 2022-08-17 | 3 comentarios | Compartir por WhatsApp
  • Operan un clúster de base de datos NoSQL (ScyllaDB) que procesa 2 millones de mensajes por segundo
  • Lo que más impacta el rendimiento de la base de datos es la latencia del hardware de disco físico
    → Cuando el volumen de consultas es bajo no importa mucho, pero al superar cierto punto, solo el tiempo de lectura de 1~2 ms hace que se formen colas de espera para leer del disco y terminen ocurriendo timeouts en las propias consultas
  • La latencia de disco normalmente se mide en microsegundos, entonces ¿por qué una operación de disco tarda 1~2 ms?
  • Discord opera la mayor parte de su hardware en Google Cloud
    • Soporta SSD locales basados en NVMe, pero tras probarlos por su cuenta encontraron problemas de confiabilidad, así que no se sentían cómodos usándolos para almacenar datos importantes
    • Persistent Disk puede conectarse o desconectarse del servidor en tiempo real, redimensionarse sin downtime, permite crear snapshots en cualquier momento y está diseñado para replicarse por defecto
      → El problema es que no está conectado directamente al servidor, sino a través de la red
  • Por más baja que sea la latencia de una conexión de red local, no puede ser menor que PCI/SATA
    → La red está en 1~2 ms, mientras que un disco conectado directamente está en 0.5 ms
  • Con los SSD locales, si ocurre un problema de hardware como en un HDD, se pierden los datos de ese disco, y si el problema ocurre en el host mismo ni siquiera es posible hacer snapshots, así que puede darse una pérdida total de datos
    → Por eso Discord no usa Local SSD y usa Persistent Disk

Análisis del problema

  • Lo ideal sería tener un dispositivo de almacenamiento que reuniera solo las ventajas de Local SSD y Persistent Disk, pero eso no existe. ¿Y si al menos se pudiera tomar parte de esas ventajas?
  • Para Discord, la latencia de escritura no era el problema. Lo que afecta el rendimiento es la "latencia de lectura"
  • "Redimensionar discos sin downtime" no es una función indispensable. El tamaño puede predecirse con anticipación
  • Los requisitos finales eran:
    • Seguir en GCP
    • Usar snapshots point-in-time para respaldo de datos
    • Dar máxima prioridad a minimizar la latencia de lectura
    • No sacrificar la garantía de uptime de la base de datos existente
  • Parecía ideal leer desde Local SSD de GCP y escribir en Persistent Disk
    → ¿Se podría crear un super-disco así a nivel de software?

Crear el Super-Disk

  • El requisito en esencia era un caché write-through. Usar Local SSD de GCP como caché y PD como capa de almacenamiento
  • Como los servidores de base de datos usan Ubuntu, podían aplicar caché a nivel de disco desde el kernel de Linux (módulos como dm-cache, lvm-cache y bcache)
  • Pero al experimentar vieron que, si aparecían sectores defectuosos en el disco de caché, fallaba toda la operación de lectura
    • Cuando aparecen sectores defectuosos, debería leerse desde la capa de almacenamiento y sobrescribirse, pero las soluciones de caché de disco que evaluaron no tenían esa capacidad
    • Si ocurrían sectores defectuosos, la base de datos terminaba apagándose por problemas de integridad de datos
  • Entonces se agregó un requisito adicional: "debe sobrevivir incluso si aparecen sectores defectuosos en el Local SSD"
  • Por eso investigaron md del kernel de Linux
    • md permite crear RAID por software
    • Hacer mirroring entre SSD y PD no resolvía el problema, porque más de la mitad de las lecturas terminarían viniendo desde PD
    • md tiene una opción llamada write-mostly que no existe en los RAID tradicionales
      • Si se marca un disco como write-mostly, se excluye de las lecturas normales y solo se lee desde él cuando no hay otra opción. Es "útil para dispositivos conectados lentamente"
      • Es decir, si se agrupan SSD y PD en RAID1 y se configura PD como write-mostly, se pueden cumplir los requisitos
  • El último problema que quedaba era que los Local SSD de GCP tienen un tamaño fijo de 375 GB
  • Para ciertas aplicaciones, Discord necesita más de 1 TB por instancia de base de datos
  • Así que decidieron agrupar varios SSD en RAID0
  • La forma final quedó así:
    • 4 Local SSD agrupados en RAID0 como md0
    • md0 y Persistent Disk agrupados en RAID1 para formar md1

Rendimiento de la base de datos

  • El resultado fue exactamente el esperado
  • Incluso en picos de carga, las operaciones de disco no se acumulan en cola y la latencia de las consultas no cambia
  • El rendimiento mejoró, así que aumentó la cantidad de consultas que cada servidor puede procesar
  • Quienes hayan usado RAID quizá se pregunten si esto realmente "simplemente funciona", pero en la práctica ocurrieron muchas cosas, y el resto lo explicarán con más detalle por separado

3 comentarios

 
eajrezz 2022-08-19

Antes no estaban satisfechos con el rendimiento de golang, y viendo que hasta programan servidores en rust, parece que el nivel de "geekismo" de la empresa Discord también es impresionante.

 
psyrenpark 2022-08-17

Se siente como intentar tapar algo pequeño con una herramienta enorme.

 
xguru 2022-08-17

En HN también se comenta si eso no será simplemente un problema de GCP, pero... https://news.ycombinator.com/item?id=32474093
Creo que vale la pena al menos tener en mente que este tipo de intento también es posible.