Dağıtılmış, olay kaynaklı bir sistemde tutarlılığı korumak için kalıplar?


12

Son zamanlarda olay kaynak okuma ve arkasındaki fikirler gibi gerçekten okudum ama aşağıdaki sorun ile sıkışmış.

Diyelim ki, komutlar alan (örneğin, web sunucuları), sonuç olarak olaylar oluşturan ve bunları merkezi bir mağazada saklayan N eşzamanlı işleminiz var. Ayrıca, tüm geçici uygulama durumunun, mağazadan olayları sırayla uygulayarak tek tek işlemlerin belleğinde tutulduğunu varsayalım.

Şimdi, aşağıdaki iş kuralına sahip olduğumuzu varsayalım: her farklı kullanıcının benzersiz bir kullanıcı adı olmalıdır.

İki işlem aynı kullanıcı adı X için bir kullanıcı kayıt komutu alırsa, her ikisi de X'in kullanıcı adları listesinde olmadığını kontrol eder, kural her iki işlem için de doğrular ve her ikisi de mağazada "X kullanıcı adıyla yeni bir kullanıcı" olayı depolar .

Şu anda tutarsız bir küresel duruma girdik çünkü iş kuralı ihlal edildi (aynı kullanıcı adına sahip iki farklı kullanıcı var).

Geleneksel bir N sunucusu <-> 1 RDBMS stil sisteminde, veritabanı bu tür tutarsızlıkları önlemeye yardımcı olan merkezi bir senkronizasyon noktası olarak kullanılır.

Benim sorum: Olay kaynaklı sistemler tipik olarak bu soruna nasıl yaklaşıyor? Her komutları sırayla işler mi (örneğin, mağazaya yazabilecek işlem miktarını 1 ile sınırlandırın)?


1
Böyle bir kısıtlama kod tarafından kontrol ediliyor mu yoksa bir db kısıtlaması mı? N olayı sırayla gönderilebilir veya gönderilemez ... N olayı aynı anda birbirinden ayrılmadan doğrulamalardan geçebilir. Sipariş önemliyse, doğrulamayı senkronize etmeniz gerekir. Veya sırayı olayları sıralamak için sıraya göre gönderir
Laiv

@Laiv doğru. Basitlik için, hiçbir veritabanı olmadığını varsaydım, tüm durum hafızada tutuldu. Belirli komut türlerini bir kuyruk aracılığıyla sırayla işlemek bir seçenek olabilir, ancak hangi komutların diğerlerini nedensel olarak etkileyebileceğine karar vermek karmaşık olabilir ve muhtemelen tüm komutları tek bir işlem işleme komutuna sahip olan aynı kuyruğa koymakla sonuçlanır. : / Örneğin bir blog yayınına yorum ekleyen bir kullanıcı varsa, "kullanıcıyı sil", "kullanıcıyı askıya al", "blog yayınını sil", "blog yayın yorumlarını devre dışı bırak" vb. Aynı sırada olmalıdır.
Olivier Lalonde

1
Sizinle aynı fikirdeyim, kuyruklar veya semaforlarla çalışmak basit değil. Ne eşzamanlılık ne de olay kaynağı kalıplarıyla çalışmayın. Ancak temelde tüm çözümler bir sistemin düzenlediği olayın trafiğiyle sonuçlanır. Ancak ilginç bir paradigma. Redis gibi, tüzel kişiliklerin son durumunu önbelleğe almak veya bu tür bir varlık şu anda işleniyorsa, düğümler arasındaki bu trafiği yönetmeye yardımcı olabilecek tuples'e yönelik harici önbellekler de vardır. Paylaşılan önbellekler bu tür gelişmelerde oldukça yaygındır. Bu karmaşık görünebilir ama giveup yok ;-) oldukça ilginç
LAIV

Yanıtlar:


6

Geleneksel bir N sunucusu <-> 1 RDBMS stil sisteminde, veritabanı bu tür tutarsızlıkları önlemeye yardımcı olan merkezi bir senkronizasyon noktası olarak kullanılır.

Olay kaynaklı sistemlerde, "olay deposu" aynı rolü üstlenir. Etkinlik kaynaklı bir nesne için, yazmanız yeni etkinliklerinizin etkinlik akışının belirli bir sürümüne eklenmesi anlamına gelir. Böylece, eşzamanlı programlamada olduğu gibi, komutu işlerken bu geçmiş üzerinde bir kilit elde edebilirsiniz. Olay kaynaklı sistemlerin daha iyimser bir yaklaşım benimsemesi daha yaygındır - önceki geçmişi yükleyin, yeni geçmişi hesaplayın, sonra karşılaştırın ve değiştirin. Bu akışa başka bir komut daha yazdıysa, karşılaştırma ve takas başarısız olur. Oradan, ya emrinizi tekrar çalıştırırsınız ya da emrinizden vazgeçersiniz, hatta sonuçlarınızı geçmişle birleştirebilirsiniz.

M komutlarına sahip tüm N sunucuları tek bir akışa yazmaya çalışıyorsa, devam etmek büyük bir sorun haline gelir. Buradaki genel cevap, modelinizdeki her olay kaynaklı varlığa bir geçmiş tahsis etmektir. Yani Kullanıcı (Bob) Kullanıcıdan (Alice) farklı bir geçmişe sahip olur ve birine yazmak, diğerine yazmayı engellemez.

Benim sorum: Olay kaynaklı sistemler tipik olarak bu soruna nasıl yaklaşıyor? Her komutu sırayla işler mi?

Set Doğrulaması için Greg Young

İş mantığını hizmet katmanına taşımadan etki alanı nesne özniteliklerindeki benzersiz çelişkileri kontrol etmenin zarif bir yolu var mı?

Kısa cevap, birçok durumda, bu gereksinimin daha derinlemesine araştırılması, ya (a) başka bir gereklilik için iyi anlaşılmamış bir vekil olduğunu ya da (b) "kural" ihlallerinin tespit edilebilirse kabul edilebilir olduğunu ortaya koymaktadır (istisna raporu) , belirli bir zaman aralığında hafifletilir veya düşük frekanslıdır (örneğin: istemciler, kullanmak üzere bir komut göndermeden önce bir adın kullanılabilir olup olmadığını kontrol edebilir).

Olay deponuzun ayar doğrulamasında iyi olduğu bazı durumlarda (yani, ilişkisel bir veritabanı), gereksinimi, olaylara devam eden aynı işlemde "benzersiz adlar" tablosuna yazarak gereksinimi uygularsınız.

Bazı durumlarda, yalnızca tüm kullanıcı adlarının aynı akışta yayınlanmasını sağlayarak gereksinimi uygulayabilirsiniz (bu, alan adı modelinizin bir parçası olarak bellekteki ad kümesini değerlendirmenize olanak tanır). - Bu durumda, iki işlem "" geçmişini güncelleme girişimini güncelleyecek, ancak karşılaştırma ve takas işlemlerinden biri başarısız olacak ve bu komutun yeniden denenmesi çakışmayı algılayabilecektir.


1) Öneriler ve referanslar için teşekkürler. "Karşılaştır ve takas et" dediğinde, işlemin bir olayı depolarken, komutu işlemeye başladığından beri yeni olayları algıladığını mı kastediyorsun? Sanırım bu "karşılaştırma ve takas" semantiği destekleyen bir olay deposu gerektirir, değil mi? (örn. "bu etkinliği yalnızca ve yalnızca son etkinlikte X kimliği varsa yaz")?
Olivier Lalonde

2) Ayrıca geçici tutarsızlıkları kabul etme ve sonunda onarma fikrini de seviyorum ama bunun için nasıl güvenilir bir şekilde kod yazacağımdan emin değilim ... belki olayları sırayla doğrulayan ve tespit ettiğinde geri alma olayları oluşturan özel bir süreç olabilir bir şeyler yanlış gitti? Teşekkürler!
Olivier Lalonde

(1) "Yeni olaylar" yerine "tarihin yeni versiyonu" diyebilirim, ama siz bir fikriniz var; geçmişi yalnızca beklediğimiz ise değiştirin.
VoiceOfUnreason

(2) Evet. Mağazadaki olayları toplu olarak okuyan bir miktar mantık ve toplu işin sonunda bir istisna raporu yayınlıyor ("Bob adında çok fazla kullanıcımız var") veya sorunu telafi etmek için komutlar gönderiyor (doğru yanıtı varsayarak) insan müdahalesi olmadan hesaplanabilir).
VoiceOfUnreason

2

Sesler Eğer (bir işletme süreci uygulamak olabilir mi sagabağlamında Domain Driven Designkullanıcı gibi muamele kullanıcı kaydı için) CRDT.

kaynaklar

  1. https://doc.akka.io/docs/akka/current/distributed-data.html http://archive.is/t0QIx

  2. "Akka Dağıtılmış Verileri olan CRDT'ler" https://www.slideshare.net/markusjura/crdts-with-akka-distributed-data hakkında bilgi edinmek için

    • CmRDTs - işleme dayalı CRDT'ler
    • CvRDTs - duruma dayalı CRTD'ler
  3. Scala'daki kod örnekleri https://github.com/akka/akka-samples/tree/master/akka-sample-distributed-data-scala . Belki "alışveriş sepeti" en uygun olanıdır.

  4. Akka Küme Turu - Akka Dağıtılmış Verileri https://manuel.bernhardt.io/2018/01/03/tour-akka-cluster-akka-distributed-data/
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.