Video Summary and Transcription
La charla de hoy analiza diferentes enfoques para implementar actualizaciones en tiempo real en aplicaciones del lado del servidor, incluyendo actualizaciones a nivel de aplicación y polling. Las desventajas del polling incluyen ineficiencia y complejidad a gran escala. Agregar infraestructura adicional, como sistemas de mensajería, puede garantizar la escalabilidad pero introduce una sobrecarga operativa. Prisma Pulse es un sistema que simplifica el cambio de captura de datos, proporcionando una configuración fácil para suscribirse a los cambios en la base de datos y resolver problemas de escalabilidad.
1. Arquitecturas de Aplicaciones en Tiempo Real
¡Hola a todos! Hoy discutiré diferentes enfoques para implementar actualizaciones en tiempo real en el lado del servidor de una aplicación en tiempo real. El primer enfoque son las actualizaciones a nivel de aplicación, donde el servidor de la aplicación se encarga de todo. Sin embargo, este enfoque no escala horizontalmente y sufre del problema de escritura dual. Otro enfoque es la consulta periódica, donde el servidor de la API solicita periódicamente actualizaciones a la base de datos. Este enfoque consume muchos recursos debido al alto número de consultas. Vamos a explorar estos enfoques en detalle.
¡Hola y bienvenidos a todos a mi charla de hoy sobre cómo no construir aplicaciones en tiempo real! Mi nombre es Nikolas Berg. Trabajo como defensor del desarrollador en Prisma, donde nos enfocamos en la experiencia del desarrollador para aquellos que trabajan con bases de datos. Hoy los llevaré en un viaje donde, primero, estableceremos el escenario sobre la arquitectura de una aplicación en tiempo real. Luego hablaré sobre tres enfoques diferentes para implementar actualizaciones en tiempo real en el lado del servidor y sus compensaciones. Y luego sacaremos algunas conclusiones. Así que empecemos y asumamos que están en una entrevista de trabajo y esta es su entrevistadora. Y esta es la pregunta que les hace. ¿Cómo diseñarían una aplicación de chat en tiempo real? Bueno, si son como yo, probablemente comenzarán hablando sobre este diagrama de arquitectura de tres niveles y que en el frontend usarán WebSockets para crear conexiones permanentes entre los clientes de la API, entre el navegador y los servidores de la API. Pero mi charla de hoy se trata realmente de la segunda parte, sobre la conexión entre el servidor de la API y la base de datos y cómo implementar actualizaciones en tiempo real allí. Entonces, ¿cómo aprende el servidor de la API sobre cualquier cambio en la base de datos? Esa es la gran pregunta de hoy. Y quiero hablar sobre tres enfoques diferentes. El primero lo llamo actualizaciones a nivel de aplicación, luego hablaré sobre la consulta periódica y luego agregar infraestructura adicional. Con las actualizaciones a nivel de aplicación, realmente permiten que el servidor de la aplicación maneje todo. Y comprendamos rápidamente cómo funciona con un escenario simple aquí. Así que supongamos que tenemos esta aplicación de chat, tenemos tres usuarios conectados al servidor de la API, Alice, Bob y Jane, y tienen estas conexiones WebSocket al servidor de la API. Ahora, primero, supongamos que Alice envía un mensaje al servidor de la API, el servidor de la API almacena ese mensaje en la base de datos y luego el servidor de la API es responsable de transmitir ese mensaje a Bob y Jane. Entonces, ¿qué podría salir mal en ese escenario? Una vez que comencemos a ver un poco más de tráfico y queramos escalar nuestra aplicación y nuestros servidores de API horizontalmente, tendremos el problema de que Alice y Bob podrían estar conectados al primer servidor de API y Jane estaría conectada a la segunda instancia del servidor de API. Debido a que estas conexiones WebSocket son permanentes, Jane no recibirá la actualización del servidor de API cuando Alice envíe un mensaje. Entonces, este enfoque no escala horizontalmente. También tenemos el problema del llamado problema de escritura dual porque el servidor de la API necesita hacer dos cosas. Necesita almacenar los datos en la base de datos y necesita transmitir el mensaje a todos los clientes conectados. ¿Qué sucede si una de estas operaciones falla? Esta es una situación bastante complicada a la que volveré en un momento. Ahora revisemos rápidamente los pros y los contras de este enfoque de actualizaciones a nivel de aplicación. Los pros son que es bastante fácil de entender, no se necesita infraestructura adicional, pero el problema es que no es posible escalar esto horizontalmente y también se sufre del problema de escritura dual aquí. Así que veamos otro enfoque y eso es la consulta periódica. Con este enfoque, simplemente permitimos que el servidor de la API solicite periódicamente actualizaciones de la base de datos enviando la misma consulta a la base de datos una y otra vez. ¿Qué podría salir mal con este enfoque? El problema aquí es que consume muchos recursos. Supongamos que tenemos N usuarios y por usuario, tenemos M consultas periódicas. Esto se vuelve muy intensivo en recursos con N veces M consultas para cada intervalo de consulta.
2. Enfoques de Actualización en Tiempo Real: Consulta Periódica
La consulta periódica es un enfoque ineficiente para las actualizaciones en tiempo real, ya que desperdicia recursos y se vuelve complejo de gestionar a gran escala. Los ingenieros deben buscar soluciones elegantes que aborden los desafíos planteados por el dominio empresarial.
Si estás consultando periódicamente cada par de milisegundos, eso es muy malo porque estás desperdiciando muchos recursos, muchas conexionesdatabase en el lado de la database, pero también en el lado del servidor de la API. Es muy costoso y no es realmente un buen enfoque para este problema. Veamos los pros y los contras. Todavía es bastante fácil de entender. Entonces, si no tienes mucho tráfico, no necesitas infraestructura adicional, es bastante fácil de implementar y no tienes el problema de escritura dual, lo cual es bastante beneficioso. Entonces no te encontrarás en un estado inconsistente con respecto a tus data. Sin embargo, los contras son que consume muchos recursos una vez que estásscaling a múltiples usuarios y la lógica de la aplicación para comparar también se vuelve compleja rápidamente porque cada vez que llegan los resultados de una consulta a la database, necesitas comparar eso con el estado actual de lo que se ha almacenado en la database anteriormente. Y eso también se vuelve realmente complicado. Y siendo honestos, creo que fundamentalmente la consulta periódica no es la herramienta adecuada para el trabajo cuando hablamos de actualizaciones en tiempo real. Creo que como ingenieros, debemos tener la ambición de encontrar soluciones elegantes a los problemas que el dominio empresarial en el que operamos nos plantea.
3. Enfoques de Actualización en Tiempo Real: Infraestructura Adicional
Agregar infraestructura adicional, como sistemas de mensajería como Kafka o RabbitMQ, puede garantizar la escalabilidad. Sin embargo, la sobrecarga operativa y el problema de escritura dual lo hacen desafiante. La captura de datos de cambio proporciona una solución al permitir que la base de datos propague las actualizaciones al sistema de mensajería, asegurando un flujo de datos unidireccional. Sin embargo, la implementación de CDC es compleja y no es fácil de mantener.
Y realmente no creo que la consulta periódica califique aquí. Entonces, otro enfoque es agregar infraestructura adicional.
Puedes garantizar la escalabilidad utilizando sistemas de mensajería como Kafka o RabbitMQ. Nuevamente, veamos cómo funciona esto con un escenario simple de Alice, Bob y Jane nuevamente. Esta vez tenemos una cola de Kafka conectada a nuestro servidor de API y el primer paso es suscribirnos a un tema de Kafka. Luego recibimos el mensaje de saludo de Alice. El servidor de API escribe el mensaje en la base de datos y luego publica el evento en Kafka. A partir de ahí, recibe nuevamente el evento y luego puede transmitirlo a Bob y Jane.
Con este enfoque, resolvemos el problema de la escalabilidad horizontal que teníamos con las actualizaciones a nivel de aplicación. Pero la sobrecarga operativa de configurar y mantener infraestructura adicional es realmente notable. Y si has trabajado con Kafka antes, creo que sabes que no es el sistema más fácil de trabajar. Entonces, un segundo problema aquí sigue siendo el problema de escritura dual. Veamos un poco más en profundidad qué es esto realmente. Aquí vemos el código de cómo podría implementarse con Kafka cuando recibimos este mensaje de uno de nuestros usuarios.
En realidad, se refiere al primer paso que vimos en la secuencia anterior. El servidor de API recibe primero el mensaje y lo escribe en la base de datos, y luego lo envía al tema de Kafka al que van los mensajes de chat. Pero, ¿qué sucede si una de estas operaciones falla? Ahora te encuentras en un estado inconsistente porque tanto la base de datos ha almacenado datos que no han llegado a tus usuarios, o viceversa, tus usuarios están viendo datos que no están almacenados en la base de datos. De cualquier manera, es una situación muy indeseable y muy difícil de resolver. Por supuesto, podrías comenzar a implementar tu propia lógica de reintento o intentar envolver todo en una transacción, pero todo esto se vuelve muy complicado y también consume muchos recursos nuevamente.
Entonces, ¿cómo podemos resolver este problema a un nivel más profundo? Y la respuesta a eso es la captura de datos de cambio. La captura de datos de cambio es un patrón de diseño basado en la idea de un flujo de datos unidireccional. Y con eso, en realidad no es el servidor de API el que transmite las actualizaciones a nuestro sistema de mensajería, sino que estas actualizaciones se propagan directamente por la base de datos. Volvamos a recorrer el mismo escenario, pero esta vez utilizando un flujo de datos unidireccional y la captura de datos de cambio. Entonces, Alice nuevamente comienza enviando el mensaje al servidor de API y luego este lo almacena en la base de datos. Ahora la base de datos es responsable de publicar esta actualización en el sistema de mensajería. Y a partir de ahí, el servidor de API recibe la actualización del sistema de mensajería que estamos utilizando y puede transmitir el mensaje a todos los clientes suscritos. Ahora resolvemos de manera muy elegante este problema de los derechos duales y las posibles inconsistencias de datos cambiando la forma en que los datos fluyen a través de nuestro sistema. Entonces, ¿cuál es el inconveniente con CDC? Si tuviera que resumirlo, es realmente esto. Se vuelve complicado. Si quieres mantener y construir tu propio sistema de CDC, esto no es una tarea fácil.
4. Enfoques de Actualización en Tiempo Real: Prisma Pulse
Prisma Pulse es un sistema que implementa CDC, proporcionando cambios de base de datos seguros en tu aplicación. Ofrece una configuración sencilla para suscribirse a los cambios de la base de datos y resuelve problemas de escalabilidad. La solución al problema de escritura dual es la captura de datos de cambio, pero implementarla y mantenerla puede ser un desafío. Prisma Pulse simplifica el uso de la captura de datos de cambio en tus aplicaciones.
Y si eres una startup o en general, un equipo de desarrollo que está realmente enfocado en brindar valor a tus usuarios, no creo que este sea el lugar donde quieras gastar tu tiempo. Así que lo que quiero recomendarte hoy es que pruebes Prisma Pulse. Prisma Pulse es un sistema que implementa CDC, la idea de un flujo de datos unidireccional basado en los trabajadores de Cloudflare, leyendo el registro de escritura anticipada de tu base de datos Postgres. Proporciona cambios de base de datos seguros en tu aplicación y es muy fácil de entender y configurar.
Así es como se ve la suscripción a los cambios de la base de datos utilizando Prisma Pulse. Solo tienes esta línea donde en la tabla de mensajes, llamas al método de suscripción y luego inicias este iterador asíncrono y esperas eventos que están ocurriendo en la tabla de mensajes de la base de datos.
Entonces, ¿qué debemos recordar de esta charla? Desplegar aplicaciones en tiempo real conlleva mucha complejidad y los enfoques ingenuos como las actualizaciones a nivel de aplicación y la consulta periódica simplemente no son suficientes. No escalan. Debes introducir infraestructura adicional como Apache Kafka para garantizar la escalabilidad, pero el problema de escritura dual, incluso entonces, es desagradable y difícil de superar. La solución elegante a este problema se llama captura de datos de cambio, pero también es difícil de implementar, operar y mantener. Por lo tanto, Prisma Pulse te brinda la forma más fácil de usar la captura de datos de cambio en tus aplicaciones. Y eso es todo lo que tengo para ti hoy. Muchas gracias.
Comments