Topları Etkinlik Mağazası yerine "anlık görüntüler" projeksiyonundan yeniden nemlendirme


14

Bu nedenle, bir süredir Etkinlik Kaynaklandırma ve CQRS ile flört ediyorum, ancak desenleri gerçek bir projeye uygulama fırsatım olmadı.

Okuma ve yazma endişelerinizi ayırmanın yararlarını anlıyorum ve Etkinlik Kaynaklandırmanın, Etkinlik Mağazanızdan farklı olan "Modeli Oku" veritabanlarına durum değişikliklerini nasıl yansıtmayı kolaylaştırdığını takdir ediyorum.

Süper net olmadığım şey, neden Agregalarınızı Etkinlik Deposunun kendisinden rehidrate edeceğinizdir.

Değişiklikleri "okuma" veritabanlarına yansıtmak bu kadar kolaysa, neden her zaman şeması etki alanı modelinize mükemmel şekilde uyan bir "yazma" veritabanına değişiklikleri yansıtmıyorsunuz? Bu etkili bir şekilde bir anlık görüntü veritabanı olacaktır.

Bunun vahşi doğada ES + CQRS uygulamalarında oldukça yaygın olması gerektiğini düşünüyorum.

Bu durumda, Olay Deposu yalnızca şema değişiklikleri sonucunda "yazma" veritabanınızı yeniden oluştururken yararlı mıdır? Yoksa daha büyük bir şey mi kaçırıyorum?


Bir yazma modeli durum deposuna eşzamansız olarak yazmak ve bunu yalnızca varlıkları yüklemek için kullanmakla ilgili yanlış bir şey yoktur. Bunu yapsanız da yapmasanız da aynı tutarlılık sorunları mevcuttur. Bu tutarlılık sorunlarını çözmenin anahtarı, varlıklarınızı farklı şekilde modellemektir. Etkinlik Kaynaklandırma konusunda bu tutarlılık sorunlarını çözen sihir yoktur. Büyü, modellemede yatar, bakımda değil. Bu düzeyde tutarlılık gerektiren, onları nasıl modellerseniz seçin, son derece çekişmeli varlıklara sahip olan ve ne olursa olsun özel dikkat gerektiren özel uygulamalar vardır.
Andrew Larsson

Sürece olayların teslimat garanti. Bunu yapmak için, uygulamanızın bir olayı kalıcı bir olay veriyolunda senkronize olarak yayınlaması yeterlidir. Yayınlandıktan sonra, başvurunun işi tamamlanır. Ardından veriyolu çeşitli olay işleyicilerine teslim eder: biri olay deposunu güncelleştirmek, diğeri eyalet deposunu güncellemek ve diğerlerini de okuma depolarını güncellemek için gerekli olanları. Etkinlik Kaynak Kullanımı'nı kullanmanızın nedeni, artık hemen tutarlılığı önemsememenizdir. Kucakla.
Andrew Larsson

Varlıklarınızı etkinlik deposundan sürekli yüklemeniz için hiçbir neden yoktur. Amacı bu değil. Amacı, sistemde meydana gelen her şeyin ham, kalıcı bir defteri sağlamaktır. Varlık durumu depoları ve denormalize edilmiş okuma modelleri yükleme ve okuma içindir.
Andrew Larsson

Yanıtlar:


14

Süper net olmadığım şey, neden Agregalarınızı Etkinlik Deposunun kendisinden rehidrate edeceğinizdir.

Çünkü "olaylar" kayıt defteri.

Değişiklikleri "okuma" veritabanlarına yansıtmak bu kadar kolaysa, neden her zaman şeması etki alanı modelinize mükemmel şekilde uyan bir "yazma" veritabanına değişiklikleri yansıtmıyorsunuz? Bu etkili bir şekilde bir anlık görüntü veritabanı olacaktır.

Evet; bu durumu her seferinde sıfırdan yeniden oluşturmak yerine, toplu durumun önbelleğe alınmış bir kopyasını kullanmak bazen yararlı bir performans optimizasyonudur. Unutmayın: performans optimizasyonunun ilk kuralı "Yapma" dır. Çözüme ekstra karmaşıklık katar ve zorlayıcı bir iş motivasyonunuz olana kadar bundan kaçınmayı tercih edersiniz.

Bu durumda, Olay Deposu yalnızca şema değişiklikleri sonucunda "yazma" veritabanınızı yeniden oluştururken yararlı mıdır? Yoksa daha büyük bir şey mi kaçırıyorum?

Daha büyük bir şey eksik.

İlk nokta, olay kaynaklı bir çözüm düşünürseniz, bunun sebebi olanların tarihini korumada değer olmasını beklemenizdir, yani yıkıcı olmayan değişiklikler yapmak istediğiniz anlamına gelir .

Bu yüzden etkinlik mağazasına yazıyoruz.

Özellikle bu, her değişikliğin olay deposuna yazılması gerektiği anlamına gelir.

Rakip yazarlar, birbirlerinin düzenlemelerinin farkında değilse, potansiyel olarak birbirlerinin yazmalarını yok edebilir veya sistemi istenmeyen bir duruma getirebilirler. Tutarlılık gerektiğinde olağan yaklaşım, yazılarınızı dergideki belirli bir konuma (HTTP api'deki koşullu PUT'a benzer) hitap etmektir. Başarısız bir yazma, yazara, dergiyle ilgili mevcut anlayışlarının senkronize olmadığını ve iyileşmeleri gerektiğini söyler.

Bilinen iyi bir pozisyona geri dönün ve o noktadan bu yana ek etkinlikleri tekrarlayın, ortak bir kurtarma stratejisidir. Bilinen bu iyi konum, yerel önbellekte olanın bir kopyası veya anlık görüntü deponuzdaki bir temsil olabilir.

Mutlu yolda, toplamın anlık görüntüsünü bellekte tutabilirsiniz; harici bir mağazaya yalnızca yerel bir kopya olmadığında ulaşmanız gerekir.

Ayrıca, kayıt defterine erişiminiz varsa, tamamen yakalanmanıza gerek yoktur .

Her zamanki yaklaşımı Yani ( eğer bir anlık havuzunu kullanarak) 'dir bunu korumak için uyumsuz . Bu şekilde, kurtarmanız gerekiyorsa, toplamın tüm geçmişini yeniden yüklemeden ve tekrar oynatmadan yapabilirsiniz.

Kapsamlı yaşam sürelerine sahip ince taneli agregalar, genellikle bir anlık görüntü önbelleği tutma maliyetlerini aşmanın faydaları için yeterli olay toplamadığından, bu karmaşıklığın ilgi çekici olmadığı birçok durum vardır.

Ancak sorun için doğru araç olduğunda, toplama modelinin eski bir temsilini yazma modeline yüklemek, daha sonra ek etkinliklerle güncellemek, yapmak için oldukça makul bir şeydir.


Bunların hepsi makul görünüyor. Bir süre önce ES'nin kukla bir uygulamasıyla oynadığımda tutarlılığı garanti etmek için EventStore'u kullandım, ancak aynı zamanda "anlık görüntü deposu" olarak adlandırdığınız şeye senkronize olarak yazdım. Bu, mevcut durumun olayları tekrarlamak zorunda kalmadan her zaman okumaya hazır olduğu anlamına geliyordu. Bunun iyi ölçeklenmeyeceğinden şüpheliydim, ama sadece bir egzersiz olduğu için aldırmadım.
MetaFight

6

"Yazma" veritabanının amacının ne olacağını belirtmediğiniz için, burada kastettiğinizin şu olduğunu varsayacağım: toplamı olay deposundan yeniden oluşturmak yerine, bir topluluğa yeni bir güncelleştirme kaydederken, "yazma" veritabanından kaldırın, değişikliği doğrulayın ve bir olay yayınlayın.

Demek istediğin buysa, bu strateji tutarsızlık için bir koşul yaratacaktır: Eğer son güncelleme "yazma" veritabanına girme şansına sahip olmadan önce yeni bir güncelleme olursa, yeni güncelleme güncel olmayan verilerle doğrulanır, böylece potansiyel olarak bir "imkansız" (yani "izin verilmedi") olayı yayınlar ve sistem durumunu bozar.

Örneğin, bir tiyatrodaki rezervasyon koltuklarının ayakta duran bir örneğini düşünün. Çift rezervasyonu önlemek için, rezerve edilen koltuğun önceden alınmadığından emin olmanız gerekir - buna "doğrulama" dediğiniz şey budur. Bunu yapmak için, önceden yazılan koltukların bir listesini "yazma" veritabanında saklarsınız. Ardından, bir rezervasyon isteği geldiğinde, talep edilen koltuğun listede olup olmadığını kontrol edersiniz ve eğer değilse, "rezerve edilmiş" bir etkinlik düzenlersiniz, aksi takdirde bir hata mesajıyla yanıt verirsiniz. Ardından, "rezerve edilmiş" olayları dinlediğiniz ve rezerve edilmiş koltukları "yazma" veritabanındaki listeye eklediğiniz bir projeksiyon işlemi gerçekleştirirsiniz.

Normalde sistem şu şekilde çalışır:

1. Request to book seat #1
2. Check in the "already booked" list: the list is empty.
3. Issue a "booked seat #1" event.
4. Projection process catches the event, adds seat #1 to the "already booked" list.
5. Another request to book seat #1.
6. Check in the list: the list contains seat #1
7. Respond with an error message.

Ancak, istekler çok hızlı bir şekilde gelirse ve 5. adım 4. adımdan önce olursa ne olur?

1. Request to book seat #1
2. Check in the "already booked" list: the list is empty.
3. Issue a "booked seat #1" event.
4. Another request to book seat #1.
5. Check in the list: the list is still empty.
6. Issue another "booked seat #1" event.

Şimdi aynı koltuğa rezervasyon yapmak için iki etkinliğiniz var. Sistem durumu bozuk.

Bunun olmasını önlemek için, bir projeksiyona karşı güncellemeleri asla doğrulamamalısınız. Bir güncelleştirmeyi doğrulamak için toplamı olay deposundan yeniden oluşturun, ardından güncelleştirmeyi bu güncelleştirmeye göre doğrulayın. Bundan sonra bir etkinlik düzenlersiniz, ancak mağazadan son okuduğunuzdan bu yana yeni etkinliklerin yayınlanmadığından emin olmak için zaman damgası koruması kullanın. Bu başarısız olursa, tekrar deneyin.

Etkinlik deposundan toplamaların yeniden oluşturulması bir performans cezası taşıyabilir. Bunu azaltmak için, toplu anlık görüntüleri doğrudan olay akışında, anlık görüntünün oluşturulduğu olayın kimliği ile etiketlenmiş olarak saklayabilirsiniz. Bu şekilde, en son anlık görüntüyü yükleyip tüm olay akışını her zaman en baştan tekrar oynatmak yerine, yalnızca ondan sonra gelen olayları yeniden oynatarak toplamı yeniden oluşturabilirsiniz.


Cevabınız için teşekkürler (ve yanıt vermek için çok uzun sürdüğünüz için üzgünüm). Yazma veritabanına karşı doğrulama hakkında söyledikleriniz mutlaka doğru değildir. Başka bir yorumda belirtildiği gibi, birlikte oynadığım örnek ES uygulamasında yazma veritabanımı senkronize olarak güncellemeyi (ve concurrencyId / timestamp'ı saklamayı) sağladım. Bu, EventStore'dan hazır olmanıza gerek kalmadan iyimser eşzamanlılık ihlallerini tespit etmeme izin verdi. Verilen, eşzamanlı yazma işlemleri tek başına veri bozulmasına karşı koruma sağlamaz, ancak aynı zamanda tek erişimli (tek iş parçacıklı) yazma işlemleri yapıyordum.
MetaFight

Bu yüzden tutarlılık sorunlarım çözüldü. Yine de, bunun ölçeklenebilirlik pahasına olduğunu varsaydım.
MetaFight

Yazma veritabanına eşzamanlı olarak yazmak hala bir yolsuzluk tehlikesi taşır: olay deposuna yazma başarılı olursa, ancak yazma veritabanına yazma başarısız olursa ne olur?
Fyodor Soikin

1
Okuma projeksiyonu başarısız olursa, başarılı olana kadar yeniden dener. Eğer açıkça çökerse, uyanacak ve çöktüğü yerden devam edecektir - başka bir deyişle, tekrar deneyin. Dış gözlemlenebilir etki, biraz yavaş çalıştığından farklı olmayacaktır. Yansıtma sürekli olarak başarısız olmaya devam ederse, bu, içinde bir hata olduğu anlamına gelir ve düzeltilmesi gerekir. Düzelttikten sonra, son iyi durumdan çalışmaya devam edecektir. Tüm okuma veritabanı hata sonucu bozulursa, sadece olay geçmişini kullanarak veritabanını sıfırdan yeniden oluşturacağım.
Fyodor Soikin

1
Hiçbir veri kaybolmaz, önemli olan budur. Veriler bir süre sakıncalı (okumak için) şeklinde takılabilir, ancak asla kaybolmaz.
Fyodor Soikin

3

Ana sebep performanstır. Her komut için bir anlık görüntü kaydedebilirsiniz (commit = tek bir komut tarafından oluşturulan olaylar, genellikle yalnızca bir olay), ancak bu maliyetlidir. Anlık görüntü boyunca taahhüdü de saklamanız gerekir, aksi takdirde Etkinlik kaynağı olmaz. Ve tüm bunlar atomik olarak yapılmalıdır, hepsi ya da hiçbir şey. Sorunuz yalnızca ayrı veritabanları / tablolar / koleksiyonlar kullanılıyorsa geçerlidir (aksi takdirde tam olarak Etkinlik kaynağı olur), bu nedenle tutarlılığı garanti etmek için işlemleri kullanmaya zorlanırsınız . İşlemler ölçeklendirilemez. Yalnızca bir etkinlik akışı (Etkinlik deposu) ölçeklenebilirliğin anasıdır.

İkinci neden Agrega kapsüllenmesidir. Onu korumalısın. Bu, Agrega'nın iç temsilini istediği zaman değiştirmekte özgür olması gerektiği anlamına gelir. Eğer saklarsanız ve büyük ölçüde ona bağlı kalırsanız, versiyonlama ile çok zor zaman geçireceksiniz, ki bu kesinlikle olacaktır. Şemalar, değişiklikleri sadece bir optimizasyon olarak anlık kullanmak durumda, sadece bu anlık (görmezden basitçe ? Gerçekten öyle düşünmüyorum; belirleyen iyi şans olduğunu Agregaların şema değişiklikleri - tüm iç içe kuruluşlar ve değer nesneler dahil - a'da verimli bir şekilde ve yönetilmesi).


Toplam şemam değiştiğinde, güncellenmiş bir "yazma" veritabanı oluşturmak için etkinliklerimi yeniden yürütmek basit bir sorun olmaz mı?
MetaFight

Sorun bu değişikliği tespit etmektir. Bir Agrega, çok sayıda dosya / sınıf içeren çok büyük olabilir.
Constantin Galbenu

Anlamıyorum. Değişiklik bir yazılım sürümünde olur. Sürüm muhtemelen "yazma" veritabanını yeniden oluşturmak için bir veritabanı komut dosyası ile gelecekti.
MetaFight

Bir geçiş komut dosyası için yapılması gereken çok iş var. Çalıştırırken uygulama kapalı olmalıdır.
Constantin Galbenu

@MetaFight, akış çok büyükse, yeni toplam şemasını yeniden oluşturmak çok zaman alacak ... Şimdi yeni toplamın yayınlanmasından önce yayınlanabilecek canlı bir projeksiyon durumu olan bir anlık görüntü düşünüyorum. şeması
Narvalex
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.