Cassandra. Bagaimana untuk tidak mati jika anda hanya tahu Oracle

Hai Habr.

Nama saya Misha Butrimov, saya ingin memberitahu anda sedikit tentang Cassandra. Kisah saya akan berguna kepada mereka yang tidak pernah menemui pangkalan data NoSQL - ia mempunyai banyak ciri pelaksanaan dan perangkap yang perlu anda ketahui. Dan jika anda tidak melihat apa-apa selain Oracle atau mana-mana pangkalan data hubungan lain, perkara ini akan menyelamatkan nyawa anda.

Apa yang bagus tentang Cassandra? Ia adalah pangkalan data NoSQL yang direka tanpa satu titik kegagalan yang berskala dengan baik. Jika anda perlu menambah beberapa terabait untuk beberapa pangkalan data, anda hanya menambah nod pada cincin. Kembangkannya ke pusat data lain? Tambahkan nod pada kelompok. Tingkatkan RPS yang diproses? Tambahkan nod pada kelompok. Ia berfungsi dalam arah yang bertentangan juga.

Cassandra. Bagaimana untuk tidak mati jika anda hanya tahu Oracle

Apa lagi yang dia pandai? Ia mengenai mengendalikan banyak permintaan. Tetapi berapa banyak? 10, 20, 30, 40 ribu permintaan sesaat tidak banyak. 100 ribu permintaan sesaat untuk rakaman - juga. Terdapat syarikat yang mengatakan bahawa mereka menyimpan 2 juta permintaan sesaat. Mereka mungkin perlu mempercayainya.

Dan pada dasarnya, Cassandra mempunyai satu perbezaan besar daripada data hubungan - ia tidak serupa dengan mereka sama sekali. Dan ini sangat penting untuk diingati.

Tidak semua yang kelihatan sama berfungsi sama

Pernah seorang rakan sekerja datang kepada saya dan bertanya: “Ini adalah bahasa pertanyaan CQL Cassandra, dan ia mempunyai pernyataan pilihan, ia mempunyai di mana, ia mempunyai dan. Saya menulis surat dan ia tidak berfungsi. Kenapa?". Melayan Cassandra seperti pangkalan data hubungan ialah cara terbaik untuk membunuh diri secara ganas. Dan saya tidak mempromosikannya, ia dilarang di Rusia. Anda hanya akan mereka bentuk sesuatu yang salah.

Sebagai contoh, seorang pelanggan datang kepada kami dan berkata: “Mari kita bina pangkalan data untuk siri TV, atau pangkalan data untuk direktori resipi. Kami akan mempunyai hidangan makanan di sana atau senarai siri TV dan pelakon di dalamnya.” Kami berkata dengan gembira: "Mari pergi!" Hanya hantar dua bait, beberapa tanda dan anda selesai, semuanya akan berfungsi dengan cepat dan boleh dipercayai. Dan semuanya baik-baik saja sehingga pelanggan datang dan mengatakan bahawa suri rumah juga menyelesaikan masalah yang bertentangan: mereka mempunyai senarai produk, dan mereka ingin tahu hidangan apa yang mereka ingin masak. awak dah mati.

Ini kerana Cassandra ialah pangkalan data hibrid: ia secara serentak menyediakan nilai utama dan menyimpan data dalam lajur lebar. Dalam Java atau Kotlin, ia boleh digambarkan seperti ini:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Iaitu, peta yang juga mengandungi peta yang disusun. Kekunci pertama pada peta ini ialah kekunci Baris atau kekunci Partition - kekunci pembahagian. Kunci kedua, yang merupakan kunci kepada peta yang telah diisih, ialah kunci Pengelompokan.

Untuk menggambarkan pengedaran pangkalan data, mari kita lukis tiga nod. Sekarang anda perlu memahami cara menguraikan data menjadi nod. Kerana jika kita menjejalkan semuanya menjadi satu (by the way, boleh ada seribu, dua ribu, lima - seberapa banyak yang anda suka), ini bukan tentang pengedaran. Oleh itu, kita memerlukan fungsi matematik yang akan mengembalikan nombor. Hanya nombor, int panjang yang akan jatuh ke dalam beberapa julat. Dan kita akan mempunyai satu nod yang bertanggungjawab untuk satu julat, yang kedua untuk yang kedua, yang ke-n untuk yang ke.

Cassandra. Bagaimana untuk tidak mati jika anda hanya tahu Oracle

Nombor ini diambil menggunakan fungsi cincang, yang digunakan pada apa yang kami panggil kekunci Partition. Ini ialah lajur yang dinyatakan dalam arahan kunci utama dan ini ialah lajur yang akan menjadi kunci pertama dan paling asas bagi peta. Ia menentukan nod mana yang akan menerima data mana. Jadual dibuat dalam Cassandra dengan sintaks yang hampir sama seperti dalam SQL:

CREATE TABLE users (
	user_id uu id,
	name text,
	year int,
	salary float,
	PRIMARY KEY(user_id)

)

Kunci Utama dalam kes ini terdiri daripada satu lajur, dan ia juga merupakan kunci pembahagian.

Bagaimanakah prestasi pengguna kami? Sesetengah akan pergi ke satu nod, beberapa ke yang lain, dan beberapa ke yang ketiga. Hasilnya ialah jadual cincang biasa, juga dikenali sebagai peta, juga dikenali sebagai kamus dalam Python, atau struktur nilai Kunci mudah yang daripadanya kita boleh membaca semua nilai, membaca dan menulis dengan kunci.

Cassandra. Bagaimana untuk tidak mati jika anda hanya tahu Oracle

Pilih: apabila membenarkan penapisan bertukar menjadi imbasan penuh, atau perkara yang tidak boleh dilakukan

Mari tulis beberapa pernyataan pilihan: select * from users where, userid = . Ternyata seperti dalam Oracle: kami menulis pilih, nyatakan syarat dan semuanya berfungsi, pengguna mendapatnya. Tetapi jika anda memilih, sebagai contoh, pengguna dengan tahun lahir tertentu, Cassandra mengadu bahawa ia tidak dapat memenuhi permintaan itu. Kerana dia tidak tahu apa-apa tentang cara kami mengedarkan data tentang tahun kelahiran - dia hanya mempunyai satu lajur yang ditunjukkan sebagai kunci. Kemudian dia berkata, “Baiklah, saya masih boleh memenuhi permintaan ini. Tambahkan benarkan penapisan." Kami menambah arahan, semuanya berfungsi. Dan pada masa ini sesuatu yang mengerikan berlaku.

Apabila kami menjalankan data ujian, semuanya baik-baik saja. Dan apabila anda melaksanakan pertanyaan dalam pengeluaran, di mana kami mempunyai, sebagai contoh, 4 juta rekod, maka semuanya tidak begitu baik untuk kami. Kerana benarkan penapisan ialah arahan yang membolehkan Cassandra mengumpul semua data daripada jadual ini daripada semua nod, semua pusat data (jika terdapat banyak daripada mereka dalam kelompok ini), dan hanya kemudian menapisnya. Ini adalah analog Imbasan Penuh, dan hampir tidak ada orang yang gembira dengannya.

Jika kami hanya memerlukan pengguna melalui ID, kami boleh melakukannya. Tetapi kadangkala kita perlu menulis pertanyaan lain dan mengenakan sekatan lain pada pemilihan. Oleh itu, kami ingat: ini semua adalah peta yang mempunyai kunci pembahagian, tetapi di dalamnya terdapat peta yang diisih.

Dan dia juga mempunyai kunci, yang kami panggil Kunci Pengelompokan. Kunci ini, yang seterusnya, terdiri daripada lajur yang kami pilih, dengan bantuan Cassandra memahami cara datanya diisih secara fizikal dan akan ditempatkan pada setiap nod. Iaitu, untuk beberapa kekunci Partition, kekunci Pengelompokan akan memberitahu anda dengan tepat cara untuk menolak data ke dalam pepohon ini, tempat ia akan dibawa ke sana.

Ini benar-benar pokok, pembanding hanya dipanggil di sana, yang mana kita lulus set lajur tertentu dalam bentuk objek, dan ia juga dinyatakan sebagai senarai lajur.

CREATE TABLE users_by_year_salary_id (
	user_id uuid,
	name text,
	year int,
	salary float,
	PRIMARY KEY((year), salary, user_id)

Beri perhatian kepada arahan kunci Utama; hujah pertamanya (dalam kes kami, tahun) sentiasa kunci Pembahagian. Ia boleh terdiri daripada satu atau lebih lajur, tidak mengapa. Jika terdapat beberapa lajur, ia perlu dialih keluar dalam kurungan sekali lagi supaya prapemproses bahasa memahami bahawa ini ialah kunci Utama, dan di belakangnya semua lajur lain ialah kunci Pengelompokan. Dalam kes ini, ia akan dihantar dalam komparator dalam susunan ia muncul. Iaitu, lajur pertama lebih signifikan, kedua kurang signifikan, dan seterusnya. Cara kami menulis, sebagai contoh, sama dengan medan untuk kelas data: kami menyenaraikan medan, dan untuknya kami menulis yang mana lebih besar dan mana yang lebih kecil. Dalam Cassandra, ini, secara relatifnya, medan kelas data, yang mana nilai yang sama ditulis untuknya akan digunakan.

Kami menetapkan pengisihan dan mengenakan sekatan

Anda perlu ingat bahawa susunan isihan (menurun, menaik, apa sahaja) ditetapkan pada masa yang sama apabila kunci dicipta, dan ia tidak boleh diubah kemudian. Ia secara fizikal menentukan cara data akan diisih dan cara ia akan disimpan. Jika anda perlu menukar kunci Pengelompokan atau menyusun susunan, anda perlu membuat jadual baharu dan memindahkan data ke dalamnya. Ini tidak akan berfungsi dengan yang sedia ada.

Cassandra. Bagaimana untuk tidak mati jika anda hanya tahu Oracle

Kami memenuhi jadual kami dengan pengguna dan melihat bahawa mereka jatuh ke dalam cincin, pertama mengikut tahun lahir, dan kemudian di dalam pada setiap nod mengikut gaji dan ID pengguna. Sekarang kita boleh memilih dengan mengenakan sekatan.

Kerja kami muncul lagi where, and, dan kami mendapat pengguna, dan semuanya baik-baik saja. Tetapi jika kami cuba menggunakan hanya sebahagian daripada kunci Pengelompokan, dan yang kurang penting, maka Cassandra akan segera mengadu bahawa ia tidak dapat mencari tempat dalam peta kami di mana objek ini, yang mempunyai medan ini untuk pembanding nol, dan yang ini. yang baru ditetapkan , - tempat dia berbaring. Saya perlu menarik semua data dari nod ini sekali lagi dan menapisnya. Dan ini adalah analog Imbasan Penuh dalam nod, ini buruk.

Dalam sebarang situasi yang tidak jelas, buat jadual baharu

Jika kita mahu dapat menyasarkan pengguna mengikut ID, atau mengikut umur, atau mengikut gaji, apakah yang perlu kita lakukan? tiada apa. Hanya gunakan dua meja. Jika anda perlu menjangkau pengguna dalam tiga cara berbeza, akan ada tiga jadual. Sudah berlalu apabila kami menjimatkan ruang pada skru. Ini adalah sumber yang paling murah. Kosnya jauh lebih rendah daripada masa tindak balas, yang boleh memudaratkan pengguna. Ia adalah lebih menyenangkan bagi pengguna untuk menerima sesuatu dalam satu saat berbanding dalam 10 minit.

Kami memperdagangkan ruang yang tidak diperlukan dan data yang tidak normal untuk keupayaan untuk membuat skala dengan baik dan beroperasi dengan pasti. Lagipun, sebenarnya, kluster yang terdiri daripada tiga pusat data, setiap satunya mempunyai lima nod, dengan tahap pemeliharaan data yang boleh diterima (apabila tiada apa-apa yang hilang), mampu bertahan dari kematian satu pusat data sepenuhnya. Dan dua lagi nod dalam setiap dua yang tinggal. Dan hanya selepas ini masalah bermula. Ini adalah redundansi yang cukup baik, ia bernilai beberapa pemacu dan pemproses SSD tambahan. Oleh itu, untuk menggunakan Cassandra, yang tidak pernah SQL, di mana tidak ada hubungan, kunci asing, anda perlu mengetahui peraturan mudah.

Kami reka semua mengikut permintaan anda. Perkara utama bukanlah data, tetapi bagaimana aplikasi akan berfungsi dengannya. Jika ia perlu menerima data yang berbeza dengan cara yang berbeza atau data yang sama dengan cara yang berbeza, kita mesti meletakkannya dalam cara yang sesuai untuk aplikasi. Jika tidak, kami akan gagal dalam Imbasan Penuh dan Cassandra tidak akan memberi kelebihan kepada kami.

Menyahnormalkan data adalah perkara biasa. Kami lupa tentang bentuk biasa, kami tidak lagi mempunyai pangkalan data hubungan. Jika kita meletakkan sesuatu 100 kali, ia akan meniarap 100 kali. Ia masih lebih murah daripada berhenti.

Kami memilih kekunci untuk pembahagian supaya ia diedarkan secara normal. Kami tidak mahu cincangan kunci kami jatuh ke dalam satu julat yang sempit. Maksudnya, tahun kelahiran dalam contoh di atas adalah contoh yang tidak baik. Lebih tepat lagi, adalah baik jika pengguna kami diagihkan secara normal mengikut tahun kelahiran, dan buruk jika kita bercakap tentang pelajar gred 5 - pembahagian di sana tidak akan menjadi sangat baik.

Isih dipilih sekali pada peringkat penciptaan Kunci Pengelompokan. Jika ia perlu diubah, kami perlu mengemas kini jadual kami dengan kunci yang berbeza.

Dan perkara yang paling penting: jika kita perlu mendapatkan semula data yang sama dalam 100 cara yang berbeza, maka kita akan mempunyai 100 jadual yang berbeza.

Sumber: www.habr.com

Tambah komen