Siirry sisältöön

Oppaat

Vilkkaiden API:en välimuisti: Redis ja Elasticsearch

· Lukuaika 6 min

Vilkkaan API:n välimuisti rakennetaan mittaamalla ensin ja lisäämällä sitten Redisiin cache-aside-kerros hitaimpien ja luetuimpien päätepisteiden eteen. Mukaan tulevat eksplisiittiset TTL-arvot, invalidointi kirjoitettaessa ja suojaus välimuistiryntäyksiä vastaan. Käytä Elasticsearchia hakuun ja suodatettuihin listauksiin, jotka ensisijainen tietokanta hoitaa huonosti, äläkä koskaan välimuistita käyttäjäkohtaisia tai ehdottoman johdonmukaisia tietoja ilman harkittua suunnitelmaa.

Mittaa P95-viive ennen kuin lisäät välimuistia

Keskiarvot kätkevät ne pyynnöt, joista käyttäjät valittavat. Seuraa P95- ja P99-viivettä päätepisteittäin sekä pyyntömääriä, jotta näet, mitkä reitit ovat sekä hitaita että paljon käytettyjä.

Selvitä sitten, mihin aika kuluu. Jäljitys tai yksinkertainen pyyntökohtainen ajoituserittely näyttää yleensä, johtuuko kustannus hitaasta kyselystä, toistuvista kyselyistä, ulkoisen API:n kutsusta vai sarjallistamisesta. Jos vastauksen todellinen ongelma on puuttuva indeksi, välimuisti vain piilottaa ongelman seuraavaan välimuistihutiin asti.

  • Kirjaa P50, P95 ja P99 päätepisteittäin, ei vain yhtä kokonaislukua
  • Järjestä päätepisteet pyyntömäärän ja viiveen tulon mukaan nähdäksesi, missä välimuisti kannattaa eniten
  • Tarkista lukujen ja kirjoitusten suhde, sillä tieto, jota luetaan paljon useammin kuin se muuttuu, on paras ehdokas
  • Korjaa puuttuvat indeksit ja N+1-kyselyt ennen kuin rakennat välimuistin niiden ympärille

Käytä cache-aside-mallia oletuksena

Cache-aside-mallissa sovellus tarkistaa ensin Redisin. Osuman sattuessa se palauttaa välimuistissa olevan arvon. Hudin sattuessa se lukee tietokannasta, kirjoittaa tuloksen Redisiin TTL:n kanssa ja palauttaa sen.

Malli pitää tietokannan totuuden lähteenä ja vikaantuu turvallisesti. Jos Redis on hidas tai poissa käytöstä, sovellus palaa tietokantaan lyhyellä aikakatkaisulla ja katkaisijalla (circuit breaker), jotta takkuileva välimuisti ei hidasta jokaista pyyntöä.

Suunnittele avaimet harkiten. Sisällytä resurssityyppi, tunniste, API-versio ja jokainen vastaukseen vaikuttava parametri, kuten kieli tai sivu. Ennustettava avainrakenne mahdollistaa myöhemmin kohdennetun invalidoinnin.

Aseta TTL sen mukaan, kuinka vanhaa tieto saa olla, ja invalidoi muutoksessa

TTL on luvuksi kirjoitettu liiketoimintapäätös. Kysy, kuinka vanhaa tieto saa olla ennen kuin siitä on haittaa käyttäjälle tai alavirran järjestelmälle, ja aseta TTL vastauksen perusteella. Live-ottelun tulos ja arkistoitu artikkeli sietävät hyvin eriasteista vanhentuneisuutta.

Pelkkään vanhenemiseen luottaminen tarkoittaa vanhentuneen tiedon tarjoamista, kunnes TTL umpeutuu. Kun oma sovelluksesi muuttaa tietoa, poista tai korvaa avain kirjoituksen vahvistamisen (commit) jälkeen, mieluiten transaktion jälkeen lähetetyn tapahtuman kautta, jotta välimuistissa ei koskaan ole tietoa, jonka tietokanta perui.

Lisää TTL-arvoihin pieni satunnainen vaihtelu (jitter), jotta samaan aikaan kirjoitetut avaimet eivät kaikki vanhene samalla hetkellä.

  • Muutaman sekunnin lyhyt TTL nopeasti muuttuvalle tiedolle, kun pieni vanhentuneisuus on hyväksyttävää
  • Pidempi TTL ja invalidointi kirjoitettaessa harvoin muuttuvalle tiedolle, jota itse hallitset
  • Versioidut avaimet, joissa versionumeron kasvattaminen invalidoi kokonaisen avainryhmän kerralla

Suojaa tietokanta välimuistiryntäyksiltä

Ryntäys (cache stampede) syntyy, kun suosittu avain vanhenee ja moni samanaikainen pyyntö osuu hutiin yhtä aikaa ja lähettää saman raskaan kyselyn tietokantaan. Vilkkaassa API:ssa tämä voi ylikuormittaa tietokannan juuri silloin, kun liikenne on huipussaan.

Yhdistä kaksi tai useampia näistä suojauksista kuumimmille avaimillesi.

  • Pyyntöjen yhdistäminen: yksi pyyntö rakentaa avaimen uudelleen lyhyen Redis-lukon alla, joka asetetaan NX-valinnalla ja vanhenemisajalla, ja muut odottavat hetken tai tarjoavat edellisen arvon
  • Stale-while-revalidate: tallenna arvon sisään pehmeä vanhenemisaika, jatka vanhentuneen kopion tarjoamista sen jälkeenkin ja päivitä taustalla
  • Varhainen todennäköisyyspohjainen päivitys: rakenna kuuma avain toisinaan uudelleen ennen sen vanhenemista niin, että todennäköisyys kasvaa vanhenemisen lähestyessä
  • Esilämmitys: täytä tunnetut kuumat avaimet ennen suunniteltua liikennepiikkiä, kuten suurta live-tapahtumaa

Käytä Elasticsearchia hakuun ja listauksiin, älä yleisenä välimuistina

Redis sopii parhaiten avain–arvo-hakuihin: yksittäinen objekti, laskettu fragmentti, pyyntörajoituksen laskuri. Elasticsearch sopii eri tehtävään: kokotekstihakuun, fasettisuodattimiin ja lajiteltuihin listauksiin, joiden laskeminen relaatiotietokannassa on raskasta.

Käsittele Elasticsearch-indeksiä lukumallina, jota syötetään ensisijaisesta tietokannasta muutostapahtumien tai ajastetun synkronoinnin kautta, ja hyväksy, että se on vain lopulta johdonmukainen (eventually consistent). Pidä tietokanta määräävänä kirjoituksissa ja kaikessa, minkä on oltava täsmällistä.

NorthStar Networkin urheilumedia-alustalla, jolla on 50M+ käyttäjää kuukaudessa, kehittäjämme uudistivat kriittisten API:en arkkitehtuurin ja suunnittelivat välimuistin uudelleen Redisin ja Elasticsearchin välillä, mikä lyhensi P95-vasteaikoja.

Tiedä, mitä ei pidä välimuistittaa

Kallein välimuistivirhe on yhden käyttäjän tietojen näyttäminen toiselle. Tarkista jokaisesta välimuistitetusta päätepisteestä, että identiteetti on avaimessa, ja testaa se kahdella eri tilillä ennen julkaisua.

  • Vastaukset, jotka riippuvat kutsujan identiteetistä tai oikeuksista, ellei avain sisällä käyttäjää tai roolia
  • Tiedot, joiden on oltava ehdottoman johdonmukaisia, kuten saldot, varastotilanne kassalla tai kaikki valtuutuspäätöksissä käytettävä
  • Kirjoittavat päätepisteet, kertakäyttöiset tunnisteet ja kaikki, millä on sivuvaikutuksia
  • Vähäliikenteiset päätepisteet, joissa välimuisti tuo monimutkaisuutta ja uuden vikaantumistavan pienellä hyödyllä
  • Hyvin suuret vastaukset, jotka häätävät muistista monta pienempää ja kuumempaa avainta

Tee välimuistista havainnoitava, muuten et voi luottaa siihen

Seuraa osumasuhdetta avainetuliitteittäin, Redisin muistinkäyttöä ja häätöjä, Redis-komentojen viivettä ja tietokannan kuormaa samassa kojelaudassa API:n P95:n rinnalla. Kun P95 muuttuu, sinun pitäisi pystyä minuuteissa sanomaan, aiheuttiko sen välimuisti, tietokanta vai ylävirran palvelu.

Hälytä osumasuhteen äkillisestä laskusta, joka tarkoittaa usein, että julkaisu muutti avainten muotoa, sekä kasvavista häädöistä, jotka tarkoittavat, että välimuisti on liian pieni työjoukolleen.

Otamme API-suorituskykytyön vastaan rajattuna kokonaisuutena: mittaus, välimuistikerroksen uudelleensuunnittelu sekä kojelautojen ja ajo-ohjeiden luovutus tiimille, joka ylläpitää järjestelmää.

Tärkeimmät havainnot

  • Mittaa P95 päätepisteittäin ja korjaa kyselyongelmat ennen välimuistin lisäämistä.
  • Cache-aside Redisissä on turvallisin oletus, koska tietokanta pysyy totuuden lähteenä.
  • Aseta TTL sen mukaan, kuinka vanhaa tieto saa olla, ja invalidoi itse hallitsemasi tieto kirjoitettaessa.
  • Suojaa kuumat avaimet ryntäyksiltä lukituksella, stale-while-revalidate-mallilla tai esilämmityksellä.
  • Käytä Elasticsearchia lopulta johdonmukaisena lukumallina hakuun ja listauksiin, älä yleisenä välimuistina.

UKK

Kannattaako API-vastausten välimuistiin käyttää Redisiä vai Elasticsearchia?

Käytä Redisiä objektien, laskettujen fragmenttien ja laskurien avain–arvo-välimuistina, koska avainhaut ovat nopeita ja helppoja invalidoida. Käytä Elasticsearchia, kun raskas osa on haku, suodatus tai lajittelu suuressa tietuemäärässä, ja käsittele sen indeksiä lukumallina eikä välimuistina.

Mikä on hyvä TTL API-vastauksille?

Yleispätevää arvoa ei ole. Aseta jokainen TTL sen mukaan, kuinka vanhaa kyseinen tieto voi olla haittaamatta käyttäjää, käytä muutamaa sekuntia nopeasti muuttuvalle tiedolle ja yhdistä pidempiin TTL-arvoihin invalidointi kirjoitettaessa. Lisää satunnaista vaihtelua, jotta toisiinsa liittyvät avaimet eivät vanhene yhtä aikaa.

Miten välimuistiryntäys estetään Redisissä?

Anna vain yhden pyynnön rakentaa vanhentunut avain uudelleen ottamalla lyhyt lukko SET-komennolla ja NX-valinnalla, ja anna muiden pyyntöjen odottaa hetki tai tarjota edellinen arvo. Stale-while-revalidate ja kuumien avainten varhainen päivitys vähentävät jo lähtökohtaisesti kovien vanhenemisten määrää.

Kerro, mitä tarvitset.

Jotain rakennettavaa, ihmisiä löydettäväksi tai kysymys, johon tarvitset vastauksen. 30 minuutin puhelussa kuuntelemme ja kerromme rehellisesti, miten voimme auttaa ja mitä se vaatisi.

Varaa puhelu

30 minuuttia ranskaksi tai englanniksi. Maksuton.

Kirjoitatko mieluummin? Lähetä sen sijaan lyhyt kuvaus.