제이온

[DB] A gyorsítótár beállításának kritériumai

  • Írás nyelve: Koreai
  • Országkód: Minden országcountry-flag
  • Informatika

Létrehozva: 2024-04-25

Létrehozva: 2024-04-25 22:24

Üdvözlet! Jayon vagyok.

Ma a cache beállításának kritériumait szeretném elmagyarázni. Mivel a saját gyakorlati tapasztalataim alapján írok, kérlek, tekintsd ezt pusztán tájékoztató jellegűnek ㅎㅎ


Mi az a Cache?

A cache lényege, hogy a későbbi kérések eredményét előre eltárolja, és így gyorsan kiszolgálja azokat. Vagyis előre eltárolja az eredményeket, és amikor egy kérés érkezik, ahelyett, hogy a DB-hez vagy API-hoz fordulna, a cache-hez fér hozzá, és onnan dolgozza fel a kérést. Ennek a cache-nek a hátterében a Pareto-elv áll.

A Pareto-elv azt jelenti, hogy az eredmények 80%-a a kiváltó okok 20%-ának köszönhető, és érdemes lehet a lenti képet is megtekinteni!


[DB] A gyorsítótár beállításának kritériumai


Vagyis a cache-nek nem kell minden eredményt tárolnia, elég, ha a szolgáltatás során leggyakrabban használt 20%-ot tárolja, ezáltal az egész rendszer hatékonyságát növelve.


Milyen adatokat érdemes tárolni a cache-ben?

A Pareto-elv alapján nem szabad minden adatot a cache-be helyezni, csak a valóban szükségeseket. De akkor mely adatokat érdemes tárolni?


Azok az adatok, amelyeket gyakran olvasunk, de ritkán írunk

Elméletileg gyakran hallani, hogy „azokat az adatokat érdemes cache-be helyezni, amelyeket gyakran olvasunk, de ritkán írunk”, de a „gyakran olvasott” és a „ritkán írt” kritériumok meglehetősen homályosak voltak.


Ezért én a következő lépéseket követem a cache-be helyezendő adatok meghatározásakor.


  • Az APM eszközök (pl. DataDog) segítségével megnézem az RDB lekérdezések TOP 5-ös listáját.
  • Ezek közül kiválasztom a lekérdezéseket, és megnézem, hogy melyik táblából származnak.
  • Megvizsgálom, hogy az adott tábla frissítési lekérdezései milyen gyakran hívódnak meg.


Ez a folyamat arról szól, hogy megvizsgáljuk, mely adatokat kérdezik le gyakran, de ritkán frissítik. A gyakorlatban egy táblánál azt láttam, hogy naponta 1,74 millió lekérdezés történik, de a frissítési lekérdezések száma maximum 500 volt. Ilyen esetben bárki számára egyértelmű, hogy ez a tábla alkalmas a cache-be helyezésre ㅎㅎ


Azok az adatok, amelyek érzékenyek a frissítésre

Azok az adatok, amelyek érzékenyek a frissítésre, azt jelentik, hogy az RDB és a cache közötti eltérésnek rövidnek kell lennie. Például a fizetési információkkal kapcsolatos adatok esetében rendkívül fontos a frissítés, ezért még akkor is, ha megfelelnek a fenti cache feltételeknek, meg kell fontolni a használatukat.


A fenti két tulajdonságnak megfelelő fizetési információkkal kapcsolatos táblákat kellett cache-be helyeznem. Ezért nem alkalmaztam a cache-t minden olyan logikára, amely a fizetési táblákat használja, hanem csak a viszonylag biztonságosabb logikákra, ahol a fizetés nem történik meg.


Lokális cache vs. globális cache

Most már tudjuk, hogy milyen adatokat és milyen mértékben érdemes cache-be helyezni. De hol tároljuk ezeket az adatokat? Általában a lokális memóriába vagy egy külön szerverre, például Redis-be tárolhatjuk.


Lokális cache

A lokális cache azt jelenti, hogy az alkalmazásszerver memóriájában tároljuk a cache-be helyezendő adatokat, és általában a Guava cache vagy a Caffeine cache használatos.


Előnyök

  • Az alkalmazás logikájának végrehajtása közben azonnal lekérdezhető a cache ugyanazon a szerveren lévő memóriából, így nagyon gyors.
  • Könnyen implementálható.


Hátrányok

  • Ha több példány fut, akkor több probléma merül fel.


Globális cache

A globális cache azt jelenti, hogy külön szerveren tároljuk a cache adatokat, például Redis-ben.


Előnyök

  • A példányok megosztják a cache-t, így ha az egyik példány módosítja a cache-t, akkor minden példány a módosított értéket fogja látni.
  • Egy új példány indításakor nem kell feltölteni a cache-t, mert már létezik egy tároló, amelyhez hozzáférhet.


Hátrányok

  • Hálózati forgalom szükséges, így lassabb, mint a lokális cache.
  • Külön cache szerver szükséges, ami infrastruktúra költségeket generál.


Melyiket választottam?

A jelenlegi cég alkalmazásszervere több példányban fut, de mégis a lokális cache-t választottam.

Ennek három fő oka van.


  • Az RDB-ben tárolt cache-be helyezendő adatok száma körülbelül 40 000, ami a memóriába betöltve 4 MB-nál kevesebb.
  • A fizetési adatok lekérdezésének gyorsnak kell lennie.
  • Bár már van Redis, a cache új Redis-be történő tárolása további infrastruktúra költségeket generál.


Hogyan frissítsük a cache-t?

Ha több alkalmazásszerverünk van, és lokális cache-t használunk, akkor a cache értékei eltérhetnek a különböző alkalmazásszervereken. Például az A szerver cache-ben tárolt érték „1” lehet, míg a B szerver cache-ben tárolt érték „2”, mert a B szerver módosította. Ebben az esetben, ha a felhasználó a terheléselosztónak (load balancer) küld egy kérelmet, akkor az A és B szerverek különböző értékeket küldenek vissza.


Ezért minden példányban automatikusan el kell távolítani a cache-t, és az RDB-ből kell lekérdezni az adatokat. Ehhez a TTL-t használjuk.


Milyen értéket adjunk meg a TTL-nek?

A TTL (Time To Live) azt jelenti, hogy egy adott idő elteltével töröljük a cache-t. Például, ha a TTL értéke 5 másodperc, akkor a cache adatok 5 másodperc múlva automatikusan törlődnek. Ezután, ha cache-hiány lép fel, lekérdezzük az adatokat az RDB-ből, és eltároljuk a cache-ben.

De akkor mekkora legyen a TTL értéke?


Ha a read/write műveletek egy cache szerveren történnek

Ha a read/write műveletek egy globális cache szerveren, például Redis-ben, vagy egy lokális cache-t használó alkalmazásszerveren történnek, akkor a TTL értéke akár órákra is növelhető. Mindenesetre a write művelet során a meglévő cache frissül, és a szerver mindig a legfrissebb adatokat fogja látni.


Ebben az esetben nem is kell beállítani a TTL-t, hanem a cache szerver automatikusan törölheti a cache-t, ha megtelik, például az LRU algoritmus használatával.


Ha a read/write műveletek több cache szerveren történnek

Ha a read/write műveletek több globális cache szerveren vagy több, lokális cache-t használó alkalmazásszerveren történnek, akkor a TTL értéke másodpercekben vagy percekben legyen. Ez azért fontos, mert előfordulhat, hogy a módosított adatokat még nem tükröző, elavult adatokat olvasunk be egy cache szerverről.


A TTL értéke sok tényezőtől függ, de minél fontosabb a frissítés és minél nagyobb a változás valószínűsége, annál rövidebb legyen a TTL. Minél kevésbé fontos a frissítés és minél kisebb a változás valószínűsége, annál hosszabb lehet a TTL.


Hogyan állítottam be a TTL-t?

A cache-be helyezendő adatok fizetési adatok, és bár a fizetéshez kapcsolódó szigorú logikákban nem használunk cache-t, a fizetési adatok természetüknél fogva érzékenyek a frissítésre. Ugyanakkor a módosítás valószínűsége alacsony, ezért a TTL-t 5 másodpercre állítottam be, ami biztonságosabb.


Következtetés

Összefoglalva, a választott cache-elési módszer a következő:


  • Fizetési adatok
  • Nagyon gyakori lekérdezések, de ritka módosítások.
  • Csak azokban a logikákban alkalmazzuk a cache-t, amelyekben nem történik fizetés, de lekérdezések vannak.
  • Lokális cache-t használunk, és a TTL 5 másodperc.


A következő lépés a cache-elési módszer teljesítményének tesztelése lesz. Még nem döntöttem el pontosan, hogyan fogjuk végrehajtani a teljesítménymérés tesztelését, de erről egy későbbi bejegyzésben fogok írni!

Hozzászólások0