V4'ten önce MongoDB'nin ASİT uyumlu olmaması ne demekti?


226

Ben bir veritabanı uzmanı değilim ve resmi bir bilgisayar bilimi arka planım yok, bu yüzden bana katlan. AS4 uyumlu olmayan eski bir MongoDB sürümü v4'ten önce kullanırsanız olabilecek gerçek dünya olumsuz şeylerini bilmek istiyorum . Bu, herhangi bir ACID uyumlu olmayan veritabanı için geçerlidir.

MongoDB'nin Atomik İşlemler gerçekleştirebileceğini , ancak çoğunlukla performans nedeniyle "geleneksel kilitleme ve karmaşık işlemleri desteklemediklerini" biliyorum. Ayrıca veritabanı işlemlerinin önemini ve veritabanınızın bir banka için ne zaman olduğunu anlıyorum ve hepsinin senkronize olması gereken birkaç kayıt güncellediğinizde, bir işlem varsa ilk işleme geri dönmesini istiyorsunuz. elektrik kesintisi böylece kredi satın alma, vb eşittir.

Ancak MongoDB hakkında konuştuğumda, veritabanlarının gerçekte nasıl uygulandığına dair teknik detayları bilmeyen bizler:

MongoDB, MySQL ve Postgres'den çok daha hızlıdır, ancak milyonda 1 gibi "doğru bir şekilde tasarruf etmeyecek" gibi küçük bir şansı vardır.

"Doğru şekilde kaydedilmeyecek" kısım bu anlayışa atıfta bulunuyorsa: MongoDB'ye yazdığınız anda bir elektrik kesintisi varsa, belirli bir kayıt için bir şans vardır (10 özelliğe sahip belgelerdeki sayfa görüntülemelerini izlediğinizi varsayalım) her biri), dokümanlardan birinin özelliklerden yalnızca 5 tanesini kaydettiğini gösterir… Bu, sayfa görüntüleme sayaçlarınızın zamanla "hafifçe" kapalı olacağı anlamına gelir. Ne kadar olduğunu asla bilemezsiniz,% 99.999 doğru olacaklarını biliyorsunuz, ancak% 100 değil. Bunun nedeni, bunu özellikle bir mongodb atomik işlemi yapmadığınız sürece, işlemin atomik olduğu garanti edilmez.

Benim sorum şu: MongoDB'nin ne zaman ve neden "doğru şekilde kaydedilemeyeceğinin" doğru yorumu nedir? Hangi ACID bölümlerini karşılamıyor ve hangi koşullar altında ve verilerinizin% 0,001'inin kapandığını nasıl bilebilirsiniz? Bu bir şekilde düzeltilemez mi? Değilse, bu usersMongoDB'de masanız gibi şeyleri saklamamanız gerektiği anlamına gelir , çünkü bir kayıt kaydedilmeyebilir. Ama sonra tekrar, 1 / 1.000.000 kullanıcının "tekrar kaydolmayı denemesi" gerekebilir, değil mi?

Ben sadece ne zaman / neden MongoDB gibi bir ACID uyumlu olmayan veritabanı ile negatif şeyler olur ve ideal bir standart arıyorum (ideal bir veri temizlemek için bir arka plan iş çalıştırmak gibi, ya da sadece bunun için SQL kullanmak, vb.) .

Yanıtlar:


133

MongoDB ile kaybettiğiniz bir şey çoklu tahsilat (masa) işlemleri. MongoDB'deki atom değiştiriciler yalnızca tek bir belgeye karşı çalışabilir.

Bir öğeyi envanterden kaldırmanız ve aynı anda birinin siparişine eklemeniz gerekiyorsa - yapamazsınız. Bu iki şey - envanter ve siparişler - aynı belgede mevcut olmadıkça (muhtemelen yoktur).

Üzerinde çalıştığım bir uygulamada aynı sorunla karşılaştım ve aralarından seçim yapabileceğim iki çözüm vardı:

1) Belgelerinizi olabildiğince iyi yapılandırın ve mümkün olan en iyi şekilde atomik değiştiricileri kullanın ve kalan bit için, senkronize olmayan kayıtları temizlemek için bir arka plan işlemi kullanın. Örneğin, öğeleri envanterden kaldırıyorum ve atomik değiştiriciler kullanarak aynı belgenin ayrılmış bir Envanter dizisine ekliyorum.

Bu, öğelerin envanterde KULLANILMADIĞINI her zaman bilmemi sağlar (çünkü bir müşteri tarafından ayrılmıştır). Müşteri check-out yaptığında, öğeleri saklıdır. Bu standart bir işlem değil ve müşteri sepeti terk edebildiğinden, geçip arabaları bulmak ve ayrılmış envanteri mevcut envanter havuzuna taşımak için bazı arka plan işlemine ihtiyacım var.

Bu açıkça idealden daha azdır, ancak mongodb'un ihtiyaca tam olarak uymadığı büyük bir uygulamanın tek parçasıdır. Artı, şimdiye kadar kusursuz çalışıyor. Bu birçok senaryo için mümkün olmayabilir, ancak kullandığım belge yapısı nedeniyle iyi uyuyor.

2) MongoDB ile birlikte bir işlem veritabanı kullanın. MonSDB'nin (veya başka bir NoSQL'in) en iyi yaptığı şeyi yapmasına izin verirken kesinlikle onlara ihtiyaç duyan şeyler için işlemler sağlamak için MySQL kullanmak yaygındır.

1 numaralı çözümüm uzun vadede işe yaramazsa, MongoDB'yi MySQL ile birleştirmek için daha fazla araştırma yapacağım, ancak şimdilik # 1 ihtiyaçlarıma iyi uyuyor.


27
" MongoDB'deki atom değiştiricileri sadece tek bir koleksiyona karşı çalışabilir " => Bence "tek bir belgeye karşı" demek istediniz .
assylias

2
Mükemmel bilgi, genel olarak MySQL kullanmayı önermek dışında mükemmel bir cevap.
Doug Molineux

Mon MongoDB ile kaybettiğiniz bir şey çoklu tahsilat (masa) işlemidir. MongoDB'deki atom değiştiriciler yalnızca tek bir belgeye karşı çalışabilir mon mongo doc'dan ( docs.mongodb.com/v3.2/core/write-operations-atomicity ): " MongoDB'de yazma işlemi tek bir düzeyde atomiktir işlem, tek bir belge içinde birden çok katıştırılmış belgeyi değiştirse bile. "
yoav.str

5
Çok belgeli ASİT işlemlerinin olmaması artık böyle değildir. MongoDB v4.0'da geleceklerini açıkladı. Bkz. Mongodb.com/blog/post/multi-document-transactions-in-mongodb
Grigori Melnik

1
Şimdilik, MongoDB 4.0 ASID uyumlu olduğundan , çoklu belge işlemleriyle mongodb.com/transactions . Göz at mongodb.com/blog/post/...
Ratah

135

Aslında MongoDB'nin ASİT uyumlu olmadığı doğru değildir. Aksine, MongoDB belge seviyesinde ASİT uyumludur .

Tek bir dokümanda yapılacak herhangi bir güncelleme

  • Atomik: Tamamen tamamlanır veya tamamlanmaz
  • Tutarlı: hiçbir okuyucu "kısmen uygulanmış" bir güncelleme görmez
  • İzole: tekrar, hiçbir okuyucu "kirli" bir okuma görmeyecek
  • Dayanıklı: (uygun yazma endişesi ile)

MongoDB'nin sahip olmadığı işlemler - yani geri alınabilen ve ACID uyumlu çoklu belge güncellemeleri.

İki aşamalı kesinleştirme kullanarak , tek bir belgede ACID uyumlu güncelleştirmelerin üzerine işlemler oluşturabileceğinizi unutmayın .


3
İki fazlı taahhütlerin işlemlerinin ACID uyumlu olmadığını unutmayın. Nedense bağlantıyı takip edene kadar tersini çıkardım.
Justin C

1
Yazma endişesi yapılandırmasına bakılmaksızın, dağıtılan MongoDB'nin belge düzeyinde dayanıklılığı hakkında bazı sorular vardır. Açık kaynaklı araç Jepsen, verilerin MAJORITY yazma endişesi ile bile bir ağ bölümü karşısında kaybolabileceğini buldu. Buradaki yazıya
jrullmann

9
RDBMS'de bir şekilde tek bir kayda eşdeğer olan tek bir belge düzeyinde ASID bulunması birçok durumda yararlı değildir. İşlem terimi tek tablo ile ilgili değildir ve iki aşamalı kesinleştirme mekanizmasına bile sahip olabilirsiniz ve birkaç XAResource'u dahil edebilirsiniz, bu nedenle tek belgeye ACID uyumlu olduğu için biraz sorunlu, IMHO.
Yair Zaslavsky

5
Yair ile aynı fikirde. "Belge seviyesinde ACID uyumlu" bir satış noktası değildir. Temel olarak "ASİT uyumlu değil" anlamına gelir. ASID hiçbir zaman "sadece bir satır / belge / varlık" anlamına gelmemiştir. Bu, tüm veritabanında verilerinizi tutarlı tutmakla ilgilidir.
joshua.paling

34

"Starbucks İki Faz İşlemini Kullanmaz" bölümünde iyi bir açıklama bulunmaktadır .

Bu, NoSQL veritabanlarıyla ilgili değildir, ancak bazen bir işlemi kaybetmeyi veya veritabanınızı geçici olarak tutarsız bir durumda tutmayı göze alabileceğiniz noktayı gösterir.

"Sabit" olması gereken bir şey olduğunu düşünmezdim. Çözüm, ACID uyumlu ilişkisel veritabanı kullanmaktır. Davranışı uygulama gereksinimlerinizi karşıladığında bir NoSQL alternatifi seçersiniz.


1
Herhangi bir benzetme gibi onun da sınırları vardır. Yazılımda, yeni Array [Cashiers] oluşturmak ve her birinin senkronize işlemleri işlemesini sağlamak kolaydır, bunun gerçek dünya maliyeti gülünç derecede pahalı olacaktır.
HRJ

16

Bence diğer insanlar zaten iyi cevaplar verdiler. Ancak ben ( http://ravendb.net/ gibi ) ACID NOSQL DB olduğunu eklemek istiyorum . Yani bu sadece karar NOSQL değil - ACID vs ACID ile İlişkisel ....


1
teşekkürler @subGate. ravenDB ile deneyimlerini paylaşabilen ve gerçekten gereksinimi karşılayan kimse var mı?
Nir Pengas

12

"doğru şekilde kaydedilmeyecek":

  1. Varsayılan olarak MongoDB, sürücüdeki değişikliklerinizi hemen kaydetmez. Bu nedenle, bir kullanıcıya "güncelleme başarılı", elektrik kesintisi meydana geldiğini ve güncelleme kaybolduğunu söyleme olasılığı vardır. MongoDB güncelleme "dayanıklılık" seviyesini kontrol etmek için seçenekler sunar. Diğer çoğaltma (lar) ın bu güncelleştirmeyi (bellekte) almasını, yazmanın yerel günlük dosyasına vb. Gelmesini bekleyebilir.

  2. Birden fazla koleksiyonda ve hatta aynı koleksiyonda birden çok belgede kolay "atomik" güncelleme yoktur. Çoğu durumda bu bir sorun değildir, çünkü İki Fazlı Taahhüt ile atlatılabilir veya şemanızı yeniden yapılandırabilir, böylece güncellemeler tek bir belgede yapılabilir. Bu soruya bakın: Belge Veritabanları: Yedekli veriler, referanslar, vb. (Özellikle MongoDB)


10

MongoDB v4.0'dan itibaren, çok belgeli ASİT işlemleri desteklenecektir. Anlık görüntü yalıtımı sayesinde işlemler, küresel olarak tutarlı bir veri görünümü sağlar ve veri bütünlüğünü korumak için ya hep ya hiç uygulamayı zorlar.

İlişkisel dünyadan gelen işlemler gibi hissediyorlar, örneğin:

with client.start_session() as s:
    s.start_transaction()
    try:
        collection.insert_one(doc1, session=s)
        collection.insert_one(doc2, session=s)
        s.commit_transaction()
    except Exception:
        s.abort_transaction()

Bkz. Https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb



5

Daha iyi anlaşılması için lütfen ACID özelliklerini okuyun .

Ayrıca MongoDB belgelerinde bir soru ve cevap bulabilirsiniz .

MongoDB, ASİT ile uyumlu değildir. ACID uyumluluğu hakkında bir tartışma için aşağıyı okuyun.

  1. MongoDB Ayalnızca belge düzeyinde tomictir. İlişkisel veritabanı sistemlerinden bildiğimiz atom tanımına, özellikle yukarıdaki bağlantıya uymaz. Bu anlamda MongoDB, ACID'den A'ya uymaz.
  2. MongoDB Cvarsayılan olarak etkindir. Ancak, ikincil sunuculardan çoğaltma kümesinde okuyabilirsiniz. Yalnızca nihai tutarlılığa sahip olabilirsinizBu durumda . Biraz eskimiş verileri okumak sakıncası yoksa bu yararlıdır.
  3. MongoDB Isolasyonu garanti etmez (yine yukarıdaki tanıma göre):
  1. Birden çok eşzamanlı okuyucu ve yazıcıya sahip sistemler için MongoDB, istemcilere yazma işlemi dönmeden önce yazma işleminin sonuçlarını okuma izni verir.
  2. Mongod dergi tamamlanmadan sona ererse, yazma başarılı bir şekilde dönse bile, sorgular mongod yeniden başladıktan sonra var olmayacak okuma verilerine sahip olabilir.

Ancak , MongoDB her belgeyi ayrı ayrı değiştirir (ekler ve güncellemeler için); çoklu belge işlemlerinde değil, yalnızca belge düzeyinde.

  1. Dİyileştirilebilirlik konusunda - bu davranışı write concernseçenekle yapılandırabilirsiniz , ancak emin değilsiniz. Belki birisi daha iyisini bilir.

NoSQL'i ACID kısıtlamalarına ya da benzerine taşımak için bazı araştırmaların devam ettiğini düşünüyorum. Bu bir sorundur çünkü NoSQL veritabanları genellikle hızlıdır (er) ve ACID kısıtlamaları performansı önemli ölçüde yavaşlatabilir.


4

Atomiklerin tek bir koleksiyona karşı çalışmayı değiştirmesinin tek nedeni, mongodb geliştiricilerinin yakın zamanda koleksiyon geniş yazma kilitli bir veritabanı kilidi alışverişinde bulunmalarıdır. Buradaki artan eşzamanlılığın değiş tokuşa değeceğine karar vermek. Özünde, mongodb bellek eşlemeli bir dosyadır: arabellek havuzu yönetimini makinenin vm alt sistemine devretmişlerdir. Her zaman bellekte olduğu için, çok dersli kilitlerle kurtulabilirler: onu tutarken sadece bellek içi işlemleri gerçekleştireceksiniz, bu da son derece hızlı olacaktır. Bu, bazen bir sayfa kilidi veya satır kilidi tutarken G / Ç gerçekleştirmeye zorlanan geleneksel bir veritabanı sisteminden önemli ölçüde farklıdır.


bunun eşzamanlılığı neden arttırdığını açıklayabilir misiniz? Burada bariz olanı kaçırırsam özür dilerim.
batbrat

@batbrat: Aynı veritabanındaki farklı koleksiyonlara aynı anda yazmaya çalışan iki müşteriyi düşünün. Bir veritabanı kilidi ile, istemcilerden birinin yazma gerçekleşmeden önce diğerinin bitmesini beklemesi gerekecektir. Bir toplama kilidi ile her iki istemci aynı anda yazabilir. Artan eşzamanlılık ile kastedilen budur. Tabii ki, her iki istemci de aynı koleksiyona yazmaya çalışırsa, o zaman beklemek zorunda kalacak.
jrullmann

2

"MongoDB'de tek bir belge üzerinde işlem atomiktir" - Bu geçmişte kaldı

MongoDB 4.0'ın yeni sürümünde şunları yapabilirsiniz:

Bununla birlikte, birden çok belgede güncelleme için atomisite veya birden çok belgeye okumalar arasında tutarlılık gerektiren durumlar için MongoDB, çoğaltma kümelerine karşı çoklu belge işlemleri gerçekleştirme olanağı sağlar. Çok belgeli işlemler birden çok işlemde, koleksiyonda, veritabanında ve belgede kullanılabilir. Çok belgeli işlemler “ya hep ya hiç” önerisi sağlar. Bir işlem gerçekleştirildiğinde, işlemde yapılan tüm veri değişiklikleri kaydedilir. İşlemdeki herhangi bir işlem başarısız olursa, işlem iptal edilir ve işlemde yapılan tüm veri değişiklikleri hiçbir zaman görünür olmadan atılır. Bir işlem tamamlanana kadar, işlemin dışında hiçbir yazma işlemi görünmez.

Nasıl ve Ne için birkaç sınırlama olsa da işlemlerin gerçekleştirilebileceği .

Mongo Doc'u kontrol edin. https://docs.mongodb.com/master/core/transactions/


1

Depolama biriminiz anahtar doğrusallaştırmayı destekliyor ve karşılaştırıp (MongoDB için doğrudur), atomik çok anahtarlı güncelleştirmeleri (serileştirilebilir işlem) istemci tarafında uygulayabilirsiniz. Bu yaklaşım Google'ın Percolator'ında ve HamamböceğiDB'de kullanılır ancak hiçbir şey MongoDB ile kullanmanızı engellemez.

Ben oluşturduk adım-adım görselleştirme tür işlemlerin sağladım. Umarım onları anlamanıza yardımcı olur.

Okunan kararlı izolasyon seviyesiyle ilgili sorun yaşıyorsanız Peter Bailis'in RAMP işlemlerine göz atmak mantıklıdır . Ayrıca istemci tarafında MongoDB için de uygulanabilir.

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.