6.1 Pertempuran Singkatan: BASE lwn. ASID
"Dalam kimia, pH mengukur keasidan relatif larutan akueus. Skala pH bermula dari 0 (bahan berasid kuat) hingga 14 (bahan beralkali kuat); air tulen pada 25°C mempunyai pH 7 dan neutral. Jurutera data telah mengambil metafora ini untuk membandingkan pangkalan data mengenai kebolehpercayaan transaksi." Mungkin, ideanya adalah ini: semakin tinggi pH, i.e. semakin dekat pangkalan data dengan "beralkali" ("BASE"), transaksi yang kurang boleh dipercayai. |
Pangkalan data hubungan popular, seperti MySQL, muncul hanya berdasarkan ACID. Tetapi sepanjang sepuluh tahun yang lalu, pangkalan data yang dipanggil NoSQL, yang menggabungkan beberapa jenis pangkalan data yang sangat berbeza di bawah nama ini, telah berfungsi dengan baik tanpa ACID. Malah, terdapat sebilangan besar pembangun yang bekerja dengan pangkalan data NoSQL dan tidak mengambil berat sama sekali tentang transaksi dan kebolehpercayaan mereka. Mari kita lihat jika mereka betul.
Anda tidak boleh bercakap secara umum tentang pangkalan data NoSQL, kerana ia hanya abstraksi yang baik. Pangkalan data NoSQL berbeza antara satu sama lain dalam reka bentuk subsistem penyimpanan data, dan juga dalam model data: NoSQL ialah CouchDB dan graf Neo4J yang berorientasikan dokumen. Tetapi jika kita bercakap tentang mereka dalam konteks urus niaga, mereka semua cenderung serupa dalam satu perkara: mereka menyediakan versi atomicity dan pengasingan terhad, dan oleh itu tidak menyediakan jaminan ACID. Untuk memahami maksud ini, mari jawab soalan: apakah yang mereka tawarkan, jika bukan ASID? tiada apa-apa?
Tidak juga. Lagipun, mereka, seperti pangkalan data hubungan, juga perlu menjual diri mereka dalam pakej yang cantik. Dan mereka datang dengan singkatan "kimia" mereka sendiri - BASE.
6.2 BASE sebagai antagonis
Dan di sini sekali lagi saya tidak akan mengikut susunan huruf, tetapi saya akan mulakan dengan istilah asas - konsistensi. Saya perlu meratakan kesan pengiktirafan anda, kerana konsistensi ini mempunyai sedikit kaitan dengan konsistensi daripada ACID. Masalah dengan istilah konsistensi ialah ia digunakan dalam terlalu banyak konteks. Tetapi konsistensi ini mempunyai konteks penggunaan yang lebih luas, dan sememangnya ini adalah konsistensi yang dibincangkan semasa membincangkan sistem teragih.
Pangkalan data hubungan yang kami bincangkan di atas menyediakan tahap pengasingan transaksi yang berbeza, dan yang paling ketat memastikan satu transaksi tidak dapat melihat perubahan tidak sah yang dibuat oleh transaksi lain. Jika anda berdiri di tempat pembayaran di kedai, dan pada masa itu wang untuk sewa dikeluarkan dari akaun anda, tetapi transaksi dengan pemindahan wang untuk sewa gagal dan akaun anda kembali kepada nilai sebelumnya (wang itu adalah tidak didebitkan), maka urus niaga pembayaran anda semasa pembayaran tidak akan melihat semua orang gerak isyarat ini - lagipun, urus niaga itu tidak pernah dilakukan, dan berdasarkan keperluan pengasingan transaksi, perubahan sementaranya tidak dapat disedari oleh urus niaga lain.
Banyak pangkalan data NoSQL melepaskan jaminan pengasingan dan menawarkan "konsistensi akhirnya" di mana anda akhirnya akan melihat data yang sah, tetapi terdapat kemungkinan transaksi anda akan membaca nilai tidak sah - iaitu, sementara, atau sebahagiannya dikemas kini, atau ketinggalan zaman. Ada kemungkinan bahawa data akan menjadi konsisten dalam mod "malas" apabila membaca ("malas pada masa membaca").
NoSQL difikirkan sebagai pangkalan data untuk analisis masa nyata, dan untuk mencapai kelajuan yang lebih tinggi, mereka mengorbankan konsistensi. Dan Eric Brewer, lelaki yang sama yang mencipta istilah BASE, merumuskan apa yang dipanggil "teorem CAP", mengikut mana:
Untuk sebarang pelaksanaan pengkomputeran teragih, adalah mungkin untuk menyediakan tidak lebih daripada dua daripada tiga sifat berikut:
- ketekalan data ( konsistensi ) - data pada nod yang berbeza (contoh) tidak bercanggah antara satu sama lain;
- ketersediaan ( ketersediaan ) - sebarang permintaan kepada sistem yang diedarkan berakhir dengan respons yang betul, tetapi tanpa jaminan bahawa respons semua nod sistem adalah sama;
- toleransi partition (toleransi partition ) - Walaupun tiada sambungan antara nod, mereka terus berfungsi secara bebas antara satu sama lain.
Jika anda mahukan penjelasan yang sangat mudah tentang CAP, maka di sini anda pergi.
Terdapat pendapat bahawa teorem CAP tidak berfungsi, dan secara amnya dirumus terlalu abstrak. Satu cara atau yang lain, pangkalan data NoSQL sering menolak konsistensi dalam konteks teorem CAP, yang menerangkan situasi berikut: data telah dikemas kini dalam kelompok dengan beberapa kejadian, tetapi perubahan masih belum disegerakkan pada semua kejadian. Ingat, saya menyebut contoh DynamoDB di atas, yang memberitahu saya: perubahan anda menjadi tahan lama - berikut ialah HTTP 200 untuk anda - tetapi saya hanya melihat perubahan selepas 10 saat? Contoh lain dari kehidupan seharian pembangun ialah DNS, sistem nama domain. Jika sesiapa tidak tahu, maka ini betul-betul "kamus" yang menterjemah alamat http (s) ke alamat IP.
Rekod DNS yang dikemas kini disebarkan ke pelayan mengikut tetapan selang caching - jadi kemas kini tidak dapat dilihat dengan serta-merta. Nah, ketidakkonsistenan temporal yang serupa (iaitu, akhirnya konsistensi) boleh berlaku kepada kluster pangkalan data hubungan (katakan, MySQL) - lagipun, konsistensi ini tidak ada kena mengena dengan konsistensi daripada ACID. Oleh itu, adalah penting untuk memahami bahawa dalam erti kata ini, pangkalan data SQL dan NoSQL tidak mungkin sangat berbeza apabila ia melibatkan beberapa kejadian dalam kelompok.
Selain itu, konsistensi hujung ke hujung boleh bermakna permintaan tulis akan dibuat di luar susunan: iaitu, semua data akan ditulis, tetapi nilai yang akhirnya akan diterima bukan yang terakhir dalam baris gilir tulis. .
Pangkalan data NoSQL bukan ACID mempunyai apa yang dipanggil "keadaan lembut" disebabkan oleh model konsistensi hujung ke hujung, yang bermaksud bahawa keadaan sistem boleh berubah dari semasa ke semasa, walaupun tanpa input. Tetapi sistem sedemikian berusaha untuk menyediakan akses yang lebih besar. Menyediakan ketersediaan 100% bukanlah tugas yang remeh, jadi kita bercakap tentang "ketersediaan asas". Dan bersama-sama ketiga-tiga konsep ini: "pada asasnya tersedia", "keadaan lembut" ("keadaan lembut") dan "konsistensi akhirnya" membentuk akronim BASE.
Sejujurnya, konsep BASE nampaknya saya menjadi pembungkus pemasaran yang lebih kosong daripada ACID - kerana ia tidak memberikan sesuatu yang baru dan tidak mencirikan pangkalan data dalam apa jua cara. Dan melampirkan label (ACID, BASE, CAP) pada pangkalan data tertentu hanya boleh mengelirukan pembangun. Saya memutuskan untuk memperkenalkan anda kepada istilah ini juga, kerana sukar untuk memintasnya apabila mengkaji pangkalan data, tetapi sekarang anda tahu apa itu, saya mahu anda melupakannya secepat mungkin. Dan mari kita kembali kepada konsep pengasingan.
6.3 Jadi pangkalan data BASE tidak memenuhi kriteria ACID sama sekali?
Pada asasnya, apabila pangkalan data ACID berbeza daripada bukan ACID ialah bukan ACID sebenarnya melepaskan pengasingan. Ini penting untuk difahami. Tetapi lebih penting lagi untuk membaca dokumentasi pangkalan data dan mengujinya seperti yang dilakukan oleh lelaki dari projek Hermitage. Ia tidak begitu penting bagaimana sebenarnya pencipta pangkalan data ini atau itu memanggil idea mereka - ACID atau BASE, CAP atau bukan CAP. Yang penting ialah apa sebenarnya yang disediakan oleh pangkalan data ini atau itu.
Jika pencipta pangkalan data mendakwa bahawa ia menyediakan jaminan ACID, maka mungkin ada sebab untuk ini, tetapi adalah dinasihatkan untuk mengujinya sendiri untuk memahami sama ada ini benar dan sejauh mana. Jika mereka mengisytiharkan bahawa pangkalan data mereka tidak menyediakan jaminan sedemikian, maka ini mungkin bermakna perkara berikut:
-
DB tidak memberikan jaminan atomicity. Walaupun sesetengah pangkalan data NoSQL menawarkan API berasingan untuk operasi atom (cth DynamoDB);
- DB tidak memberikan jaminan pengasingan. Ini mungkin bermakna, sebagai contoh, bahawa pangkalan data tidak akan menulis data dalam susunan ia ditulis.
Bagi jaminan ketahanan, banyak pangkalan data berkompromi mengenai perkara ini demi prestasi. Menulis pada cakera adalah operasi yang terlalu panjang, dan terdapat beberapa cara untuk menyelesaikan masalah ini. Saya tidak mahu pergi ke teori pangkalan data, tetapi supaya anda memahami secara kasar cara mana yang hendak dilihat, saya akan menerangkan secara umum bagaimana pangkalan data yang berbeza menyelesaikan masalah dengan ketahanan.
Untuk membandingkan pangkalan data yang berbeza, antara lain, anda perlu mengetahui struktur data yang mendasari penyimpanan data dan subsistem perolehan pangkalan data tertentu. Ringkasnya: pangkalan data yang berbeza mempunyai pelaksanaan pengindeksan yang berbeza - iaitu, mengatur akses kepada data. Sesetengah daripada mereka membenarkan anda menulis data dengan lebih pantas, yang lain - lebih pantas untuk membacanya. Tetapi tidak boleh dikatakan secara umum bahawa sesetengah struktur data menjadikan ketahanan lebih tinggi atau lebih rendah.
6.4 cara pangkalan data yang berbeza mengindeks data, dan cara ini mempengaruhi ketahanan, dan banyak lagi
Terdapat dua pendekatan utama untuk menyimpan dan mendapatkan semula data.
Cara paling mudah untuk menyimpan data ialah menambah operasi pada penghujung fail dalam cara seperti log (iaitu, operasi tambah sentiasa berlaku): tidak kira sama ada kita mahu menambah, menukar atau memadam data - semua Operasi CRUD hanya ditulis pada log. Mencari log adalah tidak cekap, dan di situlah indeks masuk - struktur data khas yang menyimpan metadata tentang tempat data disimpan dengan tepat. Strategi pengindeksan paling mudah untuk log ialah peta cincang yang menjejaki kunci dan nilai. Nilai akan menjadi rujukan kepada ofset bait untuk data yang ditulis di dalam fail, iaitu log (log) dan disimpan pada cakera. Struktur data ini disimpan sepenuhnya dalam ingatan, manakala data itu sendiri berada pada cakera, dan dipanggil pokok LSM (gabungan berstruktur log).
Anda mungkin tertanya-tanya: jika kami menulis operasi kami ke jurnal sepanjang masa, maka ia akan berkembang dengan pesat? Ya, dan oleh itu teknik pemadatan dicipta, yang "membersihkan" data dengan beberapa ketepatan, iaitu, hanya meninggalkan nilai yang paling relevan untuk setiap kunci, atau memadamkannya. Dan jika kami mempunyai lebih daripada satu log pada cakera, tetapi beberapa, dan semuanya diisih, maka kami akan mendapat struktur data baharu yang dipanggil SSTable ("jadual rentetan diisih"), dan ini sudah pasti akan meningkatkan prestasi kami. Jika kita ingin mengisih dalam ingatan, kita akan mendapat struktur yang sama - apa yang dipanggil MemTable, tetapi dengan itu masalahnya ialah jika kemalangan pangkalan data yang membawa maut berlaku, maka data yang ditulis terakhir (terletak di MemTable, tetapi belum ditulis kepada cakera) hilang . Sebenarnya,
Satu lagi pendekatan untuk pengindeksan adalah berdasarkan B-pokok (“B-pokok”). Dalam B-tree, data ditulis ke cakera dalam halaman saiz tetap. Blok data ini selalunya bersaiz sekitar 4 KB dan mempunyai pasangan nilai kunci yang diisih mengikut kunci. Satu nod B-tree adalah seperti tatasusunan dengan pautan ke julat halaman. Maks. bilangan pautan dalam tatasusunan dipanggil faktor cawangan. Setiap julat halaman ialah satu lagi nod B-tree dengan pautan ke julat halaman lain.
Akhirnya, pada peringkat helaian, anda akan menemui halaman individu. Idea ini serupa dengan penunjuk dalam bahasa pengaturcaraan peringkat rendah, kecuali rujukan halaman ini disimpan pada cakera dan bukannya dalam memori. Apabila INSERT dan DELETE berlaku dalam pangkalan data, maka beberapa nod boleh berpecah kepada dua subpohon untuk memadankan faktor percabangan. Jika pangkalan data gagal atas sebarang sebab di tengah-tengah proses, integriti data mungkin terjejas. Untuk mengelakkan perkara ini berlaku, pangkalan data yang menggunakan B-trees mengekalkan "log tulis ke hadapan", atau WAL, di mana setiap transaksi direkodkan. WAL ini digunakan untuk memulihkan keadaan B-tree jika ia rosak. Dan nampaknya inilah yang menjadikan pangkalan data menggunakan B-tree lebih baik dari segi ketahanan. Tetapi pangkalan data berasaskan LSM juga boleh mengekalkan fail yang pada asasnya menjalankan fungsi yang sama seperti WAL. Oleh itu, saya akan mengulangi apa yang telah saya katakan, dan mungkin lebih daripada sekali: fahami mekanisme operasi pangkalan data yang telah anda pilih.
Walau bagaimanapun, apa yang pasti tentang pokok-B ialah ia baik untuk transaksi: setiap kunci berlaku hanya di satu tempat dalam indeks, manakala subsistem storan berjurnal boleh mempunyai berbilang salinan kunci yang sama dalam serpihan yang berbeza (contohnya, sehingga pemadatan seterusnya dilakukan).
Walau bagaimanapun, reka bentuk indeks secara langsung mempengaruhi prestasi pangkalan data. Dengan pepohon LSM, penulisan ke cakera adalah berjujukan, dan pepohon B menyebabkan berbilang akses cakera rawak, jadi operasi tulis lebih pantas dengan LSM berbanding pepohon B. Perbezaannya amat ketara untuk pemacu cakera keras magnetik (HDD), di mana penulisan berurutan adalah lebih pantas daripada penulisan rawak. Pembacaan lebih perlahan pada pokok LSM kerana anda perlu melihat melalui beberapa struktur data dan jadual SS yang berbeza yang berada pada peringkat pemadatan yang berbeza. Lebih terperinci ia kelihatan seperti ini. Jika kami membuat pertanyaan pangkalan data mudah dengan LSM, kami akan mencari kunci dalam MemTable terlebih dahulu. Jika tiada, kita lihat SSTable yang terkini; jika tidak ada, maka kita melihat SSTable kedua, dan seterusnya. Jika kunci yang diminta tidak wujud, maka dengan LSM kita akan mengetahui perkara ini yang terakhir. Pokok LSM digunakan dalam, contohnya: LevelDB, RocksDB, Cassandra dan HBase.
Saya menerangkan semuanya dengan terperinci supaya anda memahami bahawa apabila memilih pangkalan data, anda perlu mempertimbangkan banyak perkara yang berbeza: sebagai contoh, adakah anda mengharapkan untuk menulis atau membaca data lebih banyak. Dan saya belum lagi menyebut perbezaan dalam model data (adakah anda perlu melintasi data, seperti yang dibenarkan oleh model graf? Adakah terdapat sebarang hubungan antara unit yang berbeza dalam data anda sama sekali - maka pangkalan data hubungan akan datang untuk menyelamatkan?), dan 2 jenis skema data - apabila menulis (seperti dalam banyak NoSQL) dan membaca (seperti dalam hubungan).
Jika kita kembali kepada aspek ketahanan, maka kesimpulannya adalah seperti berikut: mana-mana pangkalan data yang menulis ke cakera, tanpa mengira mekanisme pengindeksan, boleh memberikan jaminan yang baik untuk ketahanan data anda, tetapi anda perlu berurusan dengan setiap pangkalan data tertentu , apa sebenarnya yang ditawarkannya.
6.5 Cara DB dalam memori berfungsi
Dengan cara ini, sebagai tambahan kepada pangkalan data yang menulis ke cakera, terdapat juga pangkalan data yang dipanggil "dalam memori" yang berfungsi terutamanya dengan RAM. Ringkasnya, pangkalan data dalam memori biasanya menawarkan ketahanan yang lebih rendah demi kelajuan menulis dan membaca yang lebih pantas, tetapi ini mungkin sesuai untuk sesetengah aplikasi.
Hakikatnya adalah bahawa memori RAM telah lama lebih mahal daripada cakera, tetapi baru-baru ini ia telah mula menjadi lebih murah dengan cepat, yang telah menimbulkan jenis pangkalan data baru - yang logik, memandangkan kelajuan membaca dan menulis data daripada RAM. Tetapi anda betul-betul akan bertanya: bagaimana dengan keselamatan data pangkalan data ini? Di sini sekali lagi, anda perlu melihat butiran pelaksanaan. Secara umum, pembangun pangkalan data tersebut menawarkan mekanisme berikut:
- Anda boleh menggunakan RAM yang dikuasakan oleh bateri;
- Adalah mungkin untuk menulis log perubahan pada cakera (sesuatu seperti WAL yang disebutkan di atas), tetapi bukan data itu sendiri;
- Anda boleh secara berkala menulis salinan keadaan pangkalan data ke cakera (yang, tanpa menggunakan pilihan lain, tidak memberi jaminan, tetapi hanya meningkatkan ketahanan);
- Anda boleh meniru keadaan RAM kepada mesin lain.
Sebagai contoh, pangkalan data Redis dalam memori, yang digunakan terutamanya sebagai baris gilir mesej atau cache, tidak mempunyai ketahanan daripada ACID: ia tidak menjamin bahawa arahan yang berjaya dilaksanakan akan disimpan pada cakera, kerana Redis membuang data ke cakera (jika anda mempunyai ketekunan didayakan) hanya secara tak segerak, pada selang masa yang tetap.
Walau bagaimanapun, ini tidak kritikal untuk semua aplikasi: Saya menjumpai contoh editor dalam talian koperasi EtherPad, yang disiram setiap 1-2 saat, dan berkemungkinan pengguna boleh kehilangan beberapa huruf atau satu perkataan, yang hampir tidak kritikal. Jika tidak, memandangkan pangkalan data dalam memori bagus kerana ia menyediakan model data yang sukar dilaksanakan dengan indeks cakera, Redis boleh digunakan untuk melaksanakan transaksi - baris gilir keutamaannya membolehkan anda melakukan ini.