Farklı bir mikro servisin "sahip olduğu" veritabanından veri okumak neden bu kadar kötü


64

Son zamanlarda bu mikro servis mimarisi hakkındaki bu mükemmel makaleyi okudum: http://www.infoq.com/articles/microservices-intro

Amazon'a bir web sayfası yüklediğinizde, o zaman sunmak için 100'den fazla mikro hizmetin birlikte çalıştığını belirtir.

Bu makale, mikro hizmetler arasındaki tüm iletişimin yalnızca bir API üzerinden yapılabileceğini açıklar. Sorum şu ki, tüm veritabanı yazarlarının sadece bir API üzerinden geçebileceğini söylemek o kadar kötü, ama doğrudan çeşitli mikro servislerin veritabanlarından okumakta özgürsünüz. Örneğin, mikro hizmetin dışında yalnızca birkaç veritabanı görünümünün erişilebilir olduğunu söyleyebiliriz, böylece mikro hizmeti sürdüren ekip, bu görüşleri sağlam tuttukları sürece mikro hizmetlerinin veritabanı yapısını olabildiğince değiştirebildiklerini bilir. istemek.

Burada bir şey mi eksik? Verilerin sadece bir API üzerinden okunması için başka bir neden var mı?

Söylemeye gerek yok, şirketim Amazon'dan oldukça küçük (ve her zaman olacak) ve sahip olabileceğimiz maksimum kullanıcı sayısı yaklaşık 5 milyon.


Cevaplarda belirtilmeyen diğer bir genel faktör, veritabanına yazıldığında, yerel önbelleklemenin, hatta basit O / R eşlemesinin, veritabanına hemen erişildiğinde eski veriler sağlayabilmesidir. Μservice API'sini hız nedenleriyle atlamayı düşünüyorsanız, µservice mimarisini çok ileri götürmüş olabilir.
Joop Eggen

Veritabanına izin verildiğinde, veritabanının her bir detayı genel API'nin bir parçası olur. Böyle karmaşık bir API'de uyumluluğu korumak istemem.
Patrick

Ancak bu durumda, görünüm basitçe API'nin bir parçası olmaz, en azından anlamsal amaçlar için mi? Bu sadece API olarak adlandırdığınız ve sizi sürdürmeye zorlayan şeylerden ibarettir. (Genellikle veritabanının üstündeki bir katmanın tutarlı olması daha kolaydır.)
lc.

Görüşün bir API biçimi olacağı konusunda hemfikirim. Bence bu soruyu cevaplayan çoğu insan görüşlerini bir soyutlama düzeyi olarak kullanma hakkındaki fikrimi okumuyor. Anlaşılan, veritabanı teknolojisini değiştirmiş olsaydı görüşün bozulmaması önemli bir zorluk olurdu, ancak önümüzdeki 5 yıl boyunca veritabanı teknolojimizi değiştirmemize gerek olmayacağına bahse girmeye razıyım. Ayrıca, performans sadece 5 milyon kullanıcı için sorun olmayacak. Bu yüzden, bizim büyüklüğümüz göz önüne alındığında, bu sorunun çözümüne gideceğim için teşekkür ederim;
David

Yanıtlar:


69

Veritabanları bilgi saklamak konusunda pek iyi değil, ki bu oldukça mantıklı, çünkü onların işi aslında bilgiyi açığa çıkarmak. Ancak bu, kapsülleme söz konusu olduğunda onları berbat bir araç haline getirir. Neden kapsülleme istiyorsun?

Senaryo: Birkaç bileşeni doğrudan bir RDBMS'ye bağlarsınız ve belirli bir bileşenin, veritabanını normalleştirmek için kullanabileceğiniz, performans için bir şişe boynu olduğunu görürsünüz, ancak diğer tüm bileşenlerin etkileneceği için yapamazsınız. Belge deposuyla veya grafik veritabanıyla RDBMS'den daha iyi olacağınızı bile fark edebilirsiniz. Veriler küçük bir API ile kapsüllenmişse, söz konusu API'yi istediğiniz şekilde yeniden uygulamak için gerçekçi bir şansınız vardır. Önbellek katmanlarını şeffaf bir şekilde ekleyebilirsiniz.

Depolama katmanıyla doğrudan uygulama katmanından doldurulması, bağımlılık inversiyon ilkesinin yapmayı önerdiği şeyin karşıt çapının zıttıdır .


1
Bu harika bir nokta! Beni daha az endişelendiren bir şey, Postgres'in şimdi hem belge deposu hem de RDBMS'yi desteklemesidir ( withouttheloop.com/articles/2014-09-30-postgresql-nosql ). Ancak, amacınız hala geçerli ve dikkatlice inceleyeceğim.
David

3
Bir araç bir şeyi yapabilir, çünkü onu değiştirmenin bir çok şeyi kırmayacağı anlamına gelmez. Bu, bir dereceye kadar ayırma derecesine sahip olmanın amacı - kullanıcının gördüğü şeyi değiştirmeden bir API'nin arkasındaki verileri tamamen değiştirebilirsiniz. Burada bir veritabanı kullanıcısı olarak konuşuyorum ... müşterinin gördüğü şey olduğu sürece, arka ucu istediğiniz kadar değiştirebilirsiniz.
Ben

1
@David Bu ilginç bir haber olsa da, anlattığım senaryo için oldukça ilgisiz. DB şemanızı ilişkisel bir dokümana dayalı bir dokümanla değiştirirseniz, buna bağlı olarak tüm bunlar üzerinde aynı etkiye sahip olacaktır: tüm sorguları yeniden yazmanız gerekecektir. Tüm bu değişikliklerin bir kerede dağıtılması kabusu da vardır, böylece bileşenler arasında uyumluluk sistem genelinde korunur.
back2dos

1
@David: Erişimi iyi tanımlanmış birkaç görüşe sınırlamak, onunla birlikte gelen avantajlardan bazıları ile başka bir API oluşturmak anlamına gelir. Yalnızca görünümler olduğu sürece, salt okunur erişimle sınırlandırılmış olursunuz. Ve bir bileşene sahip olmak hem hizmet API'sine hem de görünüm API'sine bağlıdır. Öyleyse, bir bileşeni görünümlere bağlı yapıyorsanız, salt okunur veya yüksek bakım gerektirdiğini önceden belirlediniz. Burada teknik borç kokusu alıyorum. Ayrıca, veritabanınızın izin vermeyeceği şekilde yatay bölümleme yapmak isteyebilirsiniz.
back2dos

2
@David: Uzun vadede kod değiştirmenin yazmanın ne kadar kolay olduğundan daha kolay olduğu önemlidir. Mimarlık, "bu şekilde kod yazmamalısın" demez, "yaparsan, sürdürmeye çalışan korkunç kabuslar göreceksin" diyor. Prototiplerden bahsediyorsanız, bakım şart değildir. Devam et. Bir prototip mümkün olduğunca kolay bir noktaya kanıtlamalıdır. Ancak tüm kanıtlanmış noktaları, Sisifon'un kendi kendine işkenceye maruz bırakmadan bir sisteme entegre etmeye çalışırken, fazladan millere gitmekten daha iyi olursunuz.
back2dos

55

Bir mikro hizmette daha önemli ve önemli olan şey: API'si veya veritabanı şeması? API, çünkü bu dünyanın geri kalanıyla olan sözleşmesidir. Veri tabanı şeması, servis tarafından yönetilen verilerin depolanmasının uygun bir yoludur, umarım mikro hizmetin performansını optimize edecek şekilde düzenlenir. Geliştirme ekibi herhangi bir zamanda bu şemayı yeniden düzenlemek veya tamamen farklı bir veri deposu çözümüne geçmek için özgür olmalıdır. Dünyanın geri kalanı umrumda olmamalı. API sözleşmesi olduğu için dünyanın geri kalanı API'nin değiştiği zamanlar önemser.

Şimdi, eğer veritabanına göz atarsan

  • Şemalarına istenmeyen bir bağımlılık eklersiniz. Hizmetinizi etkilemeden değiştiremezler.
  • İstenmeyen ve öngörülemeyen yükleri içlerine eklersiniz.
  • Kendi servisinizin performansı, veritabanlarının performansından etkilenecektir ( müşterilerinin ve veritabanlarının yalnızca kendi hizmetleri için iyi performans gösterebilmesi için hizmetlerini optimize etmeye çalışacaklardır )
  • Uygulamanızı veri deposundaki kaynakları doğru ve belirgin bir şekilde temsil etmeyecek bir şemaya bağlıyorsunuz - yalnızca dahili durumu izlemek veya özel uygulamalarını (umursamamanız gereken) yerine getirmek için gereken ekstra ayrıntılara sahip olabilir.
  • Siz istemeden hizmet durumlarını istemeyerek imha edebilir ya da bozabilirsiniz (ve bunu yaptığınızı bilmeyeceklerdir)
  • Bunun olduğunu bilmeden kaynakları veritabanlarından güncelleyebilir / silebilir / kaldırabilirsiniz.

Yalnızca iki kez okumaya izin verilirse, son iki nokta olmayabilir, ancak diğer noktalar yeteri kadar iyi bir sebepten daha fazlasıdır. Paylaşılan veritabanları kötü bir şeydir.

Daha az deneyimli geliştiricilerin (veya öğrenmeyenlerin) veritabanını hizmetten daha önemli olarak görmesi, veritabanını gerçek bir şey olarak görmesi ve hizmeti yalnızca bir şekilde kullanmanın bir yoludur. Yanlış yol budur.


4
Tüm projede çalışan tek geliştirici siz olsanız bile yukarıdaki hususların geçerli olduğunu lütfen unutmayın. Karmaşık bir projeyi yönetmek, kendi başınıza bile, tüm bu kaygıları çağırıyor.
saat

15

Mikro hizmet mimarisinin tanımlanması zordur, ancak bunu düşünmenin en iyi yolu Bileşen Odaklı Mimari ve Hizmet Odaklı Mimari arasındaki bir evliliktir. Paket olarak yazılım, çok özel işletme etki alanı sorumluluğuna sahip birçok küçük işletme bileşeninden oluşur. Sağlanan hizmetlerde veya gerekli hizmetlerde dış dünyaya arayüzü, açıkça tanımlanmış hizmetlerin bir API'sidir.

Bileşeninizin dış etki alanı dışındaki bir veritabanına yazma ve hatta okuma, bu mimari tarzına aykırıdır.

Bunun birincil nedeni, başka bir yazılım bileşeni tarafından bir hizmet aracılığıyla sağlanan bir API'nin, hizmet sağlayan bileşenin yeni sürümleri kullanıma sunulduğunda API'nin büyük olasılıkla geriye dönük olarak uyumlu olacağı yönündeki makul beklentiye sahip olmasıdır. Eğer "sağlayan" bir bileşenin geliştiricisiysem, API'mla geriye dönük uyumluluk konusunda endişelenmem gerekiyor. Doğrudan veritabanıma karşı özel sorgular yazan diğer üç geliştirme ekibinin olduğunu bilirsem işim çok daha karmaşık bir hal aldı.

Daha da kötüsü, belki de bunları yazan diğer takım kritik bir projenin ortasındadır ve bu değişikliği şu anda bileşeninizden kabul edemezler. Artık, sahip olduğunuz bir işletme alanındaki bileşeniniz için yazılım geliştirme, başka bir işletme alanındaki geliştirme tarafından yönlendiriliyor.

Servisler arasında tam etkileşim, çeşitli yazılım bileşenleri arasındaki eşleşmeyi azaltır, böylece böyle durumlar çok sık gerçekleşmez. Veritabanındaki bir Görünümü kullanan diğer bileşenlere gelince, başka biri aleyhinde sorgu yazdıysa, Görünümü geriye dönük olarak daha uyumlu hale getirme yeteneğine sahipsiniz. Ancak bunun bir istisna durumu olması gerektiğini ve yalnızca bir uygulamanın çok fazla miktarda veri okuması gereken raporlama veya toplu işleme için yapılması gerektiğini düşünüyorum.

Açıkçası bu, geliştirme ekiplerinin Amazon gibi ticari alanlarla ayrıldığı büyük dağılmış ekiplerde iyi sonuç veriyor. Küçük bir geliştirme mağazasıysanız, özellikle büyük bir proje için hızla rampa yapmanız gerekiyorsa, ayrıca satıcı yazılımı ile de uğraşmanız gerekiyorsa, bu modelden yararlanabilirsiniz.


4

Son 20 yılda, birkaç büyük modüler veritabanı tasarımı gördüm ve David'in önerdiği senaryoyu, uygulamaların kendi şemalarına / tablolarına yazma ve başka bir şemaya okuma erişiminin olduğu birkaç kez gördüm. tabloların Çoğu zaman bir uygulamanın / modülün salt okunur erişime sahip olduğu bu veriler "ana veriler" olarak tanımlanabilir .

O zaman önceki cevapların benim görüşmem gerektiğini önerdiği sorunları görmedim, bu yüzden önceki cevaplarda ortaya çıkan noktalara daha ayrıntılı bir şekilde bakmaya değeceğini düşünüyorum.

Senaryo: Birkaç bileşeni doğrudan bir RDBMS'ye bağlarsınız ve belirli bir bileşenin performans biberonu olduğunu görürsünüz

Bu yorum ile aynı fikirdeyim, ancak bu ayrıca mikro hizmetin okuması için verilerin yerel olarak bir kopyasına sahip olma argümanı değildir. Yani, çoğu olgun veritabanları çoğaltmayı destekler ve böylece herhangi bir geliştirici çabası olmadan "ana veriler" istenirse veya gerekirse, fiziksel olarak mikro servis veritabanına kopyalanabilir.

Bazıları bunu, eski tablolarda çekirdek tabloları bir "Bölüm veritabanına" kopyalayan "Kurumsal veritabanı" olarak tanıyabilir. Buradaki bir nokta, bir veritabanının bunu bizim için değiştirilmiş verilerin çoğaltılmasıyla yapması iyi olur (yalnızca deltalar, ikili biçimde ve kaynak veritabanına minimum maliyetle).

Tersine, veritabanı seçimlerimiz bu 'raf dışı' çoğaltma desteğine izin vermediğinde, "ana verileri" mikro hizmet veritabanlarına itmek istediğimiz bir duruma girebiliriz ve bu, önemli miktarda geliştirici çabasına neden olabilir ve ayrıca önemli ölçüde daha az etkili bir mekanizma olabilir.

veritabanını denormalize etmek isteyebilir, ancak diğer tüm bileşenlerin etkileneceği için yapamazsınız.

Bana göre bu ifade doğru değil. Denormalizasyon "ilave" bir değişikliktir ve "kırılma değişikliği" değildir ve denormalizasyon nedeniyle hiçbir uygulama kırılmamalıdır.

Bir uygulamayı bu şekilde kırmanın tek yolu, uygulama kodunun "select * ..." gibi bir şey kullandığı ve fazladan bir sütunu işlememesidir. Bana bu uygulamada bir hata olurdu?

Denormalizasyon bir uygulamayı nasıl bozabilir? Bana FUD gibi geliyor.

Şema bağımlılığı:

Evet, uygulamanın artık veritabanı şemasına bağımlılığı var ve bunun bunun büyük bir sorun olması gerektiği anlamına geliyor. Herhangi bir ekstra bağımlılık eklemek kesinlikle ideal olmasa da, benim deneyimim, veritabanı şemasına bağımlılığın bir sorun olmadığı, bu yüzden neden böyle olabilir? Sadece şanslı mıydım?

Ana veriler

Genellikle bir mikro hizmetin salt okunur erişime sahip olmasını isteyebileceğimiz şema, genellikle şirket için " ana veriler " olarak tanımladığım şeydir . İşletme için gerekli olan temel verilere sahiptir.

Tarihsel olarak bu, bağımlılığı eklediğimiz şemanın hem olgun hem de istikrarlı olduğu (girişim için biraz temel ve değişmeyen) olduğu anlamına gelir.

normalleştirme

3 veritabanı tasarımcısı gidip normalize edilmiş bir db şeması tasarlarsa, aynı tasarımla sonuçlanır. Tamam, bazı 4NF / 5NF varyasyonları olabilir ama fazla olmayabilir. Dahası, tasarımcının modeli doğrulamak için sorabileceği bir dizi soru var, böylece tasarımcı 4NF'ye sahip olduklarından emin olabilirler (Çok iyimser miyim? İnsanlar 4NF'ye ulaşmak için mücadele ediyor mu?).

güncelleme: By 4NF burada şemadaki bütün masalar (bütün tabloları 4NF kadar uygun normalize var) 4NF kadar en yüksek normal formda lazım yani.

Normalleştirme tasarım sürecinin, veritabanı tasarımcılarının normalize edilmiş bir veritabanı şemasına bağlı olma fikrinin genellikle rahat olmasının nedeni olduğuna inanıyorum.

Normalleştirme süreci, DB tasarımını bilinen "doğru" bir tasarıma getirir ve oradaki varyasyonların performans için denormalizasyon olması gerekir.

  1. Desteklenen DB türlerine göre değişiklikler olabilir (JSON, ARRAY, Geo tipi desteği vb.)
  2. Bazıları 4NF / 5NF'ye dayanan varyasyonları tartışabilir.
  3. Fiziksel çeşitliliği hariç tutuyoruz (çünkü önemli değil)
  4. Bunu OLTP tasarımı ile sınırlıyoruz, DW tasarımıyla sınırlıyoruz çünkü bunlar salt okunur erişim vermek istediğimiz şemalar.

Uygulanacak bir tasarım (kod olarak) verilmiş olan 3 programcı için beklenti, 3 farklı uygulama için olacaktır (potansiyel olarak çok farklı).

Bana göre potansiyel olarak "normalleşmeye olan inanç" sorunu var.

Şema değişiklikleri kırılıyor mu?

Denormalizasyon, sütun ekleme, daha büyük depolama için sütunları değiştirme, tasarımı yeni tablolarla genişletme vb.

Sütunları / tabloları düşürerek veya bir kırma türü değişikliği yaparak kırılma değişikliklerini açıkça yapmanız mümkündür. Muhtemel evet, ancak pratik açıdan burada hiçbir sorun yaşamadım. Belki de hangi kırılma değişikliklerinin olduğu ve bunların iyi yönetildiği anlaşıldığından?

Paylaşılan salt okunur şema bağlamında şema değişikliklerini bozma vakalarını dinlemek isterim.

Bir mikro hizmette daha önemli ve önemli olan şey: API'si veya veritabanı şeması? API, çünkü bu dünyanın geri kalanıyla olan sözleşmesidir.

Bu ifadeye katılırken, "Veriler sonsuza dek yaşıyor" olan bir Enterprise Architect'ten duyabileceğimiz önemli bir uyarı olduğunu düşünüyorum . Yani, API en önemli şey olsa da, veriler bir bütün olarak işletme için de oldukça önemlidir ve çok uzun bir süre için önemli olacaktır.

Örneğin, bir zamanlar doldurmak için bir gereklilik yoktur Data Warehouse için İş zekası sonra şema ve bakılmaksızın API iş raporlama açısından önemli hale CDC desteği.

API ile ilgili sorunlar?

Şimdi eğer API'ler mükemmel ve kolay olsaydı, yerel salt okunur erişimden ziyade bir API seçtiğimiz için tüm noktalar tartışılır. Bu nedenle, yerel salt okunur erişimi göz önünde bulundurmanın bile motivasyonu, yerel erişimin önlediği API'leri kullanırken bazı sorunlar olabilir.

What motivates people to desire local read-only access?

API optimizasyonu:

LinkedIn , API'larını optimize etme konusunda ve kendileri için neden önemli olduklarıyla ilgili ilginç bir sunum yaptı (2009'dan itibaren). http://www.slideshare.net/linkedin/building-consistent-restful-apis-in-a-highperformance-environment

Kısacası, bir API birçok farklı kullanım durumunu desteklediğinde, bir kullanım durumunu en iyi şekilde desteklediği duruma ve geri kalanını ağ perspektifinden ve veritabanı perspektifinden oldukça kötü bir şekilde alabilir.

API, LinkedIn ile aynı özelliklere sahip değilse, aşağıdaki senaryoları kolayca alabilirsiniz:

  • API ihtiyacınız olandan çok daha fazla veri alıyor (israf)
  • Chatty API'leri API'yi birçok kez aramanız gereken yer

Evet, tabii ki API'lere önbellekleme ekleyebiliriz, ancak sonuçta API çağrısı uzak bir çağrıdır ve veriler yerel olduğunda geliştiricilere sunulan bir dizi optimizasyon vardır.

Şunu ekleyebilecek bir grup insan olduğundan şüpheleniyorum:

  • Master verilerin mikro servis veritabanına düşük maliyetli bir şekilde kopyalanması (geliştirme maliyeti olmadan ve teknik olarak verimli)
  • Normalleşmeye olan inanç ve uygulamaların şema değişikliklerine karşı dayanıklılığı
  • Her kullanım durumunu kolayca optimize edebilme ve konuşkan / boşuna / verimsiz uzak API çağrılarını potansiyel olarak önleme yeteneği
  • Ayrıca kısıtlamalar ve uyumlu tasarım açısından bazı diğer avantajlar

Bu cevap çok uzun sürdü. Özür dilemek!!


Bir sütun eklemek genellikle uygulamaları keser. Eğer “maaş” a sahipseniz, yeni bir “maaş_currency” sütunu kullanıldığında tüm maaşları toplayan başvuru kesilir.
kubanczyk

Gerçekten mi? Sanırım "sonları" tanımınıza bağlı. Uygulama üretimde ve "salary_currency" olmadan beklendiği gibi çalışıyorsa, neden bu uygulamanın şimdi bozulduğunu düşünüyorsunuz?
Rob Bygrave

Uygulama hatasız çalışır ve bazı numaralar görüntüler. Ama işe yaramaz. CEO, geçen ayki maaş tutarının 50 bin yerine 6 milyon olduğunu gördüğünde (Güney Kore Wons'da ödenen yeni bir çalışan nedeniyle), faydalı / işe yaramaz bir çıktı tanımı pek tartışılmayacak.
kubanczyk

0

Devlet yönetimi (potansiyel olarak bir veritabanı) Microservice'in konteynerine dağıtılabilir ve bir API ile gösterilebilir. Bir Microservice'in veri tabanı, kabın dışındaki diğer sistemlere görünmez - yalnızca API. Alternatif olarak, bir API üzerinden başka bir hizmetin (örneğin bir önbellek) yönetim durumunu da elde edebilirsiniz. Tüm Microservice'in bağımlılıklarının (API dışındaki servislere çağrılar dışında) tek bir konuşlandırılabilir kapta olması mimaride önemli bir ayrımdır. Biri bunu alamazsa geri dönüp mimariyi inceleyin.

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.