Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data

Catatan. terjemah: Jaana Dogan ialah seorang jurutera berpengalaman di Google yang sedang mengusahakan pemerhatian perkhidmatan pengeluaran syarikat yang ditulis dalam Go. Dalam artikel ini, yang mendapat populariti besar dalam kalangan penonton berbahasa Inggeris, dia mengumpulkan dalam 17 mata butiran teknikal penting berkenaan DBMS (dan kadangkala sistem teragih secara umum) yang berguna untuk dipertimbangkan bagi pembangun aplikasi yang besar/menuntut.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data

Sebilangan besar sistem komputer menjejaki keadaan mereka dan, oleh itu, memerlukan beberapa jenis sistem penyimpanan data. Saya mengumpul pengetahuan tentang pangkalan data dalam jangka masa yang panjang, sepanjang jalan membuat kesilapan reka bentuk yang membawa kepada kehilangan data dan gangguan. Dalam sistem yang memproses jumlah maklumat yang besar, pangkalan data terletak di tengah-tengah seni bina sistem dan bertindak sebagai elemen utama dalam memilih penyelesaian yang optimum. Walaupun fakta bahawa perhatian khusus diberikan kepada kerja pangkalan data, masalah yang cuba dijangkakan oleh pembangun aplikasi selalunya hanyalah puncak gunung ais. Dalam siri artikel ini, saya berkongsi beberapa idea yang berguna untuk pembangun yang tidak pakar dalam bidang ini.

  1. Anda bernasib baik jika 99,999% daripada masa rangkaian tidak menyebabkan masalah.
  2. ASID bermaksud banyak perkara yang berbeza.
  3. Setiap pangkalan data mempunyai mekanisme tersendiri untuk memastikan konsistensi dan pengasingan.
  4. Penyekatan optimis datang untuk menyelamatkan apabila sukar untuk mengekalkan yang biasa.
  5. Terdapat anomali lain selain bacaan kotor dan kehilangan data.
  6. Pangkalan data dan pengguna tidak selalu bersetuju dengan tindakan.
  7. Sharding peringkat aplikasi boleh dialihkan ke luar aplikasi.
  8. Autoincrementing boleh berbahaya.
  9. Data basi boleh berguna dan tidak perlu dikunci.
  10. Herotan adalah tipikal untuk sebarang sumber masa.
  11. Kelewatan mempunyai banyak makna.
  12. Keperluan prestasi hendaklah dinilai untuk transaksi tertentu.
  13. Urus niaga bersarang boleh berbahaya.
  14. Urus niaga tidak boleh terikat dengan keadaan permohonan.
  15. Perancang pertanyaan boleh memberitahu anda banyak tentang pangkalan data.
  16. Penghijrahan dalam talian adalah sukar, tetapi mungkin.
  17. Peningkatan ketara dalam pangkalan data memerlukan peningkatan dalam ketidakpastian.

Saya ingin mengucapkan terima kasih kepada Emmanuel Odeke, Rein Henrichs dan yang lain atas maklum balas mereka tentang versi awal artikel ini.

Anda bernasib baik jika 99,999% daripada masa rangkaian tidak menyebabkan masalah.

Persoalannya masih mengenai sejauh mana teknologi rangkaian moden boleh dipercayai dan kekerapan sistem rosak akibat kegagalan rangkaian. Maklumat mengenai isu ini adalah terhad dan penyelidikan sering dikuasai oleh organisasi besar dengan rangkaian khusus, peralatan dan kakitangan.

Dengan kadar ketersediaan 99,999% untuk Spanner (pangkalan data yang diedarkan secara global Google), Google mendakwa bahawa hanya 7,6% masalah berkaitan dengan rangkaian. Pada masa yang sama, syarikat itu memanggil rangkaian khususnya sebagai "tonggak utama" ketersediaan tinggi. Belajar Bailis dan Kingsbury, yang dijalankan pada 2014, mencabar salah satu daripada "salah tanggapan tentang pengkomputeran teragih", yang dirumuskan oleh Peter Deutsch pada tahun 1994. Adakah rangkaian itu benar-benar boleh dipercayai?

Penyelidikan menyeluruh di luar syarikat gergasi, yang dijalankan untuk Internet yang lebih luas, sememangnya tidak wujud. Terdapat juga data yang tidak mencukupi daripada pemain utama tentang peratusan masalah pelanggan mereka berkaitan rangkaian. Kami sedia maklum tentang gangguan dalam susunan rangkaian penyedia awan besar yang boleh menghapuskan keseluruhan bahagian Internet selama beberapa jam semata-mata kerana ia adalah acara berprofil tinggi yang menjejaskan sebilangan besar orang dan syarikat. Gangguan rangkaian boleh menyebabkan masalah dalam banyak lagi kes, walaupun tidak semua kes tersebut menjadi perhatian. Pelanggan perkhidmatan awan juga tidak tahu apa-apa tentang punca masalah. Sekiranya terdapat kegagalan, hampir mustahil untuk mengaitkannya dengan ralat rangkaian di pihak penyedia perkhidmatan. Bagi mereka, perkhidmatan pihak ketiga adalah kotak hitam. Adalah mustahil untuk menilai impak tanpa menjadi penyedia perkhidmatan yang besar.

Memandangkan apa yang dilaporkan oleh pemain besar tentang sistem mereka, selamat untuk mengatakan bahawa anda bernasib baik jika kesukaran rangkaian menyumbang hanya peratusan kecil daripada potensi isu masa henti. Komunikasi rangkaian masih mengalami perkara biasa seperti kegagalan perkakasan, perubahan topologi, perubahan konfigurasi pentadbiran dan gangguan bekalan elektrik. Baru-baru ini, saya terkejut apabila mengetahui bahawa senarai kemungkinan masalah telah ditambah gigitan jerung (ya, anda dengar betul).

ASID bermaksud banyak perkara yang berbeza

Akronim ACID bermaksud Atomicity, Consistency, Isolation, Reliability. Sifat urus niaga ini bertujuan untuk memastikan kesahihannya sekiranya berlaku kegagalan, ralat, kegagalan perkakasan, dsb. Tanpa ACID atau skim yang serupa, adalah sukar bagi pembangun aplikasi untuk membezakan antara perkara yang mereka bertanggungjawab dan apa yang pangkalan data bertanggungjawab. Kebanyakan pangkalan data transaksi hubungan cuba mematuhi ACID, tetapi pendekatan baharu seperti NoSQL telah menimbulkan banyak pangkalan data tanpa transaksi ACID kerana ia mahal untuk dilaksanakan.

Apabila saya mula-mula memasuki industri, peneraju teknikal kami bercakap tentang betapa relevannya konsep ACID. Untuk bersikap adil, ACID dianggap sebagai huraian kasar dan bukannya standard pelaksanaan yang ketat. Hari ini saya mendapati ia sangat berguna kerana ia menimbulkan kategori isu tertentu (dan mencadangkan pelbagai penyelesaian yang mungkin).

Bukan setiap DBMS mematuhi ACID; Pada masa yang sama, pelaksanaan pangkalan data yang menyokong ACID memahami set keperluan secara berbeza. Salah satu sebab mengapa pelaksanaan ACID tidak teratur adalah disebabkan oleh banyak pertukaran yang perlu dibuat untuk melaksanakan keperluan ACID. Pencipta boleh membentangkan pangkalan data mereka sebagai mematuhi ACID, tetapi tafsiran kes tepi mungkin berbeza secara mendadak, begitu juga dengan mekanisme untuk mengendalikan peristiwa "tidak mungkin". Sekurang-kurangnya, pembangun boleh memperoleh pemahaman peringkat tinggi tentang selok-belok pelaksanaan asas untuk mendapatkan pemahaman yang betul tentang tingkah laku istimewa mereka dan pertukaran reka bentuk.

Perdebatan tentang sama ada MongoDB mematuhi keperluan ACID berterusan walaupun selepas keluaran versi 4. MongoDB sudah lama tidak disokong pembalakan, walaupun secara lalai data telah dikomit ke cakera tidak lebih daripada sekali setiap 60 saat. Bayangkan senario berikut: aplikasi menyiarkan dua tulisan (w1 dan w2). MongoDB berjaya menyimpan w1, tetapi w2 hilang kerana kegagalan perkakasan.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data
Gambar rajah yang menggambarkan senario. MongoDB ranap sebelum ia boleh menulis data ke cakera

Komit pada cakera adalah proses yang mahal. Dengan mengelakkan komitmen yang kerap, pembangun meningkatkan prestasi rakaman dengan mengorbankan kebolehpercayaan. MongoDB pada masa ini menyokong pengelogan, tetapi penulisan kotor masih boleh menjejaskan integriti data kerana log ditangkap setiap 100ms secara lalai. Iaitu, senario yang sama masih mungkin untuk log dan perubahan yang dibentangkan di dalamnya, walaupun risikonya jauh lebih rendah.

Setiap pangkalan data mempunyai konsistensi dan mekanisme pengasingan sendiri

Daripada keperluan ACID, ketekalan dan pengasingan mempunyai bilangan terbesar pelaksanaan berbeza kerana julat tukar ganti adalah lebih luas. Ia mesti dikatakan bahawa konsistensi dan pengasingan adalah fungsi yang agak mahal. Mereka memerlukan penyelarasan dan meningkatkan persaingan untuk ketekalan data. Kerumitan masalah meningkat dengan ketara apabila perlu untuk menskalakan pangkalan data secara mendatar merentas berbilang pusat data (terutamanya jika ia terletak di kawasan geografi yang berbeza). Mencapai tahap konsistensi yang tinggi adalah sangat sukar, kerana ia juga mengurangkan ketersediaan dan meningkatkan pembahagian rangkaian. Untuk penjelasan yang lebih umum tentang fenomena ini, saya nasihatkan anda untuk merujuk Teorem CAP. Perlu diingatkan juga bahawa aplikasi boleh mengendalikan sejumlah kecil ketidakkonsistenan, dan pengaturcara boleh memahami nuansa masalah dengan cukup baik untuk melaksanakan logik tambahan dalam aplikasi untuk mengendalikan ketidakkonsistenan tanpa bergantung pada pangkalan data untuk mengendalikannya.

DBMS selalunya memberikan tahap pengasingan yang berbeza. Pembangun aplikasi boleh memilih yang paling berkesan berdasarkan keutamaan mereka. Pengasingan rendah membolehkan peningkatan kelajuan, tetapi juga meningkatkan risiko perlumbaan data. Penebat yang tinggi mengurangkan kebarangkalian ini, tetapi melambatkan kerja dan boleh menyebabkan persaingan, yang akan membawa kepada brek sedemikian di pangkalan yang kegagalan bermula.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data
Semakan model konkurensi sedia ada dan hubungan antara mereka

Piawaian SQL mentakrifkan hanya empat tahap pengasingan, walaupun dalam teori dan amalan terdapat banyak lagi. Jepson.io menawarkan gambaran keseluruhan yang sangat baik tentang model konkurensi sedia ada. Sebagai contoh, Google Spanner menjamin kebolehsirilan luaran dengan penyegerakan jam, dan walaupun ini adalah lapisan pengasingan yang lebih ketat, ia tidak ditakrifkan dalam lapisan pengasingan standard.

Piawaian SQL menyebut tahap pengasingan berikut:

  • Serializable (paling ketat dan mahal): Pelaksanaan boleh bersiri mempunyai kesan yang sama seperti beberapa pelaksanaan transaksi berjujukan. Pelaksanaan berurutan bermakna setiap transaksi berikutnya bermula hanya selepas yang sebelumnya selesai. Perlu diingatkan bahawa tahap Serializable sering dilaksanakan sebagai apa yang dipanggil pengasingan syot kilat (contohnya, dalam Oracle) disebabkan oleh perbezaan tafsiran, walaupun pengasingan syot kilat itu sendiri tidak diwakili dalam standard SQL.
  • Bacaan boleh berulang: Rekod tidak komited dalam urus niaga semasa tersedia untuk urus niaga semasa, tetapi perubahan yang dibuat oleh urus niaga lain (seperti baris baharu) tidak kelihatan.
  • Baca komited: Data tidak komited tidak tersedia untuk transaksi. Dalam kes ini, urus niaga hanya boleh melihat data komited dan bacaan hantu mungkin berlaku. Jika transaksi memasukkan dan melakukan baris baharu, transaksi semasa akan dapat melihatnya apabila ditanya.
  • Baca tanpa komitmen (tahap paling tidak ketat dan mahal): Bacaan kotor dibenarkan, urus niaga boleh melihat perubahan tanpa komitmen yang dibuat oleh transaksi lain. Dalam amalan, tahap ini mungkin berguna untuk anggaran kasar, seperti pertanyaan COUNT(*) di atas meja.

Уровень Serializable meminimumkan risiko perlumbaan data, sambil menjadi yang paling mahal untuk dilaksanakan dan menghasilkan beban daya saing tertinggi pada sistem. Tahap pengasingan lain lebih mudah untuk dilaksanakan, tetapi meningkatkan kemungkinan perlumbaan data. Sesetengah DBMS membenarkan anda menetapkan tahap pengasingan tersuai, yang lain mempunyai keutamaan yang kuat dan tidak semua tahap disokong.

Sokongan untuk tahap pengasingan sering diiklankan dalam DBMS tertentu, tetapi hanya kajian teliti kelakuannya boleh mendedahkan perkara yang sebenarnya berlaku.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data
Semakan anomali konkurensi pada tahap pengasingan yang berbeza untuk DBMS yang berbeza

Martin Kleppmann dalam projeknya pertapaan Membandingkan tahap pengasingan yang berbeza, bercakap tentang anomali konkurensi dan sama ada pangkalan data dapat mematuhi tahap pengasingan tertentu. Penyelidikan Kleppmann menunjukkan cara berbeza pemaju pangkalan data berfikir tentang tahap pengasingan.

Penyekatan optimis datang untuk menyelamatkan apabila sukar untuk mengekalkan yang biasa.

Penyekatan boleh menjadi sangat mahal, bukan sahaja kerana ia meningkatkan persaingan dalam pangkalan data, tetapi juga kerana ia memerlukan pelayan aplikasi untuk sentiasa menyambung ke pangkalan data. Pembahagian rangkaian boleh memburukkan lagi situasi penguncian eksklusif dan membawa kepada kebuntuan yang sukar dikenal pasti dan diselesaikan. Dalam kes di mana penguncian eksklusif tidak sesuai, penguncian optimistik membantu.

Kunci optimistik ialah kaedah di mana apabila membaca rentetan, ia mengambil kira versi, jumlah semak atau masa pengubahsuaian terakhirnya. Ini membolehkan anda memastikan bahawa tiada perubahan versi atom sebelum menukar entri:

UPDATE products
SET name = 'Telegraph receiver', version = 2
WHERE id = 1 AND version = 1

Dalam kes ini, mengemas kini jadual products tidak akan dijalankan jika operasi lain sebelum ini membuat perubahan pada baris ini. Jika tiada operasi lain dilakukan pada baris ini, perubahan untuk satu baris akan berlaku dan kita boleh mengatakan bahawa kemas kini telah berjaya.

Terdapat anomali lain selain bacaan kotor dan kehilangan data

Apabila ia datang kepada konsistensi data, tumpuan adalah pada potensi keadaan perlumbaan yang boleh membawa kepada bacaan kotor dan kehilangan data. Walau bagaimanapun, anomali data tidak berhenti di situ.

Satu contoh anomali tersebut ialah herotan rakaman (tulis condong). Herotan sukar dikesan kerana ia biasanya tidak dicari secara aktif. Ia bukan disebabkan bacaan kotor atau kehilangan data, tetapi pelanggaran kekangan logik yang diletakkan pada data.

Sebagai contoh, mari kita pertimbangkan aplikasi pemantauan yang memerlukan satu pengendali berada dalam panggilan pada setiap masa:

BEGIN tx1;                      BEGIN tx2;
SELECT COUNT(*)
FROM operators
WHERE oncall = true;
0                               SELECT COUNT(*)
                                FROM operators
                                WHERE oncall = TRUE;
                                0
UPDATE operators                UPDATE operators
SET oncall = TRUE               SET oncall = TRUE
WHERE userId = 4;               WHERE userId = 2;
COMMIT tx1;                     COMMIT tx2;

Dalam situasi di atas, rekod rasuah akan berlaku sekiranya kedua-dua transaksi berjaya dilakukan. Walaupun tiada bacaan kotor atau kehilangan data, integriti data telah terjejas: kini dua orang dianggap atas panggilan pada masa yang sama.

Pengasingan bersiri, reka bentuk skema atau kekangan pangkalan data boleh membantu menghapuskan rasuah tulis. Pembangun mesti dapat mengenal pasti anomali tersebut semasa pembangunan untuk mengelakkannya dalam pengeluaran. Pada masa yang sama, herotan rakaman amat sukar dicari dalam pangkalan kod. Terutamanya dalam sistem besar, apabila pasukan pembangunan yang berbeza bertanggungjawab untuk melaksanakan fungsi berdasarkan jadual yang sama dan tidak bersetuju dengan spesifik capaian data.

Pangkalan data dan pengguna tidak selalu bersetuju tentang perkara yang perlu dilakukan

Salah satu ciri utama pangkalan data ialah jaminan perintah pelaksanaan, tetapi perintah ini sendiri mungkin tidak telus kepada pembangun perisian. Pangkalan data melaksanakan urus niaga mengikut susunan yang diterima, bukan mengikut urutan yang pengaturcara inginkan. Susunan urus niaga sukar untuk diramal, terutamanya dalam sistem selari yang sarat tinggi.

Semasa pembangunan, terutamanya apabila bekerja dengan perpustakaan yang tidak menyekat, gaya yang buruk dan kebolehbacaan yang rendah boleh menyebabkan pengguna percaya bahawa urus niaga dilaksanakan secara berurutan, sedangkan sebenarnya mereka boleh tiba dalam pangkalan data dalam sebarang susunan.

Pada pandangan pertama, dalam program di bawah, T1 dan T2 dipanggil secara berurutan, tetapi jika fungsi ini tidak menyekat dan segera mengembalikan hasilnya dalam bentuk janji, maka susunan panggilan akan ditentukan mengikut saat apabila mereka memasuki pangkalan data:

result1 = T1() // keputusan sebenar adalah janji
keputusan2 = T2()

Jika atomicity diperlukan (iaitu, sama ada semua operasi mesti diselesaikan atau digugurkan) dan urusan urutan, maka operasi T1 dan T2 mesti dilakukan dalam satu transaksi.

Sharding peringkat aplikasi boleh dialihkan ke luar aplikasi

Sharding ialah kaedah membahagikan pangkalan data secara mendatar. Sesetengah pangkalan data boleh memisahkan data secara mendatar secara automatik, manakala yang lain tidak boleh, atau tidak begitu mahir dalam hal itu. Apabila arkitek/pembangun data dapat meramalkan dengan tepat cara data akan diakses, mereka boleh mencipta sekatan mendatar dalam ruang pengguna dan bukannya mewakilkan kerja ini kepada pangkalan data. Proses ini dipanggil "perpecahan peringkat aplikasi" (perpecahan peringkat aplikasi).

Malangnya, nama ini sering menimbulkan salah tanggapan bahawa sharding hidup dalam perkhidmatan aplikasi. Malah, ia boleh dilaksanakan sebagai lapisan berasingan di hadapan pangkalan data. Bergantung pada pertumbuhan data dan lelaran skema, keperluan sharding boleh menjadi agak rumit. Sesetengah strategi mungkin mendapat manfaat daripada keupayaan untuk melelakan tanpa perlu menggunakan semula pelayan aplikasi.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data
Contoh seni bina di mana pelayan aplikasi diasingkan daripada perkhidmatan sharding

Memindahkan sharding ke dalam perkhidmatan berasingan mengembangkan keupayaan untuk menggunakan strategi sharding yang berbeza tanpa perlu menggunakan semula aplikasi. Vitess adalah contoh sistem sharding sedemikian pada peringkat aplikasi. Vitess menyediakan sharding mendatar untuk MySQL dan membolehkan pelanggan menyambung kepadanya melalui protokol MySQL. Sistem membahagikan data ke dalam nod MySQL yang berbeza yang tidak tahu apa-apa tentang satu sama lain.

Autoincrementing boleh berbahaya

AUTOINCREMENT ialah cara biasa untuk menjana kunci utama. Selalunya terdapat kes apabila pangkalan data digunakan sebagai penjana ID, dan pangkalan data mengandungi jadual yang direka untuk menjana pengecam. Terdapat beberapa sebab mengapa menjana kunci utama menggunakan penambahan automatik adalah jauh dari ideal:

  • Dalam pangkalan data yang diedarkan, peningkatan automatik adalah masalah yang serius. Untuk menjana ID, kunci global diperlukan. Sebaliknya, anda boleh menjana UUID: ini tidak memerlukan interaksi antara nod pangkalan data yang berbeza. Penambahan automatik dengan kunci boleh menyebabkan perbalahan dan mengurangkan prestasi pada sisipan dengan ketara dalam situasi yang diedarkan. Sesetengah DBMS (contohnya, MySQL) mungkin memerlukan konfigurasi khas dan perhatian yang lebih teliti untuk mengatur replikasi induk-induk dengan betul. Dan mudah untuk membuat kesilapan semasa mengkonfigurasi, yang akan membawa kepada kegagalan rakaman.
  • Sesetengah pangkalan data mempunyai algoritma pembahagian berdasarkan kunci utama. ID berturut-turut boleh membawa kepada titik panas yang tidak dapat diramalkan dan peningkatan beban pada sesetengah partition manakala yang lain kekal melahu.
  • Kunci utama ialah cara terpantas untuk mengakses baris dalam pangkalan data. Dengan cara yang lebih baik untuk mengenal pasti rekod, ID berjujukan boleh menukar lajur yang paling penting dalam jadual menjadi lajur tidak berguna yang diisi dengan nilai tidak bermakna. Oleh itu, apabila boleh, sila pilih kunci utama yang unik dan semula jadi di peringkat global (cth nama pengguna).

Sebelum membuat keputusan tentang pendekatan, pertimbangkan kesan ID dan UUID penambahan automatik pada pengindeksan, pembahagian dan pembahagian.

Data basi boleh berguna dan tidak memerlukan penguncian

Kawalan Penukaran Pelbagai Versi (MVCC) melaksanakan banyak keperluan konsistensi yang telah dibincangkan secara ringkas di atas. Sesetengah pangkalan data (contohnya, Postgres, Spanner) menggunakan MVCC untuk "menyuap" transaksi dengan syot kilat—versi pangkalan data yang lebih lama. Transaksi syot kilat juga boleh bersiri untuk memastikan konsistensi. Apabila membaca daripada syot kilat lama, data lapuk dibaca.

Membaca data yang sedikit basi boleh berguna, contohnya, apabila menjana analisis daripada data atau mengira anggaran nilai agregat.

Kelebihan pertama bekerja dengan data lama ialah kependaman rendah (terutamanya jika pangkalan data diedarkan merentasi geografi yang berbeza). Yang kedua ialah transaksi baca sahaja adalah bebas kunci. Ini adalah kelebihan yang ketara untuk aplikasi yang banyak membaca, selagi ia boleh mengendalikan data lapuk.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data
Pelayan aplikasi membaca data daripada replika tempatan yang ketinggalan 5 saat, walaupun versi terkini tersedia di seberang Lautan Pasifik

DBMS secara automatik membersihkan versi lama dan, dalam beberapa kes, membenarkan anda melakukan ini atas permintaan. Sebagai contoh, Postgres membenarkan pengguna melakukannya VACUUM atas permintaan, dan juga secara berkala melakukan operasi ini secara automatik. Spanner menjalankan pemungut sampah untuk menyingkirkan syot kilat yang lebih lama daripada satu jam.

Mana-mana sumber masa tertakluk kepada herotan

Rahsia terbaik dalam sains komputer ialah semua API pemasaan berbohong. Malah, mesin kami tidak mengetahui masa semasa yang tepat. Komputer mengandungi kristal kuarza yang menghasilkan getaran yang digunakan untuk mengekalkan masa. Walau bagaimanapun, mereka tidak cukup tepat dan mungkin mendahului/tertinggal dari masa yang tepat. Peralihan boleh mencapai 20 saat setiap hari. Oleh itu, masa pada komputer kita mesti disegerakkan secara berkala dengan rangkaian satu.

Pelayan NTP digunakan untuk penyegerakan, tetapi proses penyegerakan itu sendiri tertakluk kepada kelewatan rangkaian. Malah menyegerakkan dengan pelayan NTP di pusat data yang sama mengambil sedikit masa. Adalah jelas bahawa bekerja dengan pelayan NTP awam boleh membawa kepada herotan yang lebih besar.

Jam atom dan rakan sejawatan GPS mereka lebih baik untuk menentukan masa semasa, tetapi ia mahal dan memerlukan persediaan yang kompleks, jadi ia tidak boleh dipasang pada setiap kereta. Oleh sebab itu, pusat data menggunakan pendekatan berperingkat. Jam atom dan/atau GPS menunjukkan masa yang tepat, selepas itu ia disiarkan ke mesin lain melalui pelayan sekunder. Ini bermakna setiap mesin akan mengalami offset tertentu dari masa yang tepat.

Keadaan ini diburukkan lagi oleh fakta bahawa aplikasi dan pangkalan data sering terletak pada mesin yang berbeza (jika tidak di pusat data yang berbeza). Oleh itu, masa akan berbeza bukan sahaja pada nod DB yang diedarkan merentasi mesin yang berbeza. Ia juga akan berbeza pada pelayan aplikasi.

Google TrueTime mengambil pendekatan yang sama sekali berbeza. Kebanyakan orang percaya bahawa kemajuan Google ke arah ini dijelaskan oleh peralihan cetek kepada jam atom dan GPS, tetapi ini hanya sebahagian daripada gambaran besar. Begini cara TrueTime berfungsi:

  • TrueTime menggunakan dua sumber berbeza: GPS dan jam atom. Jam ini mempunyai mod kegagalan tidak berkorelasi. [lihat muka surat 5 untuk butiran di sini - lebih kurang terjemah.), jadi penggunaan bersama mereka meningkatkan kebolehpercayaan.
  • TrueTime mempunyai API yang luar biasa. Ia mengembalikan masa sebagai selang dengan ralat pengukuran dan ketidakpastian terbina di dalamnya. Detik masa sebenar adalah di antara sempadan atas dan bawah selang. Spanner, pangkalan data edaran Google, hanya menunggu sehingga selamat untuk mengatakan bahawa masa semasa berada di luar julat. Kaedah ini memperkenalkan beberapa kependaman ke dalam sistem, terutamanya jika ketidakpastian pada induk adalah tinggi, tetapi memastikan ketepatan walaupun dalam situasi yang diedarkan secara global.

Lebih ramai pembangun harus mengetahui perkara ini tentang pangkalan data
Komponen Spanner menggunakan TrueTime, di mana TT.now() mengembalikan selang, jadi Spanner hanya tidur sehingga titik di mana ia boleh yakin bahawa masa semasa telah melepasi titik tertentu

Mengurangkan ketepatan dalam menentukan masa semasa bermakna peningkatan dalam tempoh operasi Spanner dan penurunan dalam prestasi. Inilah sebabnya mengapa penting untuk mengekalkan ketepatan setinggi mungkin walaupun adalah mustahil untuk mendapatkan jam tangan yang tepat sepenuhnya.

Kelewatan mempunyai banyak makna

Jika anda bertanya kepada sedozen pakar tentang apa itu kelewatan, anda mungkin akan mendapat jawapan yang berbeza. Dalam kependaman DBMS sering dipanggil "pendaman pangkalan data" dan berbeza daripada apa yang dilihat oleh klien. Hakikatnya ialah pelanggan memerhatikan jumlah kelewatan rangkaian dan kelewatan pangkalan data. Keupayaan untuk mengasingkan jenis kependaman adalah penting apabila menyahpepijat masalah yang semakin meningkat. Apabila mengumpul dan memaparkan metrik, sentiasa cuba perhatikan kedua-dua jenis.

Keperluan prestasi hendaklah dinilai untuk transaksi tertentu

Kadangkala ciri prestasi DBMS dan hadnya ditentukan dari segi pemprosesan tulis/baca dan kependaman. Ini memberikan gambaran umum parameter sistem utama, tetapi apabila menilai prestasi DBMS baharu, pendekatan yang lebih komprehensif ialah menilai secara berasingan operasi kritikal (untuk setiap pertanyaan dan/atau transaksi). Contoh:

  • Tulis daya pemprosesan dan kependaman apabila memasukkan baris baharu ke dalam jadual X (dengan 50 juta baris) dengan kekangan dan pelapik baris tertentu dalam jadual berkaitan.
  • Kelewatan dalam memaparkan rakan rakan pengguna tertentu apabila purata bilangan rakan ialah 500.
  • Latensi dalam mendapatkan semula 100 entri teratas daripada sejarah pengguna apabila pengguna mengikuti 500 pengguna lain dengan entri X sejam.

Penilaian dan percubaan mungkin termasuk kes kritikal sedemikian sehingga anda yakin bahawa pangkalan data memenuhi keperluan prestasi. Peraturan praktikal yang serupa juga mengambil kira pecahan ini apabila mengumpul metrik kependaman dan menentukan SLO.

Berhati-hati dengan kardinaliti yang tinggi semasa mengumpul metrik untuk setiap operasi. Gunakan log, pengumpulan peristiwa atau pengesanan teragih untuk mendapatkan data penyahpepijatan berkuasa tinggi. Dalam artikel "Mahu Nyahpepijat Latensi?» anda boleh membiasakan diri dengan metodologi penyahpepijatan kelewatan.

Urus niaga bersarang boleh berbahaya

Bukan setiap DBMS menyokong transaksi bersarang, tetapi apabila mereka melakukannya, urus niaga tersebut boleh mengakibatkan ralat yang tidak dijangka yang tidak selalunya mudah untuk dikesan (iaitu, ia sepatutnya jelas bahawa terdapat beberapa jenis anomali).

Anda boleh mengelak daripada menggunakan transaksi bersarang menggunakan perpustakaan pelanggan yang boleh mengesan dan memintasnya. Jika transaksi bersarang tidak boleh ditinggalkan, berhati-hati dalam pelaksanaannya untuk mengelakkan situasi yang tidak dijangka di mana transaksi yang telah selesai dibatalkan secara tidak sengaja disebabkan oleh transaksi bersarang.

Merangkum transaksi dalam lapisan yang berbeza boleh membawa kepada transaksi bersarang yang tidak dijangka, dan dari sudut kebolehbacaan kod, ia boleh menyukarkan untuk memahami niat pengarang. Lihatlah program berikut:

with newTransaction():
   Accounts.create("609-543-222")
   with newTransaction():
       Accounts.create("775-988-322")
       throw Rollback();

Apakah output kod di atas? Adakah ia akan melancarkan kedua-dua urus niaga, atau hanya transaksi dalaman? Apakah yang berlaku jika kita bergantung pada berbilang lapisan perpustakaan yang merangkumi penciptaan transaksi untuk kita? Adakah kita dapat mengenal pasti dan menambah baik kes sebegini?

Bayangkan lapisan data dengan berbilang operasi (cth. newAccount) telah pun dilaksanakan dalam urus niaganya sendiri. Apa yang berlaku jika anda menjalankannya sebagai sebahagian daripada logik perniagaan peringkat lebih tinggi yang berjalan dalam urus niaganya sendiri? Apakah pengasingan dan konsistensi dalam kes ini?

function newAccount(id string) {
  with newTransaction():
      Accounts.create(id)
}

Daripada mencari jawapan kepada soalan yang tidak berkesudahan itu, adalah lebih baik untuk mengelakkan transaksi bersarang. Lagipun, lapisan data anda boleh melakukan operasi peringkat tinggi dengan mudah tanpa membuat transaksi sendiri. Di samping itu, logik perniagaan itu sendiri mampu memulakan transaksi, melaksanakan operasi ke atasnya, melakukan atau membatalkan transaksi.

function newAccount(id string) {
   Accounts.create(id)
}
// In main application:
with newTransaction():
   // Read some data from database for configuration.
   // Generate an ID from the ID service.
   Accounts.create(id)
   Uploads.create(id) // create upload queue for the user.

Urus niaga tidak boleh terikat dengan keadaan permohonan

Kadangkala tergoda untuk menggunakan keadaan aplikasi dalam urus niaga untuk menukar nilai tertentu atau tweak parameter pertanyaan. Nuansa kritikal yang perlu dipertimbangkan ialah skop aplikasi yang betul. Pelanggan sering memulakan semula transaksi apabila terdapat masalah rangkaian. Jika transaksi kemudiannya bergantung pada keadaan yang sedang diubah oleh beberapa proses lain, ia mungkin memilih nilai yang salah bergantung pada kemungkinan perlumbaan data. Transaksi mesti mempertimbangkan risiko keadaan perlumbaan data dalam aplikasi.

var seq int64
with newTransaction():
    newSeq := atomic.Increment(&seq)
    Entries.query(newSeq)
    // Other operations...

Urus niaga di atas akan menambah nombor jujukan setiap kali ia dilaksanakan, tanpa mengira keputusan akhir. Jika komit gagal disebabkan masalah rangkaian, permintaan akan dilaksanakan dengan nombor urutan yang berbeza apabila anda mencuba lagi.

Perancang pertanyaan boleh memberitahu anda banyak tentang pangkalan data

Perancang pertanyaan menentukan cara pertanyaan akan dilaksanakan dalam pangkalan data. Mereka juga menganalisis permintaan dan mengoptimumkannya sebelum menghantarnya. Perancang hanya boleh memberikan beberapa anggaran yang mungkin berdasarkan isyarat yang mereka gunakan. Sebagai contoh, apakah kaedah carian terbaik untuk pertanyaan berikut?

SELECT * FROM articles where author = "rakyll" order by title;

Hasilnya boleh diambil dalam dua cara:

  • Imbasan meja penuh: Anda boleh melihat setiap entri dalam jadual dan mengembalikan artikel dengan nama pengarang yang sepadan, dan kemudian memesannya.
  • Imbasan indeks: Anda boleh menggunakan indeks untuk mencari ID yang sepadan, mendapatkan baris tersebut dan kemudian memesannya.

Tugas perancang pertanyaan adalah untuk menentukan strategi yang terbaik. Perlu dipertimbangkan bahawa perancang pertanyaan hanya mempunyai keupayaan ramalan yang terhad. Ini boleh membawa kepada keputusan yang tidak baik. DBA atau pembangun boleh menggunakannya untuk mendiagnosis dan memperhalusi pertanyaan yang kurang berprestasi. Versi baharu DBMS boleh mengkonfigurasi perancang pertanyaan, dan diagnosis kendiri boleh membantu semasa mengemas kini pangkalan data jika versi baharu membawa kepada masalah prestasi. Log pertanyaan yang perlahan, laporan isu kependaman atau statistik masa pelaksanaan boleh membantu mengenal pasti pertanyaan yang memerlukan pengoptimuman.

Sesetengah metrik yang dibentangkan oleh perancang pertanyaan mungkin tertakluk kepada hingar (terutamanya apabila menganggarkan kependaman atau masa CPU). Tambahan yang baik kepada penjadual ialah alat untuk mengesan dan menjejak laluan pelaksanaan. Mereka membenarkan anda mendiagnosis masalah sedemikian (malangnya, tidak semua DBMS menyediakan alat sedemikian).

Penghijrahan dalam talian adalah sukar tetapi mungkin

Migrasi dalam talian, migrasi langsung atau migrasi masa nyata bermakna berpindah dari satu pangkalan data ke pangkalan data yang lain tanpa masa henti atau rasuah data. Penghijrahan langsung lebih mudah dilakukan jika peralihan berlaku dalam DBMS/enjin yang sama. Keadaan menjadi lebih rumit apabila perlu untuk berpindah ke DBMS baharu dengan keperluan prestasi dan skema yang berbeza.

Terdapat model migrasi dalam talian yang berbeza. Berikut adalah salah satu daripadanya:

  • Dayakan kemasukan berganda dalam kedua-dua pangkalan data. Pangkalan data baharu pada peringkat ini tidak mempunyai semua data, tetapi hanya menerima data terkini. Setelah anda yakin dengan ini, anda boleh meneruskan ke langkah seterusnya.
  • Dayakan bacaan daripada kedua-dua pangkalan data.
  • Konfigurasikan sistem supaya membaca dan menulis dilakukan terutamanya pada pangkalan data baharu.
  • Berhenti menulis ke pangkalan data lama sambil terus membaca data daripadanya. Pada peringkat ini, pangkalan data baharu masih tidak mempunyai beberapa data. Mereka harus disalin dari pangkalan data lama.
  • Pangkalan data lama adalah baca sahaja. Salin data yang hilang dari pangkalan data lama ke pangkalan data baharu. Selepas penghijrahan selesai, tukar laluan ke pangkalan data baharu dan hentikan laluan lama dan padamkannya daripada sistem.

Untuk maklumat tambahan, saya cadangkan untuk menghubungi artikel, yang memperincikan strategi migrasi Stripe berdasarkan model ini.

Peningkatan ketara dalam pangkalan data memerlukan peningkatan dalam ketidakpastian

Pertumbuhan pangkalan data membawa kepada masalah yang tidak dapat diramalkan yang berkaitan dengan skalanya. Lebih banyak kita tahu tentang struktur dalaman pangkalan data, lebih baik kita boleh meramalkan bagaimana ia akan berskala. Walau bagaimanapun, beberapa saat masih mustahil untuk diramalkan.
Apabila pangkalan berkembang, andaian dan jangkaan sebelumnya mengenai volum data dan keperluan jalur lebar rangkaian mungkin menjadi lapuk. Pada masa inilah timbul persoalan tentang baik pulih reka bentuk utama, penambahbaikan operasi berskala besar, penempatan semula pemikiran atau pemindahan ke DBMS lain untuk mengelakkan masalah yang mungkin berlaku.

Tetapi jangan fikir bahawa pengetahuan yang sangat baik tentang struktur dalaman pangkalan data sedia ada adalah satu-satunya perkara yang diperlukan. Skala baru akan membawa bersama mereka yang tidak diketahui baru. Titik kesakitan yang tidak dapat diramalkan, pengedaran data yang tidak sekata, lebar jalur dan isu perkakasan yang tidak dijangka, trafik yang sentiasa meningkat dan segmen rangkaian baharu akan memaksa anda untuk memikirkan semula pendekatan pangkalan data, model data, model penggunaan dan saiz pangkalan data anda.

...

Pada masa saya mula berfikir untuk menerbitkan artikel ini, sudah ada lima lagi item dalam senarai asal saya. Kemudian datang sejumlah besar idea baru tentang apa lagi yang boleh dilindungi. Oleh itu, artikel itu menyentuh masalah yang paling tidak jelas yang memerlukan perhatian maksimum. Walau bagaimanapun, ini tidak bermakna bahawa topik itu telah kehabisan dan saya tidak akan kembali kepadanya dalam bahan masa hadapan saya dan tidak akan membuat perubahan kepada topik semasa.

PS

Baca juga di blog kami:

Sumber: www.habr.com

Beli pengehosan yang boleh dipercayai untuk tapak dengan perlindungan DDoS, pelayan VPS VDS 🔥 Beli pengehosan laman web yang boleh dipercayai dengan perlindungan DDoS, pelayan VPS VDS | ProHoster