Escalando tu base de datos con ReadySet

Rate this content
Bookmark

La base de datos puede ser una de las partes más difíciles de escalar en una aplicación web. Muchos proyectos terminan utilizando sistemas de caché ad-hoc que son complejos, propensos a errores y costosos de construir. ¿Qué pasaría si pudieras implementar un sistema de caché listo para usar para mejorar el rendimiento y la optimización de consultas sin necesidad de realizar cambios en el código de tu aplicación?


Únete a los desarrolladores Aspen Smith y Nick Marino para ver cómo puedes cambiar una línea de configuración en tu aplicación y utilizar ReadySet para escalar el rendimiento de tus consultas en órdenes de magnitud hoy mismo.


33 min
12 Apr, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

ReadySet es una solución de caché lista para usar que mejora el rendimiento de la base de datos y la optimización de consultas. Admite la escalabilidad a múltiples nodos sin carga adicional en la base de datos y garantiza actualizaciones de caché en tiempo real. ReadySet acelera significativamente las consultas y reduce el tiempo de consulta, lo que lo convierte en un cambio de juego para las aplicaciones web. No está diseñado para aplicaciones con una gran carga de escritura, pero funciona mejor para cargas de lectura intensiva. Se fomenta la retroalimentación de la comunidad y hay disponible una versión en la nube de ReadySet para uso en producción.

Available in English

1. Introducción a la escalabilidad con ReadySet

Short description:

Vamos a hablar sobre cómo escalar tu base de datos con ReadySet. Explicaremos el problema que resuelve y haremos una demostración de su uso. Luego abriremos la sesión para preguntas.

Hola a todos. Soy Nick Marino. Hola, soy Griffin Smith. Y vamos a hablar sobre cómo escalar tu base de datos con ReadySet. Para resumir, vamos a comenzar dando un poco de información de fondo, explicar cuál es el problema que ReadySet intenta resolver y cómo lo hace. Luego, Griffin hará una demostración que muestra cómo usar ReadySet con una aplicación del mundo real y te dará una idea de algunos de los beneficios de rendimiento y características que puedes esperar ver allí. Y finalmente, después de eso, abriremos la sesión para preguntas que puedan tener.

2. Introducción a ReadySet

Short description:

ReadySet es un sistema de almacenamiento en caché para MySQL y PostgreSQL que te permite crear cachés para consultas SQL individuales sobre la marcha, lo que resulta en mejoras significativas de velocidad. El problema que resuelve es la dificultad de escalar una base de datos cuando tu aplicación se vuelve popular. Comenzar con una base de datos relacional de un solo servidor es común, pero a medida que tu idea tiene éxito, la base de datos lucha por mantenerse al día. Usar MySQL o Postgres inicialmente es conveniente, pero cuando se alcanzan los límites de escalabilidad, se convierte en un problema desafiante de resolver. El punto crítico para la experiencia del usuario en una aplicación web es el rendimiento de lectura, con la carga de una página web que se siente instantánea en alrededor de 200 milisegundos. Para escalar las lecturas de la base de datos, puedes optimizar las consultas, usar réplicas de lectura o considerar otras opciones.

Muy bien. Primero, ¿qué es ReadySet? Si miras el sitio web de ReadySet, dice que es un sistema de almacenamiento en caché para MySQL y PostgreSQL, lo cual es cierto. Cuando vi el sitio web por primera vez, pensé que tal vez era solo una envoltura alrededor de Redis o Memcached o una copia de algún tipo de sistema de almacenamiento en caché popular existente. Entonces, es algo así como un producto genial y útil, pero tal vez no algo revolucionario. Resulta que en realidad es mucho más que eso. Te permite crear rápidamente y fácilmente cachés para consultas SQL individuales sobre la marcha sin necesidad de realizar cambios en tu aplicación, aparte de tal vez un cambio de configuración o dos. Y, ya sabes, no quiero revelar demasiado de la demostración más adelante, pero en una de las consultas que hemos evaluado, vemos una mejora de velocidad de alrededor de 25,000 veces. Así que eso es bastante emocionante, creo. Pero antes de entrar en todo eso, hablemos del problema. Creo que esta cita resume bastante bien el problema que estamos tratando de resolver, así que la leeré en voz alta. La capa de acceso a datos de una idea millonaria comienza como una base de datos relacional de un solo servidor. No te preocupas mucho por los problemas de escalabilidad, tienes una aplicación que escribir. Sin embargo, si tu idea millonaria termina valiendo incluso 100,000, es probable que encuentres que tu base de datos lucha por mantenerse al día con la escala. Y esta es ciertamente una historia con la que personalmente estoy familiarizado. Sé que muchas personas ahí fuera también lo están. Cuando estás comenzando una startup o un sitio web y estás en una etapa muy temprana, no tienes realmente el tiempo y los recursos para construir algo utilizando la última moda de no-SQL, escalable del día, y no hay nada de malo en usar MySQL o Postgres. Son gratuitos, son muy populares, son fáciles de usar. Y cuando solo estás tratando de obtener una versión inicial simple de algo, un producto mínimo viable un prototipo, como quieras llamarlo, no quieres pasar demasiado tiempo lidiando con sistemas de escalabilidad realmente complejos y sofisticados. Solo quieres obtener algo que funcione. Pero, por supuesto, si y cuando alcanzas los límites de escalabilidad en tu database, puede ser un problema bastante complicado de resolver. Y es un buen problema para tener, pero a menudo ocurre en un punto bastante crítico en la vida de un sitio web o una organización. Entonces, si estamos analizando el problema al que nos enfrentamos aquí, solo quiero enmarcarlo de manera muy breve. Cuando estás escalando una aplicación web en producción, creo que lo primero en lo que realmente te importa a medida que alcanzas los límites de escalabilidad de un solo servidor de database es el rendimiento de lectura. Creo que para la mayoría de las aplicaciones web, ese es el punto crítico para la experiencia del usuario, hay un número que se cita y hay algunas investigaciones bastante extensas que muestran que cargar una página web se siente instantáneo en alrededor de 200 milisegundos. Y esos 200 milisegundos, la mayor parte del tiempo lo pasas leyendo datos de tu database. Entonces, si necesitas escalar esas lecturas de la database, si necesitas que esas lecturas de la database sean más rápidas, hay tres opciones principales de alto nivel que vas a tomar. Podrías pasar mucho tiempo optimizando tus consultas. Eso puede ser tan simple como agregar índices o algo más complicado. Podrías usar una réplica de lectura para escalar la capacidad de consulta. Entonces, si estás recibiendo muchas consultas, podrías usar réplicas de lectura para aumentar el número de consultas que puedes manejar.

3. Opciones para mejorar el rendimiento de la base de datos

Short description:

Crear una solución de almacenamiento en caché personalizada u optimizar consultas son opciones para mejorar el rendimiento de la base de datos. La optimización de consultas requiere experiencia y puede implicar luchar contra ORMs o bibliotecas de clientes. Los índices tienen un costo, aumentando el tiempo de escritura, el uso de disco y el uso de memoria. Además, dedicar tiempo a la optimización de consultas puede limitar la cantidad de funciones que puedes implementar.

Otra opción es construir una solución de almacenamiento en caché personalizada donde almacenas datos que se acceden con frecuencia y que no cambian mucho en algún tipo de almacén de clave-valor al que puedes acceder de forma muy rápida.

Todas estas opciones tienen sus compensaciones. Entonces, nuestra primera opción, la optimización de consultas, es algo que requiere mucha experiencia. Debes entender cómo funcionan las bases de datos SQL. Tienes esta idea de que tu base de datos debería poder realizar la consulta de la manera más rápida posible. Pero todos los servidores de bases de datos en el mercado, al menos los que conozco, necesitan un poco de ayuda para hacer esto. Como mencioné anteriormente, esto puede ser tan simple como agregar índices o tan complejo como cambiar por completo la forma en que se escribe la consulta. Y en este último caso, a menudo estás luchando contra tu ORM. Todos los que han utilizado un ORM han tenido este problema en el que el ORM quiere emitir consultas de una manera particular. Pero sabes que hay una forma diferente de escribir la consulta que podría devolver los mismos resultados y ejecutarse más rápido en la base de datos. Y tienes que luchar contra tu ORM o biblioteca de clientes. Incluso los índices tienen un costo, ¿verdad? Aumentan el tiempo necesario para realizar una escritura. Aumentan el uso de disco. Aumentan el uso de memoria. Nada de esto es gratuito. Lo otro importante es que tu aplicación está cambiando, ¿verdad? Si estás dedicando mucho tiempo a optimizar tus consultas, algún día agregarás una nueva función y una nueva consulta se volverá importante. Esto es algo que ocurre, todas las aplicaciones están cambiando todo el tiempo. Y si estás agregando este tiempo adicional para crear índices u optimizar consultas para cada función que tienes que escribir, significa que estás implementando menos funciones, ¿verdad? La segunda opción es escalar con réplicas de lectura.

4. Características y beneficios de ReadySet

Short description:

Escalar el número de consultas se puede hacer ejecutando réplicas de lectura, pero esto agrega una carga operativa. Construir una solución de almacenamiento en caché personalizada es otra opción, pero requiere escribir código, lidiar con la invalidación de caché y presenta desafíos operativos. ReadySet ofrece una solución que elimina las desventajas de estas opciones y te permite centrarte en desarrollar funciones para tus usuarios. Es una solución plug and play.

Sabes, esta es una forma bastante estándar de escalar el número de consultas que puedes manejar. Tanto Postgres como MySQL, estoy bastante seguro de que bifurcan procesos por conexión, por lo que tienen un límite superior en el número de conexiones que pueden manejar. Y así, puedes escalar el rendimiento ejecutando réplicas de lectura, pero esto tampoco es gratuito. Tus réplicas de lectura deben conectarse a tu database principal para transmitir el registro de replicación , lo que agrega carga a tu database principal. Y estás agregando una carga operativa significativa al ejecutar tu database en producción.

Entonces, esto sigue siendo mucho trabajo. Es un costo considerable. Y al final del día, solo estás mejorando el rendimiento, no la latencia, porque es el mismo motor de database, ejecutando la misma consulta, solo en otro servidor. Y luego, eso nos lleva a la tercera opción, que es construir esta solución de almacenamiento en caché personalizada. La idea aquí es ejecutar una consulta una vez, almacenar los resultados en algo como Redis o Memcached, y luego, si los data no han cambiado, puedes leer los data de Redis o Memcached. Pero esto, ya sabes, esto es mucho trabajo. Esto es código que tienes que escribir. Antes, tu aplicación solo hacía consultas SQL contra MySQL o Postgres. Ahora, tienes que, ya sabes, tienes un patrón de acceso totalmente diferente para acceder a estas cachés. Tienes que lidiar con la invalidación de las cachés en las escrituras. Y con frecuencia, esto es algo totalmente manual. Entonces, puedes introducir errores donde olvidas invalidar una caché en una escritura en particular. Y estos errores, ya sabes, he pasado meses de mi vida rastreando errores que al final, ya sabes, resultó que simplemente olvidamos invalidar la caché en una escritura. Y aún estás agregando carga operativa, porque tienes que ejecutar este servicio adicional. Y hay muchos otros problemas, ya sabes, pequeños problemas marginales que vienen con ejecutar estas cachés. Ya sabes, la recuperación y conmutación por error, ejecutar estas cachés en un escenario distribuido puede ser realmente complicado. Y tienes este problema donde, debido a la invalidación en las escrituras, si tienes muchas escrituras, entonces debes ejecutar la consulta nuevamente contra tu database principal. Y tienes este problema de manada rugiente, donde, ya sabes, si un montón de personas solicitan los mismos data contra una entrada de caché invalidada, ya sabes, puedes poner mucha carga en tu database principal y, ya sabes, causar muchos problemas en producción.

Pero la idea aquí, la idea detrás de ReadySet es que estas tres opciones no son muy buenas. Y sería genial si no tuviéramos que hacer ninguna de ellas. Ya sabes, queremos centrarnos, en lugar de centrarnos en, ya sabes, escalar nuestra database, queremos centrarnos en desarrollar funciones que nuestros usuarios deseen, ya sabes, hacer felices a nuestros clientes. Y todo este problema de escalar la database es algo que distrae. Entonces, esto nos lleva a lo que creo que es tan emocionante de ReadySet, es que te permite escalar sin lidiar con ninguno de esos problemas de los que hablamos anteriormente y que Griffin mencionó en las últimas diapositivas. Entonces, esto muestra algunas de las características más emocionantes de ReadySet. Número uno, es plug and play.

5. Rediset: Solución de almacenamiento en caché plug and play

Short description:

Rediset es una solución de almacenamiento en caché plug and play que utiliza el mismo protocolo que Postgres y MySQL. Te permite utilizar el mismo código y las mismas bibliotecas de cliente sin realizar ningún cambio. Rediset es flexible, lo que te permite activar y desactivar la caché para consultas individuales y experimentar fácilmente con el rendimiento de la caché. Es altamente escalable, proporcionando latencias de lectura rápidas y eficientes, y admite la escalabilidad a múltiples nodos sin agregar carga adicional a la base de datos. Rediset también garantiza actualizaciones en tiempo real de la caché a medida que llegan nuevos datos a la base de datos.

En primer lugar, es plug and play. Por lo tanto, utiliza el mismo protocolo que Postgres y MySQL. Esto significa que, a diferencia de una solución de almacenamiento en caché personalizada donde tendrías que integrar, por ejemplo, una biblioteca de cliente de Redis en tu aplicación, e incluso necesitarías hablar múltiples protocolos, para poder comunicarte directamente con la database principal si necesitas retroceder en caso de que haya un problema con la caché, simplemente utilizas el mismo código y las mismas bibliotecas de cliente que ya estás utilizando. Hemos implementado todo el protocolo de comunicación para estas bases de datos existentes. Por lo tanto, no tienes que cambiar ningún código en tu aplicación. Solo tienes que cambiar una línea de configuración, por lo general, para apuntar tu aplicación a Rediset en lugar de la database.

En segundo lugar, es muy flexible. Podemos activar y desactivar la caché para consultas individuales a voluntad. Esto facilita mucho la iteración rápida sobre el impacto del performance de la caché. Puedes realizar experimentos. Puedes ver qué sucede si almaceno en caché esta consulta, qué sucede si almaceno en caché esta otra consulta? ¿Cómo afecta al performance? ¿Cómo afecta al uso de memoria? Facilita mucho la realización rápida de este tipo de experimentos, obtener resultados, ver qué funciona.

Además, Rediset es muy, muy escalable. Ya lo mencioné un poco antes, pero cuando realizas una lectura de una consulta que ha sido almacenada en caché y la caché está disponible, es simplemente una búsqueda en un HashMap. Por lo tanto, es muy rápido y eficiente. Por lo general, incluso podemos ver latencias de menos de un milisegundo allí. Además, si los beneficios de performance que obtienes de un solo nodo de Rediset no son suficientes, o no tienes suficiente memoria en una sola máquina, también admitimos la escalabilidad a múltiples nodos. Por lo tanto, no solo obtienes más margen y espacio en términos de performance, sino que además, una de las cosas interesantes de este enfoque es que aún actuamos desde la perspectiva de la database principal como una única réplica de lectura. Por lo tanto, en la diapositiva de la réplica de lectura que Griffin mostró anteriormente, si tienes más réplicas, todas reciben actualizaciones de la database principal, por lo que se agrega más carga debido a que las réplicas adicionales necesitan recuperar actualizaciones y replicar los datos. Pero con Rediset, actúa como una única réplica. Toda la escalabilidad en una configuración de múltiples nodos ocurre internamente en Rediset. Por lo tanto, no necesariamente incurres en carga adicional en tu database solo al agregar más nodos de Rediset.

Por último, este último punto, latencia negativa, puede sonar como una palabra de moda, pero permíteme explicar lo que quiero decir aquí. La latencia es el lapso de tiempo entre cuando solicitas un resultado y cuando llega el resultado en. Y parte de la gran idea de Rediset es que estamos actualizando continuamente los resultados de tu caché a medida que llegan nuevos datos antes de que los solicites. Entonces, a diferencia de una solución de almacenamiento en caché personalizada donde tal vez, ya sabes, tienes que invalidar las cosas periódicamente. Y luego, cuando solicitas los nuevos data, es temporalmente más lento porque tiene que volver a ejecutar la consulta. Constantemente intentamos mantener actualizados los resultados de tu caché en tiempo real a medida que llegan nuevos datos a la database y se replican en Rediset. Para mostrar cómo funciona esto un poco, tenemos este pequeño diagrama aquí. Lo que puedes ver aquí es que cuando tu aplicación realiza escrituras en la database, es decir, inserciones, actualizaciones, eliminaciones. Va directamente a la database, pero luego Rediset actúa como una réplica de lectura, y solo recibe actualizaciones de la database utilizando el mismo protocolo que usaría una réplica de lectura.

6. Puesta en marcha de Rediset

Short description:

Rediset utiliza el mismo protocolo y replicación que la base de datos. Mantiene las cachés actualizadas y proporciona una mejora significativa de velocidad. El proceso de configuración de Rediset es sencillo: ejecuta Rediset apuntando a tu base de datos y cambia la configuración en tu aplicación. Rediset funciona con las bibliotecas de cliente de Postgres y MySQL. Se realizará una demostración en vivo utilizando cal.com, una aplicación de producción real construida con Next.js y Prisma. Rediset almacena en caché consultas importantes, mejorando el rendimiento.

Como sabes, no necesitas ningún tipo de complemento o cambios sofisticados en la base de datos. Aún utiliza el mismo protocolo y replicación, así como las consultas. Y luego, Rediset utiliza esas actualizaciones replicadas para mantener tus cachés actualizadas, de modo que cuando la aplicación solicite un resultado de consulta, con suerte lo obtenga directamente de Rediset sin ninguna demora adicional de lectura en frío o algo así. Genial.

A continuación, te mostraré el proceso de puesta en marcha de Rediset. Hemos trabajado mucho para que el proceso de configuración de Rediset sea lo más sencillo posible. Realmente hay dos pasos en este proceso. Primero, ejecuta Rediset apuntando a tu base de datos, y luego cambia la configuración en tu aplicación para que apunte a Rediset. Como dijo Nick, hablamos el lenguaje de las bibliotecas de cliente de Postgres y MySQL, como el protocolo de conexión para Postgres y MySQL. Por lo tanto, si tu aplicación ya está conectada a una de esas bases de datos, simplemente puede conectarse a Rediset. Y luego, simplemente funciona. Puedes almacenar en caché consultas y experimentar con cuáles se almacenan en caché y cuáles no, y idealmente ver una mejora significativa de velocidad.

A continuación, realizaré una demostración en vivo utilizando cal.com. Cal.com es una aplicación de código abierto. Es una aplicación de producción del mundo real. No la escribimos. No participamos en la escritura de esta aplicación. La elegimos por varias razones. Primero, es una aplicación del mundo real. Por lo tanto, la idea aquí es que este escenario sea lo más realista posible para ejecutar Rediset. Está construida con Next.js y Prisma. Por lo tanto, es una pila que esperamos que sea relevante para parte de la audiencia aquí. Como dije, es madura. Tiene muchas consultas, algunas simples, otras que han pasado por mucha optimización y otras que son muy lentas. Algunas de esas consultas no se pueden almacenar en caché en Rediset. Como dijo Nick, no podemos almacenar en caché todo, porque aún estamos trabajando para admitir todo el SQL. Pero la idea es que no tenemos que almacenar en caché todo, solo almacenamos en caché las consultas que son más importantes y críticas para el rendimiento de la aplicación. También elegimos Cal.com porque es bastante fácil de configurar.

7. Ejecución de Cal.com con ReadySet

Short description:

Es una aplicación de Node.js. Simplemente ejecutas un comando de Yarn y las cosas funcionan. Esta es Cal.com, una versión de código abierto de Calendly. Permite a las personas reservar tiempo en tu calendario, crear diferentes tipos de eventos e incluso eventos grupales. Al ejecutarlo con Postgres, con aproximadamente 10 millones de filas en la tabla de reservas, el tiempo de carga de la página aumenta significativamente. Sin embargo, al cambiar a ReadySet, se resuelve este problema y la aplicación sigue funcionando sin problemas.

Es una aplicación de Node.js. Simplemente ejecutas un comando de Yarn y las cosas funcionan. Voy a cambiar para hacer esa demostración.

Esto es Cal.com. Lo tengo ejecutando en un navegador web aquí. Se está ejecutando a través de un servidor de desarrollo en mi máquina local aquí. La aplicación es básicamente, si están familiarizados con Calendly, es básicamente como una versión de código abierto de Calendly. La idea aquí es que puedes crear tipos de eventos que permitan a las personas reservar tiempo en tu calendario sujeto a tu disponibilidad y luego las personas pueden reservar diferentes tipos de eventos en tu calendario. Algunos de esos eventos pueden ser recurrentes. Pueden tener enlaces de reunión asociados. Puedes crear eventos grupales con personas. Es en realidad una aplicación bastante agradable.

Esto es Cal.com ejecutándose tal cual, apuntando a Postgres. Puedes ver que acabo de hacer clic en la pestaña de reservas aquí. Solo para demostrar, con ReadySet, he generado alrededor de 10 millones de filas en esta tabla de reservas. Toma un poco de tiempo cargar esta página cuando estamos ejecutándola solo con Postgres. Así que es un gran ejemplo de lo que sucede cuando de repente tu aplicación experimenta una cantidad inesperadamente alta de carga. Y podemos ver que las cosas realmente se ralentizan. Sí.

Como dije, estoy ejecutando Cal.com localmente. Vamos a pasar por el proceso de apuntar esto a ReadySet. También estoy ejecutando ReadySet localmente en mi máquina. Se está ejecutando en el puerto 5435. Entonces, todo lo que tengo que hacer para cambiar a ReadySet es ir a mi configuración, que es solo un archivo punto end. Y cambiar el puerto. Luego puedo ejecutar el servidor de desarrollo nuevamente, y tomará un segundo compilar, porque es un servidor de desarrollo, por lo que está recompilando todo. Y solo para ser más claro, normalmente probablemente tendrías que cambiar más que solo el puerto. Pero Griffin está ejecutando todo en una sola máquina, por lo que sucede que el cambio de URL para apuntar a ReadySet es bastante mínimo en este caso. Sí, eso es correcto. Pero podemos ver una vez que Next.js compila todo que todavía puedo hacer clic y la aplicación sigue funcionando perfectamente bien.

8. Caching Queries and Intelligent Caching

Short description:

No veo ninguna mejora en esta página de reservas. ReadySet realiza un seguimiento de las consultas que no están en caché y las redirige a la base de datos de origen. Las consultas se almacenan en caché para usuarios específicos que solicitan los datos, según marcadores de posición en las declaraciones preparadas. ReadySet almacena en caché de manera inteligente las consultas para diferentes identificadores de usuario. Puede mejorar significativamente el rendimiento de una consulta que funciona mal.

Sigo obteniendo los mismos resultados en todas partes. Pero en realidad no he almacenado en caché ninguna consulta, por lo que no veo ninguna mejora en esta página de reservas. Lo que podemos hacer, hay algunas formas de explorar cómo se ve almacenar en caché consultas individuales. Una opción es ver que solo estoy registrando las consultas aquí. Prisma registra por defecto las consultas que se ejecutan. Así que puedes ver que hay muchas consultas en los registros aquí.

ReadySet también realiza un seguimiento de todas las consultas que no estamos almacenando en caché. Cuando no almacenamos en caché una consulta, la redirigimos a la base de datos de origen. Puedo obtener una lista de esas consultas simplemente conectándome a ReadySet a través de una shell de PSQL como he hecho aquí, y luego ejecutando show proxy queries. Y eso me da una lista de todas las consultas que ReadySet está redirigiendo a la base de datos de origen, junto con si esta consulta se puede almacenar en caché. Y, como puedes ver, esta aplicación está ejecutando bastantes consultas.

Y para ser claro, cuando decimos la palabra consulta aquí, es útil ser preciso acerca de lo que estamos hablando aquí. Realmente, creo que la forma más fácil de entender esto es mediante declaraciones preparadas. Entonces puedes ver, cuando Prisma ejecuta una consulta, tenemos estos marcadores de posición con el signo de dólar aquí. ReadySet también piensa en las consultas en términos de que una consulta es la misma consulta modulo un valor particular para un marcador de posición en una declaración preparada. Y cuando almacenamos en caché una consulta, en realidad estamos diciendo que queremos poder almacenar en caché conjuntos de resultados individuales para valores de esos marcadores de posición. Así que puedes imaginar una consulta para cargar data para un usuario en particular filtrando por un ID de usuario. Almacenamos en caché una consulta y decimos almacenar en caché esta consulta para todos los valores del ID de usuario, excepto que no almacenamos en caché conjuntos de resultados en memoria para cada usuario individual. Solo almacenamos los conjuntos de resultados de la consulta para los usuarios que realmente están solicitando esos data. Entonces, para los usuarios que realmente inician sesión. Y la idea aquí es, ya sabes, si tienes una aplicación, es posible que tengas miles o incluso millones de usuarios en tu base de datos, pero solo unos pocos inician sesión en un semana en particular. Ya sabes, hay esta especie de distribución normal de registro de qué usuarios están iniciando sesión. Tienes tus usuarios realmente activos y luego tus usuarios que nunca abren la aplicación. Y para un usuario que nunca inicia sesión, no queremos gastar memoria ni recursos para mantener los data en la caché para esos usuarios. Entonces, lo que hará ReadySet es que solo almacenaremos data en memoria para las consultas que realmente los conjuntos de resultados que realmente se están solicitando. Y luego, a medida que tengamos presión de memoria, los eliminaremos según el uso menos reciente. Y si todo esto suena un poco abstracto, creo que la idea principal aquí es que si le dices que almacene en caché, ya sabes, selecciona todo de usuarios donde el ID de usuario es igual a 14, no solo va a almacenar en caché el resultado donde el ID de usuario es igual a 14. En realidad, es lo suficientemente inteligente como para generalizar a partir de eso y almacenar en caché la misma consulta para otros ID de usuario también. Sí. Así que hice algunas pruebas con esta aplicación de antemano y encontré una consulta que, ya sabes, funciona particularmente mal y que ReadySet puede ayudar bastante.

9. Acelerando Consultas con Ready Set

Short description:

Para acelerar esta consulta con Ready Set, puedes almacenar en caché los conjuntos de resultados de la consulta y solo almacenar los conjuntos de resultados para los ID de usuario que realmente se leen. Esto reduce significativamente el tiempo de la consulta de aproximadamente 700 milisegundos a una fracción de milisegundo, lo que permite que la carga de la página se ajuste al presupuesto de 200 milisegundos. Es un cambio de juego.

Entonces, hay esta consulta, tiene un par de agregados, tiene, ya sabes, estoy en una cuenta y está filtrando por, como dije, filtrando por ID de usuario. Y esto es, ya sabes, no estoy completamente familiarizado con cal.com, pero solo leyendo la consulta, parece que esto está obteniendo el evento recurrente más temprano. Entonces puedes tener eventos recurrentes y es posible que desees obtener la próxima reserva para un evento recurrente en particular. Y podemos ver si ejecuto esta consulta, sé que mi ID de usuario es 14, así que estoy filtrando por 14, por el ID de usuario 14. Si ejecutamos esta consulta en Postgres, sin caché de Ready Set, podemos ver que lleva bastante tiempo. Mencioné anteriormente que la mayoría de las cargas de página tienen un presupuesto de aproximadamente 200 milisegundos para que la carga de la página se sienta instantánea, subjetivamente, para el usuario, y una carga de página en particular podría hacer decenas de consultas. Por lo tanto, realmente necesitas que cada consulta individual sea bastante rápida para ajustarse a ese presupuesto de 200 milisegundos, y esta consulta por sí sola ya está superando ese presupuesto por un factor de tres. Así que veamos el proceso de acelerar esta consulta con Ready Set. Entonces, si quiero almacenar en caché esta consulta, todo lo que tengo que hacer es tomar la consulta y agregar, crear, caché, from, nuevamente, todo esto solo en una shell de PSQL. Y ahora Ready Set va a almacenar en caché los conjuntos de resultados de esa consulta y, como dijo Nick, podrá decir, okay, sabemos que este ID de usuario es 14 aquí, pero en realidad vamos a almacenar conjuntos de resultados para cualquier ID de usuario y luego, como dije, solo almacenar los conjuntos de resultados para los ID de usuario que realmente se leen. Entonces, ahora, después de crear la caché, si ejecuto la consulta nuevamente, tomará un segundo para precalcular los conjuntos de resultados la primera vez. Está calentando la caché. Pero luego, si ejecuto la consulta nuevamente, podemos ver que se ejecuta bastante rápido. Hemos pasado de, ya sabes, aproximadamente 700 milisegundos a una fracción de milisegundo. Y, ya sabes, esto, creo que cambia el juego.

10. Optimización de Consultas de Datos

Short description:

Las aplicaciones web a menudo enfrentan el problema de realizar consultas excesivas, donde se recupera más datos de los necesarios. Esto se puede solucionar optimizando las consultas o utilizando GraphQL, pero estas soluciones tienen sus compensaciones. Un enfoque alternativo es hacer que la consulta de datos innecesarios sea económica, asegurando un rendimiento rápido incluso con múltiples consultas por carga de página.

Sabes, otra cosa de la que quería hablar aquí es un problema con el que te encuentras en muchas aplicaciones web, y es que tiendes a realizar consultas de más datos de los necesarios. Existe este problema de realizar consultas excesivas. Puede que tengas una función que dice: dame toda la información que tienes sobre este usuario en particular. Y luego, cada carga de página llama a esa función porque algunas páginas necesitan ciertos datos y otras páginas necesitan otros datos. Pero, ya sabes, esa función podría estar realizando una consulta que nunca se utiliza en una página en particular. Por lo tanto, uno de los pasos que podrías tomar si estás tratando de optimizar esta aplicación sería revisar y agregar indicadores a tu función, agregar una configuración para asegurarte de que solo estás consultando los datos que necesitas. Esto es por qué la gente usa GraphQL. Pero GraphQL es complejo y tiene sus propias compensaciones. En mi opinión, una solución mucho más convincente a este problema es hacer que la consulta de datos que no necesitas sea tan económica que ya no te importe. Y creo que este tipo de latencia, si estamos hablando de una fracción de milisegundo, podríamos estar realizando decenas de estas consultas en una carga de página, y no nos acercaremos a nuestro presupuesto de tiempo de carga de página de 200 milisegundos.

11. Caching and Benchmarking with ReadySet

Short description:

Con ReadySet, el conjunto de resultados de una caché se actualiza cuando se realiza una inserción, lo que garantiza lecturas rápidas incluso con muchas escrituras. Al ejecutar pruebas de referencia contra Postgres, se observa una alta latencia y un bajo número de consultas por segundo, lo que indica la necesidad de escalar con réplicas de lectura. En cambio, al ejecutar la misma prueba de referencia contra ReadySet, se mejora significativamente la latencia y se permite escalar hasta aproximadamente 200,000 consultas por segundo.

Y luego, lo otro de lo que quería hablar aquí es que, ya sabes, ReadySet, ya sabes, la mayoría de las soluciones de caché, si hicieras una inserción en esta tabla, tendrías que descartar el resultado y luego volver a calcular el conjunto de resultados. Con ReadySet, si hago una inserción en esta tabla, se actualizará el conjunto de resultados de la caché y luego vuelvo a ejecutar la consulta, podemos ver, ya sabes, este número solía ser 100,008, ahora es 100,009. Este número cambió, pero la latencia no ha aumentado. Eso se debe a que no estamos volviendo a calcular el conjunto de resultados de la consulta. En realidad, estamos manteniendo el conjunto de resultados actualizado en su lugar basado en los data que fluyen en la database aguas arriba.

Entonces, la idea aquí es que no importa cuántas escrituras estés realizando, tus lecturas siguen siendo rápidas y siguen siendo tan rápidas como las ves aquí. Y todas estas consultas que he estado ejecutando son solo como una consulta aislada que estoy ejecutando en la shell de pSQL, lo cual no es muy realista. En una aplicación web del mundo real, no solo vas a ejecutar una consulta a la vez. Vas a ejecutar, ya sabes, miles o cientos de miles de consultas por segundo Y potencialmente, si tu aplicación está recibiendo mucha carga. Y para ver cómo se ve eso, simplemente voy a ejecutar PgBench, que es una herramienta de referencia que se distribuye con Postgres. Y solo para establecer una referencia, voy a ejecutar esto contra Postgres en sí mismo. Este archivo benchmark.sql contiene la misma consulta que hemos estado ejecutando. Y lo que estamos haciendo aquí es ejecutar 32 clientes concurrentes y hacer 32 consultas a la vez. Y podemos ver que cuando ejecutamos esto contra Postgres, nuestra latencia aumenta bastante un poco. Antes estábamos viendo alrededor de 700 milisegundos. Ahora estamos viendo de 3.5 a 4 segundos de latencia, porque Postgres, un solo servidor de database no escala muy bien. Y nuestras consultas por segundo son alrededor de nueve. Eso no es suficiente para una aplicación de producción del mundo real que está recibiendo mucha carga. Entonces, este es el escenario en el que es posible que no tengas otra opción que escalar con réplicas de lectura.

Con ReadySet, puedo ejecutar la misma prueba de referencia contra ReadySet, simplemente cambiando el puerto. Estas son las configuraciones de conexión predeterminadas. Estoy ejecutando todo esto localmente. Así que voy a ejecutar la misma prueba de referencia contra ReadySet. Y solo para enmarcar esto, cuando estamos ejecutando la shell pSQL, estamos usando el modo de consulta ad hoc. Estas pruebas de referencia utilizan declaraciones preparadas porque ReadySet, al igual que todas las bases de datos, funciona mejor con declaraciones preparadas porque solo tenemos que analizar la consulta una vez. Y podemos ver que la latencia incluso mejora más que lo que estábamos viendo en la shell pSQL por esa razón. Y las consultas por segundo pueden escalar hasta alrededor de 200,000. Y creo que 200,000 suele ser suficiente para la mayoría de las aplicaciones. Creo que tienes que estar haciendo bastante bien para que 200,000 consultas por segundo no sean suficientes. Pero en el caso de que estés haciendo tan bien para ti mismo, como dijo Nick antes, Ready Set puede escalar horizontalmente.

12. Escalado y Compensaciones

Short description:

Entonces podemos ejecutar el doble de servidores ReadySet, el doble de servidores de caché ReadySet, sin agregar carga adicional a la base de datos aguas arriba porque solo estamos replicando datos de la base de datos aguas arriba una vez, y servir el doble de esto. Por lo tanto, podemos atender 400,000 consultas por segundo con el doble de servidores. Debes tener en cuenta que estás obteniendo consistencia eventual. Los resultados que obtienes en una caché pueden estar ligeramente desactualizados. El uso de memoria es un problema con cualquier solución de caché. Funciona mejor para cargas de lectura pesadas.

Entonces podemos ejecutar el doble de servidores ReadySet, el doble de servidores de caché ReadySet, sin agregar carga adicional a la base de datos aguas arriba porque solo estamos replicando datos de la base de datos aguas arriba una vez, y servir el doble de esto. Por lo tanto, podemos atender 400,000 consultas por segundo con el doble de servidores. Y de hecho, hemos visto números aún mejores que esto en nodos individuales, pero esto es solo la máquina de desarrollo de Griffin, que se ejecuta en la misma máquina. Así que se está ejecutando en mi escritorio.

Muy bien. Entonces, podrías ver todo eso y decir, bueno, no hay tal cosa como un almuerzo gratis. ¿Qué tengo que sacrificar? ¿Es esto demasiado bueno para ser verdad? Entonces, hay algunas pequeñas compensaciones que debes hacer con ReadySet. Creo que en general, a menudo no son un gran problema, pero voy a hablar de ellas un poco para que estés consciente de ellas. En primer lugar, lo más notable es que debes tener en cuenta que estás obteniendo consistencia eventual. No obtienes las mismas garantías de consistencia fuerte que obtendrías al consultar tu base de datos aguas arriba. Lo que eso significa en la práctica es simplemente que los resultados que obtienes en una caché pueden estar ligeramente desactualizados. Hay un pequeño retraso para que los datos se repliquen y actualicen en tu caché. Eso puede ser menos malo de lo que piensas. Para muchas consultas, está bien. Para algunas no lo está. Pero como vimos, puedes habilitar y deshabilitar fácilmente la caché para consultas individuales según sea necesario. Si hay consultas específicas en las que sabes que realmente necesitas esas garantías de que todo esté actualizado, por ejemplo, como con el saldo de una cuenta bancaria, no querrás tener consistencia eventual allí porque no quieres que el usuario pueda gastar el mismo dinero dos veces porque tal vez intentaron gastarlo una segunda vez antes de que el saldo se haya actualizado en los resultados de la caché o algo similar. En ese caso, obviamente no querrías cachear esa consulta. Pero al mismo tiempo, si el mismo banco hipotético tiene un panel de control que el usuario puede ver para ver sus transacciones recientes, podría ser completamente aceptable cachear eso porque si realizan una compra y no aparece en su aplicación telefónica durante un segundo, nadie realmente lo notará o le importará. No es un gran problema en absoluto.

En segundo lugar, el uso de memoria, obviamente, es un problema con cualquier solución de caché. Cuando estás cachando datos, tienen que ir a algún lugar. Por lo tanto, cuanto más datos caches, más memoria utilizas. Pero nuevamente, poder habilitar y deshabilitar la caché para consultas individuales hace que eso generalmente sea bastante fácil de gestionar. Puedes decidir qué consultas valen la pena cachear y gastar memoria en ellas. Y además, como también mencionamos, puedes escalar a múltiples nodos si es necesario. Si realmente quieres cachear más datos de los que caben en un solo nodo. Esa también es una opción.

Finalmente, esto puede ser obvio, pero funciona mejor para cargas de lectura pesadas. Creo que cuando vimos ese diagrama anterior donde mostramos cómo ocurre la replicación y cómo ReadySet mantiene los resultados actualizados, es posible que hayas notado que había una flecha para las escrituras que va directamente desde el cliente a la base de datos aguas arriba.

13. Uso e Implementación de ReadySet

Short description:

ReadySet no está diseñado para aplicaciones con alta carga de escritura o ingestión de datos. Se enfoca en mejorar el rendimiento de lectura y optimizar las consultas. El proyecto aún se encuentra en etapas tempranas, con correcciones de errores en curso y la adición de soporte para más funciones y operadores SQL. Se alienta la retroalimentación de la comunidad y hay disponible una versión en la nube de ReadySet para uso en producción. Las opciones de instalación incluyen implementación local o uso de la versión en la nube. Se brinda asistencia para la implementación, incluido un Helm Chart para Kubernetes.

Las escrituras van directamente a la database. No pasan por ReadySet. Si estás construyendo algún tipo de aplicación con alta carga de escritura donde tienes millones de sensores IoT que envían data cada segundo, entonces ReadySet simplemente no te ayudará con eso. Tal vez aún te ayude con las lecturas si tienes un problema de rendimiento de lectura para esa misma aplicación. Pero todo esto se trata de hacer consultas y no de ingresar datos.

Y finalmente, todavía estamos en una etapa temprana. Todavía estamos encontrando y corrigiendo errores, aunque hemos estado progresando muy bien con eso últimamente. No todas las consultas son compatibles, porque para saber cómo mantener los datos actualizados en nuestras cachés, tenemos que ejecutar las consultas y conocer cómo funcionan las diferentes funciones y operadores SQL. Por lo tanto, aún no hemos implementado el soporte para todos ellos, pero estamos agregando más todo el tiempo.

Y, ya sabes, somos completamente de código abierto, por lo que siempre agradecemos los comentarios de la community. Si hay alguna función que no está presente y te gustaría ver, o cualquier tipo de problema que estés teniendo, por favor, ve a GitHub. Deja un comentario, presenta un problema y estaremos muy contentos de recibirlo y hablar contigo y ver lo que estás encontrando y viendo. Oh, tenemos una pregunta.

Oh, sí. ¿Es necesario instalar ReadySet localmente? Oh, esa es una excelente pregunta. Definitivamente no es necesario instalarlo localmente. Se puede instalar en cualquier tipo de máquina compatible que desees. Además, ofrecemos una versión cloud de ReadySet que configuramos, administramos, ejecutamos y brindamos soporte. Entonces, si solo quieres probarlo, descarga la versión de código abierto. Pero si quieres ejecutarlo en producción para tu empresa y no quieres lidiar con la instalación y el mantenimiento, estaremos encantados de hablar sobre los clientes de cloud. En cuanto a las opciones de implementación, tenemos un Helm Chart para ejecutarlo en Kubernetes. También puedes implementarlo en metal desnudo o en una instancia de EC2. Pero sí, si hay una forma particular en la que deseas implementar ReadySet y necesitas ayuda para hacerlo, te sugiero que crees un problema en GitHub y estaremos encantados de ayudarte. Sí. Sí, absolutamente. Muchas gracias a todos. Genial. Muy bien. Bueno, que tengan un buen día, todos.

Watch more workshops on topic

Remix Conf Europe 2022Remix Conf Europe 2022
195 min
How to Solve Real-World Problems with Remix
Featured Workshop
- Errors? How to render and log your server and client errorsa - When to return errors vs throwb - Setup logging service like Sentry, LogRocket, and Bugsnag- Forms? How to validate and handle multi-page formsa - Use zod to validate form data in your actionb - Step through multi-page forms without losing data- Stuck? How to patch bugs or missing features in Remix so you can move ona - Use patch-package to quickly fix your Remix installb - Show tool for managing multiple patches and cherry-pick open PRs- Users? How to handle multi-tenant apps with Prismaa - Determine tenant by host or by userb - Multiple database or single database/multiple schemasc - Ensures tenant data always separate from others
GraphQL Galaxy 2020GraphQL Galaxy 2020
106 min
Relational Database Modeling for GraphQL
Top Content
WorkshopFree
In this workshop we'll dig deeper into data modeling. We'll start with a discussion about various database types and how they map to GraphQL. Once that groundwork is laid out, the focus will shift to specific types of databases and how to build data models that work best for GraphQL within various scenarios.
Table of contentsPart 1 - Hour 1      a. Relational Database Data Modeling      b. Comparing Relational and NoSQL Databases      c. GraphQL with the Database in mindPart 2 - Hour 2      a. Designing Relational Data Models      b. Relationship, Building MultijoinsTables      c. GraphQL & Relational Data Modeling Query Complexities
Prerequisites      a. Data modeling tool. The trainer will be using dbdiagram      b. Postgres, albeit no need to install this locally, as I'll be using a Postgres Dicker image, from Docker Hub for all examples      c. Hasura
Remix Conf Europe 2022Remix Conf Europe 2022
156 min
Building a Realtime App with Remix and Supabase
Workshop
Supabase and Remix make building fullstack apps easy. In this workshop, we are going to learn how to use Supabase to implement authentication and authorization into a realtime Remix application. Join Jon Meyers as he steps through building this app from scratch and demonstrating how you can harness the power of relational databases!
GraphQL Galaxy 2021GraphQL Galaxy 2021
143 min
Building a GraphQL-native serverless backend with Fauna
WorkshopFree
Welcome to Fauna! This workshop helps GraphQL developers build performant applications with Fauna that scale to any size userbase. You start with the basics, using only the GraphQL playground in the Fauna dashboard, then build a complete full-stack application with Next.js, adding functionality as you go along.

In the first section, Getting started with Fauna, you learn how Fauna automatically creates queries, mutations, and other resources based on your GraphQL schema. You learn how to accomplish common tasks with GraphQL, how to use the Fauna Query Language (FQL) to perform more advanced tasks.

In the second section, Building with Fauna, you learn how Fauna automatically creates queries, mutations, and other resources based on your GraphQL schema. You learn how to accomplish common tasks with GraphQL, how to use the Fauna Query Language (FQL) to perform more advanced tasks.
GraphQL Galaxy 2021GraphQL Galaxy 2021
175 min
Building GraphQL APIs With The Neo4j GraphQL Library
WorkshopFree
This workshop will explore how to build GraphQL APIs backed Neo4j, a native graph database. The Neo4j GraphQL Library allows developers to quickly design and implement fully functional GraphQL APIs without writing any resolvers. This workshop will show how to use the Neo4j GraphQL Library to build a Node.js GraphQL API, including adding custom logic and authorization rules.

Table of contents:
- Overview of GraphQL and building GraphQL APIs
- Building Node.js GraphQL APIs backed a native graph database using the Neo4j GraphQL Library
- Adding custom logic to our GraphQL API using the @cypher schema directive and custom resolvers
- Adding authentication and authorization rules to our GraphQL API
JSNation Live 2021JSNation Live 2021
105 min
Build an IoT App With InfluxDB
Workshop
InfluxDB is an open source time series database that empowers developers to build IoT, analytics and monitoring software. It is purpose-built to handle the massive volumes and countless sources of time-stamped data produced sensors, applications and infrastructure.
This workshop showcases a fully functional sample application called IoT Center that is built on InfluxDB. This application demonstrates the capabilities of the InfluxDB platform to develop a JavaScript-enabled time-series-based application. It collects, stores and displays a set of values that include temperature, humidity, pressure, CO2 concentration, air quality, as well as provide GPS coordinates from a set of IoT devices. With this data stored in InfluxDB, the application can query this data for display as well as write data back into the database.
This hands-on workshop will show students how to install this open source code to learn how to query and write to InfluxDB using the InfluxDB JavaScript client, and gain familiarity with the Flux lang query language which is designed for querying, analyzing, and acting on time series data. And finally, collect and visualize performance data of the Node JS application.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

TypeScript Congress 2022TypeScript Congress 2022
27 min
TypeScript and the Database: Who Owns the Types?
Top Content
We all love writing types in TypeScript, but we often find ourselves having to write types in another language as well: SQL. This talk will present the choose-your-own-adventure story that you face when combining TypeScript and SQL and will walk you through the tradeoffs between the various options. Combined poorly, TypeScript and SQL can be duplicative and a source of headaches, but done well they can complement one another by addressing each other's weaknesses.
JSNation 2023JSNation 2023
29 min
I Would Never Use an ORM
Top Content
What's an ORM? An Object-Relational Mapping tool (ORM) is a library to map a SQL table to a Class. In most cases, ORMs force the users to structure their code to have Model objects that include both data access and business logic.
Once upon a time, I did several projects using ORMs as I followed the common belief that they would simplify the development and maintenance of projects. I was wrong. ORMs are often a hurdle to overcome for the most complex part of a project.
As the next stop of my journey, I recommended people use the native languages of their databases, e.g., SQL. This works great for the most part, but it creates quite a struggle: there is a lot of boilerplate code to write that can be pretty tedious. I was wrong, again.
Today I'm presenting you Platformatic DB.
Node Congress 2022Node Congress 2022
31 min
Database Access on the Edge with Cloudflare Workers & Prisma
Edge functions are pushing the limit of serverless computing – but with new tools, come new challenges. Due to their limitations, edge functions don't allow talking to popular databases like PostgreSQL and MySQL. In this talk, you will learn how you can connect and interact with your database from Cloudflare Workers using the Prisma Data Proxy.
You can check the slides for Alex's talk here. 
Remix Conf Europe 2022Remix Conf Europe 2022
41 min
Remix Persistence With DynamoDB
Remix is the best React framework for working with the second most important feature of the web: forms. (Anchors are more important.) But building forms is the fun part: the tricky part is what happens when a web consumer submits a form! Not the client side validation logic but the brass tacks backend logic for creating, reading, updating, destroying, and listing records in a durable database (CRUDL). Databases can be intimidating. Which one to choose? What are the tradeoffs? How do I model data for fast queries? In this talk, we'll learn about the incredibly powerful AWS DynamoDB. Dynamo promises single-digit millisecond latency no matter how much data you have stored, scaling is completely transparent, and it comes with a generous free tier. Dynamo is a different level of database but it does not have to be intimidating.
JSNation 2023JSNation 2023
31 min
Bring AI-Based Search to Your Web App
ChatGPT took the tech world by storm. Everyone talks about it, from your CTO to your hairdresser (at least my barber does). And there are many reasons why we should all be excited about it and many other AI/ML innovations.
But how do you bring them into your tech stack, your website/backend, to work with your data and provide AI-driven search and data augmentation?
There is a new generation of AI Native databases, which use deep learning models to find answers to natural language queries. We are talking about the ability to search through text, images, videos, DNA, or any unstructured data, all with a single query.
The rule of thumb: if there is an ML model, we can search through it.
Join me to learn about the foundation blocks (LLMs and vector embeddings, Vector Databases), how they all play together and most importantly - how you can build something yourself with open-source tech.
And, of course!!! There will be a live-coding demo, where I will take you through the experience of building an AI-based search – with Weaviate, an open-source Vector Database – and adding it to an app. Now the question... should this be done in Angular, React, Vue or just pure JS ;)
#MayTheDemoGodsBeWithUs