Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Laporan nampilkeun sababaraha pendekatan anu ngamungkinkeun monitor kinerja queries SQL lamun aya jutaan di antarana per poé, sareng aya ratusan server PostgreSQL anu diawaskeun.

Solusi téknis naon anu ngamungkinkeun urang épisién ngolah volume inpormasi sapertos kitu, sareng kumaha ieu ngagampangkeun kahirupan pamekar biasa?


Saha anu dipikaresep? analisis masalah husus sarta sagala rupa téhnik optimasi Patarosan SQL sareng ngarengsekeun masalah DBA khas dina PostgreSQL - anjeun ogé tiasa maca runtuyan artikel dina topik ieu.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)
Nami abdi Kirill Borovikov, abdi ngawakilan pausahaan Tensor. Husus, abdi ngahususkeun dina gawé bareng database di parusahaan urang.

Dinten ieu kuring bakal ngabejaan ka maneh kumaha urang ngaoptimalkeun queries, nalika anjeun teu kudu "nyokot eta" kinerja query tunggal, tapi ngajawab masalah en masse. Nalika aya jutaan requests, jeung anjeun kudu neangan sababaraha pendekatan kana solusi masalah badag ieu.

Sacara umum, Tensor pikeun sajuta klien kami VLSI mangrupikeun aplikasi kami: jaringan sosial perusahaan, solusi pikeun komunikasi video, pikeun aliran dokumén internal tur éksternal, sistem akuntansi pikeun akuntansi jeung gudang,... Nyaéta, misalna hiji "mega-combine" pikeun manajemén bisnis terpadu, nu aya leuwih ti 100 béda. proyék internal.

Pikeun mastikeun yén aranjeunna sadayana damel sareng mekar sacara normal, kami ngagaduhan 10 pusat pangembangan di sakumna nagara, sareng seueur deui 1000 pamekar.

Kami geus gawé bareng PostgreSQL saprak 2008 sarta geus akumulasi jumlah badag naon urang ngolah - data klien, statistik, analitik, data ti sistem informasi éksternal - leuwih ti 400TB. Aya sakitar 250 server dina produksi nyalira, sareng total aya sakitar 1000 server database anu urang pantau.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

SQL nyaéta basa déklaratif. Anjeun ngajelaskeun teu "kumaha" hal kedah dianggo, tapi "naon" rék ngahontal. DBMS langkung terang kumaha carana ngadamel JOIN - kumaha nyambungkeun méja anjeun, kaayaan naon anu kedah diterapkeun, naon anu bakal ngalangkungan indéks, naon anu henteu ...

Sababaraha DBMS nampi petunjuk: "Henteu, sambungkeun dua tabel ieu dina antrian sapertos kitu," tapi PostgreSQL henteu tiasa ngalakukeun ieu. Ieu posisi sadar pamekar ngarah: "Kami langkung resep ngabéréskeun pangoptimalkeun pamundut tibatan ngawenangkeun pamekar ngagunakeun sababaraha jinis petunjuk."

Tapi, sanaos kanyataan yén PostgreSQL henteu ngijinkeun "di luar" ngadalikeun dirina, éta sampurna ngamungkinkeun tingali naon anu lumangsung di jero anjeunnanalika anjeun ngajalankeun pamundut anjeun, sareng dimana éta gaduh masalah.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Sacara umum, naon masalah Palasik a developer [ka DBA a] biasana datangna kalawan? “Di dieu urang minuhan paménta, jeung sagalana slow kalawan kami, sagalana geus ngagantung, aya kajadian... Sababaraha jenis gangguan!”

Alesanna ampir sami:

  • algoritma query teu episien
    Pamekar: "Ayeuna kuring masihan anjeunna 10 tabel dina SQL via JOIN ..." - sareng ngarepkeun kaayaanana sacara ajaib bakal "dibeungkeut" sacara efektif sareng anjeunna bakal gancang-gancang. Tapi keajaiban teu lumangsung, sarta sagala sistem jeung variability misalna (10 tabel dina hiji FROM) salawasna méré sababaraha jenis kasalahan. [artikel]
  • statistik luntur
    titik ieu pisan relevan husus pikeun PostgreSQL, mun anjeun "dituang" dataset badag kana server, nyieun pamundut, sarta eta "sexcanits" tablet Anjeun. Kusabab kamari aya 10 rékaman di jerona, sarta kiwari aya 10 juta, tapi PostgreSQL teu acan sadar ieu, sarta kami kudu ngabejaan ngeunaan eta. [artikel]
  • "nyolok" dina sumberdaya
    Anjeun geus masang database badag tur beurat dimuat dina server lemah nu teu boga cukup disk, memori, atawa kinerja processor. Sareng éta sadayana ... Di mana waé aya siling kinerja di luhur anu anjeun moal tiasa luncat deui.
  • ngahalangan
    Ieu titik hésé, tapi aranjeunna paling relevan pikeun sagala rupa queries modifying (INSERT, UPDATE, DELETE) - ieu téh topik badag misah.

Meunang rencana

... Jeung sagalana sejenna urang peryogi rencana! Urang kedah ningali naon anu lumangsung di jero server.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Rencana palaksanaan query pikeun PostgreSQL mangrupakeun tangkal algoritma palaksanaan query dina ngagambarkeun téks. Justru algoritma anu, salaku hasil analisa ku anu ngarencanakeun, kapendak paling efektif.

Unggal titik tangkal mangrupa operasi: retrieving data tina tabel atawa indéks, ngawangun bitmap, ngagabung dua tabel, ngagabung, intersecting, atawa kaasup selections. Ngaéksekusi query ngalibatkeun leumpang ngaliwatan titik tangkal ieu.

Pikeun meunangkeun rencana query, cara panggampangna pikeun ngaéksekusi pernyataan EXPLAIN. Pikeun kéngingkeun sadaya atribut nyata, nyaéta, leres-leres ngalaksanakeun pamundut dina dasarna - EXPLAIN (ANALYZE, BUFFERS) SELECT ....

Bagian anu goréng: nalika anjeun ngajalankeun éta, éta kajadian "di dieu sareng ayeuna", janten ngan ukur cocog pikeun debugging lokal. Upami anjeun nyandak server anu sarat pisan anu aya dina aliran parobihan data anu kuat, sareng anjeun ningali: "Oh! Di dieu urang boga palaksanaan slowXia kahoyong." Satengah jam, sajam ka tukang - nalika anjeun ngajalankeun sareng nampi pamundut ieu tina log, mawa deui ka server, sadaya set data sareng statistik anjeun robih. Anjeun ngajalankeun éta pikeun debug - sareng jalanna gancang! Jeung anjeun teu bisa ngarti naha, naha ieu lalaunan.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Dina raraga ngartos naon anu lumangsung persis di momen nalika pamundut ieu dieksekusi dina server, jalma pinter wrote auto_explain modul. Éta hadir dina ampir sadaya distribusi PostgreSQL anu paling umum, sareng ngan saukur tiasa diaktipkeun dina file config.

Upami éta nyadar yén sababaraha pamundut langkung lami tibatan wates anu anjeun nyarioskeun, éta leres "snapshot" tina rencana pamundut ieu sareng nyerat aranjeunna babarengan dina log.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Sagalana sigana rupa ayeuna, urang buka log tur tingal aya ... [text footcloth]. Tapi urang teu bisa ngomong nanaon ngeunaan eta, lian ti kanyataan yén éta hiji rencana alus teuing sabab butuh 11ms sangkan ngaéksekusi.

Sagalana sigana teu kunanaon - tapi euweuh anu jelas naon sabenerna kajadian. Sajaba ti waktu umum, urang teu bener ningali nanaon. Kusabab ningali "domba" sapertos téks polos umumna henteu visual.

Tapi sanajan teu atra, sanajan teu merenah, aya masalah leuwih fundamental:

  • Node nunjukkeun jumlah sumberdaya sakabéh subtree handapeun anjeunna. Hartina, anjeun teu bisa ngan manggihan sabaraha waktos ieu spent dina Scan Index husus ieu lamun aya sababaraha kaayaan nested handapeun eta. Urang kudu dinamis kasampak ningali lamun aya "barudak" jeung variabel kondisional, CTEs jero - sarta subtract sadayana ieu "dina pikiran urang".
  • Titik kadua: waktos anu dituduhkeun dina titik nyaéta waktos palaksanaan titik tunggal. Lamun titik ieu dieksekusi salaku hasil tina, contona, hiji loop ngaliwatan catetan tabel sababaraha kali, mangka jumlah loop-siklus titik ieu-naek dina rencana. Tapi waktu palaksanaan atom sorangan tetep sarua dina watesan rencana. Hartina, dina raraga ngartos sabaraha lila titik ieu dipigawé dina total, anjeun kudu kalikeun hiji hal ku sejen - deui, "dina sirah anjeun".

Dina kaayaan kitu, ngartos "Saha nu link weakest?" ampir teu mungkin. Ku alatan éta, malah pamekar sorangan nulis dina "manual" éta "Ngartos rencana mangrupikeun seni anu kedah diajar, pangalaman ...".

Tapi urang boga 1000 pamekar, jeung anjeun teu bisa nepikeun pangalaman ieu unggal sahijina. Abdi, anjeun, anjeunna terang, tapi batur di dinya henteu terang deui. Panginten anjeunna bakal diajar, atanapi panginten henteu, tapi anjeunna kedah damel ayeuna - sareng dimana anjeunna bakal nampi pangalaman ieu?

Visualisasi rencana

Ku alatan éta, urang sadar yén dina raraga nungkulan masalah ieu, urang kudu visualisasi alus tina rencana. [artikel]

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Kami mimiti "ngaliwatan pasar" - hayu urang tingali dina Internét pikeun ningali naon anu aya.

Tapi tétéla aya sakedik pisan solusi "hirup" anu langkung atanapi kirang berkembang - sacara harfiah, ngan ukur hiji: explain.depesz.com ku Hubert Lubaczewski. Lamun anjeun ngasupkeun "feed" widang ngagambarkeun téks rencana, nembongkeun anjeun tabel kalawan data parsed:

  • waktos processing node urang sorangan
  • total waktu pikeun sakabéh subtree
  • Jumlah rékaman anu dicandak anu diperkirakeun sacara statistik
  • awak simpul sorangan

Ladenan ieu ogé gaduh kamampuan pikeun ngabagikeun arsip tautan. Anjeun ngalungkeun rencana anjeun di dinya sareng nyarios: "Eh, Vasya, ieu tautan, aya anu lepat di dinya."

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Tapi aya ogé masalah leutik.

Firstly, jumlah badag "copy-paste". Anjeun nyandak sapotong log, lengket di dinya, jeung deui, jeung deui.

Bréh, euweuh analisis jumlah data dibaca - buffers sarua kaluaran EXPLAIN (ANALYZE, BUFFERS), urang teu ningali di dieu. Anjeunna ngan saukur henteu terang kumaha ngabongkar aranjeunna, ngartos sareng damel sareng aranjeunna. Sawaktos Anjeun keur maca loba data jeung sadar yen Anjeun bisa jadi salah alokasi disk jeung cache memori, informasi ieu pohara penting.

Titik négatip katilu nyaéta ngembangkeun pisan lemah proyék ieu. The commits pisan leutik, éta alus lamun sakali unggal genep bulan, jeung kode nu aya dina Perl.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Tapi ieu sadayana "lirik", urang kumaha bae bisa hirup kalawan ieu, tapi aya hiji hal anu greatly ngancik urang jauh ti layanan ieu. Ieu kasalahan dina analisa Common Table Expression (CTE) sareng sagala rupa titik dinamis sapertos InitPlan/SubPlan.

Upami anjeun percanten kana gambar ieu, maka total waktos palaksanaan unggal titik individu langkung ageung tibatan waktos palaksanaan sadaya pamundut. Ieu basajan - waktos generasi CTE ieu teu dicokot tina titik CTE Scan. Ku alatan éta, urang henteu deui terang jawaban anu leres pikeun sabaraha lami scan CTE nyalira.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Teras we sadar yén éta waktuna pikeun nulis sorangan - hurray! Unggal pamekar nyarios: "Ayeuna urang nyerat sorangan, éta bakal gampang pisan!"

Simkuring nyandak tumpukan has pikeun layanan web: inti dumasar kana Node.js + Express, dipaké Bootstrap na D3.js pikeun diagram geulis. Sareng ekspektasi kami leres-leres leres - kami nampi prototipe munggaran dina 2 minggu:

  • parser rencana custom
    Nyaéta, ayeuna urang tiasa ngémutan rencana naon waé ti anu didamel ku PostgreSQL.
  • analisis bener tina titik dinamis - CTE Scan, InitPlan, SubPlan
  • analisis distribusi buffer - dimana kaca data dibaca tina mémori, dimana ti cache lokal, dimana ti disk
  • ngagaduhan kajelasan
    Ku kituna teu "ngagali" sadayana ieu dina log, tapi ningali "link paling lemah" langsung dina gambar.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Kami ngagaduhan anu sapertos kieu, kalebet panyorot sintaksis. Tapi biasana pamekar urang henteu deui damel sareng perwakilan lengkep rencana, tapi kalayan anu langkung pondok. Barina ogé, urang geus parsed sakabeh angka na dialungkeun aranjeunna ka kénca jeung ka katuhu, sarta di tengah urang ngan ninggalkeun garis kahiji, naon jenis titik éta: CTE Scan, CTE generasi atawa Seq Scan nurutkeun sababaraha tanda.

Ieu mangrupikeun perwakilan anu disingkat anu kami sebut témplat rencana.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Naon deui bakal merenah? Éta langkung saé pikeun ningali naon bagian tina total waktos urang dialokasikeun ka titik mana - sareng ngan ukur "nempelkeun" ka gigir. bagan pai.

Kami nunjuk dina titik sareng ningali - tétéla yén Seq Scan nyandak kirang ti saparapat tina total waktos, sareng sésana 3/4 dicandak ku CTE Scan. Kaayaan sieun! Ieu mangrupikeun catetan leutik ngeunaan "laju seuneu" CTE Scan upami anjeun aktip ngagunakeunana dina patarosan anjeun. Aranjeunna teu pisan gancang - aranjeunna inferior malah mun scanning tabel biasa. [artikel] [artikel]

Tapi biasana diagram sapertos anu leuwih narik, leuwih kompleks, lamun urang langsung nunjuk dina ruas tur tingal, contona, yén leuwih ti satengah waktu sababaraha Seq Scan "dahar". Leuwih ti éta, aya sababaraha jenis Filter jero, loba rékaman dipiceun nurutkeun eta ... Anjeun tiasa langsung maledog gambar ieu ka pamekar jeung ngomong: "Vasya, sagalana goréng di dieu pikeun anjeun! Tingali, tingali - aya anu salah!"

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Alami, aya sababaraha "rakes" aub.

Hal kahiji urang datang di sakuliah éta masalah rounding. Waktu unggal titik individu dina rencana dituduhkeun kalayan akurasi 1 μs. Sareng nalika jumlah siklus node ngaleuwihan, contona, 1000 - saatos palaksanaan PostgreSQL dibagi "dina akurasi", teras nalika ngitung deui kami nampi total waktos "di antara 0.95ms sareng 1.05ms". Nalika cacah mana kana microseconds, éta oke, tapi lamun éta geus [mili] detik, Anjeun kudu tumut kana akun informasi ieu nalika "untying" sumberdaya ka titik tina "anu dihakan sabaraha" rencana.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Titik kadua, langkung kompleks, nyaéta distribusi sumber daya (éta panyangga) diantara titik-titik dinamis. Ieu ngarugikeun urang 2 minggu mimiti prototipe ditambah 4 minggu deui.

Ieu rada gampang pikeun meunangkeun jenis ieu masalah - urang ngalakukeun CTE sarta konon maca hiji hal di dinya. Kanyataanna, PostgreSQL "pinter" sareng moal maca nanaon langsung di dinya. Teras we nyandak catetan anu munggaran ti dinya, sareng ka saratus sareng anu munggaran ti CTE anu sami.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Kami ningali rencana sareng ngartos - anéh, kami ngagaduhan 3 panyangga (halaman data) "dikonsumsi" dina Seq Scan, 1 deui dina CTE Scan, sareng 2 deui dina CTE Scan kadua. Nyaéta, upami urang ngan ukur nyimpulkeun sadayana, urang bakal nampi 6, tapi tina tablet urang ngan ukur maca 3! CTE Scan teu maca nanaon ti mana, tapi jalan langsung jeung mémori prosés. Hartina, aya anu jelas salah di dieu!

Nyatana, tétéla yén di dieu sadayana 3 halaman data anu dipénta ti Seq Scan, mimitina 1 menta CTE Scan ka-1, teras ka-2, sareng 2 deui dibacakeun ka anjeunna. 3 halaman anu maca data, sanés 6.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Sareng gambar ieu nyababkeun urang ngartos yén palaksanaan rencana henteu deui tangkal, tapi ngan ukur sababaraha jinis grafik asiklik. Sareng kami ngagaduhan diagram sapertos kieu, supados urang ngartos "naon asalna ti mana mimitina." Hartina, didieu urang dijieun CTE ti pg_class, sarta ménta eta dua kali, sarta ampir sakabéh waktu urang ieu spent dina cabang nalika urang nanya ka 2nd waktos. Éta jelas yén maca éntri ka-101 langkung mahal tibatan maca éntri ka-1 tina tablet.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Urang ambekan sakedapan. Aranjeunna nyarios: "Ayeuna, Neo, anjeun terang kung fu! Ayeuna pangalaman urang aya dina layar anjeun. Ayeuna anjeun tiasa nganggo éta." [artikel]

Log konsolidasi

1000 pamekar urang ngambekan napas lega. Tapi kami ngarti yén kami ngan ukur ngagaduhan ratusan "pertempuran" server, sareng sadaya "salinan-témpél" ieu ku pamekar henteu cocog pisan. Urang sadar yén urang kudu ngumpulkeun sorangan.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Sacara umum, aya modul standar anu tiasa ngumpulkeun statistik, tapi ogé kedah diaktipkeun dina konfigurasi - ieu modul pg_stat_statements. Tapi anjeunna henteu cocog sareng urang.

Firstly, éta nangtukeun kana queries sarua ngagunakeun schemes béda dina database sarua QueryId béda. Maksudna, lamun mimiti ngalakukeun SET search_path = '01'; SELECT * FROM user LIMIT 1;teras salajengna SET search_path = '02'; jeung pamundut sarua, mangka statistik modul ieu bakal boga rékaman béda, sarta kuring moal bisa ngumpulkeun statistik umum husus dina konteks propil pamundut ieu, tanpa nyokot kana akun schemes.

Titik kadua anu nyegah urang ngagunakeun éta kurangna rencana. Hartina, teu aya rencana, ngan aya paménta sorangan. Kami ningali naon anu ngalambatkeun, tapi kami henteu ngartos naha. Sarta di dieu urang balik deui ka masalah susunan data ngarobah gancang.

Sareng momen terakhir - kurangna "fakta". Hartina, anjeun teu bisa alamat hiji conto husus tina palaksanaan query - euweuh, aya ngan statistik aggregated. Sanajan kasebut nyaéta dimungkinkeun pikeun digawekeun ku ieu, éta ngan hésé pisan.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Ku alatan éta, urang mutuskeun pikeun ngalawan copy-paste tur mimitian nulis kolektor.

Kolektor ngahubungkeun via SSH, ngadegkeun sambungan aman ka server jeung database ngagunakeun sertipikat, jeung tail -F "clings" kana eta dina file log. Jadi dina sési ieu urang meunang "eunteung" lengkep sakabéh file log, nu server ngahasilkeun. Beban dina server sorangan minimal, sabab urang teu parse nanaon aya, urang ngan eunteung lalulintas.

Kusabab urang geus dimimitian nulis panganteur dina Node.js, urang terus nulis collector di dinya. Jeung téhnologi ieu geus diyakinkeun sorangan, sabab pohara merenah ngagunakeun JavaScript pikeun digawe sareng data téks lemah formatna, nu log. Jeung infrastruktur Node.js sorangan salaku platform backend ngidinan Anjeun pikeun gampang tur merenah dianggo kalayan sambungan jaringan, sarta memang kalawan sagala aliran data.

Sasuai, urang "manteng" dua sambungan: kahiji mun "ngadangukeun" log sorangan sarta nyandak ka diri urang sorangan, sarta kadua pikeun périodik nanya ka dasarna. "Tapi log nunjukkeun yén tanda sareng oid 123 diblokir," tapi ieu henteu hartosna nanaon pikeun pamekar, sareng langkung saé naroskeun kana pangkalan data, "Naon OID = 123 kitu?" Janten urang périodik naroskeun dasar naon anu urang henteu acan terang ngeunaan diri urang sorangan.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

"Aya ngan hiji hal nu teu tumut kana akun, aya spésiés lebah gajah-kawas!.." Urang mimitian ngamekarkeun sistem ieu nalika urang hayang ngawas 10 server. Anu paling kritis dina pamahaman urang, dimana sababaraha masalah timbul anu hese diurus. Tapi dina kuartal kahiji, kami nampi saratus pikeun ngawaskeun - sabab sistemna jalan, sadayana hoyong, sadayana nyaman.

Sadaya ieu kedah ditambihan, aliran data ageung sareng aktip. Nyatana, naon anu urang pantau, anu tiasa urang urus, nyaéta naon anu urang anggo. Urang ogé ngagunakeun PostgreSQL salaku panyimpen data. Sareng teu aya anu langkung gancang pikeun "tuang" data kana éta tibatan operator COPY Henteu acan.

Tapi saukur "tuang" data teu bener téhnologi urang. Kusabab upami anjeun gaduh kirang langkung 50k pamundut per detik dina saratus server, maka ieu bakal ngahasilkeun 100-150GB log per dinten. Ku alatan éta, urang kedah taliti "motong" dasarna.

Anu mimiti, urang ngalakukeun partitioning ku poé, sabab, sacara umum, teu aya anu kabetot dina korelasi antara poé. Naon bédana naon anu anjeun gaduh kamari, upami wengi ayeuna anjeun ngaluncurkeun versi énggal tina aplikasi - sareng parantos aya sababaraha statistik anyar.

Kadua, urang diajar (dipaksa) pisan, gancang pisan nulis ngagunakeun COPY. Hartina, henteu ngan COPYsabab anjeunna leuwih gancang ti INSERT, komo leuwih gancang.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Titik katilu - Kuring kungsi abandon pemicu masing-masing jeung konci asing. Hartina, urang teu boga integritas rujukan sama sekali. Kusabab upami anjeun gaduh méja anu ngagaduhan sapasang FK, sareng anjeun nyarios dina struktur database yén "di dieu mangrupikeun catetan log anu dirujuk ku FK, contona, ka grup rékaman," teras nalika anjeun ngalebetkeun, PostgreSQL. teu aya anu tinggaleun tapi kumaha carana nyandak sareng ngalakukeun éta jujur SELECT 1 FROM master_fk1_table WHERE ... kalawan identifier nu Anjeun nyobian nyelapkeun - ngan pikeun pariksa yen catetan ieu hadir aya, nu teu "megatkeun" Key Asing ieu kalawan sisipan Anjeun.

Gantina hiji catetan kana tabel target na indexes na, urang meunang kauntungan ditambahkeun maca tina sagala tabel eta nujul kana. Tapi urang henteu peryogi ieu pisan - tugas urang nyaéta pikeun ngarékam saloba mungkin sareng gancang-gancang kalayan beban pangsaeutikna. Janten FK - turun!

Titik salajengna nyaéta aggregation sareng hashing. Mimitina, kami ngalaksanakeunana dina pangkalan data - saatosna, éta gampang pikeun langsung, nalika catetan sumping, lakukeun dina sababaraha jinis tablet "tambah hiji" katuhu dina pemicu. Nya, éta merenah, tapi hal goréng anu sami - anjeun nyelapkeun hiji catetan, tapi kapaksa maca sareng nyerat anu sanés tina méja anu sanés. Sumawona, anjeun henteu ngan ukur maca sareng nyerat, anjeun ogé ngalakukeunana unggal waktos.

Ayeuna bayangkeun yén anjeun gaduh méja dimana anjeun ngan ukur ngitung jumlah pamundut anu parantos ngalangkungan host khusus: +1, +1, +1, ..., +1. Sareng anjeun, prinsipna, henteu peryogi ieu - éta sadayana mungkin jumlah dina mémori dina kolektor sarta ngirim ka database dina hiji lebet +10.

Leres, upami aya sababaraha masalah, integritas logis anjeun tiasa "rusak", tapi ieu mangrupikeun kasus anu ampir teu realistis - sabab anjeun gaduh server normal, éta gaduh batré dina controller, anjeun gaduh log transaksi, log on sistem file ... Sacara umum, teu patut eta. Leungitna produktivitas anjeun meunang tina ngajalankeun pemicu / FK teu patut expense anjeun ditanggung.

Éta sami sareng hashing. Hiji pamundut tangtu ngalayang ka anjeun, anjeun ngitung hiji identifier tangtu ti eta dina database, nulis ka database lajeng ngabejaan ka dulur. Sagalana henteu kunanaon dugi, dina waktos ngarékam, jalma kadua sumping ka anjeun anu hoyong ngarékam hal anu sami - sareng anjeun diblokir, sareng ieu parantos parah. Ku alatan éta, lamun bisa mindahkeun generasi sababaraha ID ka klien (relatif ka database), eta leuwih hade pikeun ngalakukeun ieu.

Ieu ngan sampurna pikeun urang ngagunakeun MD5 tina téks - pamundut, rencana, template, ... Urang ngitung eta di sisi collector, sarta "tuang" ID siap-dijieun kana database. Panjang MD5 sareng partisi sapopoé ngamungkinkeun urang henteu hariwang ngeunaan tabrakan anu mungkin.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Tapi pikeun ngarékam sadayana ieu gancang, urang kedah ngarobih prosedur ngarékam éta sorangan.

Kumaha anjeun biasana nyerat data? Simkuring gaduh sababaraha jenis dataset, urang dibagi kana sababaraha tabel, lajeng COPY - kahiji kana kahiji, lajeng kana kadua, kana katilu ... Ieu teu merenah, sabab urang sigana nulis hiji aliran data dina tilu hambalan. sacara berurutan. Teu pikaresepeun. Naha éta tiasa dilakukeun langkung gancang? Tiasa!

Jang ngalampahkeun ieu, cukup ngan ukur ngabubarkeun aliran ieu paralel. Tétéla urang gaduh kasalahan, requests, template, blockings, ... ngalayang dina threads misah - sarta kami nulis eta sadayana paralel. Cukup pikeun ieu tetep saluran COPY terus kabuka pikeun tiap tabel target individu.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Maksudna, di kolektor sok aya aliran, dimana kuring tiasa nyerat data anu kuring peryogikeun. Tapi supados pangkalan data ningali data ieu, sareng batur henteu macét ngantosan data ieu ditulis, COPY kudu diganggu dina interval nu tangtu. Pikeun kami, jaman anu paling efektif nyaéta sakitar 100ms - urang tutup sareng langsung muka deui kana méja anu sami. Tur upami urang teu boga cukup hiji aliran salila sababaraha puncak, lajeng urang ngalakukeun pooling nepi ka wates nu tangtu.

Salaku tambahan, kami mendakan yén pikeun profil beban sapertos kitu, agrégasi naon waé, nalika rékaman dikumpulkeun dina bets, jahat. Jahat klasik nyaéta INSERT ... VALUES sarta salajengna 1000 rékaman. Kusabab dina titik éta anjeun gaduh puncak nyerat dina média, sareng anu sanés nyobian nyerat hiji hal kana disk bakal ngantosan.

Pikeun ngaleungitkeun anomali sapertos kitu, kantun ulah ngahijikeun nanaon, ulah panyangga pisan. Tur upami buffering ka disk teu lumangsung (untungna, Stream API di Node.js ngidinan Anjeun pikeun manggihan) - nunda sambungan ieu. Sawaktos Anjeun nampa hiji acara éta bebas deui, nulis eta tina antrian akumulasi. Sarta bari éta sibuk, nyandak salajengna bebas tina kolam renang jeung nulis ka dinya.

Sateuacan ngenalkeun pendekatan ieu pikeun ngarékam data, kami ngagaduhan kirang langkung 4K ops nyerat, sareng ku cara ieu kami ngirangan beban ku 4 kali. Ayeuna aranjeunna parantos ningkat 6 kali deui kusabab database diawaskeun anyar - dugi ka 100MB / s. Sareng ayeuna urang nyimpen log salami 3 bulan terakhir dina volume sakitar 10-15TB, ngaharepkeun yén dina tilu bulan waé pamekar bakal tiasa ngabéréskeun masalah naon waé.

Urang ngarti masalah

Tapi ngan saukur ngumpulkeun sakabeh data ieu alus, mangpaat, relevan, tapi teu cukup - eta perlu dipikaharti. Kusabab ieu jutaan rencana béda per poé.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Tapi jutaan teu bisa diatur, urang kudu ngalakukeun "leutik". Sareng, mimitina, anjeun kedah mutuskeun kumaha anjeun bakal ngatur hal "leutik" ieu.

Kami geus ngaidentifikasi tilu titik konci:

  • saha dikirim pamundut ieu
    Nyaéta, tina aplikasi naon éta "sumping": antarmuka wéb, backend, sistem pamayaran atanapi anu sanés.
  • di mana eta kajadian
    Dina naon server husus? Kusabab upami anjeun ngagaduhan sababaraha server dina hiji aplikasi, sareng ujug-ujug hiji "bodoh" (sabab "disk rusak", "memori bocor", sababaraha masalah anu sanés), maka anjeun kedah khusus alamat server.
  • kumaha masalah manifested sorangan dina hiji atawa cara séjén

Pikeun ngartos "saha" anu ngirim pamundut ka kami, kami nganggo alat standar - netepkeun variabel sési: SET application_name = '{bl-host}:{bl-method}'; - kami ngirim nami host logika bisnis ti mana pamenta datang, sareng nami metode atanapi aplikasi anu ngamimitianana.

Saatos urang lulus "boga" pamundut, éta kedah kaluaran kana log - pikeun ieu urang ngonpigurasikeun variabel log_line_prefix = ' %m [%p:%v] [%d] %r %a'. Pikeun anu minat, meureun tingali dina manualnaon hartina kabeh. Tétéla urang ningali dina log:

  • время
  • prosés jeung identifiers transaksi
  • ngaran database
  • IP jalma anu ngirim pamundut ieu
  • jeung ngaran métode

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Teras we sadar yén teu pisan metot kasampak dina korelasi pikeun hiji pamundut antara server béda. Teu sering anjeun gaduh kaayaan dimana hiji aplikasi screws up sarua di ditu di dieu. Tapi sanajan éta sami, tingali salah sahiji server ieu.

Ku kituna di dieu éta motong "hiji server - hiji dinten" tétéla cukup keur urang pikeun analisis nanaon.

Bagian analitik munggaran sami "sampel" - wangun anu disingget tina presentasi rencana, diberesihan tina sagala indikator numeris. Potongan kadua nyaéta aplikasi atanapi metode, sareng potongan katilu nyaéta titik rencana khusus anu nyababkeun masalah urang.

Nalika urang ngalih tina instansi khusus ka témplat, urang ngagaduhan dua kauntungan sakaligus:

  • sababaraha réduksi dina jumlah objék pikeun analisis
    Urang kedah nganalisis masalah henteu deui ku rébuan patarosan atanapi rencana, tapi ku puluhan témplat.
  • garis waktu
    Nyaéta, ku nyimpulkeun "fakta" dina bagian anu tangtu, anjeun tiasa nampilkeun penampilanna salami siang. Sareng di dieu anjeun tiasa ngartos yén upami anjeun gaduh sababaraha jinis pola anu kajantenan, contona, sakali sajam, tapi kedah kajantenan sakali sadinten, anjeun kedah mikiran naon anu salah - saha anu nyababkeun éta sareng kunaon, panginten kedah aya di dieu. teu kedah. Ieu lain non-numerik, murni visual, métode analisis.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Métode sésana dumasar kana indikator anu urang nimba tina rencana: sabaraha kali pola sapertos kajantenan, total sareng rata-rata waktos, sabaraha data anu dibaca tina disk, sareng sabaraha tina mémori ...

Kusabab, contona, anjeun datang ka kaca analytics pikeun host, kasampak - hal anu dimimitian maca teuing dina disk. Disk dina server teu tiasa ngadamel - saha anu macana?

Sareng anjeun tiasa nyortir ku kolom naon waé sareng mutuskeun naon anu bakal anjeun urus ayeuna - beban dina prosésor atanapi disk, atanapi jumlah total pamundut... Kami nyortir éta, ningal anu "luhureun", ngalereskeunana sareng digulung kaluar versi anyar tina aplikasi.
[video ceramah]

Sarta geura-giru anjeun tiasa ningali aplikasi béda nu datangna kalawan template sarua ti pamundut kawas SELECT * FROM users WHERE login = 'Vasya'. Frontend, backend, processing... Sareng anjeun heran naha ngolah bakal maca pangguna upami anjeunna henteu berinteraksi sareng anjeunna.

Cara anu sabalikna nyaéta langsung ningali tina aplikasi naon anu dilakukeun. Contona, frontend ieu, ieu, ieu, jeung ieu sakali sajam (garis waktu mantuan). Sareng patarosan langsung timbul: sigana sanés padamelan frontend pikeun ngalakukeun hiji hal sajam sakali ...

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Sanggeus sababaraha waktu, urang sadar yen urang lacked aggregated statistik ku titik rencana. Urang terasing tina rencana ngan maranéhanana titik nu ngalakukeun hal kalawan data tabel sorangan (maca / nulis aranjeunna ku indéks atanapi henteu). Kanyataanna, ngan hiji aspék ditambahkeun relatif ka gambar saméméhna - Sabaraha catetan anu dibawa ku titik ieu ka urang?, jeung sabaraha anu dipiceun (Baris Dipiceun ku Filter).

Anjeun teu boga indéks cocog dina piring, anjeun nyieun pamundut ka dinya, flies kaliwat indéks dina, ragrag kana Seq Scan ... anjeun geus disaring kaluar kabeh rékaman iwal hiji. Naha anjeun peryogi 100M rékaman disaring per dinten? Naha henteu langkung saé ngagulung indéks?

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

Saatos nganalisa sadaya rencana titik ku titik, urang sadar yén aya sababaraha struktur has dina rencana anu sigana pisan curiga. Sareng langkung saé nyarioskeun ka pamekar: "Sobat, di dieu anjeun mimiti maca ku indéks, teras nyortir, teras dipotong" - sakumaha aturan, aya hiji catetan.

Saha waé anu nyerat patarosan sigana parantos mendakan pola ieu: "Pasihan abdi pesenan terakhir pikeun Vasya, tanggalna." Sareng upami anjeun henteu gaduh indéks dumasar tanggal, atanapi henteu aya tanggal dina indéks anu anjeun anggo, maka anjeun bakal napak dina persis sarua "rake" .

Tapi urang terang yén ieu mangrupikeun "rake" - janten naha henteu langsung nyarioskeun ka pamekar naon anu kedah dilakukeun. Sasuai, nalika muka rencana ayeuna, pamekar kami langsung ningali gambar anu saé kalayan tip, dimana aranjeunna langsung nyarios ka anjeunna: "Anjeun gaduh masalah di ditu di dieu, tapi aranjeunna direngsekeun ku cara ieu sareng éta."

Hasilna, jumlah pangalaman anu diperyogikeun pikeun ngarengsekeun masalah di awal sareng ayeuna parantos turun sacara signifikan. Ieu mangrupikeun jinis alat anu urang gaduh.

Optimasi bulk tina patarosan PostgreSQL. Kirill Borovikov (Tensor)

sumber: www.habr.com

Tambahkeun komentar