← Back to Blog
MIMARI

Distributed Locking Nedir?

F. Çağrı BilgehanJanuary 22, 202610 min read
distributed lockingredisdağıtık sistemeşzamanlılık

Distributed Locking Nedir? Dağıtık Kilit Yönetimi

Birden fazla sunucu aynı kaynağa aynı anda mı erişiyor? İki instance aynı anda stok mu düşürüyor? Distributed Locking ile dağıtık ortamda kaynaklara güvenli, sıralı erişim sağlayın.

Problem

Tek sunucuda mutex/lock yeterlidir. Ama birden fazla sunucuda:

Server A: stok oku (10) → 10 - 1 = 9 → yaz (9)
Server B: stok oku (10) → 10 - 1 = 9 → yaz (9)

Sonuç: 2 ürün satıldı ama stok 10→9 (1 kayıp!)

Redis ile Distributed Lock

class DistributedLock {
  constructor(private redis: Redis) {}

  async acquire(resource: string, ttl: number = 10000): Promise<string | null> {
    const token = crypto.randomUUID();
    const acquired = await this.redis.set(
      `lock:${resource}`,
      token,
      'NX',  // Sadece yoksa oluştur
      'PX',  // Milisaniye TTL
      ttl
    );
    return acquired ? token : null;
  }

  async release(resource: string, token: string): Promise<boolean> {
    // Lua script: sadece sahibi silebilir (atomic)
    const script = `
      if redis.call("get", KEYS[1]) == ARGV[1] then
        return redis.call("del", KEYS[1])
      else
        return 0
      end
    `;
    const result = await this.redis.eval(script, 1, `lock:${resource}`, token);
    return result === 1;
  }
}

Kullanım

const lock = new DistributedLock(redis);

async function processOrder(orderId: string) {
  const token = await lock.acquire(`order:${orderId}`);
  if (!token) throw new Error('Kaynak meşgul, tekrar deneyin');

  try {
    const stock = await db.getStock(productId);
    if (stock <= 0) throw new Error('Stok yok');
    await db.decrementStock(productId);
    await db.createOrder(orderId);
  } finally {
    await lock.release(`order:${orderId}`, token);
  }
}

Redlock Algoritması

Tek Redis instance'ı çökerse kilit kaybolur. Redlock, 5+ bağımsız Redis instance'ı kullanır:

1. Tüm 5 instance'a kilit isteği gönder
2. Çoğunluk (3/5) onaylarsa kilit alındı
3. Kilit süresi = TTL - edinme süresi
4. Başarısızsa tüm instance'lardan kilidi kaldır

Fencing Token

Kilit süresinin dolması durumunda eski kilit sahibinin işlem yapmasını engelle:

Client A: kilit al (token: 34) → yavaş işlem...
           ...kilit süresi doldu!
Client B: kilit al (token: 35) → işlem başla

Veritabanı:
  IF token >= last_token THEN execute
  34 < 35 → Client A'nın geç gelen yazmasını reddet

Distributed Lock Araçları

| Araç | Mekanizma | Avantaj | |------|-----------|---------| | Redis | SET NX PX | Hızlı, basit | | Redlock | Multi-Redis | Daha güvenilir | | ZooKeeper | Ephemeral node | Güçlü garanti | | etcd | Lease | Kubernetes native | | PostgreSQL | Advisory lock | Ek altyapı gereksiz |

Ne Zaman Distributed Lock?

  • ✅ Stok kontrolü (çift satış önleme)
  • ✅ Cron job tekrarını önleme
  • ✅ Payment processing (çift çekim)
  • ✅ Rate limiting (dağıtık sayaç)

Best Practices

  1. TTL zorunlu — Deadlock önlemek için kilide ömür verin
  2. Atomic release — Lua script ile sadece sahibi silsin
  3. Retry with backoff — Kilit alınamazsa exponential backoff
  4. Fencing token — Gecikmiş işlemleri engelleyin
  5. Kilidi mümkün olduğunca kısa tutun — Lock scope'u minimize edin
  6. Monitoring — Kilit bekleme süresini ve timeout'ları izleyin

Sonuç

Distributed Locking, dağıtık sistemlerde kaynak çakışmasını önlemenin temel yoludur. Redis basit senaryolar için yeterli, kritik sistemlerde Redlock veya ZooKeeper tercih edin. Her zaman TTL ve fencing token kullanmayı unutmayın.

Distributed locking ve dağıtık sistem konularını LabLudus platformunda öğrenin.

Related Posts

Message Queue Nedir?

Message Queue nedir ve neden kullanılır?

Yazılım Mimarisi Nedir? Temelden İleri Seviyeye Kapsamlı Rehber

Yazılım mimarisi nedir, neden önemlidir ve nasıl öğrenilir?