Veri çoğaltması olmayan mikro hizmetler


20

Veri çoğaltmasını veya en basit mikro hizmet tasarımı için paylaşılan bir veritabanını önlemek için zor buluyorum, bu da bir şey eksik olduğumu düşündürüyor. Karşılaştığım sorunun temel bir örneği. Birinin bir envanteri yönetmek için bir web uygulaması kullandığını varsayarsak, iki hizmete ihtiyaç duyarlar; bunlardan biri, kalemleri ve stoktaki miktarı yöneten envanter ve kullanıcı verilerini yönetecek bir kullanıcı hizmeti için. Veritabanını kimin stokladığını denetlemek istiyorsak, envanter hizmeti için kullanıcı kimliğini veritabanına son stoklama değerine göre ekleyebiliriz.

Uygulamayı kullanarak, azalmakta olan tüm öğeleri ve son kez stoklayanların bir listesini görmek isteyebiliriz, böylece tekrar stoklamalarını isteyebiliriz. Yukarıda açıklanan mimariyi kullanarak, miktarın 5'ten az olduğu tüm öğelerin öğe ayrıntılarını almak için envanter hizmetine bir istekte bulunulur. Bu, kullanıcı kimlikleri de dahil olmak üzere bir liste döndürür. Ardından, envanter hizmetinden alınan kullanıcı kimlikleri listesi için kullanıcı adı ve iletişim bilgilerini almak üzere kullanıcı hizmetine ayrı bir istekte bulunulur.

Bu çok verimsiz görünüyor ve farklı hizmetler API'larına birden fazla istek yapmadan önce birden fazla hizmet almıyor ve bu da birden fazla veritabanı sorgusu yapıyor. Bir alternatif, envanter verilerindeki kullanıcıların ayrıntılarını çoğaltmaktır. Bir kullanıcı iletişim bilgilerini değiştirdiğinde, değişikliği diğer tüm hizmetler aracılığıyla çoğaltmamız gerekir. Ancak bu, mikro hizmetlerin sınırlı bağlam fikrine uymuyor gibi görünüyor. Ayrıca tek bir veritabanı kullanabilir ve bunu farklı hizmetler arasında paylaşabiliriz ve bir entegrasyon veritabanının tüm sorunlarına sahip olabiliriz .

Bunu uygulamanın doğru / en iyi yolu nedir?


5
Mikro hizmetler paradoksuna hoş geldiniz. İşleri basitleştirecek gibi görünen şey aslında işleri daha karmaşık hale getirebilir.
Robert Harvey

"Doğru" yol her zaman olduğu gibi aynıdır: özel hedeflerinize en uygun şeyleri yapmanın bir yolunu bulmak.
Robert Harvey

1
@RobertHarvey Bu her zaman geçerli ama ders kitabı mikro hizmetlerinin yolunu anlamaya çalışıyorum. İdeal bir dünyada nasıl çalışması gerektiğini anladıktan sonra, kullanım durumuma uyacak şekilde mutlu bir şekilde değiştireceğim.
Geraint Anderson

1
Ancak, sorunuz işlevsel olmayan bir yazılım gereksinimi olan verimlilik açısından çerçevelemeniz. Verimlilik problemini çözme şekliniz veritabanına doğrudan sormaktır.
Robert Harvey

1
Tam olarak sizin gibi bir soru yazmak üzereydim. MSA'da oldukça basit web uygulamaları için hala avantajlar göremiyorum. Bence çoğu durumda modülerlik, işleri bu kadar karmaşık hale getirmeden elde edilebilir.
Glasnhost

Yanıtlar:


10

Çoğaltmanız gereken yeri tamamen özledim.

Mikro hizmetlerin merkezi bir ilkesi, hizmetin tek otorite olmasıdır. Bu, envanter ve kullanıcı yönetiminin tamamen ayrı olabileceği anlamına gelir. Kullanıcı yönetimini envanter sisteminin var olduğunu bile bilmeyecek şekilde tasarlıyorum.

Ancak envanter sistemini, kullanıcı kimliğinden başka kullanıcılar hakkında hiçbir şey saklamayacak şekilde tasarlıyorum. Bu, kullanıcı bilgisi değişikliklerini yayma sorununuzu halleder.

Hem envanter bilgileri hem de günlükler, denetimler ve çıktılar gibi kullanıcı bilgilerine ihtiyaç duyan şeylere gelince, bilgi değiştikçe güncellenmezler. Onlar ne olduğunun bir kaydı. Yine, değişikliği yaymazsınız.

Bu nedenle, her durumda, en son kullanıcı bilgisini istediğinizde, kullanıcı bilgi hizmetine sorarsınız.


@Geraint: Sisteminizde ne tür bir çoğaltma olduğu konusunda daha açık olabilir misiniz?
Robert Harvey

1
Teşekkürler. Çoğaltma, kullanıcıların iletişim bilgilerini envanter hizmetine kopyalamaya atıfta bulundu, ancak bunu ele aldınız (yani gerekli değildir). Envanter verisini ve kullanıcı verilerini bir araya getirerek alabileceğim tek bir ilişkisel veritabanından, ikincinin sonuçları döndürene kadar başlayamayacağı iki farklı API çağrısı yapmak için karşı-sezgisel görünüyor. Ancak sanırım bu, mikro hizmetler veya başka bir şey kullanıp kullanmadığımı değerlendirmenin bir parçası.
Geraint Anderson

DB'nin her ikisini de yönetmesi durumunda kullanacağı hile. Kullanıcı bilgilerini envanter tablosuna kopyalamıyorsunuz. Yabancı bir anahtar veriyorsunuz. Kullanıcı kimliği, hizmetler arasında aynı işi yapıyor. Sadece benzersiz yap.
candied_orange

It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a join"İdeal olarak" hizmet başına bir mağaza (veya daha fazlası!) Olduğunu unutmayın. Yani, "sınırlar" arasında "birleştirme" gibi bir şey yoktur. Nedeni basit, DB hizmetler arasında bağlantı üretir. @CandiedOrange önerisinin aksine, bir hizmetten diğerine minimum veri kopyalayabileceğimizi düşünüyorum. Değişmesi muhtemel olmayan verilere atıfta bulunuyorum. Bu dups verimliliği ve performansı artırırsa (ve her ikisi de gereklidir) "artıları" muhtemelen "eksilerini"
dengeleyecektir

@GeraintAnderson Yani, verimliliğe ihtiyacınız varsa (tanım gereği işlevsel olmayan bir gereksinimdir), bunu yapmanın yolları vardır. Envanter Hizmeti'nden (10 öğe gibi) veri sayfaları ister, her sayfayı alır ve Kullanıcı Hizmetinden veri istemek için bu sayfayı kullanın ve sonunda toplayın. Bu şekilde, bağımsız hizmetlerin paralelliğinden yararlanırken sınırlarınızı korursunuz. O zaman bile, uygulamanın çözülmesi gereken gerçek bir darboğaz olarak tanımlayana kadar rahatsız etmeyin - 1 saniyelik bir gece işinde ekstra 1/2 saniye beklemek kimsenin önemi yok.
Delioth

11

Veri çoğaltma önlemek için zor buluyorum ....

Mikro hizmet mimarisi hakkındaki Microsoft e-kitabına göre , veri çoğaltmada yanlış bir şey yoktur. Temel olarak, verilerin çoğaltılması, hizmetler arasındaki ayrışmayı arttırır ve bu nedenle tek bir otorite olarak rollerini güçlendirir. İlgili bir bölüm:

Ve son olarak (ve mikro hizmet oluştururken sorunların çoğu burada ortaya çıkar), eğer başlangıç ​​mikro hizmetinizin orijinal olarak diğer mikro hizmetlere ait verilere ihtiyacı varsa, bu veriler için senkronize isteklere güvenmeyin. Bunun yerine, nihai tutarlılığı kullanarak (genellikle tümleştirme olaylarını kullanarak) bu verileri (yalnızca ihtiyacınız olan öznitelikleri) ilk hizmetin veritabanına çoğaltın veya çoğaltın ...


1
Tamamen katılmıyorum. Bakımını zorlaştırır. Bir şey eklenmesi, güncellenmesi veya kaldırılması gerektiğinde mikro hizmetler arasında işlemler yapmanızı sağlar. Tek bir hata noktasını önlemek istiyorsanız, istek veya başka bir önbellekleme türü kullanabilirsiniz.
Alan Sereb

1
@AlanSereb Bakımı daha zor, ama asıl mesele bazen başka seçeneğiniz yok. Örneğin, iki veritabanında yaşayan nesneler arasında FK oluşturmanız gerekirse ne olur? Yerel bir DB'de sorgulama yaparken tutarlılığı sağlamanın tek yolu veri çoğaltmasına sahip olmaktır. Şuna bir göz atın: stackoverflow.com/a/4452586/2255491
David D.

Katılıyorum. Bir başka harika yaklaşım da olay kaynak bulma rotasını kullanmaktır. Ve tüm mutasyonlar olay hattı üzerinden gerçekleştirilsin
Alan Sereb

4

envanter hizmetine, miktarın 5'ten az olduğu tüm öğelerin öğe ayrıntılarını alması için bir istekte bulunulur. Bu, kullanıcı kimlikleri dahil bir liste döndürür. Ardından, envanter hizmetinden elde edilen kullanıcı kimlikleri listesine ilişkin kullanıcı adı ve iletişim bilgilerini almak için kullanıcı hizmetine ayrı bir istekte bulunulur.

Gerçekten evet.

Bir monolitte, ilgili öğeleri sorguladığınız bir Envanter modeline sahip olabilirsiniz, bunu bir Kullanıcı modeline besleyebilir ve aynı verileri alabilirsiniz.

Ya da daha da ileriye götürebilirsiniz, eğer aynı ilişkisel veritabanına sahipseniz ve SQL envanter tablosu ve kullanıcı tablosunu alacaksa, biraz sihir yapar ve peşinde olduğunuz verileri alırsınız.

Nasıl yaparsanız yapın, bir yerde envanter sisteminden bir kullanıcı kimliği listesi getiren, bunları kullanıcı sistemine besleyen ve bir veri listesi derleyen bir kod olacaktır .

Cevaplamanız gereken soru performans ve bakım ve diğer "yumuşak" niteliklerdir.

Mikro hizmetlerin ana yararı ölçeklendirmedir. Bir makinede on bin kullanıcınız varsa ve biraz durgunsa, başka bir makine ekleyebilirsiniz ve sistem iki kat daha hızlı hale gelir. Sekiz tane daha ekleyin ve on kat daha hızlı. (Doğrusal ölçekleme muhtemelen iyimser, ama ideal ve değildir o umut mantıksız.)

Ve bu hizmet başına . Envanter sistemi darboğazsa, kullanıcılar hakkındaki raporlardan daha fazlası için kullanılırsa, yalnızca bu hizmete daha fazla makine ekleyebilirsiniz . Makineler de uzmanlaşabilir; Bu hizmet çok fazla belleğe ihtiyaç duyar, bu hizmet ağır hesaplamalar yapar ve daha fazla işlemci gerektirir.

Ölçeklendirmeye ihtiyacınız yoksa, mikro hizmetlerin bir başka yararı daha vardır: modülerdir . Tabii ki, monolitik uygulamalar da modüler olabilir ve normalleştirilmiş bir veritabanınız vardır ve ... ancak pratikte modüller arasındaki duvarlar en iyi durumda cam duvarlar ve en kötüde kumdaki çizgiler gibidir. Mikro hizmetler katı çelikle ayrılır.

Kullanıcı sisteminiz tam anlamıyla ateş yakarsa, bu envanter sisteminizi en ufak bir şekilde etkilemez. Kimin neyi stokladığına ilişkin güzel raporlar yazdıramazsınız, ancak müşteriler stoklanmış ürünlerin orada olduğu bilgisine güvenli bir şekilde sipariş verebilirler.

Ve mikro hizmetlerde veriyi ilişkisel veritabanında (*) yaptığınızdan daha fazla çoğaltmazsınız . İlişkisel bir veritabanında birleştirme yapabilirsiniz ve eşdeğer, açıklandığı gibi koddaki listeleri birleştirmektir.

Bir görünüm de ekleyebilirsiniz , buna eşdeğer olan sizin için birleştirme yapan yeni bir hizmet eklemektir; bu üç istekle sonuçlanacaktır; Biri yeni servise, sonra da o servis orijinal ikisini yapar. İlişkisel veritabanlarında, görünümleri optimize eden ve hizmet düzeyinde uygulanması gereken süslü şeyler bulunur. "Ücretsiz" elde edemezsiniz.

Önbellekleme veri çoğaltmasından farklıdır, çünkü iki değer uyuşmazsa hangisinin yanlış olduğunu bilirsiniz. Genellikle mikro hizmetlerde tutarlılık pahasına kullanılabilirliği sağlamak için kullanılır (CAP teoremi). İlişkisel veritabanları tutarlılık sunağı üzerinde tamamen kasap kullanılabilirliği olduğundan, bunlarda daha az yaygındır. Önbelleğe almayı kolaylaştıran mikro hizmetlerin doğasında olan hiçbir şey olmadığını söyleyebilirim, ancak pratikte önbellekleme birincil endişe kaynağıdır ve mikro hizmetlerde önbelleği kolaylaştırır .

(*) Bir mikro hizmet kümesinde veri çoğaltmak mantıklıysa, muhtemelen eşdeğer ilişkisel veritabanında mantıklı olacaktır.


3
"Mikro hizmetlerde veri çoğaltma" bölümüne kadar cevabınızı gerçekten beğendim. Veri çoğaltmanın doğru yaklaşım olduğu durumlar olduğunu düşünüyorum. Hata toleransını ve özerkliğini geliştirir. Kullanıcı hizmeti düştüyse, envanter hizmeti en son stoklayanla birlikte düşük envanter listesini görüntüleyebilir.
Peter Pompeii

1
@peterpompeii Veri önleme değil, bu önbelleğe alma derdim. Veri çoğaltma, bir datum için güncellenecek iki yeriniz olduğunda, bir yer olduğunda önbelleğe alma ve diğer yerlere otomatik yayılmadır. Ayrıca ilişkisel olmaktan fazlasını söyledim. İlişkisel bir veritabanında verileri çoğaltmak mantıklıysa, bir mikro hizmette mantıklıdır. Kabul ediyorum ve bu bölüm daha net olabilir, ancak şu anda sadece bir telefonum var, bu yüzden metni şimdi güncellemeyeceğim.
Odalrick

@PeterPompeii Önbelleğe alma ile ilgili eklenen bölümün bazı endişelerinizi gidermesini umuyoruz.
Odalrick

1
@ Açıkladığınız şey veri çoğaltma gibi geliyor. Çoğaltma ve önbelleğe alma olan iki veri çoğaltma biçimleri. Çoğaltma, bir kopyanın her zaman gerekli tüm verilere sahip olacağı garanti edilir. Önbelleğe alma isteğe bağlıdır. Önbellek bir özledim olabilir. Kullanılabilirlik için önbellekleme, performans için önbellekleme kadar anlamlı değildir. TL; DR, yeterli tutarlılığa sahip bir şeyin tam bir kopyasını saklıyorsanız, asla özlülükleri kontrol etmeniz gerekmediğini garanti eder, o zaman bir önbellek değildir.
Brandon

1
@Brandon Çoğaltma ve önbellekleme arasındaki diğer bir fark, bir fark olduğunda hangi verilerin yanlış olduğunu nasıl bildiğinizdir. Çoğaltma, verilerin nasıl birleştirileceği ile ilgili bazı kuralları tanımlar. Öte yandan önbellekleme her zaman : önbellek yanlıştır.
Odalrick
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.