İçeriğe geç
edumintsBlog
Backend4 dk okuma

Dağıtık SQLite'ın On İki Yılı

Kaynak: Hacker News

Paylaş
BackendEdumints Blog
İçindekiler 4 başlık

Eylül 2014'te Philip O'Toole, rqlite projesini duyuran kısa bir yazı yayınladı. Temel fikir oldukça basitti: SQLite'ı almak, önüne bir Raft günlüğü (log) koymak ve bir düğümün (node) kaybının veri kaybı anlamına gelmemesi için her yazma işlemini bir kümeye (cluster) kopyalamak. Kaynak kodları aynı hafta sonu GitHub'a yüklendi. Bu proje, Raft ve SQLite'ı birleştiren ilk açık kaynaklı sistemdi. Yıllarca kimse benzer bir girişimde bulunmadı.

Bugün "dağıtık SQLite", içinde bir düzine proje barındıran, bazıları girişim sermayesi (venture-funded) desteği almış ve ikisi satın alınmış başlı başına bir kategori haline geldi. Günümüzde bu kategori hakkında yazanlar hikayeyi genellikle 2021 yılından başlatsa da, sürecin gerçek başlangıcı 2014 yılına dayanmaktadır.

2014: rqlite#

Projenin arkasındaki ihtiyaç oldukça somuttu. Yazarın jut.io'da üzerinde çalıştığı kümelenmiş bir sistem, az miktarda ilişkisel depolamaya ihtiyaç duyuyordu ve bu veriyi hangi düğümün tutacağı sorusunun iyi bir cevabı yoktu. SQLite'ı bir fikir birliği (consensus) protokolüyle çoğaltmak bu sorunu çözdü. Şirket içinde farklı bir yol izlenmiş olsa da, problem genel ve çözüm kompakt olduğu için rqlite geliştirilmeye devam edildi.

İlk sürümde, o dönemde InfluxDB ve etcd'nin de kullandığı goraft kütüphanesi tercih edildi. 2016'nın başlarında ise sistem, bugün hala rqlite tarafından kullanılan Hashicorp'un Raft uygulamasıyla değiştirildi. En önemli tasarım kararı o zaman verildi ve hiç değişmedi: rqlite bir CP (Tutarlılık ve Bölümleme Toleransı) sistemidir.

  • Yazma işlemleri mutlaka lider (leader) üzerinden geçmelidir.
  • Çoğunluğun (majority) işlemi onaylaması gerekir.
  • Ağdan kopan azınlık düğümler yazma işlemlerini reddeder.
  • HTTP API'si, okuma tutarlılığı seviyeleri ve anlık görüntü (snapshotting) mekanizmalarının tamamı bu temel mimari karardan türetilmiştir.

Geliştiriciler İçin Çıkarım: Bir sistem tasarlarken CAP teoremindeki konumunuzu (örneğin CP seçimi) en başta netleştirmek, API tasarımından veri yedekleme stratejilerine kadar tüm alt kararları doğrudan şekillendirir ve mimariyi basitleştirir.

2014 Öncesi ve Eşzamanlı Gelişmeler#

Tarihsel doğruluk adına iki önemli projeden daha bahsetmek gerekir:

  • Bedrock (Expensify): Expensify, kendi altyapısı içinde yıllarca Paxos benzeri bir protokolle SQLite'ı çoğaltıyordu ve bunu 2016 yılında Bedrock adıyla açık kaynak olarak yayınladı.
  • ActorDB: Her "aktöre" Raft ile çoğaltılan kendi SQLite veritabanını veren Erlang tabanlı bu sistem, rqlite ile yaklaşık aynı zamanlarda ortaya çıktı.

Her iki proje de kendi doğdukları ortamın dışında geniş çapta benimsenmedi, ancak bu fikrin o dönemde zaten olgunlaşmakta olduğunu gösterdiler. rqlite'ın asıl başarısı, bu yaklaşımı herkesin çalıştırabileceği bağımsız, genel amaçlı ve açık kaynaklı bir araca dönüştürmesiydi.

2017: dqlite#

Canonical, etcd çalıştırmaya gerek kalmadan LXD ve daha sonra MicroK8s için gömülü (embedded) ve çoğaltılmış bir veri deposu elde etmek amacıyla dqlite'ı geliştirdi. Mark Shuttleworth, rqlite'ın bu ihtiyaca uyarlanıp uyarlanamayacağını görüşmek için yazarla iletişime geçse de rqlite bu senaryoya tam olarak uymadı.

dqlite, Go dilinde başladı ve daha sonra kendi Raft kütüphanesiyle C dilinde yeniden yazıldı. Amaç bakımından rqlite'a en çok benzeyen projedir ve aralarındaki temel fark paketleme biçimidir:

  • dqlite: Uygulamanızın içine gömdüğünüz bir kütüphanedir (ürünün içindeki veritabanı).
  • rqlite: Doğrudan çalıştırdığınız bağımsız bir sunucudur (herhangi bir ürünün yanındaki veritabanı).

Geliştiriciler İçin Çıkarım: Aynı teknik problemi çözen iki araç, sırf dağıtım ve entegrasyon modelleri (gömülü kütüphane vs. bağımsız sunucu) farklı olduğu için tamamen ayrı kullanım senaryolarına hitap edebilir.

2021: Litestream ve Yaklaşım Değişikliği#

2021'in başlarında Ben Johnson, Litestream'i yayınladı. Litestream hiçbir şekilde fikir birliği (consensus) protokolü kullanmaz. Bunun yerine SQLite'ın WAL (Write-Ahead Logging) dosyasını izler ve neredeyse sıfır maliyetle tek düğümlü bir SQLite veritabanı için felaket kurtarma (disaster recovery) sağlamak üzere bunu anlık olarak S3'e aktarır.

Ben'in temel argümanı şuydu: Çoğu uygulamanın bir kümeye (cluster) ihtiyacı yoktur; tek bir makine kullanırlar ve sadece o makine çökerse veriyi kurtarmanın bir yoluna ihtiyaç duyarlar. Bu tespit birçok uygulama için oldukça doğruydu. Sonraki yıllarda blog yazılarına ve konferans konuşmalarına konu olan "SQLite yeterlidir" akımı, bu argümana çok şey borçludur.

Geliştiriciler İçin Çıkarım: Karmaşık dağıtık sistemler ve consensus protokolleri kurmak yerine, bazen sadece mevcut tekil yapıyı yedekli hale getirmek (WAL akışı gibi) mühendislik maliyeti açısından çok daha efektif bir çözüm sunar.

Kaynak ve atıf

Bu yazı, Hacker News üzerinde yayımlanan içerikten yararlanılarak Edumints tarafından yapay zekâ desteğiyle Türkçe hazırlandı. Ayrıntılar ve yazarların kendi anlatımı için orijinaline bakabilirsin:

  • philipotoole.com/twelve-years-of-distributed-sqlite