- Apple, iCloud ve CloudKit için Cassandra ve FoundationDB kullanıyor
- Bu veritabanları, aşırı çok kiracılı bir mimaride milyarlarca veritabanını barındırıyor
Zamana meydan okuyan gerçek dünya dersleri
- Meta ve Apple, kullanıcı özelliklerini sorunsuz hale getirmek için asenkron işlemeyi kullanıyor
- Her iki şirket de ölçeklenebilirlik sorunlarını çözmek için stateless mimari kullanıyor
- Kaynakları mantıksal olarak izole ederek güvenilirlik ve erişilebilirlik sağlıyorlar
- Farklı gereksinimleri basit şekilde ele alıyorlar
- Geliştirici deneyimini iyileştirmek için soyutlama katmanları inşa ediyorlar
- Kullanıcıyı tanıyıp her katmanı, API'yi ve tasarımı buna göre belirliyorlar
Cassandra
- Cassandra, geniş sütunlu NoSQL veritabanı yönetim sistemidir
- Başlangıçta Facebook'ta, Facebook gelen kutusu arama özelliği için geliştirildi
- İlginç bir şekilde Meta, Cassandra kullanımının büyük bölümünü ZippyDB ile değiştirdi
- iCloud kısmen Cassandra kullanıyor ve Apple dünyadaki en büyük Cassandra kurulumlarından birini işletiyor
- 300 binden fazla instance/node
- yüzlerce petabayt veri
- küme başına 2 petabayttan fazla
- saniyede milyonlarca sorgu
- binlerce uygulama
- Cassandra, Apple içinde hâlâ aktif biçimde geliştiriliyor
- Ancak CloudKit + Cassandra, ölçeklenebilirlik sınırlarına çarptığı için FoundationDB benimsenmiş
FoundationDB
- Apple, FoundationDB'yi açık biçimde kullanıyor ve 2015'te satın aldı
- FoundationDB, büyük ölçekli veriyi işlemek için tasarlanmış açık kaynaklı, dağıtık, işlemsel bir key-value depolama sistemi
- Hem okuma/yazma iş yükleri hem de yazma ağırlıklı iş yükleri için uygun
- Apple, CloudKit'te FoundationDB Record Layer'ı yoğun biçimde kullanıyor
- FoundationDB Record Layer, yapılandırılmış veri depolama için Java API'si sağlıyor
- Record Layer, aşırı çok kiracılığı destekliyor
FoundationDB'de neden Record Layer kullanılıyor
- FoundationDB, dağıtık sistem ve eşzamanlılık denetimi işlerini üstleniyor.
- Record Layer ise FoundationDB'yi kullanımı kolay hale getiren ilişkisel veritabanı gibi davranıyor.
- CloudKit en üst katmanda yer alıyor ve uygulama geliştiricileri için özellikler ile API'ler sunuyor.
- Record Layer sayesinde Apple, büyük ölçekli çok kiracılığı destekliyor
- Her uygulamanın her kullanıcısına bağımsız bir kayıt deposu sağlayan aşırı çok kiracılık için kullanılıyor
- Binlerce şemayı paylaşan milyarlarca bağımsız veritabanını barındırıyor
CloudKit'in FoundationDB ve Record Layer'ı kullanma biçimi
- CloudKit'te uygulamalar, tanımlı bir şemayı izleyen 'mantıksal kapsayıcılar' olarak temsil ediliyor
- Bu şema, verimli veri erişimi ve sorgular için gerekli kayıt türlerini, alanları ve indeksleri özetliyor
- Uygulamalar, verileri CloudKit içinde 'bölgeler' halinde düzenleyerek kayıtları mantıksal olarak gruplayabiliyor ve bunları istemci cihazlarla isteğe bağlı olarak senkronize edebiliyor
- Her kullanıcıya FoundationDB içinde benzersiz bir alt alan atanıyor ve kullanıcının etkileşim kurduğu her uygulama için bir kayıt deposu oluşturuluyor
- Temelde CloudKit, kullanıcı sayısı ile uygulama sayısının çarpımı kadar devasa sayıda mantıksal veritabanını yönetiyor
- Her veritabanı kendi kayıt, indeks ve metadata setini içeriyor; toplam sayı milyarlarca veritabanına ulaşıyor
- CloudKit, istemci cihazlardan istek aldığında yük dengeleme yoluyla bu istekleri uygun durumdaki CloudKit servis süreçlerine iletiyor
- Süreç, belirli bir Record Layer kayıt deposuyla etkileşime girerek isteği işliyor
- CloudKit, tanımlı uygulama şemasını, ayrı bir metadata deposunda saklanan Record Layer içindeki metadata tanımlarına dönüştürüyor
- Bu metadata, kayıt oluşturma/değiştirme zamanı ile kaydın bulunduğu bölgeyi izleyen CloudKit'e özgü sistem alanlarıyla zenginleştiriliyor
- Her bölgedeki kayıtlara verimli erişim için birincil anahtara bölge adı önek olarak ekleniyor
- Kullanıcı tanımlı indekslere ek olarak CloudKit, kayıtların tür bazlı boyutunu izleyen indeksler tutuyor ve depolama kotası yönetimi gibi dahili amaçlar için 'sistem indeksleri' de yönetiyor
FoundationDB ve Record Layer birlikte kullanıldığında, yalnızca Cassandra ile çözülemeyen Apple'ın 4 temel sorununu çözüyor
1. Kişiselleştirilmiş tam metin arama sorununu çözme
- FoundationDB, kullanıcıların kendi verilerine hızlı erişebilmesi için kişiselleştirilmiş tam metin aramayı destekliyor
- FoundationDB'nin anahtar sıralamasından yararlanarak metnin başlangıcını hızlıca aramak (önek eşleştirme) mümkün olurken, ek yük olmadan daha karmaşık aramalar da yapılabiliyor; örneğin yakınlık araması ve ifade araması gibi, birbirine yakın ya da belirli sıradaki kelimeleri bulma işlemleri
- Geleneksel arama sistemlerinde arama indeksini güncel tutmak için arka planda ek süreçler çalıştırmak gerekebiliyor; ancak Apple'ın sistemi her şeyi gerçek zamanlı işlediği için veri değiştiği anda arama indeksi de hemen güncelleniyor ve ek adıma ihtiyaç kalmıyor
2. Yüksek eşzamanlılıklı bölge sorununu çözme
- CloudKit, aynı anda gerçekleşen çok sayıdaki güncellemeyi sorunsuz işlemek için FoundationDB kullanıyor
- Önceden Cassandra kullanılırken CloudKit, birden fazla cihaz arasında veri senkronizasyonu için her bölgedeki değişiklikleri izleyen özel bir indekse dayanıyordu
- Bir cihaz veriyi güncellemesi gerektiğinde yeni içerikleri görmek için bu indeksi kontrol ediyordu
- Ancak birden fazla güncelleme aynı anda olduğunda çakışmalar yaşanabiliyordu
- FoundationDB ile CloudKit, çakışma yaratmadan her değişikliğin tam sırasını izleyen özel bir indeks türü kullanıyor
- Bu, her değişikliğe benzersiz bir 'sürüm' atayarak yapılıyor; senkronizasyon gerektiğinde CloudKit bu sürümleri kontrol ederek cihazın hangi güncellemeleri kaçırdığını belirliyor
- Yükü daha dengeli dağıtmak için CloudKit'in veriyi birden çok depolama kümesi arasında taşıması gerektiğinde işler karmaşıklaşıyor; çünkü her kümedeki sürüm numaraları birbiriyle uyuşmuyor
- Bunu çözmek için CloudKit, her kullanıcının verisine 'taşınma sayısı' ('incarnation') veriyor ve veri her yeni kümeye taşındığında bu sayı artıyor
- Her kayıt güncellemesi kullanıcının mevcut 'incarnation' numarasını içeriyor; böylece taşıma sonrasında da CloudKit hem incarnation hem sürüm numarasına bakarak doğru güncelleme sırasını belirleyebiliyor
- Yeni sisteme geçildiğinde CloudKit, bu sürüm numaralarına sahip olmayan eski verileri ele alma sorunuyla karşılaştı
- Ancak önceki sistemde yapılan güncellemeleri, yeni sistemde yapılanlardan önce sıralayan özel bir mekanizmayla bu sorun akıllıca aşıldı
- Böylece uygulamaları karmaşık biçimde değiştirmeye ya da eski kodu elde tutmaya gerek kalmadı
- Doğru kayıt sırasını korumak için incarnation, sürüm ve eski güncelleme sayacı değerleri birlikte dikkate alınıyor
3. Yüksek gecikmeli sorgu sorununu çözme
- FoundationDB, düşük gecikmeden çok yüksek eşzamanlılık için tasarlanmış. Yani tek tek işlemleri hızlandırmaktan ziyade aynı anda çok sayıda işlemi yürütebiliyor
- Bu tasarımdan en iyi şekilde yararlanmak için Record Layer pek çok işi 'asenkron' olarak yürütüyor
- Gelecekte tamamlanacak işleri kuyruğa alıp bu sırada başka işler yapmaya olanak tanıyor
- Bu yaklaşım, bu işler sırasında ortaya çıkabilecek gecikmeyi örtmeye yardımcı oluyor
- Ancak FoundationDB'nin veritabanıyla iletişim kurmak için kullandığı araç, ağ iletişimi için tek bir thread kullanıyor ve aynı anda tek bir işi yapacak şekilde tasarlanmış
- Önceki sürümlerde bu yapı, tüm işler bu ağ thread'inde sırasını beklediği için sistemde trafik sıkışıklığına neden oluyordu
- Record Layer bu tek thread yaklaşımını kullandığından bir darboğaz oluşuyordu
- Bunu iyileştirmek için Apple, bu ağ thread'inin iş yükünü azalttı
- Artık sistem kuyruk oluşturmadan veritabanıyla birden çok açıdan aynı anda çalıştığı için karmaşık işler daha hızlı tamamlanıyor
- Böylece sistem, başka işe başlamadan önce tek bir işin bitmesini beklemediği için gecikme yani dışarıdan hissedilen yavaşlık gizlenmiş oluyor
4. Çakışan transaction sorununu çözme
- FoundationDB'de bir transaction belirli bir anahtarı okurken başka bir transaction aynı anahtarı değiştirirse 'transaction çakışması' oluşuyor
- FoundationDB, okuma veya yazma sırasında bu tür çakışmalara neden olabilecek anahtar kümelerini kontrol etmeye olanak tanıyarak bu çakışmaların hassas biçimde yönetilmesini sağlıyor
- Gereksiz çakışmaları önlemenin yaygın bir yolu, çakışma yaratmayan özel bir okuma türü olan 'snapshot' okumayı çeşitli anahtarlar üzerinde yapmak
- Bu okumada önemli bir anahtar bulunursa transaction, tüm aralık yerine yalnızca potansiyel çakışma taşıyan belirli anahtarı işaretliyor
- Böylece transaction'ın gerçekten yalnızca sonuç açısından önemli değişikliklerden etkilenmesi sağlanıyor
- Record Layer, bu stratejiyi sıralama indeksi sisteminin parçası olan skip list adlı yapıyı verimli biçimde yönetmek için kullanıyor
- Ancak bu çakışma aralıklarını elle ayarlamak zor olabilir ve özellikle uygulamanın ana mantığıyla iç içe geçtiğinde tespiti güç hatalara yol açabilir
- Bu yüzden FoundationDB üzerine kurulan sistemlerde, bu kalıpları ele almak için custom index gibi daha yüksek seviyeli araçlar oluşturmak daha iyi bir yaklaşım
- Bu yaklaşım, çakışma kurallarını gevşetme sorumluluğunu tek tek istemci uygulamalarına bırakıp hata ve tutarsızlık yaratabilecek durumların önüne geçmeye yardımcı oluyor
1 yorum
Hacker News görüşleri
Bir Hacker News kullanıcısı, Apple'da çalışırken veritabanları ile dosya sistemleri arasındaki farklara dair içgörülerini paylaşıyor. Veritabanları ve dosya sistemlerinin temelde aynı işi yaptığını ve belirli sorunları çözmek için yapılmış optimizasyonlar olduğunu belirtiyor. Örneğin iCloud, bir veritabanı üzerinde dosya sisteminin nasıl tanımlanabileceğini gösteriyor. Bu kullanıcı ayrıca video depolamak için Cassandra kullanma deneyimini de paylaşıyor.
Başka bir kullanıcı, önceki şirketinde FoundationDB ve RecordLayer kullanarak işlemsel bir katalog sistemi kurma deneyiminden bahsediyor. Bu sistemin çok etkili olduğunu ve gRPC ile Protobuf kullanmanın doğal hissettirdiğini söylüyor. Ancak FoundationDB'yi büyük ölçekte işletmenin giriş eşiğinin yüksek olduğunu da belirtiyor.
Bir kullanıcı, Apple Notes'un senkronizasyonunun Markdown tabanlı not uygulamalarına kıyasla çakışmaları daha iyi yönettiğini değerlendiriyor. Bu nedenle sonunda Apple Notes'a geçtiğini söylüyor.
FoundationDB hakkında önceki gönderilere de değiniliyor. Bunlar FoundationDB'nin dağıtık anahtar-değer deposu, Record Layer, Apple tarafından satın alınması ve FoundationDB'nin çalışma biçimi ile özellikleri hakkında bağlantılar içeriyor.
Bulut tabanlı depolama ve iş birliğine doğru kademeli olarak kayan yerel masaüstü yazılımlarının mimarisine dair ilginç bir noktadan söz ediliyor. Şema değişikliklerini ve sürüm geçişlerini iyi yönetmek önemli; üstelik bunlar yönetici müdahalesi olmadan büyük ölçekte gerçekleşiyor.
Bir kullanıcı, iCloud'un Time Machine yedeklerini saklayabilmesini istediğini söylüyor.
FoundationDB'nin SQLite tabanlı olması nedeniyle, HCTree motorunun FoundationDB'ye uygulanma ihtimali merak ediliyor. HCTree'nin SQLite'ın okuma/yazma performansını 10 kat artırma potansiyeline sahip olduğu belirtiliyor.
iCloud'un kullanıcı dosyalarını yönetme biçimine yönelik şikayetler de var. Son kullanılan dosyaları, uygulamaları ve fotoğrafları alan açmak için otomatik olarak buluta taşımasının bazen sorun yarattığı söyleniyor.
Bir kullanıcı, geçmişte bir bankada çalışırken kullandığı Hyperion adlı raporlama sistemini hatırlıyor. Bu sistemin her rapor için yeni bir veritabanı oluşturduğunu, o zamanlar bunun garip geldiğini ama şimdi düşününce zamanının ötesinde bir yaklaşım olduğunu söylüyor.