Cómo Discord redujo el tráfico de WebSocket en un 40%
Discord, una popular plataforma de comunicación, tenía un problema significativo en sus manos. Su servicio de comunicación en tiempo real, Gateway, estaba consumiendo cada vez más recursos, lo que llevó a costos crecientes estimados en cientos de miles de dólares. Este era un problema importante para la empresa hasta que descubrieron una forma de reducir el tráfico en un 40%.
Servicio de comunicación en tiempo real de Discord
Gateway, un servicio que proporciona actualizaciones instantáneas a los clientes, ha estado utilizando la compresión zlib para estas conexiones desde 2017. zlib es una biblioteca de compresión de datos ampliamente utilizada que proporciona compresión sin pérdida. Está diseñada para ser compacta, rápida y portátil, lo que la hace adecuada para una variedad de aplicaciones.
Cómo funciona la compresión zlib
La compresión zlib combina la codificación LZ77 y Huffman. La compresión LZ77 funciona manteniendo una ventana deslizante de tamaño n de datos previamente vistos y una ventana de anticipación de tamaño M. Busca la coincidencia más larga entre la ventana de anticipación y la ventana deslizante. La salida consiste en una secuencia de literales y referencias cruzadas a la ventana deslizante.
La codificación Huffman es un método de encodear datos utilizando códigos de longitud variable. Asigna códigos más cortos a caracteres más frecuentes, reduciendo el tamaño general de los datos.
Compresión de streaming
El equipo de Discord experimentó con la compresión de streaming, que permite al compresor mantener el contexto a través de múltiples mensajes. Esto permite al compresor optimizar la compresión basándose en datos históricos sin tener que empezar de nuevo con cada mensaje.
Sin embargo, el servicio Gateway de Discord estaba escrito en un lenguaje antiguo, y no podían encontrar bindings existentes que ofrecieran esta funcionalidad. Para superar esta limitación, el equipo bifurcó el repositorio y agregó soporte de streaming. Luego contribuyeron esta mejora al proyecto original.
Experimentos y optimizaciones
El equipo de Discord experimentó con varios algoritmos de compresión y parámetros para lograr la mejor relación de compresión. Se centraron en tres parámetros clave: cadena de bloqueo, bloqueo de hash y bloqueo de ventana. Estos parámetros ofrecen untrade-off entre velocidad de compresión, uso de memoria y relación de compresión.
Después de experimentar con diferentes settings, se establecieron en configuraciones ligeramente superiores a las predeterminadas, lo que proporcionó una compresión mejorada mientras se ajustaba cómodamente dentro de las restricciones de memoria del nodo de gateway.
Actualización pasiva v2
El equipo también notó que la actualización pasiva v1, que representaba más del 35% del ancho de banda de Gateway, estaba enviando información innecesaria. Crearon la actualización pasiva v2, que solo envía la información requerida, reduciendo el uso de actualización pasiva del 35% al 5% del tráfico total de Gateway.
Implementación y lanzamiento
El equipo implementó Zstandard para usuarios de escritorio, lo que involucró encontrar y integrar bindings apropiados de Zstandard para cada plataforma. También tuvieron que escribir sus propios bindings para Rust.
Para minimizar el riesgo de un cambio tan grande, el lanzamiento se realizó detrás de una flag de características, lo que permitió un rollback rápido si surgían problemas, ayudó a validar los resultados y habilitó la supervisión y las métricas de baseline para asegurarse de que los cambios no afectaban negativamente la experiencia del usuario.
Resultados
Después de todos los cambios, Discord redujo su ancho de banda de Gateway en casi un 40%. Este es un gran logro, ahorrándoles cientos de miles de dólares al año.