Apa yang MongoDB tidak patuh pada ACID sebelum v4 benar-benar berarti?

226

Saya bukan ahli basis data dan tidak memiliki latar belakang ilmu komputer formal, jadi bersabarlah. Saya ingin mengetahui hal-hal negatif dunia nyata yang dapat terjadi jika Anda menggunakan versi MongoDB lama sebelum v4 , yang tidak sesuai dengan ACID . Ini berlaku untuk semua basis data ACID yang tidak patuh.

Saya mengerti bahwa MongoDB dapat melakukan Operasi Atom , tetapi mereka tidak "mendukung penguncian tradisional dan transaksi kompleks", kebanyakan karena alasan kinerja. Saya juga memahami pentingnya transaksi basis data, dan contoh kapan basis data Anda untuk bank, dan Anda memperbarui beberapa catatan yang semuanya harus disinkronkan, Anda ingin transaksi kembali ke keadaan awal jika ada pemadaman listrik sehingga kredit sama dengan pembelian, dll.

Tetapi ketika saya masuk ke percakapan tentang MongoDB, kita yang tidak tahu detail teknis tentang bagaimana database sebenarnya dilaksanakan mulai melemparkan pernyataan seperti:

MongoDB jauh lebih cepat daripada MySQL dan Postgres, tetapi ada kemungkinan kecil, seperti 1 dalam sejuta, "itu tidak akan disimpan dengan benar".

Bagian "tidak akan disimpan dengan benar" mengacu pada pemahaman ini: Jika ada pemadaman listrik tepat saat Anda menulis ke MongoDB, ada peluang untuk catatan tertentu (misalnya Anda melacak tampilan halaman dalam dokumen dengan 10 atribut masing-masing), bahwa salah satu dokumen hanya menyimpan 5 atribut ... yang berarti seiring waktu penghitung tampilan halaman Anda akan "sedikit" mati. Anda tidak akan pernah tahu seberapa banyak, Anda tahu mereka akan menjadi 99,999% benar, tetapi tidak 100%. Ini karena, kecuali jika Anda secara khusus menjadikan ini operasi atom mongodb , operasi tersebut tidak dijamin sebagai atom.

Jadi pertanyaan saya adalah, apa interpretasi yang benar tentang kapan dan mengapa MongoDB mungkin tidak "menyelamatkan dengan benar"? Bagian mana dari ACID yang tidak memuaskan, dan dalam keadaan apa, dan bagaimana Anda tahu kapan 0,001% data Anda tidak aktif? Tidak bisakah ini diperbaiki? Jika tidak, ini tampaknya berarti Anda tidak boleh menyimpan hal-hal seperti usersmeja Anda di MongoDB, karena catatan mungkin tidak menyimpan. Tetapi sekali lagi, bahwa pengguna 1 / 1.000.000 mungkin hanya perlu "mencoba mendaftar lagi", bukan?

Saya hanya mencari mungkin daftar kapan / mengapa hal-hal negatif terjadi dengan database tidak patuh ACID seperti MongoDB, dan idealnya jika ada solusi standar (seperti menjalankan pekerjaan latar belakang untuk membersihkan data, atau hanya menggunakan SQL untuk ini, dll.) .

Lance Pollard
sumber

Jawaban:

133

Satu hal yang hilang dengan MongoDB adalah transaksi multi-koleksi (tabel). Pengubah atom dalam MongoDB hanya dapat bekerja melawan satu dokumen.

Jika Anda perlu menghapus item dari inventaris dan menambahkannya ke pesanan seseorang secara bersamaan - Anda tidak bisa. Kecuali kedua hal itu - persediaan dan pesanan - ada dalam dokumen yang sama (yang mungkin tidak ada).

Saya mengalami masalah yang sama ini dalam aplikasi yang sedang saya kerjakan dan memiliki dua kemungkinan solusi untuk dipilih:

1) Struktur dokumen Anda sebaik mungkin dan gunakan pengubah atom sebaik mungkin dan untuk sisanya, gunakan proses latar belakang untuk membersihkan catatan yang mungkin tidak sinkron. Sebagai contoh, saya menghapus item dari inventaris dan menambahkannya ke array Inventory cadangan dari dokumen yang sama menggunakan pengubah atom.

Ini membuat saya selalu tahu bahwa barang TIDAK tersedia dalam inventaris (karena mereka dipesan oleh pelanggan). Ketika pelanggan check out, saya kemudian menghapus item dari inventori yang dipesan. Ini bukan transaksi standar dan karena pelanggan dapat meninggalkan gerobak, saya memerlukan beberapa proses latar belakang untuk melewati dan menemukan gerobak yang ditinggalkan dan memindahkan persediaan yang dipesan kembali ke kumpulan inventaris yang tersedia.

Ini jelas kurang ideal, tetapi itu satu-satunya bagian dari aplikasi besar di mana mongodb tidak sesuai dengan kebutuhan dengan sempurna. Plus, ia bekerja dengan sempurna sejauh ini. Ini mungkin tidak memungkinkan untuk banyak skenario, tetapi karena struktur dokumen yang saya gunakan, ini sangat cocok.

2) Gunakan database transaksional dalam hubungannya dengan MongoDB. Adalah umum untuk menggunakan MySQL untuk menyediakan transaksi untuk hal-hal yang benar-benar membutuhkannya sambil membiarkan MongoDB (atau NoSQL lainnya) melakukan apa yang terbaik.

Jika solusi saya dari # 1 tidak berfungsi dalam jangka panjang, saya akan menyelidiki lebih jauh untuk menggabungkan MongoDB dengan MySQL tetapi untuk sekarang # 1 cocok dengan kebutuhan saya dengan baik.

Bryan Migliorisi
sumber
27
" Pengubah atom di MongoDB hanya dapat bekerja melawan satu koleksi " => Saya pikir Anda bermaksud "terhadap satu dokumen ".
assylias
2
Informasi yang sangat baik, umumnya jawaban yang bagus dengan pengecualian menyarankan untuk menggunakan MySQL.
Doug Molineux
״ Satu hal yang Anda kehilangan dengan MongoDB adalah transaksi multi-koleksi (tabel). Pengubah atom dalam MongoDB hanya dapat bekerja melawan satu dokumen ״ dari mongo doc ( docs.mongodb.com/v3.2/core/write-operations-atomicity ): "Dalam MongoDB, operasi penulisan adalah atom pada level satu tunggal dokumen, bahkan jika operasi memodifikasi beberapa dokumen yang disematkan dalam satu dokumen. "
yoav.str
5
Kurangnya transaksi multi-dokumen ACID tidak lagi terjadi. MongoDB mengumumkan mereka akan datang di v4.0. Lihat mongodb.com/blog/post/multi-document-transactions-in-mongodb
Grigori Melnik
1
Seperti untuk saat ini, karena MongoDB 4.0 adalah ACID yang memenuhi syarat mongodb.com/transactions dengan transaksi multi-dokumen. Silahkan lihat pada mongodb.com/blog/post/...
Ratah
134

Sebenarnya tidak benar bahwa MongoDB tidak sesuai dengan ACID. Sebaliknya, MongoDB adalah ACID-compilant di tingkat dokumen .

Setiap pembaruan pada satu dokumen adalah

  • Atom: sepenuhnya selesai atau tidak
  • Konsisten: tidak ada pembaca yang akan melihat pembaruan "diterapkan sebagian"
  • Terisolasi: sekali lagi, tidak ada pembaca akan melihat "kotor" membaca
  • Tahan lama: (dengan perhatian tulis yang sesuai)

Apa yang tidak dimiliki MongoDB adalah transaksi - yaitu, pembaruan banyak dokumen yang dapat dibatalkan dan sesuai dengan ACID.

Perhatikan bahwa Anda dapat membangun transaksi di atas pembaruan yang sesuai dengan ACID ke satu dokumen, dengan menggunakan komit dua fase .

William Z
sumber
3
Perhatikan bahwa transaksi komitmen dua fase tidak sesuai dengan ACID. Untuk beberapa alasan saya menyimpulkan sebaliknya sampai saya mengikuti tautan.
Justin C
1
Ada beberapa pertanyaan tentang daya tahan MongoDB terdistribusi di tingkat dokumen, terlepas dari konfigurasi penulisan kekhawatiran. Alat open-source Jepsen menemukan bahwa data dapat hilang dalam menghadapi partisi jaringan bahkan dengan keprihatinan menulis MAJORITY. Lihat artikelnya
jrullmann
9
Memiliki ACID pada tingkat dokumen tunggal yang dalam beberapa cara setara dengan catatan tunggal dalam RDBMS tidak berguna dalam banyak kasus. Istilah transaksi tidak berhubungan dengan tabel tunggal, dan Anda bahkan dapat memiliki mekanisme komitmen dua fase dan melibatkan beberapa sumber XAR, karenanya merujuk pada dokumen tunggal sebagai ACID compliant agak bermasalah, IMHO.
Yair Zaslavsky
5
Setuju dengan Yair. "Sesuai ACID di tingkat dokumen" bukan titik penjualan. Ini pada dasarnya hanya berarti "tidak sesuai ACID". ACID tidak pernah dimaksudkan sebagai "hanya satu baris / dokumen / entitas". Ini tentang menjaga agar data Anda konsisten di seluruh basis data.
joshua.paling
34

Penjelasan yang baik tercantum dalam "Starbucks Tidak Menggunakan Komitmen Dua Fase" .

Ini bukan tentang basis data NoSQL, tetapi menggambarkan titik yang kadang-kadang Anda mampu kehilangan transaksi atau memiliki database Anda dalam keadaan tidak konsisten untuk sementara waktu.

Saya tidak akan menganggapnya sebagai sesuatu yang perlu "diperbaiki". Cara mengatasinya adalah dengan menggunakan database relasional ACID-compliant. Anda memilih alternatif NoSQL ketika perilakunya memenuhi persyaratan aplikasi Anda.

Duffymo
sumber
1
Seperti analogi apa pun ia memiliki keterbatasan. Dalam perangkat lunak, mudah untuk membuat Array [Kasir] baru dan meminta mereka memproses transaksi sinkron masing-masing, sementara biaya dunia nyata itu akan sangat mahal.
HRJ
16

Saya pikir orang lain sudah memberikan jawaban yang baik. Namun saya ingin menambahkan bahwa ada ACID NOSQL DBs (seperti http://ravendb.net/ ). Jadi bukan hanya keputusan NOSQL - tidak ada ACID vs Relasional dengan ACID ....

SubGate
sumber
1
terima kasih @subGate. adakah orang di luar sana yang dapat berbagi pengalaman mereka dengan ravenDB dan jika memang memenuhi persyaratan?
Nir Pengas
12

"tidak akan menyimpan dengan benar" dapat berarti:

  1. Secara default MongoDB tidak langsung menyimpan perubahan Anda ke drive. Jadi ada kemungkinan Anda memberi tahu pengguna "pembaruan berhasil", pemadaman listrik terjadi dan pembaruan hilang. MongoDB menyediakan opsi untuk mengontrol tingkat pembaruan "daya tahan". Bisa menunggu replika lain menerima pembaruan ini (dalam memori), menunggu penulisan terjadi pada file jurnal lokal, dll.

  2. Tidak ada pembaruan "atom" yang mudah untuk banyak koleksi dan bahkan banyak dokumen dalam koleksi yang sama. Dalam kebanyakan kasus, ini bukan masalah karena dapat dielakkan dengan Two Phase Commit , atau merestrukturisasi skema Anda sehingga pembaruan dibuat untuk satu dokumen. Lihat pertanyaan ini: Database Dokumen: Data berlebihan, referensi, dll. (Khusus MongoDB)

Sergey
sumber
10

Pada MongoDB v4.0, transaksi ACID multi-dokumen harus didukung. Melalui isolasi snapshot, transaksi akan memberikan tampilan data yang konsisten secara global, dan menegakkan eksekusi semua atau tidak sama sekali untuk menjaga integritas data.

Mereka merasa seperti transaksi dari dunia relasional, misalnya:

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()

Lihat https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb

Grigori Melnik
sumber
Kandidat rilis pertama MongoDB4.0 keluar - linkedin.com/pulse/mongodb-40-rc0-sekarang- tersedia
Grigori Melnik
5

Harap baca tentang properti ACID untuk mendapatkan pemahaman yang lebih baik.

Juga dalam dokumentasi MongoDB Anda dapat menemukan pertanyaan dan jawaban .

MongoDB tidak memenuhi ACID. Baca di bawah untuk pembahasan kepatuhan ACID.

  1. MongoDB hanya Apada tingkat dokumen saja. Itu tidak sesuai dengan definisi atom yang kita ketahui dari sistem basis data relasional, khususnya tautan di atas. Dalam hal ini MongoDB tidak mematuhi A dari ACID.
  2. MongoDB adalah Consitent secara default. Namun, Anda dapat membaca dari server sekunder dalam set replika. Anda hanya dapat memiliki konsistensi akhirnya dalam kasus ini. Ini berguna jika Anda tidak keberatan membaca data yang sedikit usang.
  3. MongoDB tidak menjamin Isolasi (sekali lagi sesuai dengan definisi di atas):
  1. Untuk sistem dengan banyak pembaca dan penulis secara bersamaan, MongoDB akan memungkinkan klien untuk membaca hasil operasi tulis sebelum operasi tulis kembali.
  2. Jika mongod berakhir sebelum jurnal melakukan, bahkan jika menulis berhasil kembali, kueri mungkin telah membaca data yang tidak akan ada setelah mongod restart.

Namun , MongoDB memodifikasi setiap dokumen secara terpisah (untuk menyisipkan dan memperbarui); hanya pada level dokumen, bukan pada transaksi multi-dokumen.

  1. Dalam hal Durability - Anda dapat mengkonfigurasi perilaku ini dengan write concernopsi, tidak yakin sekalipun. Mungkin seseorang lebih tahu.

Saya percaya beberapa penelitian sedang berlangsung untuk memindahkan NoSQL ke kendala ACID atau serupa. Ini adalah tantangan karena database NoSQL biasanya cepat (er) dan kendala ACID dapat memperlambat kinerja secara signifikan.

Ely
sumber
4

Satu-satunya alasan atom memodifikasi kerja terhadap satu-koleksi adalah karena pengembang mongodb baru-baru ini bertukar kunci database dengan kunci-lebar koleksi koleksi. Memutuskan bahwa peningkatan konkurensi di sini sepadan dengan trade-off. Pada intinya, mongodb adalah file yang dipetakan memori: mereka telah mendelegasikan manajemen buffer-pool ke subsistem vm mesin. Karena selalu ada dalam memori, mereka dapat lolos dengan kunci berbutir saja: Anda akan melakukan operasi dalam-memori saja sambil memegangnya, yang akan sangat cepat. Ini berbeda secara signifikan dari sistem basis data tradisional yang terkadang dipaksa untuk melakukan I / O sambil memegang pagelock atau rowlock.

joeshmoe
sumber
Bisakah Anda jelaskan mengapa ini meningkatkan konkurensi? Maaf jika saya kehilangan yang jelas di sini.
batbrat
@batbrat: Pertimbangkan dua klien yang mencoba untuk secara bersamaan menulis ke berbagai koleksi di database yang sama. Dengan kunci basis data, salah satu klien harus menunggu yang lain selesai sebelum penulisan dapat terjadi. Dengan kunci koleksi, kedua klien dapat menulis pada saat bersamaan. Itulah yang dimaksud dengan peningkatan konkurensi. Tentu saja, jika kedua klien mencoba untuk menulis ke koleksi yang sama maka kita harus menunggu.
jrullmann
2

"Dalam MongoDB, operasi pada satu dokumen adalah atom" - Itulah yang terjadi di masa lalu

Dalam versi baru MongoDB 4.0 Anda BISA:

Namun, untuk situasi yang memerlukan atomicity untuk memperbarui beberapa dokumen atau konsistensi antara membaca ke beberapa dokumen, MongoDB menyediakan kemampuan untuk melakukan transaksi multi-dokumen terhadap set replika. Transaksi multi-dokumen dapat digunakan di berbagai operasi, koleksi, database, dan dokumen. Transaksi multi-dokumen memberikan proposisi "semua atau tidak sama sekali". Ketika transaksi dilakukan, semua perubahan data yang dilakukan dalam transaksi disimpan. Jika ada operasi dalam transaksi gagal, transaksi dibatalkan dan semua perubahan data yang dibuat dalam transaksi dibuang tanpa pernah menjadi terlihat. Sampai transaksi dilakukan, tidak ada operasi penulisan dalam transaksi yang terlihat di luar transaksi.

Meskipun ada beberapa batasan untuk operasi Bagaimana dan Apa yang dapat dilakukan.

Periksa Mongo Doc. https://docs.mongodb.com/master/core/transactions/

Misterius25K
sumber
1

Anda dapat menerapkan pembaruan multi-kunci atom (transaksi serializable) di sisi klien jika penyimpanan Anda mendukung per linearitas kunci dan membandingkan dan mengatur (yang berlaku untuk MongoDB). Pendekatan ini digunakan di Google Percolator dan di CockroachDB tetapi tidak ada yang mencegah Anda menggunakannya dengan MongoDB.

Saya telah membuat visualisasi langkah demi langkah dari transaksi tersebut. Saya harap ini akan membantu Anda untuk memahaminya.

Jika Anda baik-baik saja dengan tingkat isolasi yang dilakukan baca maka masuk akal untuk melihat transaksi RAMP oleh Peter Bailis. Mereka juga dapat diimplementasikan untuk MongoDB di sisi klien.

rystsov
sumber