Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

Bubar aku pitutur marang kowe carane, nggunakake resep-resep standar nambah kinerja query maca SQL saka database PostgreSQL. Dina iki kita bakal ngomong babagan carane ngrekam bisa rampung luwih irit ing basis data tanpa nggunakake "twists" ing konfigurasi - mung kanthi ngatur aliran data kanthi bener.

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

#1. Seksi

Artikel bab carane lan apa iku worth ngatur partisi sing ditrapake "ing teori" wis, kene kita bakal pirembagan bab laku nglamar sawetara pendekatan ing kita layanan ngawasi kanggo atusan server PostgreSQL.

"Dina-dina kepungkur ..."

Kaping pisanan, kaya MVP apa wae, proyek kita diwiwiti kanthi beban sing cukup entheng - pemantauan ditindakake mung kanggo sepuluh server sing paling kritis, kabeh tabel relatif kompak ... Nanging saya suwe saya suwe, jumlah host sing dipantau dadi luwih akeh. , lan sepisan maneh kita nyoba kanggo nindakake soko karo salah siji saka Tabel ukuran 1.5TB, kita nyadari yen sanajan bisa terus urip kaya iki, nanging ora nyenengake.

Wektu meh kaya jaman epik, versi PostgreSQL 9.x sing beda-beda relevan, mula kabeh partisi kudu ditindakake "kanthi manual" - liwat pusaka Tabel lan micu routing kanthi dinamis EXECUTE.

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB
Solusi sing diasilake dadi cukup universal supaya bisa diterjemahake menyang kabeh tabel:

  • Tabel induk "header" kosong diumumake, sing diterangake kabeh indeks perlu lan pemicu.
  • Rekaman saka sudut pandang klien digawe ing tabel "root", lan nggunakake internal routing pemicu BEFORE INSERT rekaman iki "fisik" dipasang menyang bagean dibutuhake. Yen durung ana, kita entuk pengecualian lan ...
  • … kanthi nggunakake CREATE TABLE ... (LIKE ... INCLUDING ...) digawe adhedhasar cithakan tabel induk bagean karo watesan ing tanggal sing dikarepakesupaya nalika data dijupuk, maca mung dileksanakake ing.

PG10: nyoba pisanan

Nanging partisi liwat warisan historis ora cocog banget kanggo nggarap stream nulis aktif utawa akeh partisi turunan. Contone, sampeyan bisa kelingan sing algoritma kanggo milih bagean dibutuhake wis kompleksitas kuadrat, sing dianggo karo 100+ bagean, sampeyan dhewe ngerti carane ...

Ing PG10, kahanan iki dioptimalake kanthi nggunakake dhukungan pemisahan asli. Mulane, kita langsung nyoba aplikasi kasebut langsung sawise migrasi panyimpenan, nanging ...

Minangka ternyata sawise ngeduk manual, tabel partisi asli ing versi iki yaiku:

  • ora ndhukung katrangan indeks
  • ora ndhukung pemicu ing
  • ora bisa dadi "keturunan" sapa wae
  • ora ndhukung INSERT ... ON CONFLICT
  • ora bisa ngasilake bagean kanthi otomatis

Sawise nampa jotosan nglarani ing bathuk karo rake, kita temen maujud sing ora bisa kanggo nindakake tanpa ngowahi aplikasi, lan postponed riset luwih kanggo nem sasi.

PG10: kaloro kasempatan

Dadi, kita wiwit ngrampungake masalah sing muncul siji-siji:

  1. Amarga micu lan ON CONFLICT Kita nemokake yen kita isih butuh ing kene, mula kita nggawe tahap penengah kanggo ngrampungake tabel proxy.
  2. Ngilangi "rute" ing pemicu - sing, saka EXECUTE.
  3. Padha njupuk metu dhewe tabel Cithakan karo kabeh indekssupaya padha ora malah ana ing meja proxy.

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB
Pungkasan, sawise kabeh iki, kita misahake tabel utama kanthi asli. Nggawe bagean anyar isih ditinggalake ing kalbu aplikasi.

Kamus "Sawing".

Kaya ing sistem analitis, kita uga duwe "fakta" lan "potongan" (kamus). Ing kasus kita, ing kapasitas iki padha tumindak, contone, awak cithakan pitakon alon sing padha utawa teks pitakon kasebut dhewe.

"Fakta" wis dipΓ©rang ing dina kanggo wektu sing suwe, mula kita kanthi tenang mbusak bagean sing wis lawas, lan ora ngganggu kita (log!). Nanging ana masalah karo kamus ...

Ora ngomong yen ana akeh, nanging kira-kira 100TB "fakta" ngasilake kamus 2.5TB. Sampeyan ora bisa kanthi gampang mbusak apa wae saka tabel kasebut, sampeyan ora bisa ngompres ing wektu sing cukup, lan nulis kanthi alon-alon.

Kaya kamus ... ing, saben entri kudu diwenehi persis sapisan ... lan iki bener, nanging!.. Ora ana sing ngalangi kita duwe. kamus kapisah kanggo saben dina! Ya, iki nggawa redundansi tartamtu, nanging ngidini:

  • nulis / maca luwih cepet amarga ukuran bagean cilik
  • nggunakake memori kurang kanthi nggarap indeks sing luwih kompak
  • nyimpen data kurang amarga kemampuan kanggo cepet mbusak outdated

Minangka asil saka kabèh Komplek saka ngukur Beban CPU suda ~30%, beban disk nganti ~50%:

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB
Ing wektu sing padha, kita terus nulis bab sing padha menyang database, mung kanthi kurang muatan.

#2. Evolusi database lan refactoring

Dadi kita mapan ing apa sing kita duwe saben dina duwe bagean dhewe karo data. Bener, CHECK (dt = '2018-10-12'::date) - lan ana tombol pemisahan lan kondisi kanggo rekaman tiba menyang bagean tartamtu.

Amarga kabeh laporan ing layanan kita dibangun ing konteks tanggal tartamtu, indeks kanggo wong-wong mau wiwit "wektu non-partisi" wis kabeh jinis. (Server, Tanggal, Cithakan Rencana), (Server, Tanggal, Plan node), (Tanggal, Kelas kesalahan, Server)...

Nanging saiki padha manggon ing saben bagean salinan Panjenengan saben indeks kuwi... Lan ing saben bagean tanggal punika pancet... Ternyata saiki kita ana ing saben indeks kasebut mung ngetik konstanta minangka salah sawijining lapangan, sing nambah volume lan wektu telusuran, nanging ora ngasilake asil. Padha ninggalake rake kanggo awake dhewe, oops ...

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB
Arah optimasi jelas - prasaja mbusak kolom tanggal saka kabeh indeks ing tabel partisi. Diwenehi volume kita, gain kira 1TB / minggu!

Saiki elinga yen terabyte iki isih kudu direkam. Sing, kita uga disk saiki kudu mbukak kurang! Gambar iki kanthi jelas nuduhake efek sing dipikolehi saka reresik, sing ditindakake seminggu:

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

#3. "Nyebar" beban puncak

Salah sawijining masalah gedhe saka sistem sing dimuat yaiku sinkronisasi keluwih sawetara operasi sing ora mbutuhake. Kadhangkala "amarga ora weruh", kadhangkala "luwih gampang kaya ngono", nanging cepet utawa mengko sampeyan kudu nyingkirake.

Ayo nggedhekake gambar sadurunge lan ndeleng manawa kita duwe disk "pompa" ing beban kanthi amplitudo ganda antarane conto jejer, kang cetha "statistik" ngirim ora kelakon karo sawetara operasi:

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

Iki cukup gampang kanggo entuk. Kita wis miwiti ngawasi meh 1000 server, saben diproses dening utas logis sing kapisah, lan saben utas ngreset informasi akumulasi kanggo dikirim menyang basis data kanthi frekuensi tartamtu, kaya mangkene:

setInterval(sendToDB, interval)

Masalah kene dumunung sabenere ing kasunyatan sing kabeh Utas diwiwiti ing kira-kira wektu sing padha, dadi wektu ngirim meh mesthi pas "to the point". Waduh #2...

Untunge, iki cukup gampang kanggo ndandani, nambah "acak" run-up dening wektu:

setInterval(sendToDB, interval * (1 + 0.1 * (Math.random() - 0.5)))

#4. We cache apa kita kudu

Masalah highload tradisional katelu yaiku ora cache ngendi dheweke bisa dadi

Contone, kita bisa nganalisa babagan node rencana (kabeh iki Seq Scan on users), nanging langsung mikir sing padha, kanggo sisih paling, padha - padha lali.

Ora, mesthi, ora ana sing ditulis ing database maneh, iki ngethok pemicu karo INSERT ... ON CONFLICT DO NOTHING. Nanging data iki isih tekan database, lan ora perlu maca kanggo mriksa konflik kudu nindakake. Waduh #3...

Bentenipun ing jumlah cathetan sing dikirim menyang database sadurunge / sawise caching diaktifake ketok:

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

Lan iki minangka penurunan beban panyimpenan:

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

Total

"Terabyte-saben-dina" mung muni medeni. Yen sampeyan nindakake kabeh kanthi bener, mula iki mung 2^40 bita / 86400 detik = ~12.5MB/ssing malah ngawut-awut IDE desktop dianakakΓ©. πŸ™‚

Nanging kanthi serius, sanajan kanthi "skew" tenfold saka beban ing wayah awan, sampeyan bisa kanthi gampang nemokake kemampuan SSD modern.

Kita nulis ing PostgreSQL ing sublight: 1 host, 1 dina, 1TB

Source: www.habr.com

Add a comment