Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Laporan kasebut nyedhiyakake sawetara pendekatan sing ngidini ngawasi kinerja pitakon SQL nalika ana mayuta-yuta saben dina, lan ana atusan server PostgreSQL sing dipantau.

Solusi teknis apa sing ngidini kita ngolah volume informasi kanthi efisien, lan kepiye carane nggawe pangembang biasa luwih gampang?


Sapa sing kasengsem? analisis masalah tartamtu lan macem-macem Techniques optimasi Pitakonan SQL lan ngrampungake masalah DBA khas ing PostgreSQL - sampeyan uga bisa maca seri artikel ing topik iki.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)
Jenengku Kirill Borovikov, aku makili Perusahaan Tensor. Khusus, aku spesialis nggarap database ing perusahaan kita.

Dina iki aku bakal pitutur marang kowe carane ngoptimalake pitakon, nalika sampeyan ora perlu "milih" kinerja pitakonan siji, nanging ngatasi masalah kanthi massal. Nalika ana yuta panjalukan, lan sampeyan kudu golek sawetara pendekatan kanggo solusi masalah gedhe iki.

Umumé, Tensor kanggo yuta klien kita VLSI minangka aplikasi kita: jaringan sosial perusahaan, solusi kanggo komunikasi video, kanggo aliran dokumen internal lan eksternal, sistem akuntansi kanggo akuntansi lan gudang,... Yaiku, "mega-combine" kanggo manajemen bisnis terpadu, sing ana luwih saka 100 beda. proyek internal.

Kanggo mesthekake yen kabeh bisa kerja lan berkembang kanthi normal, kita duwe 10 pusat pangembangan ing saindenging negara, kanthi luwih akeh 1000 pangembang.

Kita wis nggarap PostgreSQL wiwit 2008 lan wis nglumpukake akeh sing diproses - data klien, statistik, analitis, data saka sistem informasi eksternal - luwih saka 400TB. Ana sekitar 250 server ing produksi piyambak, lan total ana kira-kira 1000 server database sing kita monitor.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

SQL minangka basa deklaratif. Sampeyan ora nggambarake "carane" apa sing kudu ditindakake, nanging "apa" sing pengin digayuh. DBMS luwih ngerti carane nggawe JOIN - carane nyambungake tabel, kahanan apa sing kudu dileksanakake, apa sing bakal ditindakake indeks, apa sing ora bakal ...

Sawetara DBMS nampa pitunjuk: "Ora, sambungake rong tabel iki ing antrian kasebut lan kaya ngono," nanging PostgreSQL ora bisa nindakake iki. Iki minangka posisi sadar para pangembang utama: "Kita luwih seneng ngrampungake pangoptimal pitakon tinimbang ngidini pangembang nggunakake sawetara pitunjuk."

Nanging, senadyan kasunyatan sing PostgreSQL ora ngidini "njaba" kanggo ngontrol dhewe, iku sampurna ngidini ndeleng apa sing ana ing njero dhewekenalika sampeyan mbukak pitakon, lan ing ngendi ana masalah.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Umumé, apa masalah klasik pangembang [kanggo DBA] biasane teka karo? “Ing kene panjaluke dituruti, lan kabeh alon karo kita, kabeh gantung, ana sing kedaden... Akeh masalah!”

Alasane meh padha:

  • algoritma pitakon sing ora efisien
    Pangembang: "Saiki aku menehi dheweke 10 tabel ing SQL liwat NGGABUNGA ..." - lan ngarepake yen kahanane bakal kanthi ajaib "diikat" lan dheweke bakal entuk kabeh kanthi cepet. Nanging kaelokan ora kelakon, lan sistem sembarang karo variasi kuwi (10 tabel ing siji FROM) tansah menehi sawetara jenis kesalahan. [artikel]
  • statistik sing ora cocog
    Titik iki cocog banget khusus kanggo PostgreSQL, nalika sampeyan "diwutahake" dataset gedhe menyang server, nggawe panjalukan, lan "sexcanits" tablet sampeyan. Amarga wingi ana 10 cathetan, lan saiki ana 10 yuta, nanging PostgreSQL durung ngerti babagan iki, lan kita kudu nyritakake babagan iki. [artikel]
  • "plug" ing sumber daya
    Sampeyan wis nginstal database gedhe lan akeh dimuat ing server lemah sing ora cukup kinerja disk, memori, utawa prosesor. Lan kabeh ... Nang endi wae ana langit-langit kinerja ing ndhuwur sing ora bisa mlumpat maneh.
  • pamblokiran
    Iki minangka titik sing angel, nanging paling relevan kanggo macem-macem pitakon modifikasi (INSERT, UPDATE, DELETE) - iki minangka topik gedhe sing kapisah.

Njupuk rencana

... Lan kanggo kabeh liyane kita butuh rencana! Kita kudu ndeleng apa sing kedadeyan ing server.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Rencana eksekusi pitakon kanggo PostgreSQL minangka wit algoritma eksekusi query ing representasi teks. Iki minangka algoritma sing, minangka asil analisis dening perencana, ditemokake minangka sing paling efektif.

Saben simpul wit minangka operasi: njupuk data saka tabel utawa indeks, mbangun bitmap, nggabungake rong tabel, gabung, intersecting, utawa ora kalebu pilihan. Nglakokake pitakon kalebu mlaku liwat simpul wit iki.

Kanggo entuk rencana pitakon, cara paling gampang yaiku nglakokake pernyataan kasebut EXPLAIN. Kanggo entuk kabeh atribut nyata, yaiku, nglakokake pitakon ing basis - EXPLAIN (ANALYZE, BUFFERS) SELECT ....

Sisih ala: nalika sampeyan mbukak, kedadeyan "kene lan saiki", dadi mung cocok kanggo debugging lokal. Yen sampeyan njupuk server sing dimuat kanthi akeh owah-owahan data, lan sampeyan ndeleng: "Oh! Kene kita duwe eksekusi alondheweke njaluk." Setengah jam, jam kepungkur - nalika sampeyan lagi mlaku lan njaluk panjalukan iki saka log, nggawa bali menyang server, kabeh set data lan statistik sampeyan diganti. Sampeyan mbukak kanggo debug - lan mlaku cepet! Lan sampeyan ora ngerti sebabe, kenapa yaiku alon-alon.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Kanggo ngerti apa sing kedadeyan persis nalika panjaluk kasebut ditindakake ing server, wong pinter nulis auto_explain modul. Ana ing meh kabeh distribusi PostgreSQL sing paling umum, lan mung bisa diaktifake ing file konfigurasi.

Yen nyadari yen sawetara panyuwunan mlaku luwih dawa tinimbang watesan sing sampeyan ucapake, mula "Snapshot" saka rencana panjalukan iki lan nulis mau bebarengan ing log.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Kabeh katon apik saiki, kita menyang log lan ndeleng ana ... [text footcloth]. Nanging kita ora bisa ngomong apa-apa bab iku, liyane saka kasunyatan sing rencana banget amarga njupuk 11ms kanggo nglakokaké.

Kabeh katon apik - nanging ora ana sing jelas apa sing kedadeyan. Loro saka wektu umum, kita ora weruh apa-apa. Amarga ndeleng "cempe" kaya teks biasa umume ora visual.

Nanging sanajan ora jelas, sanajan ora trep, ana masalah sing luwih dhasar:

  • Node nuduhake jumlah sumber daya saka kabeh subtree ing ngisor dheweke. Tegese, sampeyan ora mung bisa ngerteni sepira suwene wektu kanggo Pindai Indeks tartamtu iki yen ana sawetara kondisi nested ing ngisor iki. Kita kudu kanthi dinamis ndeleng manawa ana "bocah" lan variabel kondisional, CTE ing njero - lan nyuda kabeh "ing pikiran kita".
  • Titik kapindho: wektu sing dituduhake ing simpul yaiku wektu eksekusi simpul tunggal. Yen simpul iki dileksanakake minangka asil saka, contone, daur ulang liwat tabel cathetan kaping pirang-pirang, banjur nomer puteran-siklus saka simpul iki-munggah ing rencana. Nanging wektu eksekusi atom dhewe tetep padha ing babagan rencana. Sing, kanggo ngerti suwene simpul iki dileksanakake ing total, sampeyan kudu Multiply siji bab liyane - maneh, "ing sirah."

Ing kahanan kaya mengkono, ngerti "Sapa link sing paling lemah?" meh mokal. Mulane, malah gawe dhewe nulis ing "manual" sing "Mangertos rencana minangka seni sing kudu dipelajari, pengalaman ...".

Nanging kita duwe 1000 pangembang, lan sampeyan ora bisa ngirim pengalaman iki kanggo saben wong. Aku, sampeyan, dheweke ngerti, nanging ana sing ora ngerti maneh. Mungkin dheweke bakal sinau, utawa ora, nanging dheweke kudu kerja saiki - lan ing ngendi dheweke bakal entuk pengalaman iki?

Visualisasi rencana

Mulane, kita nyadari yen kanggo ngatasi masalah kasebut, kita kudu visualisasi apik saka rencana. [artikel]

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Kita pisanan "liwat pasar" - ayo goleki ing Internet kanggo ndeleng apa sing ana.

Nanging ternyata ana sawetara solusi sing relatif "urip" sing luwih utawa kurang berkembang - secara harfiah, mung siji: nerangake.depesz.com dening Hubert Lubaczewski. Nalika sampeyan ngetik lapangan "feed" representasi teks saka rencana, iku nuduhake sampeyan tabel karo data parsed:

  • wektu Processing simpul dhewe
  • total wektu kanggo kabeh subtree
  • nomer cathetan sing dijupuk sing wis samesthine statistik
  • awak simpul dhewe

Layanan iki uga nduweni kemampuan kanggo nuduhake arsip pranala. Sampeyan mbuwang rencana sampeyan ing kana lan ujar: "Hei, Vasya, iki link, ana sing salah."

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Nanging ana uga masalah cilik.

Kaping pisanan, jumlah "copy-paste" ageng. Sampeyan njupuk Piece saka log, tetep ing kono, lan maneh, lan maneh.

Sareh, ora ana analisis jumlah data sing diwaca - buffer padha sing output EXPLAIN (ANALYZE, BUFFERS), kita ora weruh ing kene. Dheweke mung ora ngerti carane mbongkar, ngerti lan bisa karo wong-wong mau. Nalika sampeyan maca akeh data lan ngerti yen sampeyan bisa uga salah alokasi disk lan cache memori, informasi iki penting banget.

Titik negatif katelu yaiku pangembangan proyek iki banget. Komitmen cilik banget, luwih becik yen saben nem sasi sapisan, lan kode kasebut ana ing Perl.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Nanging iki kabeh "lirik", kita bisa manggon karo iki, nanging ana siji bab sing banget nguripake kita adoh saka layanan iki. Iki minangka kesalahan ing analisis Common Table Expression (CTE) lan macem-macem simpul dinamis kaya InitPlan/SubPlan.

Yen sampeyan pracaya gambar iki, banjur total wektu eksekusi saben simpul individu luwih saka total wektu eksekusi kabeh request. Iku prasaja - wektu generasi CTE iki ora dikurangi saka simpul CTE Scan. Mulane, kita ora ngerti maneh jawaban sing bener babagan suwene scan CTE dhewe.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Banjur kita nyadari yen iki wektu kanggo nulis dhewe - hurray! Saben pangembang ujar: "Saiki kita bakal nulis dhewe, bakal gampang banget!"

We njupuk tumpukan khas kanggo layanan web: inti adhedhasar Node.js + Express, digunakake Bootstrap lan D3.js kanggo diagram ayu. Lan pangarepan kita wis bener - kita nampa prototipe pisanan ing 2 minggu:

  • parser rencana khusus
    Yaiku, saiki kita bisa ngurai rencana apa wae saka sing digawe dening PostgreSQL.
  • analisis sing bener saka simpul dinamis - CTE Scan, InitPlan, SubPlan
  • analisis distribusi buffer - ngendi kaca data diwaca saka memori, ngendi saka cache lokal, ngendi saka disk
  • entuk kajelasan
    Supaya ora "ngeduk" kabeh iki ing log, nanging kanggo ndeleng "link paling lemah" langsung ing gambar.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Kita entuk kaya iki, kanthi nyorot sintaks. Nanging biasane pangembang kita ora bisa nggarap perwakilan lengkap rencana kasebut, nanging kanthi luwih cendhek. Sawise kabeh, kita wis ngurai kabeh nomer lan mbuwang kiwa lan tengen, lan ing tengah kita mung ninggalake baris pisanan, apa jenis simpul: CTE Scan, generasi CTE utawa Seq Scan miturut sawetara tandha.

Iki minangka perwakilan singkatan sing kita sebut cithakan rencana.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Apa maneh sing luwih trep? Iku bakal trep kanggo ndeleng apa bagean saka total wektu kita dialokasikan menyang simpul - lan mung "tempelake" ing sisih diagram pie.

We titik ing simpul lan ndeleng - iku dadi metu sing Seq Scan njupuk kurang saka seprapat saka total wektu, lan isih 3/4 dijupuk dening CTE Scan. medeni! Iki minangka cathetan cilik babagan "tingkat geni" saka CTE Scan yen sampeyan nggunakake kanthi aktif ing pitakon sampeyan. Padha ora cepet banget - padha rodok olo malah kanggo mindhai Tabel biasa. [artikel] [artikel]

Nanging biasane diagram kasebut luwih menarik, luwih rumit, nalika kita langsung nuding segmen lan ndeleng, contone, luwih saka setengah wektu sawetara Seq Scan "mangan". Menapa malih, ana sawetara jinis Filter ing jero, akeh cathetan sing dibuwang miturut ... Sampeyan bisa langsung mbuwang gambar iki menyang pangembang lan ujar: "Vasya, kabeh iki ala kanggo sampeyan! Coba pikirake, deleng - ana sing salah!"

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Alami, ana sawetara "rake" melu.

Wangsulan: Bab ingkang pisanan kita teka tengen ana masalah rounding. Wektu saben simpul individu ing rencana kasebut dituduhake kanthi akurasi 1 μs. Lan nalika jumlah siklus simpul ngluwihi, contone, 1000 - sawise eksekusi PostgreSQL dibagi "ing akurasi", banjur nalika ngetung maneh, kita entuk total wektu "ing endi wae antarane 0.95ms lan 1.05ms". Nalika count dadi microseconds, ora apa-apa, nanging nalika iku wis [mili] detik, sampeyan kudu njupuk informasi iki menyang akun nalika "untying" sumber kanggo kelenjar "sing migunakaken pinten" rencana.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Titik kapindho, sing luwih rumit, yaiku distribusi sumber daya (buffers kasebut) ing antarane simpul dinamis. Iki biaya kita 2 minggu pisanan prototipe plus liyane 4 minggu.

Cukup gampang kanggo ngatasi masalah kaya iki - kita nindakake CTE lan mesthine maca apa wae. Nyatane, PostgreSQL "pinter" lan ora bakal maca apa-apa langsung ing kana. Banjur kita njupuk rekaman pisanan saka iku, lan siji atus siji saka CTE padha.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Kita ndeleng rencana lan ngerti - aneh, kita duwe 3 buffer (kaca data) "digunakake" ing Seq Scan, 1 liyane ing CTE Scan, lan 2 liyane ing CTE Scan kapindho. Yaiku, yen kita mung nyimpulake kabeh, kita bakal entuk 6, nanging saka tablet kita mung maca 3! CTE Scan ora maca apa-apa saka ngendi wae, nanging bisa langsung karo memori proses. Tegese, ana sing jelas salah ing kene!

Nyatane, ing kene kabeh 3 halaman data sing dijaluk saka Seq Scan, pisanan 1 njaluk CTE Scan kaping 1, banjur kaping 2, lan 2 maneh diwaca kanggo dheweke, yaiku total 3 kaca diwaca data, ora 6.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Lan gambar iki mimpin kita kanggo pangerten sing eksekusi rencana ora wit, nanging mung sawetara jinis graph acyclic. Lan kita entuk diagram kaya iki, supaya kita ngerti "apa sing asale saka ngendi." Sing, kene kita digawe CTE saka pg_class, lan takon kanggo kaping pindho, lan meh kabeh wektu kita ngginakaken ing cabang nalika kita takon kanggo kaping 2. Cetha yen maca entri kaping 101 luwih larang tinimbang mung maca entri 1 saka tablet.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

We exhaled kanggo sawetara wektu. Padha ngomong: "Saiki, Neo, sampeyan ngerti kung fu! Saiki pengalaman kita wis ana ing layar sampeyan. Saiki sampeyan bisa nggunakake." [artikel]

konsolidasi log

1000 pangembang kita ambegan lega. Nanging kita mangertos yen kita mung duwe atusan "pertempuran" server, lan kabeh iki "copy-paste" saka pangembang ora trep. Kita nyadari yen kita kudu ngumpulake dhewe.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Umumé, ana modul standar sing bisa ngumpulake statistik, nanging uga kudu diaktifake ing konfigurasi - iki modul pg_stat_statements. Nanging dheweke ora cocog karo kita.

Kaping pisanan, menehi pitakon sing padha nggunakake skema sing beda ing basis data sing padha QueryId beda. Sing, yen sampeyan pisanan nindakake SET search_path = '01'; SELECT * FROM user LIMIT 1;lan banjur SET search_path = '02'; lan request padha, banjur statistik modul iki bakal duwe cathetan beda, lan aku ora bakal bisa kanggo ngumpulake statistik umum khusus ing konteks profil request iki, tanpa njupuk menyang akun rencana.

Titik kapindho sing nyegah kita nggunakake yaiku lack of plans. Tegese ora ana rencana, mung ana panjaluke dhewe. Kita ndeleng apa sing saya alon, nanging ora ngerti sebabe. Lan ing kene kita bali menyang masalah dataset kanthi cepet.

Lan wayahe pungkasan - kekurangan "fakta". Yaiku, sampeyan ora bisa ngatasi conto eksekusi query tartamtu - ora ana, mung ana statistik agregat. Senajan iku bisa kanggo bisa karo iki, iku mung angel banget.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Поэтому мы решили с «копипастой» бороться и начали писать tukang nglumpukake.

Penagih nyambung liwat SSH, netepake sambungan aman kanggo server karo database nggunakake sertifikat, lan tail -F "clings" ing file log. Dadi ing sesi iki kita entuk "pangilon" lengkap kabeh file log, sing digawe server. Beban ing server dhewe minimal, amarga kita ora ngurai apa-apa ana, kita mung nggambarake lalu lintas.

Awit kita wis miwiti nulis antarmuka ing Node.js, kita terus nulis kolektor ing. Lan teknologi iki wis mbenerake dhewe, amarga trep banget kanggo nggunakake JavaScript kanggo nggarap data teks sing diformat kanthi lemah, yaiku log. Lan infrastruktur Node.js dhewe minangka platform backend ngidini sampeyan bisa kanthi gampang lan gampang nggarap sambungan jaringan, lan pancen nganggo aliran data apa wae.

Patut, kita "mulet" loro sambungan: pisanan kanggo "ngrungokake" log dhewe lan njupuk kanggo awake dhewe, lan liya kanggo periodik takon basa. "Nanging log nuduhake yen tandha karo oid 123 diblokir," nanging iki ora ateges apa-apa kanggo pangembang, lan iku bakal becik kanggo takon database, "Apa OID = 123 tho?" Lan supaya kita takon kanthi periodik dhasar apa sing durung ngerti babagan awake dhewe.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

"Ana mung siji bab sampeyan ora njupuk menyang akun, ana spesies tawon kaya gajah!.." Kita miwiti ngembangaken sistem iki nalika kita wanted kanggo ngawasi 10 server. Sing paling kritis ing pemahaman kita, ing ngendi sawetara masalah muncul sing angel ditangani. Nanging sajrone kuartal pisanan, kita nampa satus kanggo ngawasi - amarga sistem kasebut bisa digunakake, kabeh wong pengin, kabeh wong kepenak.

Kabeh iki kudu ditambahake, aliran data gedhe lan aktif. Nyatane, apa sing kita monitor, apa sing bisa ditindakake, yaiku apa sing kita gunakake. Kita uga nggunakake PostgreSQL minangka panyimpenan data. Lan ora ana sing luwih cepet kanggo "nyuwak" data kasebut tinimbang operator COPY durung.

Nanging mung "ngeculake" data dudu teknologi kita. Amarga yen sampeyan duwe kira-kira 50k panjalukan saben detik ing satus server, mula iki bakal ngasilake 100-150GB log saben dina. Mulane, kita kudu kasebut kanthi teliti, "motong" basa.

Kaping pisanan, kita nindakake pemisahan dening dina, amarga, dening lan gedhe, ora ana sing kasengsem ing korélasi antarane dina. Apa bedane apa sing sampeyan duwe wingi, yen bengi iki sampeyan ngluncurake versi aplikasi anyar - lan wis ana sawetara statistik anyar.

Kapindho, kita sinau (dipeksa) banget, cepet banget kanggo nulis nggunakake COPY. Tegese, ora mung COPYamarga dheweke luwih cepet tinimbang INSERT, lan malah luwih cepet.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Titik katelu - aku kudu ninggalake pemicu, mungguh, lan tombol manca. Tegese, kita ora duwe integritas referensial. Amarga yen sampeyan duwe tabel sing duwe pasangan FKs, lan sampeyan ngomong ing struktur database sing "punika cathetan log sing dirujuk dening FK, contone, kanggo klompok cathetan," banjur nalika sampeyan masang, PostgreSQL. wis ora ana apa-apa kajaba carane njupuk lan nindakake kanthi jujur SELECT 1 FROM master_fk1_table WHERE ... karo pengenal sing nyoba kanggo masang - mung kanggo mriksa sing cathetan iki saiki ana, sing ora "break mati" Key Asing iki karo sisipan Panjenengan.

Tinimbang siji rekaman menyang tabel target lan indeks, kita entuk manfaat tambahan kanggo maca saka kabeh tabel sing dirujuk. Nanging kita ora mbutuhake iki - tugas kita kanggo ngrekam sabisa-bisa lan kanthi cepet sabisa kanthi beban paling sithik. Dadi FK - mudhun!

Titik sabanjure yaiku agregasi lan hashing. Kaping pisanan, kita nindakake ing database - sawise kabeh, trep kanggo langsung, nalika rekaman teka, nindakake ing sawetara jenis tablet "plus siji" tengen ing pemicu. Inggih, iku trep, nanging bab ala sing padha - sampeyan masang siji rekaman, nanging dipeksa kanggo maca lan nulis soko liyane saka meja liyane. Kajaba iku, sampeyan ora mung maca lan nulis, sampeyan uga nindakake saben wektu.

Saiki bayangake yen sampeyan duwe tabel ing ngendi sampeyan mung ngetung jumlah panjalukan sing wis liwati host tartamtu: +1, +1, +1, ..., +1. Lan sampeyan, ing asas, ora perlu iki - iku kabeh bisa jumlah ing memori ing kolektor lan ngirim menyang database ing siji Go +10.

Ya, yen ana sawetara masalah, integritas logis sampeyan bisa uga "rusak", nanging iki kasus sing meh ora nyata - amarga sampeyan duwe server normal, ana baterei ing pengontrol, sampeyan duwe log transaksi, log ing sistem file ... Umumé, ora worth iku. Mundhut produktivitas sing sampeyan entuk saka pemicu / FK ora cocog karo biaya sing sampeyan lakoni.

Iku padha karo hashing. A request tartamtu mabur kanggo sampeyan, sampeyan ngetung pengenal tartamtu saka ing database, nulis menyang database lan banjur marang kabeh wong. Kabeh apik nganti, nalika ngrekam, ana wong liya sing pengin ngrekam perkara sing padha - lan sampeyan bakal diblokir, lan iki wis ala. Mulane, yen sampeyan bisa nransfer generasi sawetara ID menyang klien (relatif kanggo database), iku luwih apik kanggo nindakake iki.

Iku mung sampurna kanggo kita nggunakake MD5 saka teks - request, rencana, cithakan, ... Kita ngetung ing sisih Penagih, lan "pour" siap-digawe ID menyang database. Dawane MD5 lan pemisahan saben dina ngidini kita ora kuwatir babagan tabrakan.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Nanging kanggo ngrekam kabeh iki kanthi cepet, kita kudu ngowahi prosedur rekaman kasebut dhewe.

Kepiye carane sampeyan nulis data? Kita duwe sawetara jinis dataset, kita dibagi dadi pirang-pirang tabel, banjur COPY - pisanan menyang pisanan, banjur menyang kaloro, menyang katelu ... Iku ora trep, amarga kita koyone nulis siji stream data ing telung langkah. kanthi runtut. ora nyenengake. Apa bisa rampung luwih cepet? Saget!

Kanggo nindakake iki, cukup mung kanggo decompose aliran iki podo karo saben liyane. Pranyata yen kita duwe kesalahan, panjaluk, template, pamblokiran, ... mabur ing benang sing kapisah - lan kita nulis kabeh kanthi paralel. Cukup kanggo iki supaya saluran COPY terus mbukak kanggo saben tabel target individu.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Yaiku, ing kolektor tansah ana aliran, ing ngendi aku bisa nulis data sing dibutuhake. Nanging supaya database ndeleng data iki, lan wong ora macet nunggu data iki ditulis, COPY kudu diselani ing interval tartamtu. Kanggo kita, wektu sing paling efektif yaiku udakara 100ms - kita nutup lan langsung mbukak maneh menyang meja sing padha. Lan yen kita ora duwe cukup siji aliran sak sawetara puncak, banjur kita pooling nganti watesan tartamtu.

Kajaba iku, kita nemokake manawa kanggo profil beban kasebut, panggabungan apa wae, nalika cathetan diklumpukake kanthi batch, iku ala. Klasik ala iku INSERT ... VALUES lan luwih 1000 cathetan. Amarga ing titik sampeyan duwe puncak nulis ing media, lan wong liya sing nyoba nulis soko menyang disk bakal nunggu.

Kanggo ngilangi anomali kasebut, aja nglumpukake apa wae, ora buffer babar pisan. Lan yen buffering kanggo disk ora kelakon (untung, Stream API ing Node.js ngijini sampeyan kanggo mangerteni) - nundha sambungan iki. Nalika sampeyan nampa acara sing free maneh, nulis saka antrian akumulasi. Lan nalika iku sibuk, njupuk sabanjuré free saka blumbang lan nulis menyang.

Sadurunge ngenalake pendekatan iki kanggo ngrekam data, kita duwe kira-kira 4K nulis ops, lan kanthi cara iki kita nyuda beban nganti 4 kali. Saiki dheweke wis tuwuh maneh 6 kaping amarga database sing diawasi anyar - nganti 100MB / s. Lan saiki kita nyimpen log sajrone 3 wulan pungkasan kanthi volume udakara 10-15TB, ngarep-arep yen mung telung wulan pangembang bakal bisa ngrampungake masalah apa wae.

Kita ngerti masalah

Nanging mung ngumpulake kabeh data iki apik, migunani, relevan, nanging ora cukup - kudu dimangerteni. Amarga iki yuta rencana beda saben dina.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Nanging mayuta-yuta ora bisa diatur, kita kudu nindakake "luwih cilik". Lan, pisanan kabeh, sampeyan kudu mutusake carane sampeyan bakal ngatur bab "cilik" iki.

Kita wis nemtokake telung poin utama:

  • sing dikirim panjalukan iki
    Yaiku, saka aplikasi apa "teka": antarmuka web, backend, sistem pembayaran utawa liya-liyane.
  • ngendi iku kedaden
    Ing server tartamtu apa? Amarga yen sampeyan duwe sawetara server ing siji aplikasi, lan dumadakan siji "dadi bodho" (amarga "disk bosok", "memori bocor", sawetara masalah liyane), mula sampeyan kudu ngatasi server kasebut.
  • carane masalah manifested dhewe ing salah siji cara utawa liyane

Kanggo mangerteni "sapa" sing ngirim panjalukan, kita nggunakake alat standar - nyetel variabel sesi: SET application_name = '{bl-host}:{bl-method}'; - kita ngirim jeneng host logika bisnis saka ngendi panjaluk kasebut, lan jeneng metode utawa aplikasi sing miwiti.

Sawise kita wis ngliwati "pemilik" panyuwunan kasebut, kudu dadi output menyang log - kanggo iki kita ngatur variabel log_line_prefix = ' %m [%p:%v] [%d] %r %a'. Kanggo sing kasengsem, mbok menawa katon ing manualapa tegese kabeh. Pranyata kita ndeleng ing log:

  • время
  • proses lan pengenal transaksi
  • jeneng database
  • IP saka wong sing ngirim panjalukan iki
  • lan jeneng metode

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Banjur kita nyadari yen ora menarik banget kanggo ndeleng korélasi siji panyuwunan antarane server sing beda. Iku ora asring sing duwe kahanan ngendi siji aplikasi ngawut-awut munggah merata ana kene. Nanging sanajan iku padha, katon ing samubarang server iki.

Dadi kene potong "siji server - siji dina" ternyata cukup kanggo kita kanggo analisis apa wae.

Bagean analitis pisanan padha "sampel" - wangun sing disingkat saka presentation saka rencana, dibusak kabeh indikator numerik. Potongan kapindho yaiku aplikasi utawa metode, lan potongan katelu yaiku simpul rencana khusus sing nyebabake masalah.

Nalika kita pindhah saka conto tartamtu menyang cithakan, kita entuk rong kaluwihan bebarengan:

  • sawetara abang ing jumlah obyek kanggo analisis
    Kita kudu nganalisa masalah ora maneh dening ewu pitakon utawa rencana, nanging kanthi puluhan template.
  • garis wektu
    Yaiku, kanthi ngringkes "fakta" ing bagean tartamtu, sampeyan bisa nampilake penampilan ing wayah awan. Lan ing kene sampeyan bisa ngerti yen sampeyan duwe sawetara jinis pola sing kedadeyan, umpamane, sapisan jam, nanging kudu kedadeyan sapisan dina, sampeyan kudu mikir babagan apa sing salah - sapa sing nyebabake lan kenapa, bisa uga ana ing kene. ora kudu. Iki minangka metode analisis non-numerik, murni visual.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Cara sing isih ana adhedhasar indikator sing diekstrak saka rencana kasebut: kaping pirang-pirang pola kasebut kedadeyan, total lan rata-rata wektu, jumlah data sing diwaca saka disk, lan pira saka memori ...

Amarga, contone, sampeyan teka menyang kaca analytics kanggo host, katon - ana sing wiwit maca akeh banget ing disk. Disk ing server ora bisa nangani - sing maca saka iku?

Lan sampeyan bisa ngurutake miturut kolom lan mutusake apa sing bakal sampeyan lakoni saiki - beban ing prosesor utawa disk, utawa jumlah panjalukan ... mbalek metu versi anyar saka aplikasi.
[video ceramah]

Lan langsung sampeyan bisa ndeleng aplikasi beda sing teka karo cithakan padha saka panjalukan kaya SELECT * FROM users WHERE login = 'Vasya'. Frontend, backend, Processing ... Lan sampeyan wonder kok Processing bakal maca pangguna yen ora sesambungan karo wong.

Cara ngelawan yaiku langsung ndeleng saka aplikasi apa sing ditindakake. Contone, frontend iki, iki, iki, lan iki sapisan jam (garis wektu mbantu). Lan pitakonan langsung muncul: misale jek dudu tugas frontend kanggo nindakake apa wae saben jam ...

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Sawise sawetara wektu, kita nyadari yen kita kurang agregat statistik dening simpul rencana. We diisolasi saka plans mung kelenjar sing nindakake soko karo data saka tabel dhewe (maca / nulis mau dening indeks utawa ora). Nyatane, mung siji aspek sing ditambahake karo gambar sadurunge - pinten cathetan simpul iki nggawa kita?, lan pira sing dibuwang (Larik Dibusak dening Filter).

Sampeyan ora duwe indeks cocok ing piring, sampeyan nggawe panjalukan kanggo, mabur liwat indeks, tumiba ing Seq Scan ... sampeyan wis nyaring kabeh cathetan kajaba siji. Napa sampeyan butuh cathetan sing disaring 100M saben dina? Apa ora luwih apik kanggo nggulung indeks kasebut?

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Sawise nganalisa kabeh simpul rencana kanthi simpul, kita ngerti manawa ana sawetara struktur khas ing rencana kasebut sing bisa uga katon curiga. Lan bakal luwih becik kanggo ngandhani pangembang: "Kanca, ing kene sampeyan maca kanthi indeks, banjur diurutake, banjur dipotong" - minangka aturan, ana siji rekaman.

Saben uwong sing nulis pitakon mesthine nemoni pola iki: "Wenehana pesenan pungkasan kanggo Vasya, tanggale." Lan yen sampeyan ora duwe indeks miturut tanggal, utawa ora ana tanggal ing indeks sing digunakake, sampeyan bakal langkah ing persis padha "rake" .

Nanging kita ngerti manawa iki minangka "rake" - mula kenapa ora langsung ngandhani pangembang apa sing kudu ditindakake. Mangkono, nalika mbukak rencana saiki, pangembang kita langsung ndeleng gambar sing apik kanthi tips, ing ngendi dheweke langsung ngandhani: "Sampeyan duwe masalah ing kene, nanging wis ditanggulangi kanthi cara iki."

Akibaté, jumlah pengalaman sing dibutuhake kanggo ngatasi masalah ing wiwitan lan saiki wis mudhun banget. Iki jenis alat sing kita duwe.

Optimasi massal pitakon PostgreSQL. Kirill Borovikov (Tensor)

Source: www.habr.com

Add a comment