Kuinka käyttää Redistä Web-sovellusliittymien lataamiseen

Suorituskyky on tärkeä parametri, joka on otettava huomioon suunniteltaessa mitä tahansa ohjelmistoa. Se on erityisen tärkeää, mitä tulee kulissien takana.

Kehittäjinä ja teknikoina otamme käyttöön useita parannuksia ja parannuksia suorituskyvyn parantamiseksi. Täällä välimuisti tulee esiin.

Välimuisti on määritelty mekanismiksi tietojen tai tiedostojen tallentamiseksi väliaikaiseen tallennuspaikkaan, josta sitä voidaan käyttää heti tarvittaessa.

Välimuistista on tullut välttämätöntä Web-sovelluksissa nykyään. Voimme käyttää Redistä web-sovellusliittymien lataamiseen - jotka on rakennettu Node.js: n ja MongoDB: n avulla.

Redis: Maallikon yleiskatsaus

Redis määritellään virallisen dokumentaation mukaan muistin sisäiseksi tietorakennevarastoksi, jota käytetään tietokantana, viestien välittäjänä tai välimuistitallennuksena. Se tukee tietorakenteita, kuten merkkijonoja, hajautuksia, luetteloita, sarjoja, lajiteltuja sarjoja, joissa on aluekyselyjä, bittikarttoja, hyperlogogeja, paikkatietohakemistoja, joissa on sädekyselyt ja -virtoja.

Okei, siinä on melko paljon tietorakenteita. Yksinkertaisuuden vuoksi melkein kaikki tuetut tietorakenteet voidaan tiivistää yhdeksi tai toiseksi merkkijonoksi. Saat enemmän selkeyttä, kun käytämme toteutusta läpi.

Mutta yksi asia on selvä. Redis on tehokas, ja oikein käytettynä se voi tehdä sovelluksistamme paitsi nopeammat myös hämmästyttävän tehokkaat. Tarpeeksi puhetta. Lasketaan kätemme.

Let's Talk Code

Ennen kuin aloitamme, sinun täytyy saada uudelleenasetus paikalliseen järjestelmään. Voit seurata tätä pika-asennusprosessia saadaksesi uudelleen käyttöön.

Tehty? Viileä. Aloitetaan. Meillä on yksinkertainen Express-sovelluksessa luotu sovellus, joka käyttää MongoDB Atlas -esimerkkiä tietojen lukemiseen ja kirjoittamiseen.

Reittitiedostoon on luotu kaksi suurta sovellusliittymää /blogs.

... // GET - Fetches all blog posts for required user blogsRouter.route('/:user') .get(async (req, res, next) => { const blogs = await Blog.find({ user: req.params.user }); res.status(200).json({ blogs, }); }); // POST - Creates a new blog post blogsRouter.route('/') .post(async (req, res, next) => { const existingBlog = await Blog.findOne({ title: req.body.title }); if (!existingBlog) { let newBlog = new Blog(req.body); const result = await newBlog.save(); return res.status(200).json({ message: `Blog ${result.id} is successfully created`, result, }); } res.status(200).json({ message: 'Blog with same title exists', }); }); ...

Ripottelemalla Redis-hyvyyttä

Aloitamme lataamalla npm-paketin redismuodostaaksesi yhteyden paikalliseen redis-palvelimeen.

const mongoose = require('mongoose'); const redis = require('redis'); const util = require('util'); const redisUrl = 'redis://127.0.0.1:6379'; const client = redis.createClient(redisUrl); client.hget = util.promisify(client.hget); ...

Käytämme utils.promisifyfunktiota muuntamaan client.hgetfunktion palauttamaan lupauksen takaisinsoiton sijaan. Voit lukea lisää promisificationtäältä.

Redis-yhteys on paikallaan. Ennen kuin aloitamme välimuistikoodin kirjoittamisen, ottakaamme askel taaksepäin ja yritämme ymmärtää, mitkä vaatimukset meidän on täytettävä, ja todennäköiset haasteet, joita voimme kohdata.

Välimuististrategiamme pitäisi pystyä vastaamaan seuraaviin seikkoihin.

  • Välimuisti tietyn käyttäjän kaikkien blogiviestien pyyntö
  • Tyhjennä välimuisti aina, kun uusi blogiviesti luodaan

Todennäköiset haasteet, joihin meidän tulisi olla varovaisia ​​strategiamme edetessä, ovat:

  • Oikea tapa käsitellä avaimen luomista välimuistidatan tallentamiseksi
  • Välimuistin vanhentumislogiikka ja pakotettu vanhentuminen välimuistin tuoreuden ylläpitämiseksi
  • Välimuistilogiikan uudelleenkäytettävä toteutus

Selvä. Pisteemme on merkitty alas ja uudelleen kytkettyinä. Siirry seuraavaan vaiheeseen.

Oletus Mongoose Exec -toiminnon ohittaminen

Haluamme välimuistilogiikkamme olevan uudelleenkäytettävissä. Eikä vain uudelleenkäytettävissä, mutta haluamme myös, että se on ensimmäinen tarkistuspiste ennen minkään kyselyn tekemistä tietokantaan. Tämä voidaan helposti tehdä käyttämällä yksinkertaista säästöpossun tukea mongoose exec -toiminnolle.

... const exec = mongoose.Query.prototype.exec; ... mongoose.Query.prototype.exec = async function() { ... const result = await exec.apply(this, arguments); console.log('Data Source: Database'); return result; } ...

Lisäämme välimuistilogiikkakoodin kyselyn ensimmäiseksi suoritukseksi mongoose-prototyyppi-objektin avulla.

Välimuistin lisääminen kyselyksi

Välimuistiin tallennettavien kyselyjen merkitsemiseksi luomme mongoose-kyselyn. Tarjoamme mahdollisuuden siirtää userhash-avaimena käytettävä optionskohde objektin läpi .

Huomaa: Hashkey toimii tunnuksena hash-tietorakenteelle, joka maallikon termein voidaan sanoa vanhemman avaimeksi joukolle avain-arvo-pareja. Siten mahdollistetaan suuremman määrän kysely-arvojoukon välimuistiin tallentaminen. Voit lukea lisää hasisista redisissä täältä.
... mongoose.Query.prototype.cache = function(options = {})  'default'); return this; ; ...

Tämän jälkeen voimme helposti käyttää cache()kyselyä välimuistiin tallennettujen kyselyjen kanssa seuraavalla tavalla.

... const blogs = await Blog .find({ user: req.params.user }) .cache({ key: req.params.user }); ...

Välimuistilogiikan luominen

Olemme asettaneet yhteisen uudelleenkäytettävän kyselyn merkitsemään välimuistiin tallennettavat kyselyt. Mennään eteenpäin ja kirjoitetaan keskeinen välimuistilogiikka.

... mongoose.Query.prototype.exec = async function() { if (!this.enableCache) { console.log('Data Source: Database'); return exec.apply(this, arguments); } const key = JSON.stringify(Object.assign({}, this.getQuery(), { collection: this.mongooseCollection.name, })); const cachedValue = await client.hget(this.hashKey, key); if (cachedValue) { const parsedCache = JSON.parse(cachedValue); console.log('Data Source: Cache'); return Array.isArray(parsedCache) ? parsedCache.map(doc => new this.model(doc)) : new this.model(parsedCache); } const result = await exec.apply(this, arguments); client.hmset(this.hashKey, key, JSON.stringify(result), 'EX', 300); console.log('Data Source: Database'); return result; }; ...

Aina kun käytämme cache()kyselyä pääkyselymme kanssa, asetamme enableCacheavaimen totta.

Jos avain on väärä, palautamme execpääkyselyn oletuksena. Jos ei, muodostamme ensin avaimen välimuistidatan noutamiseen ja tallentamiseen / päivittämiseen.

Käytämme collectionnimeä ja oletuskyselyä avaimen nimellä ainutlaatuisuuden vuoksi. Käytetty hash-avain on sen nimen nimi, userjonka olemme jo asettaneet cache()funktion määritelmässä.

Välimuistitiedot haetaan käyttämällä client.hget()funktiota, joka vaatii parametreina hash-avaimen ja sitä seuraavan avaimen.

Huomaa: Käytämme aina JSON.parse()tietoja noudettaessa uudelleen. Ja vastaavasti käytämme JSON.stringify()avainta ja tietoja ennen kuin tallennamme mitään uudelleen. Tämä tehdään, koska redis ei tue JSON-tietorakenteita.

Kun olemme saaneet välimuistitiedot, meidän on muutettava jokainen välimuistissa oleva objekti mongoose-malliksi. Tämä voidaan tehdä yksinkertaisesti käyttämällä new this.model().

If the cache does not contain the required data, we make a query to the database. Then, having returned the data to the API, we refresh the cache using client.hmset(). We also set a default cache expiration time of 300 seconds. This is customizable based on your caching strategy.

The caching logic is in place. We have also set a default expiration time. Next up, we look at forcing cache expiration whenever a new blog post is created.

Forced Cache Expiration

In certain cases, such as when a user creates a new blog post, the user expects that the new post should be available when they fetche all the posts.

In order to do so, we have to clear the cache related to that user and update it with new data. So we have to force expiration. We can do that by invoking the del() function provided by redis.

... module.exports = { clearCache(hashKey) { console.log('Cache cleaned'); client.del(JSON.stringify(hashKey)); } } ...

We also have to keep in mind that we will be forcing expiration on multiple routes. One extensible way is to use this clearCache() as a middleware and call it once any query related to a route has finished execution.

const { clearCache } = require('../services/cache'); module.exports = async (req, res, next) => { // wait for route handler to finish running await next(); clearCache(req.body.user); } 

This middleware can be easily called on a particular route in the following way.

... blogsRouter.route('/') .post(cleanCache, async (req, res, next) => { ... } ...

And we are done. I agree that was a quite a lot of code. But with that last part, we have set up redis with our application and taken care of almost all the likely challenges. It is time to see our caching strategy in action.

Redis in Action

We make use of Postman as the API client to see our caching strategy in action. Here we go. Let's run through the API operations, one by one.

  1. We create a new blog post using the /blogs route

2. We then fetch all the blog posts related to user tejaz

3. Haemme kaikki blogikirjoitukset käyttäjälle tejazvielä kerran.

Voit selvästi nähdä, että kun haemme välimuistista, kulunut aika on laskenut 409 ms: sta 24 ms : iin . Tämä lataa sovellusliittymän vähentämällä kulutettua aikaa lähes 95%.

Lisäksi voimme selvästi nähdä, että välimuistin vanhentuminen ja päivitystoiminnot toimivat odotetusti.

Löydät koko lähdekoodin redis-expresskansiosta täältä.

tarique93102 / article-snippets -tietovarasto, joka sisältää prototyyppisovelluksia ja käsitteiden levittämiseen liittyviä koodikatkelmia - tarique93102 / article-snippets tarique93102 GitHub

Johtopäätös

Välimuisti on pakollinen vaihe kaikissa suorituskykyisissä ja datavaltaisissa sovelluksissa. Redis auttaa sinua saavuttamaan tämän helposti verkkosovelluksissasi. Se on erittäin tehokas työkalu, ja oikein käytettynä se voi varmasti tarjota erinomaisen kokemuksen sekä kehittäjille että käyttäjille ympäri.

Täältä löydät kaikki redis-komennot. Voit käyttää sitä redis-cliseurata välimuistidataa ja sovellusprosesseja.

Minkä tahansa tietyn tekniikan tarjoamat mahdollisuudet ovat todella rajattomat. Jos sinulla on kysyttävää, voit ottaa yhteyttä minuun LinkedIn.

Sillä välin jatka koodausta.