1 puan yazan GN⁺ 2024-05-17 | 1 yorum | WhatsApp'ta paylaş
  • Datomic Pro 1.0.7075, testlerde işlemler arası güvenlik açısından belgelerde iddia edilenden daha güçlü görünse de işlem içi semantik genel seri yürütme modelinden oldukça farklıydı
  • Tüm test geçmişleri Serializable görünüyordu; tek bir peer oturumu Strong Session Serializable, yazmalar ve d/sync okumaları ise Strong Serializable’a yakın görünüyordu
  • Datomic’in add, retract ve transaction function’ları işlem içinde sırayla birikimli olarak yürütülmez; her fonksiyon yalnızca başlangıç anındaki DB durumunu görüyormuş gibi çalışır
  • Aynı işlemde approve ve deny gibi tek başına güvenli transaction function’lar birleştirildiğinde, bileşik sonuç invariant ihlali oluşturabilir
  • Birden fazla transaction function’ı tek bir işleme koyarken read set ve write set ilişkisini kontrol etmek; entity predicate, attribute predicate, entity spec gibi açık kısıtları birlikte kullanmak gerekir

Datomic Pro’nun modeli ve mimarisi

  • Datomic, zaman kavramını açıkça modelleyen bir Entity-Attribute-Value OLTP veritabanıdır
    • Belirli bir andaki DB durumu, [entity, attribute, value] biçimindeki datom kümesiyle ifade edilir
    • Her datom için hangi işlemin onu eklediği ya da geri çektiği de korunur
    • Tam datom, [entity, attribute, value, transaction, asserted-or-retracted?] biçiminde 5’li bir tuple’dır
  • Datomic bir temporal database olduğundan, yalnızca güncel durumu değil geçmişteki mantıksal zamanlara veya wall-clock zamanlarına göre anlık görüntüler de isteyebilirsiniz
    • Tam geçmiş görünümüyle, geçmişte belirli bir olgunun var olup olmadığı da sorgulanabilir
    • Sorgulama yöntemi olarak Datalog tarzı API, grafik dolaşma API’si ve ODM tarzı Entity tipi sunar
  • Datomic Pro, kullanıcıların kendilerinin işletebildiği sürümdür; Datomic Cloud ise AWS üzerinde çalışır ve mimarisi kısmen farklıdır
  • Datomic Pro, birden fazla bileşenin birlikte çalıştığı bir yapıya sahiptir
    • Transactor, yazma işlemlerinin yürütülmesinden, indekslerin korunmasından ve depolamaya kayıt yapılmasından sorumludur
    • Peer, JVM kütüphanesini gömülü olarak içeren kalın bir istemcidir; işlem gönderme, depolama hedefinden okuma sorguları ve önbellekleme yapar
    • Diğer dillerdeki uygulamalar için thin client ve peer server tabanlı client-server modeli de sunar
  • Datomic, içeride her işlemi zaman sıralı bir log’a append eder ve entity·attribute·value·time bileşimine göre sıralanmış 4 indeks tutar
    • Log ve indeksler, Cassandra veya DynamoDB gibi depolamalarda kalıcı ve değişmez ağaçlar olarak saklanır
    • Ağaç düğümleri değişmez olduğu için backing storage’ın yalnızca eventual consistency garanti etmesi yeterlidir
    • Commit sırasında transactor yeni değişmez ağaç düğümünü kaydettikten sonra kök işaretçisini compare-and-set (CaS) ile ilerletir; bu CaS için Sequential consistency gerekir
  • Sequential CaS, işlemlerin küresel sırasını garanti eder; ancak yazma throughput’unu tek bir transactor’ın hızına bağlar
    • Datomic genellikle aynı anda yalnızca bir active transactor bulundurur ve hata toleransı için birden fazla transactor dağıtır
    • Peer’ler depolamaya ve transactor’a doğrudan bağlanır ve her biri monoton artan kök işaretçisi kopyasını tutar
    • Okumalar değişmez ağaç düğümlerini önbelleğe alabileceği için peer sayısı artırıldığında okuma tarafında neredeyse doğrusal ölçeklenme sağlanabilir

Datomic’in işlem modeli

  • Datomic, tipik OLTP veritabanları gibi interactive transaction sunmaz
    • İşlemi başlatıp, operasyon sonucunu aldıktan sonra sonraki operasyonu gönderip en sonunda commit eden bir model değildir
    • Stored procedure’a benzeyen transaction function’lar vardır, ancak çağırana keyfi değerler döndüremezler
  • Okuma ve yazma yolları kesin biçimde ayrılmıştır
    • db, peer’in bildiği en güncel DB durumunu döndürür
    • d/sync, tüm peer’ler açısından en güncel durumu veya belirli bir zamandan sonraki durumu elde etmek için transactor ile senkronize olur
    • d/as-of, geçmiş bir zamandaki DB durumunu alır
    • DB durumu değişmez olduğundan, aynı durum üzerindeki birden fazla sorgu tam olarak aynı mantıksal zamanda çalıştırılır
  • Yazma işlemi, ordered list biçiminde operation’larla ifade edilir
    • Örnekler arasında :db/add, :db/retract, db/cas ve kullanıcı tanımlı transaction function çağrıları bulunur
    • Transaction function, işlemin başlangıç anındaki DB durumunu ve argümanları alıp yeni bir operation kümesi döndürür
    • Fonksiyon çağrıları, geriye yalnızca assertion ve retraction kalana kadar özyinelemeli olarak genişletilir
  • Transaction function, içeride okuma yaparak koşullu yazmaya karar verebilir; ancak okuma sonucunu veya keyfi bilgileri transact çağırıcısına doğrudan döndürmez
    • transact, işlemden hemen önceki DB durumunu, işlem sonucu oluşan DB durumunu ve genişletilmiş datom kümesini döndürür
    • Çağıran taraf, koşullu yazmanın gerçekleşip gerçekleşmediğini anlamak için pre-state ve post-state’i kullanabilir
  • Datomic, ucuz ve aktarılabilir DB anlık görüntülerini merkeze alarak problemleri çözmek üzere tasarlanmış bir modeldir
    • Nubank, Datomic’in mevcut geliştirici şirketidir; finansal hizmetlerini yaklaşık 94 milyon kullanıcıya sunar ve günde ortalama 2,3 milyar kullanıcı işlemi işler
    • Nubank’in neredeyse tüm ürünleri Datomic’i system of record olarak kullanır

Tutarlılık iddiaları ve test tasarımı

  • Datomic belgeleri ACID transaction’lar sunduğunu iddia eder; transaction’ların tek bir atomic write olarak depolamaya yazıldığını ve her peer’ın belirli bir ana kadar tamamlanmış tüm transaction’ları total order içinde gözlemlediğini varsayar
    • İstemci acknowledgement’ından önce transaction durable storage’a flush edilir
  • Analizin başladığı 2024 Ocak başındaki belgeler, write transaction’ların Serializable olduğunu gayriresmî olarak iddia ediyordu
    • Belgeler Datomic’i “single-writer” bir sistem olarak da tanımlıyordu; ancak Jepsen bu açıklamanın iki nedenle hatalı olduğunu düşünüyor
    • Hata toleransı için birden fazla transactor çalıştırılabilir ve arıza algılayıcıları kusursuz olamayacağından, birden fazla transactor’ın aynı anda active olduğunu düşündüğü bir zaman aralığı oluşabilir
    • Yalnızca tek bir transactor olsa bile, ağ gecikmesi nedeniyle depolama mesajları başka transactor mesajlarıyla interleave olabilir
  • Datomic’in güvenliğinin “single-writer” mantığından değil, depolama CaS operation’ının Sequential consistency özelliğinden geldiği değerlendiriliyor
    • Birden fazla concurrent transactor olsa bile güvenliği CaS sağlamalıdır
  • Testler, Jepsen testing library ile yazılmış Datomic test suite kullanılarak yapıldı
    • Datomic Pro 1.0.7075, Debian Bookworm düğümlerinden oluşan bir kümeye kuruldu
    • Depolama için AWS DynamoDB table kullanıldı
    • İki düğüm transactor çalıştırdı, kalan düğümler peer çalıştırdı
  • peer, Datomic peer library kullanan küçük bir Clojure programıydı ve test işlemleri için bir HTTP API sunuyordu
    • Testler hem d/db kullanan stale read’e açık modu hem de d/sync ile güncelliği garanti eden modu çalıştırdı
  • fault injection hem transactor’lara hem de peer’lara uygulandı
    • Süreç pause, crash ve clock error enjeksiyonları yapıldı
    • transactor ile peer arasında ve düğümler ile depolama arasında network partition’lar oluşturuldu
    • Datomic garbage collection da istendi
  • transactor, depolamayla kararlı bağlantıyı sürdüremezse kendini sonlandırır
    • AWS dışındaki düğümlerde varsayılan 5 saniyelik timeout kullanıldığında, normal ağ dalgalanmaları nedeniyle bile birkaç dakikada bir kapanıyordu
    • EC2 test ortamında da 1 saniyelik timeout ile 10–20 dakikada bir kapanıyordu
    • Datomic, operatörün transactor’ı bir supervisor daemon ile yeniden başlatmasını önerir; testler Restart=on-failure ayarlı bir systemd service kullandı

Dört iş yükü

  • List Append

    • List Append iş yükü, Elle transaction checker ile birlikte kullanıldı
    • Mantıksal olarak tamsayı öğelerden oluşan listelerle çalışır; her liste bir tamsayı primary key ile tanımlanır
    • İstemciler, liste okuma veya benzersiz öğe append etme işlemlerinden oluşan rastgele transaction’lar gerçekleştirir
    • Elle, aborted read, intermediate read, internal consistency ihlali ve öğe sırası uyuşmazlığını denetler; dependency graph cycle’larını bularak tutarlılık modeli ihlallerini belirler
    • Datomic’te liste, tek bir entity ve iki attribute ile kodlanır
    • append/key primary key görevi görür
    • append/elements, listenin tamsayı öğelerini saklayan çok değerli bir attribute’tur
    • Çok değerli attribute’lar sırasız set olduğundan Jepsen, Elle’nin ihtiyaç duyduğu sırayı elde etmek için her datom’un transaction timestamp’ine göre öğeleri sıralar
    • mixed read-write transaction olmaması kısıtı, transaction function ve pre-state hesaplamasıyla aşıldı
    • Yazmalar transaction function ile yapıldı
    • transact tarafından döndürülen pre-state kullanılarak transaction içi okumanın neyi görmüş olacağı hesaplandı
    • Aynı fonksiyon iki kez çalıştırıldı: bir kez transact içinde, bir kez de peer’da pre-state tabanlı okuma tamamlama için
  • CaS ile List Append

    • CaS ile List Append iş yükü db/cas pattern’ını kullanır
    • Kullanıcı mevcut durumu d/db ile okuyabilir ve örneğin değer 4 ise onu 5’e değiştiren [:db/cas 123 :counter/value 4 5] ifadesini gönderebilir
    • Tüm yazmalarda db/cas kullanıldığında, mantıksal “user transaction” üzerinde ad hoc Snapshot Isolation kurulabilir
    • Bu iş yükü listeyi çok değerli olarak değil, single-valued comma-separated string olarak saklar
    • Transaction başında okunur, okuma ve yazmalar yerelde uygulanır; ardından okunduktan sonra değişmediğini garanti eden bir CaS transaction’ı oluşturulur
  • Internal

    • Internal iş yükü, transaction içi tutarlılığı doğrudan ölçer
    • Aynı entity attribute’una önce 1, sonra 2 assert etme durumu
    • Aynı transaction’da bir fact’i assert ve retract etme durumu
    • Bir değeri assert ettikten sonra CaS ile değiştirmeye çalışma durumu
    • 1→2, 2→3 gibi birden fazla CaS gerçekleştirme durumu
    • Entity oluşturduktan sonra lookup ref ile değiştirme durumu
    • transaction function ile bir değeri iki kez increment etmeye çalışma durumunu içerir
  • Grant

    • Grant iş yükü, transaction function’ın fonksiyon invariant’ını koruyup korumadığını kontrol eder
    • grant; created-at, approved-at, denied-at adlı üç attribute’a sahip tek bir entity olarak kodlanır
    • grant aynı anda hem approved hem de denied durumda olmamalıdır
    • approve ve deny fonksiyonları önce grant’in zaten approved veya denied olup olmadığını kontrol eder, gerekirse abort eder
    • Çeşitli transaction boundary kombinasyonlarında grant’in aynı anda hem approved hem de denied olup olmadığı denetlenir

Test sonuçları: Transaction’lar arası güvenlik güçlü görünüyor

  • Jepsen, Datomic’in temel güvenlik iddialarına aykırı bir davranış bulamadı
    • Transaction’lar total order ile uygulanmış gibi görünüyordu
    • Bu sıra, her peer’daki local operation order ile uyumluydu
  • Yalnızca write transaction’larla sınırlı geçmişler ve okumalarda (d/sync conn) kullanan geçmişler real-time order ile uyumluydu
    • Jepsen bunun Strict Serializable göründüğünü değerlendiriyor
  • Session tek bir peer’a bağlanarak yorumlandığında Datomic’in Strong Session Serializability sağladığı görülüyor
    • Transaction geçmişi, bir total order ile çalıştırılmış bir geçmişten ayırt edilemiyor
    • Bu order, her peer’da gözlemlenen sırayla uyumlu
  • d/db, asenkron güncellenen bir DB kopyası döndürdüğü için stale read mümkündür
    • Datomic belgeleri de peer read’in yakın zamanda commit edilmiş transaction’ların bir kısmını gözlemleyemeyebileceğini açıkça belirtir
    • d/sync, transactor ile senkronize olarak stale read’i önler
  • Deneysel doğrulamanın sınırları var
    • Bir bug’ın varlığı kanıtlanabilir, ancak yokluğu kanıtlanamaz
    • Datomic’in dayandığı depolama sistemindeki correctness error, Datomic garantilerinin ihlaline yol açabilir
    • DynamoDB üzerindeki Datomic, DynamoDB’nin compare-and-set operation’ı kadar güvenlidir

İşlem içi semantik: sıralama değil, eşzamanlılık

  • Çoğu veritabanı ve başlıca işlem izolasyonu biçimselleştirmeleri, işlem içinde seri yürütme semantiği sağlar
    • set x = 1; read x; ise read genellikle 1 görür
    • Adya, Cerone·Bernardi·Gotsman, Crooks·Alvisi·Pu·Clement gibi biçimselleştirmeler, işlem içi operation sırasını ve “önceki write’ı sonraki read’in gözlemlemesi” özelliğini açıkça belirtir
  • Datomic’in transaction request’i ordered list’tir, ancak yürütme bu sırayı korumaz
    • add, retract ve transaction function’lar birbirleriyle eşzamanlı çalışıyormuş gibi davranır
    • transaction function her zaman işlemin başlangıç anındaki DB durumunu gözlemler
    • Önceki assertion, retraction veya transaction function’ın etkilerini görmez
  • Geçerli değeri 0 olan bir entity’ye aynı CaS iki kez konursa, Datomic’te ikisi de başlangıç durumu 0ı görür ve başarılı olur
[[:db/cas 123 :internal/value 0 1]
 [:db/cas 123 :internal/value 0 1]]
  • Seri modelde ilk CaS değeri 1e çevirmeli, ikinci CaS ise başarısız olmalıdır
    • Datomic’te iki CaS yinelenen assertion’lar oluşturur ve nihai değer 1 olur
  • İki increment transaction function’ı da seri modelden farklı sonuç verir
[['internal/increment "x"]
 ['internal/increment "x"]]
  • Başlangıç değeri 0 ise seri modelin sonucu 2dir
  • Datomic’te iki fonksiyon da başlangıç durumu 0ı görür ve nihai değer 1 olur
  • transaction function önceki assertion’ı da görmez
[[:db/add id-of-x :internal/value 1]
 ['internal/increment "x"]]
  • Datomic’te nihai değer 2 değil 1 olur
  • lookup ref de işlemin başlangıç anındaki DB durumunu kullanır
    • Aynı işlemde entity eklendikten sonra lookup ref ile o entity’ye başvurulamaz
    • Bu durumda Unable to resolve entity hatasıyla abort edilir

Çakışma algılama ve pseudo write skew

  • Datomic, aynı işlem içinde single cardinality bir attribute için farklı değerler assert edilirse :db.error/datoms-conflict ile abort eder
    • Başlangıç değeri 0 için değer 2 assert edilirken, aynı anda increment function değer 1 assertion’ı oluşturursa çakışma olur
    • Bu çakışma algılaması, transaction function’ların hatalı bileşiminden doğabilecek birçok şaşırtıcı sonucu engelleyebilir
  • Write set farklı [entity, attribute] çiftlerinden oluşuyorsa yalnızca çakışma algılamasıyla invariant’ları korumak zordur
    • grant iş yükü bu durumu gösterir
    • approve ve deny, grant’in henüz approved da denied da olmadığını kontrol ettikten sonra farklı attribute’lar ekler
  • Farklı işlemlerden approve ve deny çağrılırsa Datomic’in Serializable işlemleri invariant’ı garanti eder
    • Ancak aynı işlem içinde ikisi birlikte çağrılırsa ikisi de başlangıç durumunu görür ve başarılı olur
[['grant/approve id]
 ['grant/deny id]]
  • Sonuçta grant hem approved-at hem de denied-at sahibi olur
    • “grant aynı anda approved ve denied olmamalı” invariant’ı bozulur
    • Datomic’in in-transaction conflict checker’ı, iki fonksiyon farklı attribute’lar için assertion oluşturduğu için bunu engellemez
  • Bu olgu Berenson ve diğerlerinin Write Skew’ine benzer
    • İki fonksiyon birbirlerinin etkisini göremediği için read-write anti-dependency cycle oluşur
    • transaction function’lar işlem gibi görülürse, Repeatable Read ve Serializability’nin yasakladığı G2-item anomaly’ye benzer
  • Datomic ve Nubank bu davranışı bug değil, Datomic’in beklenen davranışı olarak görür
    • Nubank, Datomic’in concurrent intra-transaction semantics’ini korumayı planlıyor

Entity predicate ile invariant’ı güçlendirme

  • Datomic; type, uniqueness, belirli attribute predicate ve entity predicate gibi kısıtlama mekanizmaları sağlar
    • entity predicate, tüm işlem etkileri uygulanmış candidate DB durumunu ve entity ID’sini alır; commit’e izin verilip verilmeyeceğini true veya false olarak döndürür
    • Adı entity predicate olsa da tüm DB durumuna erişebildiği için belirli bir entity’nin ötesinde global kısıtlar da ifade edilebilir
  • grant örneğinde valid-grant? predicate’iyle approved-at ve denied-atın aynı anda var olması engellenebilir
(defn valid-grant?
  [db eid]
  (let [{:grant/keys [approved-at denied-at]}
        (d/pull db '[:grant/approved-at
                     :grant/denied-at]
                   eid)]
   (not (and approved-at denied-at))))
  • schema’ya bu predicate’e referans veren bir entity spec eklenir
    • entity spec ile bağlantılı entity predicate’ler tüm işlemlere otomatik uygulanmaz
    • Datomic, entity spec’in uygulanıp uygulanmamasını domain decision olarak görür ve her işlemin bunu açıkça istemesi gerektiğini savunur
  • approve ve deny fonksiyonları, attribute’u ekledikten sonra :db/ensure virtual datom ile entity spec uygulanmasını isteyebilir
(defn approve
  [db id]
  [[:db/add id :grant/approved-at (Date.)]
   [:db/add id :db/ensure :grant/valid?]])
  • Bu entity spec kullanıldığında, aynı işlemde approve ve deny birlikte denenirse entity predicate hatası oluşur ve invariant korunur
    • Hata :db.error/entity-pred, :db.error/pred-return false içerir

Belge değişiklikleri ve kullanıcılara öneriler

  • Datomic, Jepsen ile iş birliğinin ardından belgelerini önemli ölçüde revize etti
    • transaction safety documentation, Datomic’in fiilen sunduğu düşünülen daha güçlü güvenlik özelliklerini yansıtıyor
    • Küresel Serializability, peer bazında monotonicity ve yazma ya da sync kullanılan okumalar için Strict Serializability açıkça belirtiliyor
    • “single-writer” argümanı güvenlik belgesinden kaldırıldı
  • transaction syntax and semantics belgesi, transaction request yapısını, map formu ile transaction function genişletme kurallarını ve transaction uygulama sürecini kapsamlı biçimde ele alıyor
  • transaction functions belgesi de revize edildi
    • consistency sağlayan çeşitli mekanizmaları, fonksiyon oluşturma ve çağırmayı, yerleşik fonksiyonların davranışını açıklıyor
    • transaction function’ın “atomically analyze and transform database values” yapabildiği ya da “atomic read-modify-write processing” sağladığı yönündeki ifadeler kaldırıldı
  • Datomic, d/transact’a iletilen veri yapısını bundan böyle “transaction” yerine transaction request olarak adlandırmak istiyor
    • Bunun öğelerini “statements” veya “operations” yerine “data” olarak adlandırmak istiyor
    • [:db/add ...] ve [:db/retract ...] sırasıyla assertion request ve retraction request’tir
    • Bu, gerçek assertion datom ile transaction request içindeki eksik assertion request’i ayırt etmeye yardımcı olur
  • Kullanıcıların dikkat etmesi gereken noktalar açık
    • Datomic’in transaction’lar arası Serializability özelliğine güvenilebilir
    • Transaction içindeki concurrent execution semantics alışılmadık bir tercih olduğundan, aynı transaction’da birden fazla transaction function çağırırken dikkatli olunmalı
    • Özellikle read set’lerin çakışıp write set’lerin ayrıştığı durumlara dikkat edilmeli
    • Birden fazla increment sessizce tek bir update’e collapse olabilir
    • attribute predicate ve entity spec kullanılabilir, ancak entity spec gerekli tüm transaction’larda açıkça talep edilmelidir
  • Operasyonel açıdan da transactor yeniden başlatmaları ve ağ dalgalanmaları dikkate alınmalı
    • Datomic transactor, birkaç dakika boyunca storage ile iletişim kuramazsa kendi kendini sonlandırır
    • Jepsen, ağ dalgalanmalarına daha dayanıklı olması için transactor’a bir retry loop eklenmesini öneriyor

Sınırlar ve gelecekteki araştırma soruları

  • Bu testte değerlendirme kapsamı dışında kalan noktalar var
    • excision ve historical query değerlendirilmedi
    • Datomic client library de incelenmedi; ancak Jepsen, davranışının test için kullanılan peer’a benzer olma ihtimalinin bulunduğunu düşünüyor
    • Storage engine olarak yalnızca DynamoDB kullanıldı
    • Datomic Cloud da değerlendirilmedi; Datomic Cloud biraz farklı bir mimari kullanıyor
  • Jepsen, transaction’lar arası Serializability ile transaction içi concurrent semantics’i birlikte sunan çok az sistem ya da biçimselleştirme bildiğini belirtiyor
  • Datomic’in modeli çeşitli araştırma soruları doğuruyor
    • Datomic transaction’ın geleneksel transaction’ın dual’i ya da bir “co-transaction” modeli olarak görülüp görülemeyeceği
    • Bu modelin artı ve eksilerinin static analysis, runtime check ve API extension ile hafifletilip hafifletilemeyeceği
    • Gerçek kullanıcıların invariant’ları bozan transaction’lar yazma olasılığının ne kadar olduğu
  • Karşılaştırma için temporal Datalog araştırma projesi Alvaro’s Dedalus ve Fauna anılıyor
    • Dedalus’ta da Datomic’te olduğu gibi transaction “all at once” gerçekleşir
    • Fauna, temporal database olmasının yanında Strong Serializability de destekliyor ve Datomic’ten farklı olarak transaction içinde serial execution ile incremental side effect sağlıyor gibi görünüyor
  • Datomic’in end-of-transaction conflict checker’ı ile Snapshot Isolation’daki first-committer-wins kuralı arasındaki benzerlik de bir araştırma fırsatı olarak duruyor
    • Snapshot Isolation literatürünün hangi bölümlerinin Datomic’e uygulanabileceği
    • Datomic transaction içindeki cycle’ın hangi anti-dependency edge ile ifade edileceği
    • lost update, Fractured Read, read-only transaction anomaly ve Long Fork gibi olgulara karşılık gelen iç semantik analogue’ların olup olmadığı soruları açık kalıyor
  • CALM theorem ile bağlantı da ayrıca incelenebilir
    • Mantıksal olarak monotonic transaction function’ların aynı Datomic transaction içinde güvenle birleştirilip birleştirilemeyeceği
    • Negation içermeyen Datalog programlarının bu yürütme modelinde de güvenli olup olmadığı araştırılabilir

1 yorum

 
GN⁺ 2024-05-17
Hacker News yorumları
  • Bu çalışmanın yürütülmesini yakından izledim; tartışma sürecini görmek gerçekten ilginçti.
    Jepsen’in kritik bir hata bulamamış olması da şaşırtıcıydı; yalnızca dokümantasyonu ve amaçlanan sıra dışı davranışları netleştirmiş olması bile çok faydalı bir sonuçtu.
    Datomic üzerinde bir banka işlettiğimiz düşünülürse, güven inşa etme egzersizi olarak fazlasıyla değerliydi.

    • Rich Hickey tarafından tasarlanmış bir veritabanı olduğu düşünülürse sonuç pek de şaşırtıcı değil.
      Gerçekten harika bir yazı; insan kendini epey zeki hissettiği her seferinde bir Jepsen analizi okumak, alçakgönüllü olmak için iyi geliyor.
    • Hangi banka olduğunu sorabilir miyim?
    • “Jepsen’in kritik bir hata bulamamış olması da şaşırtıcıydı” kısmıyla ilgili olarak raporda, “hataların varlığı kanıtlanabilir, ama hataların yokluğu kanıtlanamaz” deniyor.
    • Bankayı bunun üzerinde işletmeden önce bu tür doğrulamaları kendiniz yapmadınız mı?
  • Jepsen raporunu derinlemesine ilk kez okudum; Datomic’in transaction iç işleyişini net biçimde açıklayan kısmı beğendim.
    Datomic transaction’ları ile SQL veritabanı transaction’ları arasındaki farkı ne kadar anlamadığımı da fark ettim.
    Özellikle şu paragraf dikkatimi çekti: “Datomic eskiden d/transact’e iletilen veri yapısına ‘transaction’, bunun öğelerine de ‘statements’ ya da ‘operations’ diyordu. Bundan sonra bu yapıya ‘transaction request’, öğelerine ise ‘data’ demek istiyoruz.”
    Bunun datomic.api namespace’indeki d/transact-async ve ilgili işlevler için ne anlama geldiğini merak ediyorum.
    Neredeyse 1 yıldır Datomic kullanmadım; pek çok şey değişmiş gibi görünüyor.

    • Jepsen test sonuçları nedeniyle Datomic yazılımında herhangi bir değişiklik gerekmedi.
      datomic.api içindeki tüm işlevler olduğu gibi duruyor.
  • Gerçekten iyi bir veritabanı hakkında harika ve ayrıntılı bir rapor.
    Dokümantasyonun netleşmesi ve güncellenmesi de çok sevindirici.
    Ek olarak, Apple’ın FoundationDB için bir Jepsen analizi maliyetini karşılamasını gerçekten isterdim.
    Aphyr’ın “onların testleri muhtemelen daha iyidir” dediğini biliyorum, ama Jepsen FoundationDB’de gerçekten sorun bulamazsa, bu da bir başka harika veritabanı olduğuna dair güçlü bir kanıt olurdu.

    • Aphyr’ın geçimini elinden almak gibi hiçbir niyetim yok, ama yeterince motive bir katkıcının Jepsen testlerini kendi başına yazmasının özellikle imkânsız olmasının bir nedeni var mı, yoksa “GoFundMe benzeri bir yöntemle” bile karşılanamayacak kadar pahalı mı, merak ediyorum.
      Bu alanı iyi bildiğim söylenemez, ama “keşke $foo masrafları karşılasa” denince kulaklarım kabarıyor.
      Sermaye fazlasıyla var, ama Apple’ın bir şey yapmasını beklemek benim deneyimime göre uzun sürüyor.
  • Jepsen’ın değişmez koşul ihlaline yol açan net bir durum bulması, Datomic tarafının yanıtının ise yalnızca dokümantasyonu netleştirmekten ibaret görünmesi etkileyiciydi
    Sonuçta Datomic ekibi bu tür bir ihlalin gerçekleştiğini kabul ediyor ama umursamıyor mu demek oluyor?
    Yazıda şöyle deniyor: “Datomic açısından grant iş yükündeki değişmez koşul ihlali kullanıcı hatasıdır. Transaction function’lar sırayla ve atomik olarak çalıştırılmaz. Transaction içindeki başka bir işlem o önkoşulu geçersiz kılabiliyorsa, bir transaction function içinde önkoşul kontrol etmek güvenli değildir.”

    • Jepsen’ın doğruladığı gibi, Datomic’in değişmez koşul zorlama mekanizması tasarlandığı gibi çalışıyor
      Bunun kullanıcı açısından ne anlama geldiğini görmek için şu tür bir transaction sözde verisi düşünülebilir
      [ [Stu favorite-number 41] ;; maybe more stuff [Stu favorite-number 42] ]
      Bunu işlemsel olarak okursak, transaction’ın başlarında 41’i sevdiğim, daha sonra 42’yi sevmeye başladığım gibi görünür
      Transaction bittikten sonra gözlemcinin yalnızca 42’yi sevdiğimi görmesini bekleriz ve hangi koşullarda 41’i görebileceğini dert etmemiz gerekir
      Transaction içi semantiğin bu işlemsel yorumu birçok veritabanında yaygındır, ancak transaction içinde birden fazla zaman noktası bulunduğunu varsayar
      Datomic’te böyle zaman noktaları yoktur, olması da istenmez; “transaction’ın ortasında” ne olduğuyla ilgilenmek zorunda kalmamayı tercih eder
      Datomic’te bir transaction’daki tüm olgular aynı anda gerçekleşir; dolayısıyla bu transaction, iki sayıyı aynı anda sevmeye başladığımı söyler
      Datomic transaction’larını birden çok işlemin birleşimi olarak yanlış okursanız doğal olarak her türden “değişmez koşul anomalisi” bulabilirsiniz
      Tersine, SQL transaction’larına Datomic modelini yanlış biçimde giydirseniz de “değişmez koşul anomalileri” bulabilirsiniz
      Bu yanlış anlaşılma olasılığı nedeniyle iyi dokümantasyona ihtiyaç vardı; Jepsen ile birlikte dokümanları iyileştirerek [1] özensiz ifadeleri düzelttik ve yanlış anlaşılmaları azaltmaya çalıştık
      Bu belirli yanlış anlamayı doğrudan ele alan bir teknik not da ekledik [2]
      [1] https://docs.datomic.com/transactions/transactions.html#tran...
      [2] https://docs.datomic.com/tech-notes/comparison-with-updating...
    • Özetle bu, “potansiyel bir tuzak ama dokümantasyonla tutarlı ve tasarlandığı gibi çalışıyor” ifadesine daha yakın
      Gerçekten önemli olup olmadığı, kullanıcının hangi değişmez koşulu korumak için transaction function yazdığına ve o function’ın değişmez koşulu yalnızca eşzamanlı değil sıralı yürütüldüğünde koruyup korumadığına bağlı
      Datomic’in tutumu —ya da Datomic tarafı araya girip söylese iyi olur— kullanıcıların bu tür transaction function’ları pek sık yazmadığı yönünde
      Bu tutum savunulabilir. Çünkü dokümanlarda transaction function’ların birbirini değil, transaction başlangıç durumunu gözlemlediği açıkça belirtilmişti
      Öte yandan dokümanlarda transaction function’ların değişmez koşulları korumak için kullanılabileceğini ima eden ifadeler de vardı: “[txn fns] can atomically analyze and transform database values. You can use them to ensure atomic read-modify-update processing, and integrity constraints...”
      Bu ifade ve neredeyse tüm diğer serializable veritabanlarının transaction içi sıralı semantik kullanması nedeniyle raporda bu konuya epey yer ayırdık
      Karmaşık bir soru; net bir yanıt yok. Genel veritabanı topluluğunun ve özellikle Datomic kullanıcılarının bu semantiği nasıl karşıladığını duymak isterim
    • Yazının 3.1 bölümünün sonunda zaten yanıtın verildiğini düşünüyorum: “Bu davranış şaşırtıcı olabilir, ancak genel olarak Datomic dokümantasyonuyla tutarlıdır. Nubank bu davranışı değiştirmeyi planlamıyor ve biz bunu bir bug olarak görmüyoruz”
      “Değişmez koşul ihlaline yol açan durum” dendiğinde kulağa Datomic bug’ı gibi geliyor ama bu öyle bir şey değil
      Datomic’in transaction’ları nasıl işlediğini anlamak ve kodu buna göre yazmak gerekiyor
      Nubank ile ilgisi yok ama Datomic’i genel amaçlı veritabanı olarak kullanırken bunun sorun olduğu bir durum yaşamadım
    • Bazı ilişkisel veritabanlarında, az önce seçtiğiniz değere dayanarak güncelleme yapmak istiyorsanız SELECT ... FOR UPDATE gerektiğini bilmeniz gereken duruma benziyor
  • Bilmeyenler için ekleyeyim: Jepsen adı, “call me maybe” şarkısını söyleyen Carly Rae Jepsen’dan gelen bir kelime oyunu
    Dağıtık sistem araştırma projesi adı olarak mükemmel olduğunu düşünüyorum

  • Datomic’i pratikte uzun süre kullanmadım ama o kadar kendine özgü ki bunların arasında şaşırtıcı bir şey var mı emin değilim
    Datomic transaction’ları temelde batch’e yakın ve her zaman tek thread’li diye düşündüğüm için yarış koşullarının çok olmaması doğal görünüyor
    Tasarım olarak yavaş ve güvenli tarafta

    • “Aynı transaction’da x’i iki kez artırırsanız x+2 değil x+1 olur” örneği oldukça önemli görünüyor
      Epey dikkatli olmak gerekecek gibi
    • Datomic transaction log’unu bir gün sıkıştırıyor mu?
  • Teşekkürler Kyle
    Dokümantasyonumuzun yetersiz olduğu açık
    Rich ile birlikte Datomic’in transaction modeli hakkında daha net ve kapsamlı bir doküman yazmaya çalıştık
    Yaygın yanlış anlamaları baştan önleyebilmesini umuyoruz; her türlü geri bildirime açığız
    https://docs.datomic.com/transactions/model.html

  • Datomic’in veri modeli, üçlü depolarına veya RDF’ye aşinaysanız oldukça sezgisel
    Ancak belgelerde ya da çevrimiçi tartışmalarda bu benzerliklerden pek sık söz edilmiyor
    Bunun insanların bu kavramlara aşina olmamasından mı, yoksa semantik web çağrışımlarını dikkat dağıtıcı görmelerinden mi kaynaklandığını, ya da benim kaçırdığım temel bir fark olup olmadığını merak ediyorum

  • Bu analizi gerçekten bekliyordum
    Son zamanlarda Datomic benzeri bir veri deposunu kendim geliştirdiğim için faydalı olacak gibi, şu anda okuyorum
    MongoDB analizi de ilginçti; Redis, RethinkDB ve diğer analizlere de mutlaka bakmak iyi olur
    Bir gün rqlite/dqlite ya da turso/libsql hakkında da bir analiz olursa güzel olur