1 of 49

FusionCache: hybrid caching in .NET

Jody Donetti

R&D + coding

FusionCache

Free + OSS

2 of 49

Jody Donetti

R&D + coding

Faccio cose (principalmente) sul web da quasi 30 anni.

Ho avuto a che fare con la maggior parte dei tipi di cache: memory, distributed, hybrid, HTTP, CDN, offline.

🏆 Google Open Source Award

🏆 Microsoft MVP Award

3 of 49

FusionCache

Free + OSS

E’ una hybrid cache facile da usare, veloce e robusta con funzionalità di resilienza avanzate.

Battle tested in produzione da anni, usata anche da Microsoft (eg: Data API Builder).

⬇️ 6M+ downloads

⭐ 1600+ stars

https://github.com/ZiggyCreatures/FusionCache

4 of 49

5 of 49

🧠 Cosa significa usare una cache?

6 of 49

🧠 Cosa significa usare una cache?

Accettare un compromesso.

Utilizzare una copia del dato originale

potenzialmente non aggiornata

in cambio di performance

e robustezza.

7 of 49

🧠 Quanto è importante?

E’ parte delle fondamenta stesse del web:

  • 1990: HTTP 1.0 con header Pragma (poi deprecato)
  • 1997: HTTP 1.1 con header Cache-Control
  • varie estensioni successive come ETag, stale-while-revalidate, etc

Senza caching il web non esisterebbe.

8 of 49

🧠 Quanto è importante?

Di nuovo: senza caching il web non esisterebbe.

Gheto capio? 😬

9 of 49

🤓 Tipi di cache

Quali sono i principali tipi di cache?

In breve:

  • memory cache: vedi IMemoryCache, RCache (a breve, forse)
  • distributed cache: vedi IDistributedCache + implementazioni per Redis, Memcached, etc
  • hybrid cache: come FusionCache, HybridCache di Microsoft (a breve, forse)

Pro e contro?

10 of 49

🤓 Memory Cache

E’ il tipo di cache base, rappresenta una cache in-memory (in-process).

In pratica, è un concurrent dictionary + expiration.

Caratteristiche principali:

✅ data locality: i dati sono nella stessa memoria dell’applicazione

✅ cost: no chiamate remote, no (de)serializzazione

✅ always there: sempre disponibile

❌ cold starts: ad ogni riavvio la cache è vuota

❌ scaling orizzontale: dati non condivisi con altri nodi

11 of 49

🤓 Distributed Cache

Rappresenta tipicamente un key-value store remoto (eg: Redis, Memcached).

Caratteristiche principali:

❌ data locality: i dati sono out of process, tipicamente remoti

❌ cost: chiamate remote + (de)serializzazione

❌ always there: potrebbe non essere sempre disponibile

✅ cold starts: ad ogni riavvio la cache è già popolata

✅ scaling orizzontale: dati condivisi con altri nodi

NOTA: più precisamente è «out of process», vedi SQLite.

12 of 49

🤓 Hybrid Cache

E’ il tipo di cache più avanzato.

Può essere composta da un solo livello (L1, memory) o da più livelli (L1 + L2, memory + distributed).

Gestisce in modo trasparente il coordinamento fra i diversi livelli e più nodi.

Caratteristiche principali:

✅ data locality: i dati sono nella stessa memoria dell’applicazione (L1)

✅ cost: no chiamate remote, no (de)serializzazione (L1)

✅ always there: sempre disponibile (L1)

✅ cold starts: ad ogni riavvio L1 è vuota, ma si popola automaticamente da L2 (già popolata)

✅ scaling orizzontale: dati condivisi con altri nodi (L2)

In breve: unisce il meglio di entrambi i mondi, memory e distributed.

13 of 49

14 of 49

🦥 FusionCache

Hybrid cache basata su IMemoryCache (L1) + IDistributedCache (L2, opzionale).

Supporta:

  • dependency injection + builder
  • sync/async
  • options (default + granular)
  • named caches
  • cancellation (via CancellationToken)
  • logging (via ILogger)
  • observability (traces + metrics, via OTEL)
  • docs (IntelliSense + online)
  • licenza MIT
  • .NET Standard 2.0 (old + new)

15 of 49

🦥 FusionCache

16 of 49

😩��“C’ho Probblemi”�(cit. Herbert Ballerina)

17 of 49

🛡️ Cache Stampede

18 of 49

🛡️ Cache Stampede Prevention

Basta usare il metodo GetOrSet() invece che Get() + Set() separate.���������������

⚠️ GetOrCreate() in MemoryCache non protegge da Cache Stampede

19 of 49

🛡️ Cache Stampede (dopo)

20 of 49

💣 Database Failures

💀

💥

💥

💥

21 of 49

💣 Fail-Safe

���������������💪 aiuto contro attacchi DDoS

❤️ Sidney Lumet

22 of 49

💣 Database Failures (dopo)

💀

💥

💥

👍

23 of 49

⏱️ Database Lento

24 of 49

⏱️ Timeouts (Soft + Hard)

���������������⚡ Background Factory Completion (niente sprechi!)

🌍 SEO (Web Vitals: TTFB/LCP/CLS)

25 of 49

⏱️ Database Lento (dopo)

26 of 49

🦅 Eager Refresh

Se arriva una richiesta dopo X % della Duration, esegui un background refresh non bloccante.���������������ℹ️ Valori ragionevoli possono essere da 80% (0.8) in su

⚠️ Valori troppo bassi come 10% (0.1) creerebbero un ciclo continuo di refresh, sovraccaricando il database

27 of 49

🧙‍♂️ Adaptive Caching

28 of 49

🔂 Conditional Refresh

29 of 49

🔀 2nd Level

Basta aggiungere un setup iniziale:

������������ℹ️ Qualunque implementazione di IDistributedCache è supportata (Redis, Memcached, etc)

30 of 49

🧑‍🎤 Sincronicità

Ogni nodo ha una sua memory cache.

A fronte di un update su un nodo, vengono aggiornati:

  • il database
  • la cache distribuita
  • la memory cache di quel nodo

Se quel dato fosse però già presente nella memory cache di altri nodi, si creerebbe un problema di disallineamento.

31 of 49

📢 Backplane

Basta aggiungere un setup iniziale:

���������

32 of 49

🐲 Hic Sunt Dracones

La distributed cache ed il backplane sono component distribuiti: Fallacies of Distributed Computing (vedere Wikipedia)!��E quindi cosa succede se, per esempio, database e memory cache funzionano correttamente ma la distributed cache risulta temporaneamente non disponibile?

O il backplane? O entambi?�

Oppure avvengono 2 operazioni, per lo stesso dato, in rapida successione e su due nodi diversi e le relative chiamate a distributed cache e backplane hanno errori transienti?

O dei ritardi? O un mix di errori transienti e ritardi?��Oppure...

33 of 49

↩️ Auto-Recovery

������������😉 Demo a breve...

34 of 49

🔭 Observability

Full observability, including OpenTelemetry, for:

  • Logs
  • Traces
  • Metrics

35 of 49

🔭 Observability (risultati)

Utilizzabile con qualunque software compatibile con OpenTelemetry come Jaeger, Prometheus, Honeycomb, etc.

36 of 49

😑 Aspetta, non sto capendo

I sistemi distribuiti in generale possono diventare molto complessi.

Le nostre infrastrutture possono diventare molto complesse, ed essere anche distribuite.

Il caching può essere molto complesso, ed essere anche distribuito.

FusionCache è una cache ibrida, opzionalmente distribuita, che lavora con le nostre infrastrutture, anch’esse distribuite.

“Ah, ok” (cit)

37 of 49

🖥️ Simulator

38 of 49

🖥️ Demo Time

39 of 49

🦥 FusionCache

40 of 49

🦥 Idealmente

�����������������Ci aiuta quando 💩 hits the fan

41 of 49

42 of 49

🆕 HybridCache (from Microsoft)

Col rilascio di .NET 9 verso metà/fine novembre Microsoft introdurrà una sua hybrid cache, chiamata HybridCache (bel nome 😏).

Usa IMemoryCache (L1) + IDistributedCache (L2, opzionale).

Offre Cache Stampede protection e eviction notification (vedi Backplane di FusionCache).

Si, suona familiare 🙂

Oltre ad essere una implementazione di base è anche una shared abstraction (nota: abstract class, non interface): idealmente potrebbe diventare una sorta di lingua franca per le hybrid cache in .NET, come IDistributedCache lo è già per le cache distribuite.

43 of 49

🆕 HybridCache e FusionCache

Feature in comune (sia FusionCache che HybridCache):

  • Cache Stampede protection
  • L1 only (memory)
  • L1 + L2 (memory + distributed)
  • multi-node notifications (in FusionCache it is the Backplane)

44 of 49

🆕 HybridCache e FusionCache

Feature esclusive di FusionCache:

  • Fail-Safe
  • Soft/Hard Timeouts
  • Adaptive Caching
  • Conditional Refresh
  • Eager Refresh
  • Auto-Recovery
  • Multiple Named Caches (via IFusionCacheProvider o keyed services)
  • Background Distributed Operations
  • Observability: Logging + OpenTelemetry
  • Events
  • Full sync + async (HybridCache sarà async-only)

45 of 49

🆕 HybridCache e FusionCache

Feature esclusive di Microsoft HybridCache (forse):

  • Eviction By Tags
  • Compression

NOTA: in realtà sto già lavorando ad entrambe.

46 of 49

🆕 HybridCache e FusionCache

E FusionCache in tutto questo?

FusionCache continuerà a progredire ed evolversi come ha fatto fino ad oggi, in modo indipendente.

Ma: sarà anche disponibile come implementazione 3rd party di HybridCache di Microsoft (sarà la prima).

Più info https://github.com/ZiggyCreatures/FusionCache/discussions/266

47 of 49

🖥️ Demo Time

48 of 49

❤️ Grazie

49 of 49

👋 Contatti

/jodydonetti

/jody-donetti

/jody-donetti

/ZiggyCreatures/FusionCache

/FusionCache