Cómo Notion resolvió su crisis de escalabilidad
En 2021, la popularidad de Notion se disparó, pero su servicio se volvió insoportablemente lento. La base de datos de la empresa posterior a la crisis tenía terabytes de volumen, incluso comprimida, y estaba a punto de explotar. Ante la posibilidad de perder clientes, Notion necesitaba resolver este problema rápidamente.
En esencia, todo en Notion es un bloque, que puede ser un fragmento de texto, una imagen o una página completa. Cada bloque se almacena como un RLE en PostgreSQL con su propio ID único. Los bloques pueden anidarse dentro de otros bloques para crear estructuras complejas en forma de árbol, lo que permite una versatilidad increíble. Sin embargo, esta estructura también significa que incluso un documento simple puede resultar en cientos o miles de entradas en la base de datos.
Con millones de usuarios, la base de datos de Notion se vio abrumada, lo que provocó un aumento de la latencia y respuestas retrasadas. La base de datos monolítica única de la empresa ya no podía manejar la carga, y los costos aumentaban exponencialmente.
La solución: Escalabilidad horizontal
Notion decidió realizar el sharding de todas las tablas vinculadas a la tabla de bloques a través de claves foráneas. Esto incluyó espacios de trabajo, debates y comentarios, manteniendo los datos relacionados en el mismo shard. La clave de partición se eligió como el ID del espacio de trabajo, ya que los usuarios normalmente solicitan datos para un solo espacio de trabajo a la vez.
La nueva configuración de sharding debía manejar los datos existentes y escalar para satisfacer el crecimiento proyectado durante al menos dos años. El tipo de instancia necesitaba al menos 60k IOPs totales, y para mantener la replicación de RDS, establecieron límites de 500 GB por tabla y 10 terabytes por instancia física.
Después de una cuidadosa consideración, Notion decidió crear 32 instancias de base de datos físicas, con cada instancia conteniendo 15 shards lógicos separados. Esto resultó en un total de 480 shards en las 32 bases de datos físicas.
El mecanismo de enrutamiento
El mecanismo de enrutamiento se determinó a nivel de aplicación para determinar dónde se almacenan los datos. La aplicación utiliza el aprovisionamiento de distribución de carga de instancias más pequeñas para nuevos shards y espera reducir la CPU, los IOPs y los costos.
El plan de migración
El plan de migración de Notion implicó agregar 96 nuevas entradas al PG bouncer, reflejándolas temporalmente en los 32 shards existentes. Esto les permitió migrar gradualmente los datos a los nuevos shards a medida que se escribían datos en la nueva base de datos.
Sin embargo, las pruebas descubrieron un problema crítico: dado que cada shard antiguo se mapeaba a tres nuevos shards, necesitaban reducir la cantidad de conexiones por instancia de PG bouncer o aumentarla por 3. La solución fue crear un gráfico del clúster PG bouncer, creando cuatro nuevos clústeres, cada uno administrando 24 bases de datos. Esto les permitió aumentar las conexiones por PG bouncer por shard a 8, limitando las conexiones totales por instancia de Postgres a 200.
Lecturas oscuras y pruebas
Antes de implementar estos cambios en producción, Notion implementó lecturas oscuras para realizar pruebas. Agregaron una funcionalidad para obtener datos de las bases de datos antiguas y nuevas cuando se realizaban solicitudes, comparando los resultados para verificar la coherencia y bloqueando cualquier discrepancia para evitar afectar la experiencia del usuario.
El proceso de conmutación por error
El proceso de conmutación por error implicó una pausa del tráfico, deteniendo nuevas conexiones mientras se permitía que las consultas en curso se completaran, una verificación de replicación, asegurando que las nuevas bases de datos estuvieran completamente actualizadas, y actualizaciones de configuración. El acceso de la aplicación a las bases de datos antiguas se revocó, y el PG bouncer se actualizó para apuntar a las nuevas bases de datos, invirtiendo la dirección de replicación mediante la transmisión de cambios de las nuevas bases de datos a las antiguas por si acaso.
Resultado
El proyecto de re-sharding fue un éxito significativo para Notion. Los resultados clave incluyeron:
- Mayor capacidad
- Rendimiento mejorado
- La utilización de CPU e IOPs disminuyó drásticamente, con una nueva utilización que ronda el 20% durante el tráfico máximo, en comparación con el 90% anterior.
Esta nueva arquitectura posiciona a Notion para manejar el crecimiento continuo de usuarios y las demandas de datos.