Pendekatan sharding MySQL?

88

Apa pendekatan terbaik untuk tabel Sharding MySQL. Pendekatan yang dapat saya pikirkan adalah:

  1. Sharding Level Aplikasi?
  2. Sharding di lapisan proxy MySQL?
  3. Server pencarian pusat untuk sharding?

Apakah Anda mengetahui proyek atau alat menarik di bidang ini?

sheki
sumber

Jawaban:

116

Pendekatan terbaik untuk memecah tabel MySQL adalah tidak melakukannya kecuali benar-benar tidak dapat dihindari untuk melakukannya.

Saat Anda menulis aplikasi, Anda biasanya ingin melakukannya dengan cara yang memaksimalkan kecepatan, kecepatan pengembang. Anda mengoptimalkan latensi (waktu hingga jawaban siap) atau throughput (jumlah jawaban per unit waktu) hanya jika diperlukan.

Anda mempartisi dan kemudian menetapkan partisi ke host yang berbeda (= shard) hanya jika jumlah dari semua partisi ini tidak lagi sesuai dengan satu instance server database - alasannya adalah untuk menulis atau membaca.

Kasus penulisan adalah a) frekuensi penulisan membebani disk server ini secara permanen atau b) ada terlalu banyak penulisan yang terjadi sehingga replikasi secara permanen tertinggal dalam hierarki replikasi ini.

Kasus pembacaan untuk sharding adalah saat ukuran datanya begitu besar sehingga kumpulan yang berfungsi tidak lagi cocok dengan memori dan pembacaan data mulai mengenai disk alih-alih disajikan dari memori sebagian besar waktu.

Hanya ketika Anda harus memecah Anda melakukannya.


Saat Anda memecah, Anda membayarnya dengan berbagai cara:

Sebagian besar SQL Anda tidak lagi bersifat deklaratif.

Biasanya, dalam SQL Anda memberi tahu database data apa yang Anda inginkan dan menyerahkannya kepada pengoptimal untuk mengubah spesifikasi itu menjadi program akses data. Itu bagus, karena fleksibel, dan karena menulis program akses data ini adalah pekerjaan membosankan yang merusak kecepatan.

Dengan lingkungan sharded Anda mungkin menggabungkan tabel pada node A terhadap data pada node B, atau Anda memiliki tabel yang lebih besar dari node, pada node A dan B dan menggabungkan data darinya terhadap data yang ada di node B dan C. Anda mulai menulis resolusi gabungan berbasis hash sisi aplikasi secara manual untuk menyelesaikannya (atau Anda menciptakan kembali kluster MySQL), yang berarti Anda berakhir dengan banyak SQL yang tidak lagi deklaratif, tetapi mengekspresikan fungsionalitas SQL secara prosedural (misalnya Anda menggunakan pernyataan SELECT dalam loop).

Anda mengalami banyak latensi jaringan.

Biasanya, kueri SQL dapat diselesaikan secara lokal dan pengoptimal mengetahui tentang biaya yang terkait dengan akses disk lokal dan menyelesaikan kueri dengan cara yang meminimalkan biaya untuk itu.

Dalam lingkungan yang dipecah, kueri diselesaikan dengan menjalankan akses nilai kunci di seluruh jaringan ke beberapa node (mudah-mudahan dengan akses kunci bertumpuk dan bukan pencarian kunci individu per perjalanan) atau dengan mendorong bagian WHEREklausa ke node di mana mereka bisa. diterapkan (yang disebut 'kondisi pushdown'), atau keduanya.

Tetapi bahkan dalam kasus terbaik ini melibatkan lebih banyak perjalanan pulang pergi jaringan daripada situasi lokal, dan ini lebih rumit. Terutama karena pengoptimal MySQL sama sekali tidak tahu tentang latensi jaringan (Ok, cluster MySQL perlahan menjadi lebih baik dalam hal itu, tetapi untuk vanilla MySQL di luar cluster itu masih berlaku).

Anda kehilangan banyak kekuatan ekspresif dari SQL.

Oke, itu mungkin kurang penting, tetapi batasan kunci asing dan mekanisme SQL lainnya untuk integritas data tidak dapat mencakup beberapa pecahan.

MySQL tidak memiliki API yang memungkinkan kueri asinkron yang berfungsi dengan baik.

Ketika data dengan tipe yang sama berada di beberapa node (misalnya data pengguna pada node A, B dan C), pertanyaan horizontal sering kali perlu diselesaikan terhadap semua node ini ("Temukan semua akun pengguna yang belum masuk selama 90 hari atau lebih"). Waktu akses data tumbuh secara linier dengan jumlah node, kecuali beberapa node dapat diminta secara paralel dan hasilnya dikumpulkan saat mereka masuk ("Map-Reduce").

Prasyarat untuk itu adalah API komunikasi asinkron, yang tidak ada untuk MySQL dalam bentuk kerja yang baik. Alternatifnya adalah banyak percabangan dan koneksi dalam proses anak, yang mengunjungi dunia mengisap tiket masuk musim.


Setelah Anda memulai sharding, struktur data dan topologi jaringan menjadi terlihat sebagai poin kinerja untuk aplikasi Anda. Untuk berkinerja cukup baik, aplikasi Anda perlu menyadari hal-hal ini, dan itu berarti hanya sharding level aplikasi yang masuk akal.

Pertanyaannya lebih lanjut jika Anda ingin melakukan pecahan otomatis (menentukan baris mana yang masuk ke node mana dengan mencirikan kunci utama misalnya) atau jika Anda ingin memisahkan secara fungsional dengan cara manual ("Tabel yang terkait dengan cerita pengguna xyz masuk ke sini master, sedangkan tabel terkait abc dan def pergi ke master itu ").

Sharding fungsional memiliki keuntungan yang, jika dilakukan dengan benar, tidak akan terlihat oleh sebagian besar pengembang di sebagian besar waktu, karena semua tabel yang terkait dengan kisah pengguna mereka akan tersedia secara lokal. Hal ini memungkinkan mereka untuk tetap mendapatkan keuntungan dari SQL deklaratif selama mungkin, dan juga akan menimbulkan latensi jaringan yang lebih sedikit karena jumlah transfer lintas jaringan dijaga agar tetap minimal.

Sharding fungsional memiliki kelemahan yaitu tidak memungkinkan tabel tunggal lebih besar dari satu instans, dan memerlukan perhatian manual dari seorang desainer.

Keunggulan sharding fungsional adalah relatif mudah dilakukan pada basis kode yang sudah ada dengan jumlah perubahan yang tidak terlalu besar. http://Booking.com telah melakukannya beberapa kali dalam beberapa tahun terakhir dan berhasil dengan baik untuk mereka.


Setelah mengatakan semua itu, melihat pertanyaan Anda, saya yakin Anda mengajukan pertanyaan yang salah, atau saya benar-benar salah memahami pernyataan masalah Anda.

Isotopp
sumber
2
Ini jawaban yang bagus. Namun saya ingin menunjukkan bahwa sharding benar-benar hanya diperlukan untuk aplikasi volume tinggi dan kemungkinan besar menghasilkan semacam pendapatan. Aplikasi sharding pihak ketiga akan menangani semua masalah yang Anda hadapi terkait penggabungan, transaksi lintas-pecahan, dll. Dan jika Anda mendapatkan yang bagus, itu akan menjaga integritas database "relasional". Aplikasi lain, Anda benar, akan dengan mudah mengubah database Anda menjadi pasangan nilai-kunci dan dengan demikian mengalahkan tujuan SQL.
pelayan
3
Saya belum menemukan aplikasi sharding, komersial atau tidak, yang berhasil menyembunyikan fakta bahwa data sekarang tersebar di seluruh jaringan dan mengalami latensi atau inkonsistensi karena kurangnya waktu tunggu yang disebabkan oleh latensi. Jika Anda melakukan sharding, aplikasi Anda akan melihat dan membutuhkan perubahan. Anda mungkin juga mengendalikannya sendiri. Tidak ada peluru perak, tapi ada banyak minyak ular.
Isotopp
1
Anda harus memeriksa dbShards. Skala ini lebih baik daripada secara linier per # "pecahan" yang Anda tambahkan. Anda hanya memerlukan sedikit, jika ada, perubahan pada sisi aplikasi, dan ya aplikasi Anda tidak tahu perbedaannya. Itu hanya mengirim dan mendapatkan transaksi yang sama seperti yang Anda lakukan dengan ODBC atau JDBC. dbShards juga memungkinkan petunjuk shard jika Anda ingin kontrol lebih atas transaksi. Anda dapat memberi tahu dbShards dengan tepat pecahan apa yang ingin Anda baca atau tulis.
Chantheman
1
@Gigala yah, menghabiskan waktu untuk menyusun jawaban yang terdefinisi dengan baik seperti ini, terlepas dari luasnya, juga tidak perlu, tetapi saya senang itu dilakukan, karena jawaban ini terbukti membantu saya. Harap jangan mengecilkan hati pengguna untuk tidak "berpikir di luar kebiasaan" saat menjawab.
mewm
12
  1. Aplikasi Level sharding: dbShards adalah satu-satunya produk yang saya tahu yang melakukan "application aware sharding". Ada beberapa artikel bagus di situs web. Secara definisi, sharding yang sadar aplikasi akan lebih efisien. Jika aplikasi tahu persis ke mana harus pergi dengan transaksi tanpa harus mencarinya atau dialihkan oleh proxy, itu sendiri akan lebih cepat. Dan kecepatan sering kali menjadi salah satu perhatian utama, jika bukan satu-satunya perhatian, ketika seseorang mencari sharding.

  2. Beberapa orang "memecah" dengan proxy, tetapi di mata saya itu mengalahkan tujuan dari pecahan. Anda hanya menggunakan server lain untuk memberi tahu transaksi Anda di mana menemukan data atau di mana menyimpannya. Dengan sharding yang sadar aplikasi, aplikasi Anda tahu ke mana harus pergi sendiri. Jauh lebih hemat.

  3. Ini sama dengan # 2 sebenarnya.

chantheman
sumber
apakah dbShards digunakan dalam produksi di suatu tempat? juga bukan open source.
sheki
Juga pendekatan 2 dan 3 dapat berbeda jika proxy mencari berdasarkan hash, bukan DB atau penyimpanan.
sheki
1
dbShards diproduksi dengan berbagai klien, tetapi tidak, ini bukan open source. Saya tidak berpikir Anda akan menemukan produk sharding open source yang bagus. Dan ya, Anda benar bahwa hash dapat digunakan sebagai pencarian, tetapi dalam hal ini Anda masih harus mengambil satu "stop" lagi untuk memasukkan transaksi Anda ke database. Itulah mengapa sharding "aplikasi sadar" akan hampir selalu lebih cepat.
Chantheman
Tapi seperti yang saya katakan, jika Anda bisa mendapatkan aplikasi sharding yang menjaga integritas hubungan, Anda akan berada dalam kondisi yang baik. Saya menyebut dbShards karena hanya itu yang saya tahu yang melakukannya. Dan karena itu terjadi, itu menskalakan kecepatan tulis dan baca Anda secara linier. Anda menambahkan 4 "shard" atau Anda membagi satu server MySQL Anda menjadi 4 dan itu akan berjalan 4 kali lebih cepat.
pelayan
7

Apakah Anda mengetahui proyek atau alat menarik di bidang ini?

Beberapa proyek baru di ruang ini:

  • citusdata.com
  • spockproxy.sourceforge.net
  • github.com/twitter/gizzard/
btcbb
sumber
5

Shard-Query adalah solusi sharding berbasis OLAP untuk MySQL. Ini memungkinkan Anda untuk menentukan kombinasi tabel dengan sharded dan tabel tanpa shard. Tabel yang tidak dipisahkan (seperti tabel pencarian) dapat digabungkan secara bebas ke tabel yang dipisahkan, dan tabel yang dipisahkan dapat digabungkan satu sama lain selama tabel tersebut digabungkan dengan kunci beling (tidak ada pecahan silang atau penggabungan mandiri yang melintasi batas pecahan). Sebagai solusi OLAP, Shard-Query biasanya memiliki waktu respons minimum 100 md atau kurang, bahkan untuk kueri sederhana sehingga tidak akan berfungsi untuk OLTP. Shard-Query dirancang untuk menganalisis kumpulan data besar secara paralel.

Solusi sharding OLTP juga tersedia untuk MySQL. Solusi sumber tertutup termasuk ScaleDB , DBShards . Solusi OLTP open source termasuk JetPants , Cubrid atau Flock / Gizzard (infrastruktur Twitter).

Justin Swanhart
sumber
3

Tingkat aplikasi tentu saja.

Pendekatan terbaik yang pernah saya temukan dalam buku ini

MySQL Kinerja Tinggi http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064

Deskripsi singkat: Anda dapat membagi data Anda menjadi banyak bagian dan menyimpan ~ 50 bagian di setiap server. Ini akan membantu Anda menghindari masalah terbesar kedua dari sharding - penyeimbangan ulang. Pindahkan saja beberapa di antaranya ke server baru dan semuanya akan baik-baik saja :)

Saya sangat menyarankan Anda untuk membelinya dan membaca bagian "skala mysql".

Andrey Frolov
sumber
Buku yang Anda rekomendasikan berusia 8 tahun ... apakah mencakup sharding yang relevan dengan teknologi saat ini?
raffian
1
Ini mencakup beberapa pendekatan dasar untuk skala mysql. AFAIK tidak ada yang berubah dalam penskalaan mysql. Teknik sharding dan replikasi tingkat aplikasi yang sama banyak digunakan saat ini.
Andrey Frolov
Saya bisa saja salah, tetapi saya telah melakukan banyak penelitian tentang ini selama seminggu terakhir dan sepertinya mySQL sendiri telah membuat banyak perubahan dalam 8 tahun terakhir, terutama terkait partisi dan cache. Ada versi baru yang keluar tahun ini: amazon.com/High-Performance-MySQL-Optimization-Replication/dp/… Saya belum membacanya tetapi saya pikir itu mencakup model replikasi baru yang tersedia.
NateDSaint
4
Buku .. kenapa tidak dijelaskan disini saja.
DDD
2

Pada 2018, tampaknya ada solusi asli MySql untuk itu. Sebenarnya ada setidaknya 2 - InnoDB Cluster dan NDB Cluster (ada versi komersial dan komunitasnya).

Karena kebanyakan orang yang menggunakan edisi komunitas MySql lebih akrab dengan mesin InnoDB, inilah yang harus dieksplorasi sebagai prioritas pertama. Ini mendukung replikasi dan partisi / sharding out of the box dan didasarkan pada MySql Router untuk berbagai opsi perutean / load-balancing.

Sintaks untuk pembuatan tabel Anda perlu diubah, misalnya:

    CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );

(ini hanya satu dari empat jenis partisi )

Satu batasan yang sangat penting:

Kunci asing InnoDB dan partisi MySQL tidak kompatibel. Tabel InnoDB yang dipartisi tidak boleh memiliki referensi kunci asing, juga tidak dapat memiliki kolom yang direferensikan oleh kunci asing. Tabel InnoDB yang memiliki atau yang direferensikan oleh kunci asing tidak dapat dipartisi.

yuranos
sumber
Ketahuilah bahwa PARTITION BY HASH(YEAR...)akan memindai semua partisi jika Anda memiliki rentang tanggal. Yuck.
Rick James