İki veritabanı taşımak: mesajlar Scylla, geri kalanı Postgres

İkinci bir veritabanı eklemek her zaman bir yenilgidir — bir tanesinin yetmediğini kabul ediyorsun. Xaron'da bu kararı vermemizin sebebi ölçek değil, iki verinin birbirine hiç benzememesiydi.

Xaron'da ilişkisel çekirdek PostgreSQL'de, mesaj akışı ScyllaDB'de. İki veritabanı taşımak, iki yedekleme stratejisi, iki operasyon bilgisi ve iki hata modu demek.

Bu kararı savunmadan önce şunu söyleyeyim: ikinci bir veritabanı eklemek varsayılan olarak yanlış. Çoğu ekip bunu ölçek geldiğinde değil, ölçek geleceğini hayal ettiğinde yapıyor ve karşılığında sadece karmaşıklık alıyor.

İki veri birbirine benzemiyor

Bizim gerekçemiz istek sayısı değildi. Erişim deseninin kendisiydi.

Kullanıcılar, sunucular, kanallar, üyelikler, roller, abonelikler — bunlar ilişkisel veriler. Birbirlerine bağlılar, aralarında kısıtlar var, ve bir üyeliği silerken beş tabloyu tutarlı bırakmak zorundasın. Bu tam olarak Postgres'in var olma sebebi.

Mesajlar ise başka bir şey. Neredeyse hiç güncellenmiyorlar, hiç birleştirilmiyorlar, ve tek bir desenle okunuyorlar: şu kanalın şu zamandan öncesindeki elli mesajı. Ama yazma hacmi geri kalan her şeyin toplamından yüksek, ve tablo sonsuza kadar büyüyor.

Aynı motora hem "beş tabloyu tutarlı güncelle" hem "durmadan yaz, hiç silme" dedirtmek mümkün. Ama bir noktada birinin ihtiyacı diğerinin ayarını bozuyor.

Postgres'in gerçekten zorlandığı yer

Dürüst olmak gerekirse, Postgres mesaj tablosunu uzun süre taşıyabiliyor. Bölümleme, doğru indeksler ve arşivleme ile epey yol gidiyorsun.

Zorlandığı yer, yazma hacmi arttıkça bakım işlerinin büyümesi. Sürekli ekleme yapılan devasa bir tabloda vakumlama, indeks şişmesi ve bölüm yönetimi kendi başına bir iş hâline geliyor. Sorgu yavaşlamıyor — operasyon ağırlaşıyor.

Scylla ise tam bu deseni için tasarlanmış: bölüm anahtarı kanal, kümeleme anahtarı zaman. Sorgu her zaman aynı şekil, veri diskte zaten o sırada duruyor, ve yatay büyümek düğüm eklemek demek.

İkinci bir veritabanı eklemenin bedeli operasyon. Faydası, iki veriye birbirinden bağımsız ayar yapabilmek.

Ödediğimiz fatura

Karşılığında kaybettiğimiz şeyler net.

Birleştirme yok. Bir mesajı gönderenin adıyla göstermek istiyorsan, iki veritabanından iki sorgu atıp uygulamada birleştiriyorsun. Bu her ekranda karşına çıkıyor ve önbellek katmanını zorunlu kılıyor.

İşlem yok. Bir mesaj yazıp aynı anda ilişkisel tarafta bir sayacı güncellemek atomik değil. İki tarafın da doğru olduğu bir dünya istiyorsan, bunu ya kabullenip nihai tutarlılıkla yaşıyorsun ya da telafi mantığı yazıyorsun.

İki operasyon bilgisi. Yedekleme, geri yükleme, sürüm yükseltme, izleme — hepsi iki kez. Küçük bir ekipte bu, en az veritabanı seçimi kadar önemli bir maliyet.

Ne zaman yapılmaz

Bir ürün henüz erişim desenlerini bilmiyorsa, bu ayrımı yapmak erken. Çünkü ayrımı yanlış yere koyduğunda, geri almak veri taşımak demek.

Ayrıca "ölçeklenir" diye seçilen ikinci veritabanı genelde hiç ölçeğe ulaşmıyor. Elinde kalan şey, tek bir Postgres'in rahatça yapacağı işi iki sistemle yapmak oluyor.

Bizde bu karar doğru geldi çünkü mesaj akışının deseni ürünün ilk gününden belliydi — bir iletişim ürünü yazıyorsan mesajların nasıl okunacağını tahmin etmiyorsun, biliyorsun.

Ama Sperare ve Teck tek Postgres üzerinde. İkisinde de veri hacmi değil, ilişkilerin doğruluğu belirleyici. Ve orada ikinci bir veritabanı, çözdüğünden fazla problem üretirdi.