Skip to content

Perf: HybridCache (in-process L1) a ContentCache elé #70

Description

@Xentinus

Jelenség

A ContentCache minden olvasásnál Redis felé megy, akkor is, ha ugyanaz a folyamat egy pillanattal korábban már kiolvasta ugyanazt a kulcsot:

public async Task<T> GetOrSetAsync<T>(
    string key, Func<Task<T>> factory, TimeSpan? ttl = null, Func<T, bool>? shouldCache = null)
{
    try
    {
        var cached = await cache.GetStringAsync(key);

Ez a forró útvonalakon összeadódik. Egy főoldal-betöltés ma a works:list, skills:list, experiences:list és about kulcsot kéri, a SPA fallback ezen felül a meta és a routes kulcsot — vagyis hat Redis round-trip és hat JSON deszerializálás olyan adatra, ami hetekig nem változik. Ehhez jön minden csatolmány-kérés (attachments:slug:*), ott a payload is nagyobb (max 512 KB).

Ugyanaz a folyamat több példányban is deszerializálja ugyanazt a bájtsort, tehát nem csak hálózat, CPU is.

Javaslat

  1. Microsoft.Extensions.Caching.Hybrid (HybridCache) bevezetése a ContentCache belsejében: L1 in-process memória + L2 a meglévő Redis. A hívók felülete (GetOrSetAsync, InvalidateSectionAsync, InvalidateAboutAsync, InvalidateSlugAsync) ne változzon — a csere maradjon egyetlen fájlon belül.
  2. Az L1 TTL legyen rövid (30–60 s), az L2 marad a mai DefaultTtl (1 nap). Két host fut, tehát egy admin írás után a publikus host L1 másolata legfeljebb az L1 TTL-ig lehet elavult.
  3. Az invalidálás a kritikus rész. Ma az admin írás Redis kulcsokat dob, ami a másik folyamatra is hat. L1-gyel ez nem elég: a publikus host memóriájában lévő példányt semmi nem dobja. Két megoldás:
    • HybridCache tag-alapú invalidálás (RemoveByTagAsync) + Redis pub/sub értesítés a másik hostnak (a IConnectionMultiplexer már injektálva van)
    • vagy szándékosan rövid L1 TTL, és a tudomásul vett legfeljebb ~1 perces késés
      A döntést a ContentCache XML kommentjében kell rögzíteni, mert ez viselkedésváltozás a mai "minden írás azonnal látszik" garanciához képest.
  4. A fail-open viselkedés maradjon: ha a Redis nem elérhető, az L1 és a factory (adatbázis) továbbra is kiszolgál. Ez ma explicit tesztelt viselkedés (ContentCacheTests), a teszteknek L1-gyel is át kell menniük.
  5. Mérés előtte/utána: a ContentCache LogDebug hit/miss sorai már megvannak ehhez, plusz egy egyszerű terheléses összehasonlítás a főlapra.

Érintett fájlok

  • PortfolioCMS.Core/Services/ContentCache.cs
  • PortfolioCMS.Core/Extensions/CoreStartupExtensions.cs (regisztráció)
  • PortfolioCMS.Core/Controllers/AttachmentsController.cs (a legnagyobb payload, érdemes külön mérni)
  • PortfolioCMS.Tests/ContentCacheTests.cs
  • PortfolioCMS.*/packages.lock.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions