Monolitten mikro hizmetlere geçerken yabancı anahtar kısıtlamaları nasıl ele alınır?


20

Ekibim monolitik bir ASP.NET uygulamasından .NET Core ve Kubernetes'e geçiş yapıyor. Kod değişiklikleri beklendiği gibi gidiyor gibi görünüyor, ancak ekibimin çok fazla anlaşmazlık yaşadığı yerlerde veritabanı etrafında.

Şu anda tüm işimiz için tüm verileri barındıran oldukça büyük bir SQL Server veritabanına sahibiz. Ben veritabanı bir (mantıksal) veritabanında katalog verileri, başka bir envanter verileri, başka bir siparişler, vb - bölmek için benzer bir şekilde veritabanı bölmek ve her mikro hizmet veritabanı için ağ geçidi olacak .

Buradaki sonuç, mikro hizmet sınırlarını aşan yabancı anahtarların kaldırılması ve sınırlara ulaşan zincir dişlilerinin ve görüşlerin yasaklanmasıdır. Tüm veri modelleri aynı fiziksel veritabanında bulunabilir veya bulunmayabilir, ancak öyle olsalar bile, birbirleriyle doğrudan etkileşime girmemelidirler. Siparişler katalog öğelerini yine Id ile referans gösterebilir, ancak veri bütünlüğü veritabanı düzeyinde sıkı bir şekilde uygulanmayacaktır ve verilerin SQL yerine kodda birleştirilmesi gerekecektir.

Bunların kaybını mikro hizmete geçişte ve beraberinde gelen ölçeklenebilirlik avantajlarından yararlanmak için gerekli değişimler olarak görüyorum. Dikişlerimizi akıllıca seçtiğimiz ve onların çevresinde geliştiğimiz sürece sorun olmamalı. Diğer ekip üyeleri her şeyin aynı monolitik veritabanında kalması gerektiği konusunda kararlıdır, böylece her şey ASİT olabilir ve her yerde referans bütünlüğünün korunmasını sağlayabilir.

Bu beni soruma getiriyor. Birincisi, yabancı anahtar kısıtlamaları ve katılma konusundaki tavrım makul mü? Eğer öyleyse, meslektaşlarıma sunabileceğim güvenilir bir okuma materyalinin farkında mı? Pozisyonları neredeyse dindar ve Martin Fowler'ın kendilerinin yanlış olduğunu söyleyen kısa bir şey tarafından sallanacak gibi görünmüyorlar.


5
Referans bütünlüğü son derece değerlidir. Veritabanının ölçeği gerçekten buradaki darboğaz mı? Gerçekten mikro hizmet tarzı ölçeklenebilirliğe mi ihtiyacınız var? Mimarideki bu değişikliğin kuruluşunuz için uygun olup olmadığını benden daha iyi biliyorsunuz, ancak bunun birçok kullanım durumu için uygun olmadığını lütfen unutmayın. Daha cazip ödünleşmelerle ölçeklendirmenin başka yolları da olabilir. Örneğin, saniye başına veritabanı sorguları çok yüksekse, tüm gerekli olan veritabanı çoğaltmasıdır. Ayrıca mikro sunucuları kullanmak zorunda kalmadan web sunucularını yatay olarak ölçeklendirebilirsiniz.
amon

Güzel nokta. Kısa vadeli kazançlar için bu seçeneklerden bazılarını araştırıyoruz. Yine de mikro hizmetlere geçiş uzun oyundur. Kanımca aylar yerine yıllarca ölçeklendirmemize izin verecek.
Raymond Saltrelli

3
Müşterilerinizin 0,05ms daha hızlı yerleştirdikleri siparişin iptal edildiğinden emin olacağınızdan eminim çünkü stokta sadece bir tane kaldığında başka biri aynı ürünü sipariş etti.
Andy

@ amon Bunu cevapla ben oylayacağım. Bu iyi bir soru ve artıları ve eksileri adil bir şekilde temsil edilmesi gerekiyor.
mcottle

@mcottle tamam, bitti!
amon

Yanıtlar:


20

Net bir çözüm yoktur, çünkü bu tamamen bağlamınıza bağlıdır - özellikle, sisteminizin hangi boyutlarda ölçekleneceği ve gerçek sorunlarınızın ne olduğu. Veritabanı gerçekten sizin darboğazınız mı?

Bu (ne yazık ki oldukça uzun) cevap biraz “mikroservisler kötü, ömür boyu yekpare!” Şeklinde okunacak, ama bu benim niyetim değil. Demek istediğim, mikro hizmetlerin ve dağıtılmış veritabanlarının çeşitli sorunları çözebileceği, ancak bazı sorunları olmadan çözemeyeceği. Mimariniz için güçlü bir argüman yapmak için, bu sorunların geçerli olmadığını, azaltılabileceğini ve bu mimarinin iş ihtiyaçlarınız için en iyi seçim olduğunu göstermelisiniz.

Dağıtılmış veriler zordur.

Daha iyi ölçeklendirme sağlayan aynı esneklik, zayıf garantilerin kapak tarafıdır. Özellikle, dağıtılmış sistemlerin akla gelmesi çok daha zordur.

Atomik güncellemeler, işlemler, tutarlılık / referans bütünlüğü ve dayanıklılık son derece değerlidir ve derhal feragat edilmemelidir. Eksik, güncel veya tamamen yanlışsa veri sahibi olmanın çok az anlamı vardır. Bir iş gereksinimi olarak ACID'niz varsa, ancak onu kutudan çıkartamayacak veritabanı teknolojisi kullandığınızda (örneğin, birçok NoSQL veritabanı veya mikro hizmet başına DB mimarisi), uygulamanızın boşluğu doldurması ve bu garantileri sağlaması gerekir.

  • Bunu yapmak imkansız değil, doğru olmak zor. Çok zor. Özellikle her veritabanına birden çok yazarın bulunduğu dağıtılmış bir ortamda. Bu zorluk, muhtemelen düşürülen veriler, tutarsız veriler vb. Dahil olmak üzere yüksek bir hata şansına dönüşür.

    Örneğin , belki de Cassandra'nın analizinden başlayarak, iyi bilinen dağıtılmış veritabanı sistemlerinin Jepsen analizlerini okumayı düşünün . Bu analizin yarısını anlamıyorum, ama TL; DR, dağıtılmış sistemlerin o kadar zor olduğudur ki, sektör lideri projeler bile bazen onları yanlış anlarlar ve bu da görünse de açıkça görülebilir.

  • Dağıtık sistemler aynı zamanda daha büyük bir geliştirme çabası anlamına gelir. Belli bir dereceye kadar, geliştirme maliyetleri veya daha bej donanımlara para bırakmak arasında doğrudan bir denge vardır.

Örnek: sarkan referanslar

Uygulamada, bilgisayar bilimine değil, ACID'in rahatlayıp rahatlayamayacağını ve nasıl yapılacağını görmek için iş gereksinimlerinize bakmalısınız. Örneğin, birçok yabancı anahtar ilişkisi göründüğü kadar önemli olmayabilir. Bir ürün - kategori n: m ilişkisini düşünün. Bir RDBMS'de, yalnızca mevcut ürünlerin ve mevcut kategorilerin bu ilişkinin bir parçası olabilmesi için bir yabancı anahtar kısıtlaması kullanabiliriz. Ayrı ürün ve kategori hizmetleri sunarsak ve bir ürün veya kategori silinirse ne olur?

Bu durumda, bu büyük bir sorun olmayabilir ve uygulamamızı artık mevcut olmayan ürünleri veya kategorileri filtreleyecek şekilde yazabiliriz. Ama ödünleşmeler var!

  • Bunun JOIN, yalnızca veritabanı sunucusundan uygulamanıza taşınmasını sağlayan birden çok veritabanı / mikro hizmet üzerinde uygulama düzeyi gerektirebileceğini unutmayın . Bu toplam yükü arttırır ve ekstra veriyi ağ üzerinden taşımak zorundadır.

  • Bu sayfalama ile uğraşabilir. Örneğin, bir kategoriden sonraki 25 ürünü talep edersiniz ve kullanılamayan ürünleri bu yanıttan filtreleyebilirsiniz. Şimdi uygulamanız 23 ürün görüntülüyor. Teorik olarak, sıfır ürün içeren bir sayfa da mümkün olacaktır!

  • Her ilgili değişiklikten sonra veya düzenli aralıklarla sarkan referansları temizleyen bir komut dosyası çalıştırmak isteyeceksiniz. Bu tür komut dosyalarının oldukça pahalı olduğunu unutmayın, çünkü destek veritabanından / mikro hizmetten her ürün / kategoriyi hala var olup olmadığını görmek için istemek zorundadırlar.

  • Bu açık olmalı, ancak açıklık sağlamak için: kimlikleri tekrar kullanmayın. Otomatik giriş stili kimlikleri iyi olabilir veya olmayabilir. GUID'ler veya karmalar size daha fazla esneklik sağlar, örneğin, öğe bir veritabanına eklenmeden önce bir kimlik atayarak.

Örnek: eşzamanlı siparişler

Şimdi bunun yerine bir ürün siparişi ilişkisi düşünün. Bir ürün silinir veya değiştirilirse siparişe ne olur? Tamam, ilgili ürün verilerini kullanılabilir tutmak için sipariş girişine kopyalayabiliriz - basitlik için disk alanı takas edin. Ancak, ürünün fiyatı değişirse veya ürün, bu ürün için sipariş verilmeden hemen önce kullanılamazsa ne olur? Dağıtılmış bir sistemde, efektlerin yayılması zaman alır ve sipariş büyük olasılıkla eski verilerle geçer.

Yine, buna nasıl yaklaşacağınız iş gereksinimlerinize bağlıdır. Belki eski sipariş kabul edilebilir ve yerine getirilemezse siparişi iptal edebilirsiniz.

Ancak bu, örneğin yüksek eşzamanlı ayarlar için bir seçenek değildir. İlk 10 saniye içinde konser bileti almak için acele eden 3000 kişiyi düşünün ve uygunluktaki bir değişikliğin yayılması için 10 ms gerektireceğini varsayalım. Son bileti birden fazla kişiye satma olasılığı nedir? Bu çarpışmaların nasıl ele alındığına bağlıdır, ancak Poisson dağılımı kullanarak 10 ms aralıklarla çarpışma şansı λ = 3000 / (10s / 10ms) = 3elde ederiz P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%. Dolandırıcılık yapmadan siparişlerinizin çoğunu satıp sonra iptal etmenin mümkün olup olmadığı hukuk departmanınızla ilginç bir görüşmeye yol açabilir.

Pragmatizm, kirazın en iyi özellikleri seçmesi anlamına gelir.

İyi haber şu ki, aksi belirtilmedikçe dağıtılmış bir veritabanı modeline geçmek zorunda değilsiniz. Mikroservisleri “düzgün” yapmazsanız kimse Microservice Club üyeliğinizi iptal edemez, çünkü böyle bir kulüp yoktur ve mikroservisler oluşturmanın gerçek bir yolu yoktur.

Pragmatizm her seferinde kazanır, bu yüzden probleminizi çözerken çeşitli yaklaşımları karıştırın ve eşleştirin. Bu, merkezi bir veritabanına sahip mikro hizmetler anlamına da gelebilir. Gerçekten, eğer gerekmiyorsa dağıtılmış veritabanlarının acılarından geçmeyin.

Mikro hizmetler olmadan ölçeklendirebilirsiniz.

Mikro hizmetlerin iki önemli faydası vardır:

  • Ayrı ekipler tarafından bağımsız olarak geliştirilip konuşlandırılabilecek örgütsel fayda (bu da hizmetlerin istikrarlı bir arayüz sunmasını gerektirir).
  • Her mikro hizmetin bağımsız olarak ölçeklendirilebileceği operasyonel fayda .

Bağımsız ölçeklendirme gerekli değilse, mikro hizmetler çok daha az caziptir.

Bir veritabanı sunucusu zaten bağımsız olarak ölçeklendirebileceğiniz (örneğin, okuma kopyaları ekleyerek) bir tür hizmettir. Saklı yordamlardan bahsediyorsunuz. Bunları azaltmak o kadar büyük bir etkiye sahip olabilir ki diğer tüm ölçeklenebilirlik tartışmaları tartışmalıdır.

Ve tüm hizmetleri kütüphane olarak içeren ölçeklenebilir bir monolite sahip olmak mükemmel bir şekilde mümkündür. Daha sonra monolitin daha fazla örneğini başlatarak ölçekleyebilirsiniz, bu da elbette her örneğin vatansız olmasını gerektirir.

Monolit makul bir şekilde konuşlandırılamayacak kadar büyük olana kadar veya bazı hizmetlerin özel kaynak gereksinimleri varsa, böylece bunları bağımsız olarak ölçeklendirmek isteyebilirsiniz. Fazladan kaynak içeren sorunlu alanlar ayrı bir veri modeli içermeyebilir.

Güçlü bir iş vakanız var mı?

Kuruluşunuzun iş gereksinimlerinin farkındasınız ve bu nedenle, bir hizmete dayalı olarak mikro hizmet başına veritabanı mimarisi için bir argüman oluşturabilirsiniz:

  • belirli bir ölçeğin gerekli olduğunu ve bu mimarinin, böyle bir kurulum ve alternatif çözümler için artan geliştirme çabasını dikkate alarak, ölçeklenebilirliği elde etmek için en uygun maliyetli yaklaşım olduğunu; ve
  • iş gereksinimlerinizin, yukarıda tartışılanlar gibi çeşitli sorunlara yol açmadan ilgili ACID garantilerinin gevşetilmesine izin vermesi.

Tersine, bunu gösteremiyorsanız, özellikle mevcut veritabanı tasarımı geleceğe yeterli ölçeği destekleyebiliyorsa (iş arkadaşlarınız inanıyor gibi), o zaman cevabınız da vardır.

Ölçeklenebilirlik için de büyük bir YAGNI bileşeni var. Belirsizlik karşısında, ölçeklenebilirlik için bazı çalışmaların ertelenmesine karşı (gerekirse daha yüksek toplam maliyetler vardır, ancak daha iyi bir değere sahipsiniz gerçek ölçek fikri). Bu öncelikle teknik bir karar değildir.


Mükemmel cevap, teşekkür ederim. Bu ifadeyi açıklayabilir misiniz? Prosedür sayısını azaltmanın performans üzerinde büyük etkisi olabilir mi demek istediniz? Saklı yordamlardan bahsediyorsunuz. Bunları azaltmak o kadar büyük bir etkiye sahip olabilir ki diğer tüm ölçeklenebilirlik tartışmaları tartışmalıdır.
alan

1
@alan Saklı yordamlar iyi için kullanılabilir, ancak iki performans sorunu oluşturur: (1) Veritabanının optimize edilmesi için daha karmaşık sorguların yapılması daha zordur. (2) Sprocs kullanmak, DB sunucusunda daha fazla iş yapmak anlamına gelir. OP, daha fazla ölçeklemek için DB'yi bölmek istiyor, ancak karmaşık sprocs'lardan kaçınmak zaten bu boşluğu sağlayabilir. Tabii ki, sprocs ve karmaşık sorgular da performans için iyi olabilir, örneğin bir sorgu yanıtı için DB'den aktarılması gereken veri miktarını en aza indirdiklerinde. DB'nin bölünmesi, sunucular arası JOIN'ler gerektiğinde bu sorunu daha da kötüleştirir.
amon

0

Her iki yaklaşımın da makul olduğuna inanıyorum. ACID ve monolitik veritabanlarının faydalarından ödün verilebilir ölçeklenebilirlik kazanmayı seçebilir, aynı zamanda mevcut mimariyi koruyabilir ve daha dağıtılmış bir mimarinin ölçeklenebilirliğini ve çevikliğini feda edebilirsiniz. Doğru karar, gelecek yıllar için mevcut iş modeli ve buz stratejisinden alınacaktır. Tamamen teknoloji bakış açısından monolitik tutan ve daha dağılmış bir yaklaşıma yönelen ağrılar var. Sistemi analiz eder ve monolitik mimaride beklemesi veya devam etmesi gerekenlere karar vermek için riskleri, maliyetleri ve faydaları ölçeklendirmek ve değerlendirmek için hangi uygulamaların / modüllerin / iş süreçlerinin daha kritik olduğunu görürdüm.


-1

Duruşunuz makul ve doğrudur.

Yine de yün db bağımlılarında boyalı ikna nasıl başka bir soru. İki seçeneğiniz olduğunu söyleyebilirim.

  1. DB'nin sınırlarına ulaştığı somut bir örnek bulun. Örneğin 'arşiv tablolarınız' var mı? Neden iyi? Saniyede alabileceğiniz maksimum sipariş sayısı nedir? DB'nin gereksinimleri karşılamadığını ve çözümünüzün bunları düzelttiğini gösterin.

  2. Size en iyi çözümü söylemek için pahalı müteahhitler işe. Çünkü masrafları var ve blogları var, herkes onlara inanacak


1
Ben -1 değilim ama bunun iyi bir cevap olması için 2. noktanın sersemlemesini kaybederim ve birden fazla veritabanına ihtiyaç duyulduğunda ne zaman genişlerdim. Arşiv tablolarının mutlaka desteklemeyen veritabanlarında bir karşıtlık olduğunu düşünmüyorum, bölümleme. Şu anda kullandığım veritabanı 26 tablo> 10M satır ile yaklaşık 130GB veri vardır ve performans veritabanını bölmek için gereken bir sorun uzaktan yeterli değildir; bu yüzden çok şüpheliyim ve bunun neden iyi bir fikir olduğunu ve ne zaman yapılması gerektiğini duymak istiyorum - bu cevap şimdiye kadar gördüğüm en yakın şey.
mcottle

iyi. Arşiv kısıtlamalarından bahsediyorum çünkü FK kısıtlamalarını etkiliyorlar. bu zırhta bir şıklık. microservice tarafından bölme db şey bir boyutu değil onun bir mikro hizmetler ayrı bir şey tutmak. Birini kapatamaz ve atamazsanız, bu gerçekten bir mikro hizmet değildir. yeniden nokta 2. OP MF den bahseder, kelimenin tam anlamıyla onu gelip düşünmek için onları işe olabilir ve db
Ewan

"Birini kapatamaz ve atamazsan, bu gerçekten bir mikro hizmet değildir." Bu hizmetin kendisi için doğrudur, ancak hizmetin neden kendi veritabanına ihtiyaç duyduğuna dair bir argüman olması gerekmez. Sonuçta, veritabanının kendisi mikro hizmet tarafından kullanılan bir hizmettir. Mikro hizmet, kullandığı verilerin ayrı bir veritabanında mı yoksa paylaşılan bir veritabanında mı olduğunu gerçekten bilmiyor veya önemsemiyor. Bu mikro hizmetin kopyalarını yukarı veya aşağı döndürebilirsiniz ve hiçbir şey gerçekten değişmez.
Chris Pratt

Hizmet başına veritabanı için en iyi argüman bağlantı sınırlarıdır. Bağlantı havuzunun kullanılması nadir değildir, bu nedenle her mikro hizmet zaten veritabanı örneğine birden çok bağlantı gerektirir, bu durumda her biri kendi havuzlarına sahip bu mikro hizmetlerin her birinin birden çok örneğine sahip olabilirsiniz. Sonunda işler kafaya gelebilir, burada veritabanının aldığı tüm bağlantıları yönetme yeteneğini tükettiniz.
Chris Pratt
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.