Blog

CRDT’ler Neden Sadece Düzenlemeleri Birleştirir?

Alper Kocan 09 June 2026 37 görüntülenme

Selamlar, ben Alper. Bugün yazılım dünyasının son yıllarda iyice popülerleşen, özellikle "real-time" (gerçek zamanlı) iş birliği araçlarının kalbinde yatan bir konuyu, yani CRDT (Conflict-free Replicated Data Types - Çatışmasız Çoğaltılmış Veri Tipleri) kavramını konuşacağız. Eğer Google Docs gibi aynı anda birden fazla kişinin yazı yazdığı bir uygulama geliştirmeyi düşündüyseniz, karşınıza çıkan en büyük engel "çatışmalar" (conflicts) olmuştur. CRDT'ler bu çatışmaları matematiksel bir zarafetle çözüyor. Ancak akıllarda hep o soru var: "Düzenlemeleri birleştiriyoruz da, aynı anda bir şeyler oluşturduğumuzda neden bu kadar büyük bir olay olmuyor?" Gelin, bu konuyu derinlemesine ama bir o kadar da sade bir dille inceleyelim.

CRDT Nedir ve Neyi Çözer?

Öncelikle kısa bir özet geçelim. Dağıtık bir sistemde (distributed system), verinin kopyaları farklı makinelerde bulunur. İki kullanıcı aynı anda aynı veriyi değiştirdiğinde, bu değişikliklerin bir noktada senkronize edilmesi gerekir. Geleneksel yöntemlerde bir "merkezi sunucu" (central server) hakemlik yapar. Ancak CRDT'ler, merkezi bir hakeme ihtiyaç duymadan, her kopyanın bağımsızca güncellenebildiği ve sonunda herkesin aynı sonuca ulaştığı eventual consistency (nihai tutarlılık) sağlayan veri yapılarıdır.

CRDT'lerin en büyük sihri, matematiksel özelliklerinde yatar. Bu yapılar commutative (değişmeli) özelliktedir. Yani işlemlerin hangi sırayla yapıldığı önemli değildir; sonuç hep aynı çıkar. Siz bir harf eklediniz, arkadaşınız bir kelime sildi; bu işlemlerin sunucuya hangi sırayla ulaştığının bir önemi kalmaz.

Neden Hep "Düzenleme" (Edit) Üzerinden Konuşuyoruz?

CRDT denince akla hemen metin editörleri gelir. Çünkü metin üzerinde yapılan işlemler (karakter ekleme veya silme), aslında birer "güncelleme" veya "düzenleme" işlemidir. Bir belgenin ortasına bir "A" harfi eklemek, mevcut veri yapısını mutasyona uğratmaktır. CRDT'ler, bu mutasyonların çakışmamasını sağlamak için her karaktere eşsiz bir kimlik ve bir konum (index) atar.

Peki ya "oluşturma" (creation)? Neden "Aynı anda iki kişi aynı dosyayı oluşturursa ne olur?" sorusu, "Aynı anda iki kişi aynı cümleyi değiştirirse ne olur?" sorusu kadar sık sorulmuyor? İşte işin püf noktası burada başlıyor.

Oluşturma Aslında Bir İllüzyondur

Teknik olarak baktığımızda, CRDT dünyasında "oluşturma" (creation) diye ayrı bir kategoriye pek ihtiyaç duyulmaz. Bunun birkaç temel sebebi vardır:

  • Eşsiz Kimlikler (UUIDs): Dağıtık sistemlerde nesne oluştururken genellikle UUID (Universally Unique Identifier) kullanılır. Eğer iki kullanıcı aynı anda bir "Kullanıcı" nesnesi oluşturuyorsa, bunlar aslında iki farklı nesnedir. Sistem bunları "aynı şeyin iki farklı versiyonu" olarak değil, "iki farklı yeni şey" olarak görür. Dolayısıyla bir çakışma (conflict) yaşanmaz; sadece listeye iki yeni eleman eklenmiş olur.
  • Kümeler (Sets) ve Ekleme İşlemi: CRDT'lerde veri genellikle kümeler (sets) içinde tutulur. Yeni bir öğe oluşturmak, kümeye bir eleman eklemek (add operation) demektir. CRDT'nin OR-Set (Observed-Remove Set) gibi yapıları, aynı elemanın birden fazla kez eklenmesini veya aynı anda silinip eklenmesini matematiksel olarak zaten çözer.
  • Kök Nesne (Root Object): Çoğu uygulamada "oluşturma" işlemi, aslında mevcut bir üst nesnenin (örneğin bir klasörün veya bir listenin) güncellenmesidir. Yani teknik olarak yine bir "düzenleme" (edit) işlemine dönüşür.

Peki Ya Aynı Kimlikle Oluşturmaya Çalışırsak?

İşte zurnanın zırt dediği yer burası. Eğer sisteminiz kullanıcıların kendi kimliklerini (örneğin kullanıcı adı) belirlemesine izin veriyorsa ve iki kişi aynı anda "alper" kullanıcı adını almaya çalışırsa ne olur? Bu bir semantic conflict (anlamsal çatışma) türüdür.

CRDT'ler veri yapısı düzeyinde (data structure level) çatışmaları çözer, ancak iş mantığı (business logic) düzeyindeki çatışmaları çözmek için ek katmanlara ihtiyaç duyarlar. Eğer iki kişi aynı kimlikle bir şey oluşturursa, CRDT bunu genellikle bir "birleştirme" (merge) işlemi olarak görür. Yani iki ayrı "oluşturma" isteği, aslında aynı nesnenin farklı alanlarını güncelleyen iki "düzenleme" isteği gibi işlenir. Sonuçta iki kullanıcının gönderdiği veriler birleşir (LWW - Last Write Wins veya benzeri bir yöntemle).

Neden Eşzamanlı Oluşturma Bir Problem Değil?

Özetlemek gerekirse, CRDT'lerin "oluşturma" aşamasında özel bir çaba sarf etmemesinin sebebi, oluşturma işleminin aslında veri yapısı perspektifinden bakıldığında bir insert (ekleme) veya update (güncelleme) olmasıdır.

  • Bağımsızlık: Her yeni oluşturulan nesne kendi eşsiz ID'si ile doğduğu için birbirlerinin ayağına basmazlar.
  • Birleştirme Mantığı: Eğer kazara aynı ID ile iki nesne oluşturulursa, CRDT'nin birleştirme algoritmaları (örneğin LWW-Element-Set) devreye girer ve hangi verinin kalacağına karar verir.
  • Tombstones (Mezar Taşları): Bir nesne silindiğinde bile CRDT onu tamamen yok etmez, üzerine bir "silindi" işareti (tombstone) koyar. Böylece biri o nesneyi düzenlerken diğeri silerse, sistem kimin haklı olduğuna karar verebilir.

Sonuç Olarak

CRDT'ler, "eşzamanlı düzenleme" (concurrent editing) konusuna odaklanır çünkü gerçek dünyadaki en karmaşık ve iç içe geçmiş çatışmalar orada yaşanır. "Oluşturma" ise genellikle eşsiz kimlikler ve küme mantığıyla kendiliğinden çözülen, daha doğrusal bir problemdir. Eğer bir gün kendi dağıtık sisteminizi kurarsanız, nesnelerinize sağlam birer UUID vermeyi unutmayın; geri kalan karmaşayı CRDT sizin yerinize halledecektir.

Bir sonraki yazıda görüşmek üzere, kodunuz hatasız, veriniz tutarlı olsun!

Yorumlar (0)
Yorum Yap