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
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.
- 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.
- 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.
- 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.
- 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
Jelenség
A
ContentCacheminden olvasásnál Redis felé megy, akkor is, ha ugyanaz a folyamat egy pillanattal korábban már kiolvasta ugyanazt a kulcsot:Ez a forró útvonalakon összeadódik. Egy főoldal-betöltés ma a
works:list,skills:list,experiences:listésaboutkulcsot kéri, a SPA fallback ezen felül ametaés arouteskulcsot — 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
Microsoft.Extensions.Caching.Hybrid(HybridCache) bevezetése aContentCachebelsejé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.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.HybridCachetag-alapú invalidálás (RemoveByTagAsync) + Redis pub/sub értesítés a másik hostnak (aIConnectionMultiplexermár injektálva van)A döntést a
ContentCacheXML kommentjében kell rögzíteni, mert ez viselkedésváltozás a mai "minden írás azonnal látszik" garanciához képest.ContentCacheTests), a teszteknek L1-gyel is át kell menniük.ContentCacheLogDebughit/miss sorai már megvannak ehhez, plusz egy egyszerű terheléses összehasonlítás a főlapra.Érintett fájlok
PortfolioCMS.Core/Services/ContentCache.csPortfolioCMS.Core/Extensions/CoreStartupExtensions.cs(regisztráció)PortfolioCMS.Core/Controllers/AttachmentsController.cs(a legnagyobb payload, érdemes külön mérni)PortfolioCMS.Tests/ContentCacheTests.csPortfolioCMS.*/packages.lock.json