DevOps & Cloud

Redis Cache-Verwaltung: .NET Core & Leistungsoptimierung

11 Min. Lesezeit16. März 2026
Redis cacheRedis .NETDistributed cacheRedis TürkiyeCache yönetimiRedis pub/subSignalR Redis backplanePerformans optimizasyonuRedis sessionIn-memory cache

Redis ist ein leistungsstarker In-Memory-Datenstrukturspeicher, der fuer Distributed Cache, Session-Verwaltung, Nachrichtenwarteschlangen und Echtzeitanwendungen unverzichtbar ist. Im .NET-Oekosystem laesst sich Redis nahtlos ueber die IDistributedCache-Schnittstelle integrieren und dient als SignalR-Backplane fuer die Echtzeitkommunikation ueber mehrere Serverinstanzen hinweg.

Redis .NET-Integration

Grundlegende Verwendung mit IDistributedCache

Die IDistributedCache-Schnittstelle von .NET bietet eine anbieterunabhaengige Abstraktion. Der Wechsel zu Redis erfordert nur eine Registrierungsaenderung.

csharp
// Program.cs - Redis Cache Registrierung
builder.Services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = builder.Configuration.GetConnectionString("Redis");
    options.InstanceName = "MyApp:";
});

// Cache-Verwendung in der Serviceschicht
public class ProductService
{
    private readonly IDistributedCache _cache;
    private readonly ApplicationDbContext _context;
    private static readonly DistributedCacheEntryOptions CacheOptions = new()
    {
        AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30),
        SlidingExpiration = TimeSpan.FromMinutes(10)
    };

    public ProductService(IDistributedCache cache, ApplicationDbContext context)
    {
        _cache = cache;
        _context = context;
    }

    public async Task<ProductDto?> GetProductAsync(int id, CancellationToken ct)
    {
        var cacheKey = $"product:{id}";

        // Aus dem Cache lesen
        var cached = await _cache.GetStringAsync(cacheKey, ct);
        if (cached is not null)
            return JsonSerializer.Deserialize<ProductDto>(cached);

        // Aus der Datenbank abrufen und in den Cache schreiben
        var product = await _context.Products
            .Where(p => p.Id == id)
            .Select(p => new ProductDto(p.Id, p.Name, p.Price))
            .FirstOrDefaultAsync(ct);

        if (product is not null)
        {
            var json = JsonSerializer.Serialize(product);
            await _cache.SetStringAsync(cacheKey, json, CacheOptions, ct);
        }

        return product;
    }
}

Erweiterte Operationen mit StackExchange.Redis

Fuer die volle Nutzung der Redis-Funktionalitaet koennen Sie die StackExchange.Redis-Bibliothek direkt verwenden:

csharp
// Redis Connection Multiplexer Registrierung
builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
{
    var config = ConfigurationOptions.Parse(
        builder.Configuration.GetConnectionString("Redis")!);
    config.AbortOnConnectFail = false;
    config.ConnectRetry = 3;
    config.ConnectTimeout = 5000;
    return ConnectionMultiplexer.Connect(config);
});

// Erweiterte Redis-Operationen
public class RedisCacheService
{
    private readonly IDatabase _db;

    public RedisCacheService(IConnectionMultiplexer redis)
    {
        _db = redis.GetDatabase();
    }

    // Sorted Set fuer Rangliste
    public async Task UpdateLeaderboardAsync(string userId, double score)
    {
        await _db.SortedSetAddAsync("leaderboard", userId, score);
    }

    // Distributed Lock
    public async Task<bool> AcquireLockAsync(string resource, TimeSpan expiry)
    {
        return await _db.StringSetAsync(
            $"lock:{resource}", Environment.MachineName, expiry, When.NotExists);
    }
}

SignalR Redis Backplane

Wenn Ihre Anwendung auf mehreren Servern laeuft, muessen SignalR-Nachrichten an alle Server uebermittelt werden. Das Redis-Backplane loest dieses Problem.

csharp
// Program.cs - SignalR Redis Backplane Konfiguration
builder.Services.AddSignalR()
    .AddStackExchangeRedis(builder.Configuration.GetConnectionString("Redis")!, options =>
    {
        options.Configuration.ChannelPrefix = RedisChannel.Literal("MyApp");
    });

Cache-Strategien und Invalidierung

Cache-Invalidierung ist eines der schwierigsten Probleme in verteilten Systemen. Eine falsche Invalidierung fuehrt zu veralteten Daten oder unnoetigen Cache-Misses:

  • Cache-Aside: Daten werden zuerst aus dem Cache gelesen; falls nicht vorhanden, aus der Quelle abgerufen
  • Write-Through: Datenbank und Cache werden gleichzeitig aktualisiert
  • TTL-basiert: Automatische Ablaufzeit fuer einfache Invalidierung
  • Event-basiert: Aktives Loeschen des Caches bei Datenaenderungen
  • Pattern-basiert: Massenhaftes Loeschen basierend auf Key-Mustern
csharp
// Pattern-basierte Cache-Invalidierung
public class CacheInvalidationService
{
    private readonly IConnectionMultiplexer _redis;

    public CacheInvalidationService(IConnectionMultiplexer redis)
    {
        _redis = redis;
    }

    // Cache fuer alle Produkte einer Kategorie invalidieren
    public async Task InvalidateCategoryProductsAsync(int categoryId)
    {
        var server = _redis.GetServer(_redis.GetEndPoints().First());
        var db = _redis.GetDatabase();

        var keys = server.Keys(pattern: $"MyApp:product:category:{categoryId}:*");
        foreach (var key in keys)
        {
            await db.KeyDeleteAsync(key);
        }
    }
}

Redis Streams fuer Event-Driven Architektur

Redis Streams ermoeglicht den Aufbau eines Kafka-aehnlichen Nachrichtensystems auf Redis. Mit Consumer Groups koennen Nachrichten auf mehrere Verbraucher verteilt werden:

csharp
// Nachrichten mit Redis Streams veroeffentlichen
public async Task PublishOrderEventAsync(OrderEvent orderEvent)
{
    var db = _redis.GetDatabase();
    var entries = new NameValueEntry[]
    {
        new("type", orderEvent.Type),
        new("orderId", orderEvent.OrderId.ToString()),
        new("data", JsonSerializer.Serialize(orderEvent))
    };

    await db.StreamAddAsync("order-events", entries, maxLength: 10000);
}

Redis-Ueberwachung und Leistungsanalyse

Monitoring mit redis-cli

In Produktionsumgebungen ist redis-cli ein leistungsstarkes Werkzeug zur Ueberwachung:

bash
# Redis-Serverstatistiken
redis-cli INFO stats

# Speichernutzungsdetails
redis-cli INFO memory

# Langsame Abfragen protokollieren (langsamer als 10ms)
redis-cli CONFIG SET slowlog-log-slower-than 10000
redis-cli SLOWLOG GET 10

# Key-Anzahl und Groessenanalyse
redis-cli DBSIZE
redis-cli --bigkeys

Speicheroptimierung

  • maxmemory-policy: allkeys-lru ist die haeufigste Wahl und loescht die am wenigsten genutzten Keys
  • Key-Ablaufzeit: Fuer jeden Key eine angemessene TTL festlegen
  • Datenkompression: Grosse JSON-Werte mit LZ4 oder Gzip komprimieren
  • Hash vs String: Fuer kleine Objekte mit wenigen Feldern ist die Hash-Datenstruktur speichereffizienter
  • Key-Benennung: Kurze aber aussagekraeftige Key-Namen verwenden

Praktische Tipps

  1. Cache-Key-Design: Konsistente und aussagekraeftige Benennung verwenden
  2. TTL-Strategie: Angemessene Ablaufzeiten fuer jeden Datentyp definieren
  3. Monitoring: Leistung mit Redis INFO und RedisInsight ueberwachen
  4. Speicherverwaltung: maxmemory nicht ueber 70% des Server-RAMs setzen
  5. Serialisierung: System.Text.Json fuer schnelle Serialisierung verwenden

Redis kann die Leistung Ihrer Anwendung bei korrekter Verwendung vervielfachen. Der Schluessel liegt in der Wahl der richtigen Datenstruktur und Cache-Strategie fuer jedes Szenario.

Verwandte Artikel

Haben Sie ein Flutter-Projekt?

Ich entwickle hochleistungsfähige Flutter-Anwendungen für iOS, Android und Web.

Kontakt aufnehmen