Cacheo y Optimización de Consultas en Microservicios
Resumen
¿Cómo integramos el caché en nuestro microservicio?
Ha llegado el momento de integrar el caché en nuestra API para optimizar su rendimiento. El uso de caché en un ambiente de producción puede mejorar significativamente la velocidad y eficiencia, además de reducir la carga en la base de datos. Veamos cómo realizar esta integración paso a paso.
¿Cómo inyectamos el servicio de caché?
Para empezar, vamos a modificar el componente control dentro de nuestra API. Hasta ahora hemos estado trabajando con el Store, pero es hora de integrar el caché:
const cache =injectCache();// Inyectamos el caché en nuestro controlador, igual que hicimos con el store
Al usar una instancia Dummy para el caché, garantizamos que siempre haya un caché disponible, aunque esta implementación inicial funcione más como una plantilla. En un entorno de producción, debe reemplazarse con una solución de almacenamiento en caché robusta, como Redis.
¿Cómo funciona la estrategia de caché?
La estrategia ideal consiste en comprobar primero si los datos requeridos están en caché antes de hacer una solicitud a la base de datos:
asyncfunctionlist(){const cachedUsers = cache.get('users');if(!cachedUsers){const usersFromStore =await store.list(); cache.add('users', usersFromStore);console.log('No estaba en caché, buscando en base de datos');return usersFromStore;}console.log('Datos traídos de caché');return cachedUsers;}
Este método verifica si la lista de usuarios ya está almacenada en el caché. Si no, la solicita al Store (nuestra base de datos) y luego la almacena en el caché para futuras consultas.
¿Cómo afecta el caché al rendimiento del sistema?
Implementar un sistema de caché puede tener un gran impacto en el rendimiento. Como se muestra en el ejemplo, el tiempo de respuesta mejora significativamente al consultar datos desde el caché en vez de la base de datos:
Sin caché: Alrededor de 252 ms
Con caché: Aproximadamente 35 ms
Estos tiempos ilustran cuán crítico puede ser el caché para aplicaciones que manejan grandes volúmenes de datos o reciben un tráfico considerable.
¿Cuándo es recomendable implementar un sistema de caché?
Si tu aplicación está creciendo y esperas manejar grandes volúmenes de tráfico, es prudente implementar un sistema de caché desde el principio. Sin embargo, si aún no tienes claro cómo evolucionará la carga de tu aplicación, es mejor empezar con soluciones más simples y luego expandir:
Para grandes sistemas: Implementa caché desde el inicio para evitar sobrecargar la base de datos.
Para nuevos o pequeños sistemas: Comienza con una arquitectura sencilla y adapta el uso del caché a medida que crece la demanda.
No olvides que la complejidad añadida también conlleva mayores responsabilidades, como el mantenimiento de servicios adicionales como Redis. Asegúrate de balancear la inversión de tiempo y esfuerzo con los beneficios reales.
Este primer paso nos prepara para proceder con la configuración y optimización de nuestros servicios, asegurando una arquitectura robusta y eficiente. ¡En la próxima clase descubriremos cómo realizar despliegues más complejos!
Cacheo y Optimización de Consultas en Microservicios
Excelente profesor, todo es muy claro y rápido con él.
Odio los profesores que se tiran 1 hora explicando algo que podemos leer en las documentaciones de cada tecnología.
el mejor profesor de platzi, a que si
Sí, el mejor!!
de acuerdo
El profe Carlos debería dar todos los cursos de Node, una chulada todos los cursos que he tomando con el.
Este deberia ser el ultimo video de la seccion de cache.
Sí, el orden no está bien
gracias por reportarlo, ya está corregido :)
Es increible la cantidad de cosas que aprendimos en un solo curso
Les comparto un método que sirve para implementar el cache de forma general a cualquier función que lea datos del store.
// store/addOns/cacheUtils.jsconstcacheUtils=(cacheApi)=>{constapply=async(cache_id,{fn, args})=>{let data =await cacheApi.get(cache_id);if(!data){ data =awaitfn(...args);await cacheApi.upsert(cache_id, data);}return data;} cacheApi.apply= apply;return cacheApi;}module.exports= cacheUtils;
esto estara alojado en el cache del navegador///???
no , esta alojado en memoria , para el frontend hay otras alternativas del uso de cache
Bien, entendido. Muy claro el ejemplo y la práctica.
De los mejores profesores de platzi! 🎉😎
Cache del microservicio de post hecho:
Así me quedó el controller de posts
asyncfunctionlist(){let posts =await cache.list(TABLE)if(!posts){console.info(`${TABLE} were not in cache, bringing from DB`) posts =await store.list(TABLE) cache.upsert(TABLE, posts)}else{console.log(`Bringing ${TABLE} from cache`)}return posts
}
Cuanto tiempo seria el óptimo para dejar en cache?
Pregunta. Para ver si entendí bien. ¿El caché estaría guardado en Redis cierto?
Hay varias cosas que me dejan duda, la primera es sobre la dependencia que se presenta de los servicios de redis y mysql con el store, ¿No se supone que el microservicio debe ser independiente y funcionar por si solo?, y dos, si voy a llevar los microservicios a contenedores docker o servidores aparte, voy a necesitar instalar las dependencias de express, los drivers de base de datos y demas, de lo contrario se rompería el código. Partiendo de esto pensaría que cada microservicio es una aplicación completa de nodejs, cons su archivo de inicio, su package,json y el node_modules.
Creo que estás teniendo el mismo debate en tu mente que yo monoRepo "todo el código en un repo" VS multi-repo "diferentes repos para cada microServicio". Yo pensaría que es mejor monorepo como lo estamos trabajando en el curso porque uno tiene visibilidad y todo el código en un solo lado, pienso que mejora reusar el código también. Lo que mencionas de las dependencias se puede trabajar mejor con yarn que te permite tener libs generales para todos los repos y libs particulares por repo.
Osea que lo que el profe menciona es que es una buena praćtica tener una base de datos de pruebas mientras el desarrollo de la aplicación?
Es correcto. En lo personal tengo 3 bases de datos:
En mi laptop local. (Para desarrollar)
En el servidor de producción y con la configuración idéntica a la base de datos de producción. (Para hacer pruebas sin afectar a la aplicación productiva en un ambiente idéntico al productivo)
En el servidor de producción y base de producción. (100% productivo)
Con esto minimizas errores al implementar tu aplicación.
Exacto, con esto evitas el problema mas grande de un desarrollador jr., interactuar directamente con la db en prod. sin cerciorarse del buen funcionamiento del backend.
Todo muy lindo pero deberia enseñar correctamente como nombrar archivos y variables.
Super desprolijo.
se está usando redis para chache es porque node corre en el server. Es correcto?
uhmm no queda muy clara tu afirmación / pregunta.
Pero el servicio de Redis como cache se usa para acelerar la consulta de alguna información que previamente se había consultado desde la DB.
Ejemplo inventado: cada vez que ingresas a Platzi el front-end pide el dato de tu PlatziRank al backend que se lo pide a la DB (posiblemente el punto más lento de todo el proceso), pero como cada vez que actualices o cierras el navegador por un corto período entonces el vuelve a pedir el dato, pero está vez el dato está copiado en una área de memoria rápida <Redis> (sea local o remota, pero más rápido que preguntarle a mysql en remoto) y lo trae de redis.
No estoy seguro si esto aclara algo. Sino, replaneta tú pregunta o describe un poco sobre que es lo que deseas confirmar.
Y creo que Redis esta muy optimizado para trabajar con cache
esta clase esta genial
excelente gracias
hace tiempo completé el curso pero… Ahora tengo un error que no entiendo, he visto miles de veces los archivos del curso y videos pero lo tengo tal cual en la logica de microservicios y es que hay un microservicio de muchos que he hecho que cuando lo ejecuto con nodemon, con node o con pm2 sale com dependente del main del package.json y sale un mensaje como esto
<code><code>nodemon MSV_events/event.js[nodemon]2.0.7[nodemon] to restart at any time, enter `rs`[nodemon] watching path(s):*.*[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node MSV_events/event.js index.js`internal/modules/cjs/loader.js:818throw err;^Error:Cannot find module '/var/www/ConfirmAppNodeJS/index.js' at Function.Module._resolveFilename(internal/modules/cjs/loader.js:815:15) at Function.Module._load(internal/modules/cjs/loader.js:667:27) at Function.executeUserEntryPoint[as runMain](internal/modules/run_main.js:60:12) at internal/main/run_main_module.js:17:47{code:'MODULE_NOT_FOUND',requireStack:[]}
luego veo el package.json y colico en el “main” la outa de mi index principal (api) y luego ejecuto nuevamente nodemon o node y me dice que pue el Puerto 3000 (donde tengo mi servicio principal y que si está andando) anda ocupado. miro el config.js y normal este microservicio en problema está haciendo un app.listend hacia un Puerto 3002 asi que no comprendo… igual en el script dice “executing nodemon MSV_event/event.js. api/index.js” pero yo no coloco e n el command el “api/index”… Cierro entonces el proceso principal, el index donde está mi carpet api y luego eject entonces este proceso y sale como que se ejecutan los dos a la vez "api escuchando en el Puerto 3000, microservicio de eventos escuchando en el Puerto 3002"
Excelente los consejos que el profesor brinda al final de la clase