- Discord rediseñó por completo su infraestructura de búsqueda basada en Elasticsearch sobre Kubernetes para superar las limitaciones del sistema anterior, mejorando de forma drástica el rendimiento y la estabilidad del indexado de mensajes
- La cola existente basada en Redis tenía riesgo de pérdida de mensajes, pero fue reemplazada por PubSub, garantizando una entrega estable; al mismo tiempo, los mensajes se clasifican por clúster/índice para procesarse de forma eficiente
- Se introdujo una arquitectura de "celdas (cells)" para distribuir la carga en múltiples clústeres pequeños de Elasticsearch, resolviendo la sobrecarga de nodos y los problemas de actualización
- Los mensajes de DM individuales y los mensajes de servidores (
guild) se indexan en celdas separadas, sentando la base de la nueva función de búsqueda global en DM
- Las comunidades extremadamente grandes (BFGs) pueden escalar más allá del límite máximo de mensajes de Lucene mediante celdas dedicadas e índices con múltiples shards
Limitaciones de la infraestructura existente
- La cola de mensajes basada en Redis generaba cuellos de botella cuando fallaban nodos de Elasticsearch, con posibilidad de pérdida de mensajes
- Los clústeres grandes (más de 200 nodos) llegaban a una tasa de fallas de indexado del 40% por la caída de un solo nodo
- Los índices que alcanzaban el límite
MAX_DOCS de Lucene (2 mil millones de mensajes) provocaban una detención total del indexado
- Debido al envejecimiento del sistema, incluso aplicar el parche de log4shell requería poner todo el sistema fuera de línea
Estrategia de solución
Reconstrucción basada en Kubernetes
- Uso de Elastic Kubernetes Operator (ECK) para automatizar la operación de clústeres de Elasticsearch
- Ahora es posible realizar reinicios graduales, actualizaciones del sistema operativo y del software de forma segura
Distribución de clústeres con arquitectura de “celdas (cells)”
- En lugar de un único clúster monolítico, se construyeron varios clústeres pequeños agrupados en una celda
- Dentro de cada celda, se limita la cantidad de índices y se mantiene el tamaño de los shards en 50 GB y menos de 200 millones de mensajes
- Mejora el rendimiento de indexado y consultas, y reduce la carga de mantener el estado del clúster
Cola de mensajes basada en PubSub
- El cambio de Redis → PubSub permite mantener la cola sin pérdida de mensajes
- También se está ampliando el uso de PubSub a otras funciones, como la programación de trabajos
Indexado por lotes por clúster
- Los mensajes recibidos por PubSub se clasifican según el clúster e índice de destino y se procesan en paralelo como tareas separadas
- La estructura de procesamiento distribuido de mensajes se implementó con tasks y channels de tokio en Rust
Mejoras en la búsqueda
Búsqueda de DM basada en usuario
- Antes, los DM se indexaban por canal, por lo que la búsqueda global en DM era ineficiente
- Ahora, los mensajes de DM se indexan por duplicado en índices por usuario, permitiendo buscar en todos los DM de una sola vez
Soporte para BFG (Big Freaking Guilds)
- Se introdujeron índices con múltiples shards para comunidades gigantes que superan el límite de cantidad de mensajes de Lucene
- Los BFG se procesan en una celda dedicada de Elasticsearch con una estructura de múltiples primary shards
- Tras indexar por duplicado tanto en los índices existentes como en los nuevos, las consultas se migran gradualmente al nuevo destino
Resultados
- Indexado de billones de mensajes, con el doble de throughput de indexado frente a antes
- Velocidad de respuesta de consultas: promedio de 500 ms → 100 ms, p99 de 1 s → menos de 500 ms
- Más de 40 clústeres y miles de índices en operación
- Las actualizaciones de clúster y los reinicios graduales están totalmente automatizados y sin interrupciones del servicio
4 comentarios
Que hagan ese trabajo mientras lo operan... mis respetos.
La ingeniería de Discord siempre es un referente. Les tengo envidia.
No sabía qué era pubsub y resulta que era un IaaS que ofrece GCP.
https://cloud.google.com/pubsub?hl=en
Impresionante. También el hecho de rehacerlo todo para resolver el problema.