TEMEL
String İşlemleri
Temel key-value. Counter, cache, session, flag depolama.
Kod örneği görünümü
Bu sayfadaki eşleşen örnekleri seçilen istemciye göre gösterir.
# Temel CRUD
SET user:1:name "Erdem"
GET user:1:name # "Erdem"
DEL user:1:name
# TTL ile
SET session:abc "data" EX 3600 # 1 saat
TTL session:abc # kalan saniye
PERSIST session:abc # TTL kaldır
# Conditional
SET lock:resource "owner" NX EX 30 # sadece yoksa set et
SET counter 100 XX # sadece varsa set et
# Batch
MSET user:1:name "Erdem" user:1:email "a@b.com"
MGET user:1:name user:1:email
# Atomik sayaç
INCR pageviews:home
INCRBY user:1:score 50
DECRBY stock:product:1 1
public class StringOperationsService
{
private readonly IDatabase _redis;
public StringOperationsService(IConnectionMultiplexer mux)
=> _redis = mux.GetDatabase();
// Temel CRUD
public async Task BasicCrudAsync()
{
await _redis.StringSetAsync("user:1:name", "Erdem");
string? name = await _redis.StringGetAsync("user:1:name");
await _redis.KeyDeleteAsync("user:1:name");
}
// TTL ile cache
public async Task SetWithTtlAsync(string key, string value, TimeSpan expiry)
{
await _redis.StringSetAsync(key, value, expiry);
}
// Conditional set (distributed lock temeli)
public async Task<bool> TryAcquireLockAsync(string resource, string owner, TimeSpan expiry)
{
return await _redis.StringSetAsync(
$"lock:{resource}", owner, expiry, When.NotExists);
}
// Batch (roundtrip azaltır)
public async Task BatchSetAsync(Dictionary<string, string> pairs)
{
var entries = pairs.Select(p =>
new KeyValuePair<RedisKey, RedisValue>(p.Key, p.Value)).ToArray();
await _redis.StringSetAsync(entries);
}
// Atomik sayaç
public async Task<long> IncrementAsync(string key, long amount = 1)
{
return await _redis.StringIncrementAsync(key, amount);
}
// JSON serialize ile obje cache
public async Task<T?> GetOrSetAsync<T>(string key, Func<Task<T>> factory, TimeSpan ttl)
{
var cached = await _redis.StringGetAsync(key);
if (cached.HasValue)
{
try
{
return JsonSerializer.Deserialize<T>(cached!);
}
catch (JsonException)
{
// Corrupt/incompatible data — sil ve yeniden üret
await _redis.KeyDeleteAsync(key);
}
}
var value = await factory();
if (value is not null)
await _redis.StringSetAsync(key,
JsonSerializer.Serialize(value), ttl);
return value;
}
}
StringSet vs IDistributedCache: StackExchange.Redis doğrudan kullanımda her Redis komutuna erişirsin.
IDistributedCacheise sadeceGet/Set/Removesunar — başka provider'a geçiş kolaylığı sağlar ama Redis'in gücünü kısıtlar.
Cache Stampede: Yukarıdaki
GetOrSetAsyncbasit implementasyondur. Yoğun trafikte aynı key için eşzamanlı N request gelirse hepsi cache miss yaşar → N kez DB'ye gider. Çözüm: lock-based double-check pattern (Caching Patterns bölümündekiGetWithStampedeProtectionAsyncörneğine bak).