1.1 Apa sharding?

Yen sampeyan terus-terusan google, jebule ana wates sing rada burem antarane sing diarani partisi lan sing diarani sharding. Saben uwong nyebut apa sing dikarepake, apa wae sing dikarepake. Sawetara wong mbedakake antarane partisi horisontal lan sharding. Liyane ujar manawa sharding minangka partisi horisontal tartamtu.

Aku ora nemokake standar terminologi siji sing bakal disetujoni dening founding rama lan certified dening ISO. Keyakinan batin pribadi kaya mangkene: Pemisahan rata-rata yaiku "nglereni dhasar dadi potongan-potongan" kanthi cara sing sewenang-wenang.

  • Pemisahan vertikal - miturut kolom. Contone, ana meja raksasa kanthi rong milyar cathetan ing 60 kolom. Nanging saka tetep siji Tabel buta kuwi, kita tetep 60 paling tabel buta 2 milyar cathetan saben - lan iki ora basis kolom, nanging pemisahan vertikal (minangka conto terminologi).
  • Pemisahan horisontal - kita ngethok baris kanthi baris, bisa uga ana ing server.

Wayahe kikuk ing kene yaiku bedane subtle antarane partisi horisontal lan sharding. Aku bisa Cut menyang bêsik, nanging aku ora bisa pitutur marang kowe manawa apa iku. Ana perasaan sing sharding lan partisi horisontal meh padha.

Sharding punika, ing umum, nalika Tabel gedhe ing syarat-syarat database utawa pro-koleksi dokumen, obyek, yen sampeyan ora duwe database, nanging nyimpen document, Cut persis dening obyek. Yaiku, saka 2 milyar obyek, potongan dipilih ora preduli ukurane. Obyek dhewe ing saben obyek ora dipotong dadi potongan, kita ora dilebokake ing kolom sing kapisah, yaiku, dilebokake ing macem-macem papan.

Ana beda terminologi subtle. Contone, relatif ngandika, pangembang Postgres bisa ngomong sing pemisahan horisontal nalika kabeh tabel ing ngendi tabel utama dipérang dumunung ing skema padha, lan nalika ing mesin beda, iki wis sharding.

Ing pangertèn umum, tanpa disambungake menyang terminologi database tartamtu lan sistem manajemen data tartamtu, ana perasaan sing sharding mung ngiris baris dening baris / dokumen dening dokumen, lan ing - iku kabeh.

Aku nandheske khas. Ing pangertèn sing kita nindakake kabeh iki ora mung kanggo Cut 2 milyar dokumen menyang 20 tabel, saben kang bakal luwih bisa diatur, nanging kanggo disebaraké liwat akeh intine, akeh disk utawa akeh beda fisik utawa server virtual .

1.2 Dibagi sing ora bisa dibagi

Dimangerteni manawa kita nindakake iki supaya saben beling - saben potongan data - ditiru kaping pirang-pirang. Nanging tenan, ora.

INSERT INTO docs00 
SELECT * FROM documents WHERE (id%16)=0 
... 
 
INSERT INTO docs15 
SELECT * FROM documents WHERE (id%16)=15 

Nyatane, yen sampeyan nindakake irisan data kasebut, lan saka siji tabel SQL raksasa ing MySQL ing laptop sing gagah berani, sampeyan bakal ngasilake 16 tabel cilik, tanpa ngluwihi laptop siji, ora skema siji, ora database siji, etc . lan liya-liyane. - iku, sampeyan wis duwe sharding.

Iki nyebabake ing ngisor iki:

  • Bandwidth mundhak.
  • Latensi ora owah, yaiku, saben wong, supaya bisa ngomong, buruh utawa konsumen ing kasus iki, entuk dhewe. Panjaluk sing beda-beda dilayani ing wektu sing padha.
  • Utawa loro-lorone, lan liyane, lan uga kasedhiyan dhuwur (replikasi).

Kenapa bandwidth? Kadhangkala kita bisa duwe volume data sing ora cocog - ora jelas ing endi, nanging ora cocog - ing 1 {kernel | disk | server | ...}. Ana mung ora cukup sumber daya, iku kabeh. Kanggo nggarap dataset gedhe iki, sampeyan kudu ngethok.

Kenapa latensi? Ing siji inti, mindhai tabel 2 milyar baris 20 kaping luwih alon tinimbang mindhai 20 tabel ing 20 intine, nindakaken ing podo karo. Data diproses alon banget ing siji sumber.

Apa kasedhiyan dhuwur? Utawa kita Cut data kanggo nindakake loro ing wektu sing padha, lan ing wektu sing padha sawetara salinan saben shard - replikasi njamin kasedhiyan dhuwur.

1.3 Conto prasaja "carane nganggo tangan"

Sharding kondisional bisa dipotong kanthi nggunakake test tabel test.documents kanggo 32 dokumen, lan ngasilake 16 tabel test saka tabel iki, kira-kira 2 dokumen saben test.docs00, 01, 02, ..., 15.

INSERT INTO docs00 
SELECT * FROM documents WHERE (id%16)=0 
... 
 
INSERT INTO docs15 
SELECT * FROM documents WHERE (id%16)=15 

Kenging punapa? Amarga a priori kita ora ngerti carane id disebarake, yen saka 1 kanggo 32 klebu, banjur bakal ana persis 2 dokumen saben, digunakake ora.

We nindakake kene kok. Sawise kita wis nggawe 16 tabel, kita bisa "nyekel" 16 saka apa kita kudu. Preduli saka apa kita kenek, kita bisa parallelize sumber daya iki. Contone, yen ora ana cukup ruang disk, iku bakal nggawe pangertèn kanggo decompose tabel iki ing disk kapisah.

Kabeh iki, sayangé, ora gratis. Aku curiga yen ing kasus standar SQL kanonik (aku wis suwe ora maca standar SQL, mungkin wis suwe ora dianyari), ora ana sintaksis standar resmi kanggo ngomong menyang server SQL apa wae. : "Server SQL sing dihormati, gawe aku 32 pecahan lan dibagi dadi 4 disk. Nanging ing implementasine individu, asring ana sintaks khusus kanggo nindakake perkara sing padha. PostgreSQL duwe mekanisme pemisahan, MySQL duwe MariaDB, Oracle bisa uga wis suwe.

Nanging, yen kita nindakake kanthi tangan, tanpa dhukungan database lan ing kerangka standar, mula kita mbayar kanthi syarat kanthi kerumitan akses data . Ing endi ana prasaja SELECT * FROM documents WHERE id=123, saiki 16 x SELECT * FROM docsXX. Lan luwih becik yen kita nyoba njupuk rekaman kanthi kunci. Luwih menarik yen kita nyoba entuk sawetara rekaman awal. Saiki (yen kita, aku nandheske, kaya wong bodho, lan tetep ing framework standar), asil iki 16 PILIH * FROM kudu digabungake ing aplikasi.

Apa owah-owahan kinerja sampeyan bisa nyana?

  • Intuisi - linear.
  • Secara teoritis - sublinear, amarga hukum Amdahl.
  • Praktis, bisa uga meh linear, bisa uga ora.

Nyatane, jawaban sing bener ora dingerteni. Kanthi aplikasi pinter saka technique sharding, sampeyan bisa entuk degradasi super-linear pinunjul ing kinerja aplikasi, lan malah DBA bakal teka karo poker abang-panas.

Ayo ndeleng carane iki bisa digayuh. Cetha yen mung nyetel setelan kanggo PostgreSQL shards = 16, banjur njupuk mati dhewe, ora menarik. Ayo dipikirake carane nggawe manawa kita alon-alon saka sharding 16 kaping 32 - iki menarik saka sudut pandang carane ora nindakake iki.

Kita usaha kanggo nyepetake utawa alon mudhun bakal tansah mbukak menyang klasik - hukum Amdahl lawas apik, kang ngandika sing ora ana parallelization sampurna saka request sembarang, ana tansah sawetara bagean konsisten.

1.4 Hukum Amdahl

Ana tansah bagean serialized.

Ana mesthi bagean saka eksekusi query sing paralel, lan mesthi ana bagean sing ora paralel. Malah yen misale jek sing pitakonan podo sampurna, paling koleksi baris asil sing arep dikirim menyang klien saka larik ditampa saka saben beling tansah ana, lan iku tansah urutan.

Ana tansah sawetara bagean konsisten. Bisa dadi cilik, ora katon ing latar mburi umum, bisa dadi gigantic lan, kanthi mangkono, banget mengaruhi paralelisasi, nanging mesthi ana.

Kajaba iku, pengaruhe ganti lan bisa tuwuh kanthi signifikan, umpamane, yen kita ngethok meja - ayo ngunggahake taruhan - saka 64 cathetan dadi 16 tabel saka 4 cathetan, bagean iki bakal diganti. Mesthi, miturut jumlah data sing gedhe banget, kita nggarap ponsel lan prosesor 2 MHz 86, lan ora duwe file sing cukup sing bisa dibukak ing wektu sing padha. Ketoke, kanthi input kasebut, kita mbukak siji file sekaligus.

  • Iku Total = Serial + Paralel . Where, contone, podo karo kabeh karya nang DB, lan serial ngirim asil kanggo klien.
  • Dadi Total2 = Serial + Paralel / N + Xserial . Contone, nalika sakabèhé ORDER BY, Xserial>0.

Kanthi conto prasaja iki, aku nyoba nuduhake yen sawetara Xserial katon. Saliyane kasunyatan sing ana tansah bagean serialized, lan kasunyatan sing kita nyoba kanggo bisa karo data ing podo karo, ana bagean tambahan kanggo nyedhiyani slicing data iki. Secara kasar, kita butuh:

  • golek iki 16 tabel ing kamus internal database kang;
  • mbukak file;
  • alokasi memori;
  • memori unallocate;
  • asil gabungan;
  • nyinkronake antarane inti.

Sawetara efek out-of-sync isih katon. Padha bisa dadi ora pati penting lan manggoni siji milyar saka total wektu, nanging padha tansah non-nol lan tansah ana. Kanthi bantuan, kita bisa ngilangi kinerja kanthi dramatis sawise sharding.

Iki minangka gambar standar babagan hukum Amdahl. Sing penting ing kene yaiku garis-garis, sing saenipun kudu lurus lan tuwuh kanthi linear, dadi asimtot. Nanging amarga grafik saka Internet ora bisa diwaca, aku nggawe, miturut pendapatku, luwih akeh tabel visual kanthi nomer.

Ayo dadi ngomong kita duwe sawetara bagean serialized saka Processing request sing mung njupuk 5%: serial = 0,05 = 1 / 20 .

Intuisi, iku bakal koyone sing karo bagean serialized sing njupuk mung 1/20 saka Processing request, yen kita parallelize pangolahan request kanggo 20 intine, iku bakal dadi bab 20, ing kasus paling awon 18, kaping luwih cepet.

Nyatane, matematika iku bab sing ora duwe ati :

tembok = 0,05 + 0,95/num_inti, kacepetan = 1 / (0,05 + 0,95/num_inti)

Pranyata yen sampeyan ngetung kanthi teliti, kanthi bagean serial 5%, kacepetan bakal 10 kaping (10,3), yaiku 51% dibandhingake karo ideal teoritis.

8 iron = 5.9 = 74%
10 intine = 6.9 = 69%
20 intine = 10.3 = 51%
40 intine = 13.6 = 34%
128 intine = 17.4 = 14%

Sawise nggunakake 20 intine (20 disk, yen sampeyan seneng) kanggo tugas sing digunakake, kita ora bakal bisa kanthi teoritis akselerasi luwih saka 20 kaping, nanging ing praktik - luwih sithik. Kajaba iku, kanthi nambah jumlah paralel, inefisiensi mundhak banget.

Nalika mung 1% karya serial, lan 99% paralel, nilai nyepetake rada nambah:

8 iron = 7.5 = 93%
16 intine = 13.9 = 87%
32 intine = 24.4 = 76%
64 ijo = 39.3 = 61%

Kanggo pitakon termonuklir sing sampurna, sing mesthi butuh jam kanggo ngrampungake, lan kerja persiapan lan ngumpulake asil mbutuhake wektu sing sithik (seri = 0,001), kita bakal weruh efisiensi sing apik:

8 iron = 7.94 = 99%
16 intine = 15,76 = 99%
32 intine = 31.04 = 97%
64 ijo = 60,20 = 94%

Elinga yen kita ora bakal bisa ndeleng 100% . Ing kasus utamané apik, sampeyan bisa ndeleng, contone, 99,999%, nanging ora persis 100%.