Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

De Rapport presentéiert e puer Approche déi et erlaben Monitor d'Leeschtung vun SQL Ufroen wann et Millioune vun hinnen pro Dag sinn, an et ginn Honnerte vu iwwerwaachte PostgreSQL Serveren.

Wéi eng technesch Léisungen erlaben eis esou e Volumen vun Informatioun effizient ze veraarbechten, a wéi mécht dat d'Liewen vun engem gewéinlechen Entwéckler méi einfach?


Wien ass interesséiert? Analyse vu spezifesche Probleemer a verschidde Optimisatiounstechniken SQL Ufroen a léisen typesch DBA Probleemer am PostgreSQL - Dir kënnt och liesen eng Serie vun Artikelen zu dësem Thema.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)
Mäin Numm ass Kirill Borovikov, ech representéieren Tensor Firma. Konkret sinn ech spezialiséiert op d'Aarbecht mat Datenbanken an eiser Firma.

Haut wäert ech Iech soen wéi mir Ufroen optimiséieren, wann Dir d'Performance vun enger eenzeger Ufro net "austauschen" braucht, awer de Problem masseg léisen. Wann et Millioune Ufroe sinn, an Dir musst e puer fannen Approche zu der Léisung dëse grousse Problem.

Am Allgemengen, Tensor fir eng Millioun vun eise Clienten ass VLSI ass eis Applikatioun: Firmensozial Netzwierk, Léisunge fir Videokommunikatioun, fir internen an externen Dokumentfloss, Comptabilitéitssystemer fir Comptabilitéit a Lager, ... Dat heescht, sou eng "Mega-Kombinatioun" fir integréiert Geschäftsmanagement, an där et méi wéi 100 verschidde sinn intern Projeten.

Fir datt se all normal funktionnéieren an entwéckelen, hu mir 10 Entwécklungszenteren am ganze Land, mat méi dran 1000 Entwéckler.

Mir schaffen zënter 2008 mat PostgreSQL an hunn eng grouss Quantitéit vun deem gesammelt wat mir veraarbechten - Clientdaten, statistesch, analytesch, Daten aus externen Informatiounssystemer - méi wéi 400TB. Et gi ongeféier 250 Serveren eleng an der Produktioun, an am Ganzen sinn et ongeféier 1000 Datebankserver déi mir iwwerwaachen.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

SQL ass eng deklarativ Sprooch. Dir beschreift net "wéi" eppes soll funktionnéieren, mee "wat" Dir wëllt erreechen. D'DBMS weess besser wéi een e JOIN mécht - wéi Dir Är Dëscher verbënnt, wéi eng Bedéngungen ze imposéieren, wat duerch den Index geet, wat net ...

E puer DBMSs akzeptéieren Hiweiser: "Nee, verbënnt dës zwee Dëscher an esou an esou enger Schlaang", awer PostgreSQL kann dat net maachen. Dëst ass déi bewosst Positioun vu féierende Entwéckler: "Mir léiwer de Query Optimizer fäerdeg maachen wéi d'Entwéckler eng Aart vun Hiweiser ze benotzen."

Awer, trotz der Tatsaach, datt PostgreSQL net erlaabt datt de "ausserhalb" sech selwer kontrolléiert, et erlaabt et perfekt kuckt wat an him lass asswann Dir Är Ufro lafen, a wou et Problemer huet.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Am Allgemengen, wat klassesch Problemer en Entwéckler [zu engem DBA] normalerweis kommen mat? "Hei hu mir d'Demande erfëllt, an bei eis geet alles lues, alles hängt, eppes geschitt... Eng Zort Ierger!

D'Grënn si bal ëmmer déiselwecht:

  • ineffizienten Ufro Algorithmus
    Entwéckler: "Elo ginn ech him 10 Dëscher an SQL iwwer JOIN ..." - an erwaart datt seng Konditioune wonnerbar effektiv "untiéiert" ginn an hien alles séier kritt. Awer Wonner geschéien net, an all System mat esou Verännerlechkeet (10 Dëscher an engem FROM) gëtt ëmmer eng Zort Feeler. [en Artikel]
  • irrelevant Statistiken
    Dëse Punkt ass ganz relevant speziell fir PostgreSQL, wann Dir e grousst Datesaz op de Server "gegoss" hutt, eng Ufro maacht, an et "sexcanits" Ären Tablet. Well gëschter waren et 10 records dran, an haut sinn et der 10 Milliounen, mee PostgreSQL ass nach net bewosst vun dëser, a mir mussen et doriwwer soen. [en Artikel]
  • "Plug" op Ressourcen
    Dir hutt eng grouss a schwéier gelueden Datebank op engem schwaache Server installéiert, deen net genuch Disk, Erënnerung oder Prozessor Leeschtung huet. An dat ass alles ... Iergendwou gëtt et eng Leeschtungsplafong iwwer déi Dir net méi sprange kënnt.
  • blockéieren
    Dëst ass e schwéiere Punkt, awer si sinn am meeschte relevant fir verschidde Ännerungsufroen (INSERT, UPDATE, DELETE) - dëst ass en separat grousst Thema.

Kréien e Plang

... A fir alles anescht mir brauch e Plang! Mir musse kucken wat am Server geschitt.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

E Ufro Ausféierungsplang fir PostgreSQL ass e Bam vum Ufro Ausféierung Algorithmus an der Textrepresentatioun. Et ass genee den Algorithmus, deen, als Resultat vun der Analyse vum Planer, am effektivsten fonnt gouf.

All Bam Node ass eng Operatioun: Daten aus enger Tabell oder Index zréckzéien, e Bitmap bauen, zwee Dëscher verbannen, verbannen, intersectéieren oder Selektiounen ausschléissen. Eng Ufro auszeféieren involvéiert duerch d'Node vun dësem Bam ze goen.

Fir den Ufroplang ze kréien, ass deen einfachste Wee fir d'Ausso auszeféieren EXPLAIN. Fir mat all realen Attributer ze kréien, dat ass, fir tatsächlech eng Ufro op der Basis auszeféieren - EXPLAIN (ANALYZE, BUFFERS) SELECT ....

De schlechten Deel: wann Dir et leeft, geschitt et "hei an elo", also ass et nëmme gëeegent fir lokal Debugging. Wann Dir en héich gelueden Server hëlt deen ënner engem staarke Flux vun Daten Ännerungen ass, an Dir gesitt: "Oh! Hei hu mir eng lues Ausféierungся Demande." Eng hallef Stonn, virun enger Stonn - wärend Dir laaft an dës Ufro aus de Logbicher kritt hutt, se zréck op de Server bruecht huet, ass Är ganz Dataset a Statistiken geännert. Dir leeft et fir ze Debuggen - an et leeft séier! An Dir kënnt net verstoen firwat, firwat war lues.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Fir ze verstoen wat genau geschitt ass am Moment wou d'Ufro um Server ausgefouert gouf, hunn intelligent Leit geschriwwen auto_explain Modul. Et ass präsent a bal all de meeschte verbreet PostgreSQL Verdeelungen, a kann einfach an der Configuratiounsdatei aktivéiert ginn.

Wann et mierkt datt eng Ufro méi laang leeft wéi d'Limite, déi Dir gesot hutt, mécht et "Snapshot" vum Plang vun dëser Ufro a schreift se zesummen am Logbuch.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Elo schéngt alles gutt ze sinn, mir ginn op de Logbicher a gesinn do ... [Textfußduch]. Awer mir kënnen näischt doriwwer soen, ausser d'Tatsaach datt et en exzellente Plang ass well et 11ms gedauert huet fir auszeféieren.

Alles schéngt gutt ze sinn - awer näischt ass kloer wat tatsächlech geschitt ass. Ofgesi vun der allgemenger Zäit gesi mir näischt wierklech. Well sou e "Lämmchen" vu Kloertext kucken ass allgemeng net visuell.

Awer och wann et net offensichtlech ass, och wann et onbequem ass, ginn et méi fundamental Problemer:

  • Den Node weist Zomm vun Ressourcen vun der ganzer subtree ënnert him. Dat ass, Dir kënnt net just erausfannen wéi vill Zäit un dësem speziellen Index Scan verbruecht gouf, wann et e geneteschen Zoustand ass. Mir mussen dynamesch kucken fir ze kucken ob et "Kanner" a bedingungsvariablen, CTEs dobannen sinn - an dat alles "an eisem Kapp" ​​subtrahéieren.
  • Zweete Punkt: d'Zäit déi um Node uginn ass ass eenzeg Node Ausféierung Zäit. Wann dësen Node ausgefouert gouf, zum Beispill, eng Loop duerch Tabelle records e puer Mol, da klëmmt d'Zuel vun de Loopen - Zyklen vun dësem Node - am Plang. Awer déi atomar Ausféierungszäit selwer bleift d'selwecht a punkto Plang. Dat ass, fir ze verstoen wéi laang dësen Node am Ganzen duerchgefouert gouf, musst Dir eng Saach mat engem aneren multiplizéieren - erëm "an Ärem Kapp."

An esou Situatiounen, verstitt "Wien ass de schwaachste Link?" bal onméiglech. Dofir schreiwen och d'Entwéckler selwer am "Handbuch" dat "E Plang verstoen ass eng Konscht déi muss geléiert ginn, Erfahrung ...".

Mä mir hunn 1000 Entwéckler, an Dir kënnt dës Erfahrung net jiddereng vun hinnen vermëttelen. Ech, Dir, hie weess, awer een do weess net méi. Vläicht wäert hien léieren, oder vläicht net, awer hien muss elo schaffen - a wou géif hien dës Erfahrung kréien?

Plan Visualiséierung

Dofir hu mir gemierkt datt fir dës Problemer ze këmmeren, mir brauchen gutt Visualiséierung vum Plang. [Artikel]

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Mir sinn als éischt "duerch de Maart" gaang - loosst eis um Internet kucken fir ze kucken wat iwwerhaapt existéiert.

Awer et huet sech erausgestallt datt et ganz wéineg relativ "live" Léisunge sinn, déi méi oder manner entwéckelen - wuertwiertlech nëmmen eng: erkläert.depesz.com vum Hubert Lubaczewski. Wann Dir am Feld "Feed" eng Textrepresentatioun vum Plang gitt, weist et Iech eng Tabell mat de parséierten Donnéeën:

  • Node seng eege Veraarbechtungszäit
  • Gesamtzäit fir de ganze Subtree
  • Zuel vun Opzeechnungen, déi erëmfonnt goufen, déi statistesch erwaart goufen
  • den Node Kierper selwer

Dëse Service huet och d'Fäegkeet en Archiv vu Linken ze deelen. Dir hutt Äre Plang dohinner gehäit a sot: "Hey, Vasya, hei ass e Link, do ass eppes falsch."

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Mä et ginn och kleng Problemer.

Als éischt eng grouss Quantitéit un "Copy-Paste". Dir huelt e Stéck vum Logbicher, stécht et do dran, an erëm, an erëm.

Zweetens, keng Analyse vun der Quantitéit vun Daten liesen - déiselwecht Puffer déi erausginn EXPLAIN (ANALYZE, BUFFERS), mir gesinn et net hei. Hien weess einfach net wéi se ze disassemble, se verstoen a mat hinnen schaffen. Wann Dir vill Daten liest a feststellt datt Dir d'Disk an d'Erënnerungscache falsch verdeelt, ass dës Informatioun ganz wichteg.

Den drëtten negativen Punkt ass déi ganz schwaach Entwécklung vun dësem Projet. D'Verpflichtungen si ganz kleng, et ass gutt wann eemol all sechs Méint, an de Code ass an Perl.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Awer dëst ass alles "Texter", mir kéinten iergendwéi domat liewen, awer et ass eng Saach déi eis staark vun dësem Service ewechgehäit huet. Dëst si Feeler an der Analyse vum Common Table Expression (CTE) a verschidde dynamesch Wirbelen wéi InitPlan / SubPlan.

Wann Dir dëst Bild gleeft, dann ass d'total Ausféierungszäit vun all eenzelen Node méi grouss wéi d'total Ausféierungszäit vun der ganzer Ufro. Et ass einfach - d'Generatiounszäit vun dësem CTE gouf net vum CTE Scan Node subtrahéiert. Dofir wësse mir net méi déi richteg Äntwert op wéi laang den CTE Scan selwer gedauert huet.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Dunn hu mer gemierkt datt et Zäit war fir eis eegen ze schreiwen - hurra! All Entwéckler seet: "Elo schreiwen mir eis eegen, et wäert super einfach sinn!"

Mir hunn e Stack typesch fir Web Servicer geholl: e Kär baséiert op Node.js + Express, benotzt Bootstrap an D3.js fir schéin Diagrammer. An eis Erwaardunge ware voll gerechtfäerdegt - mir kruten den éischte Prototyp an 2 Wochen:

  • Benotzerdefinéiert Plang Parser
    Dat ass, elo kënne mir all Plang parse vun deenen generéiert vu PostgreSQL.
  • korrekt Analyse vun dynamesche Wirbelen - CTE Scan, InitPlan, SubPlan
  • Analyse vun Puffer Verdeelung - wou Daten Säiten aus Erënnerung gelies ginn, wou aus dem lokal Cache, wou aus Scheif
  • krut Kloerheet
    Fir dëst net alles am Logbuch ze "graven", mee direkt de "schwaachste Link" am Bild ze gesinn.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Mir hunn eppes wéi dëst, mat Syntax Highlight abegraff. Mee normalerweis schaffen eis Entwéckler net méi mat enger kompletter Representatioun vum Plang, mee mat enger méi kuerzer. Nodeems mir all d'Zuelen schonns parséiert hunn an se lénks a riets geworf hunn, an an der Mëtt hu mir nëmmen déi éischt Zeil verlooss, wéi eng Node et ass: CTE Scan, CTE Generatioun oder Seq Scan no engem Zeechen.

Dëst ass déi verkierzte Representatioun déi mir nennen Plang Schabloun.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Wat wier soss bequem? Et wier bequem ze gesinn wéi en Undeel vun eiser Gesamtzäit un wéi engem Node zougewisen ass - a just op d'Säit "stech" Punkteplang.

Mir weisen op den Node a gesinn - et stellt sech eraus datt de Seq Scan manner wéi e Véierel vun der Gesamtzäit gedauert huet, an déi reschtlech 3/4 gouf vum CTE Scan geholl. Horror! Dëst ass eng kleng Notiz iwwer den "Feuerrate" vum CTE Scan wann Dir se aktiv an Ären Ufroen benotzt. Si sinn net ganz séier - si sinn ënnergeuerdnet och fir regelméisseg Dësch Scannen. [Artikel] [Artikel]

Awer normalerweis sinn esou Diagrammer méi interessant, méi komplex, wa mir direkt op e Segment weisen a gesinn, zum Beispill, datt méi wéi d'Halschent vun der Zäit e puer Seq Scan "giess". Ausserdeem war et eng Zort Filter dobannen, vill Opzeechnunge goufen no deem verworf ... Dir kënnt dëst Bild direkt un den Entwéckler werfen a soen: "Vasya, alles ass schlecht hei fir Iech! Fannt et eraus, kuckt - eppes ass falsch!"

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Natierlech waren et e puer "Rakes" involvéiert.

Dat éischt wat mir begéint sinn, war de Problem vun der Ronn. D'Zäit vun all eenzelen Node am Plang gëtt mat enger Genauegkeet vun 1 μs uginn. A wann d'Zuel vun den Node-Zyklen iwwerschreift, zum Beispill, 1000 - no der Ausféierung PostgreSQL gedeelt "bannent Genauegkeet", da kréie mir d'Gesamtzäit "irgendwo tëscht 0.95ms an 1.05ms". Wann d'Zuel op Mikrosekonne geet, ass dat an der Rei, awer wann et scho [Milli] Sekonnen ass, musst Dir dës Informatioun berücksichtegen wann Dir Ressourcen un d'Node vum "Wien verbraucht huet wéi vill" Plang "entloossen".

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Den zweete Punkt, méi komplex, ass d'Verdeelung vu Ressourcen (déi Puffer) ënner dynamesche Wirbelen. Dat kascht eis déi éischt 2 Woche vum Prototyp plus nach 4 Wochen.

Et ass zimmlech einfach dës Zort vu Problem ze kréien - mir maachen en CTE a liesen vermeintlech eppes dran. Tatsächlech ass PostgreSQL "schlau" a wäert näischt direkt do liesen. Dann huele mer den éischte Rekord dovunner, an dozou den honnert an éischten aus deemselwechten CTE.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Mir kucken de Plang a verstinn - et ass komesch, mir hunn 3 Puffer (Datesäiten) "verbraucht" am Seq Scan, 1 méi am CTE Scan, an 2 méi am zweeten CTE Scan. Dat ass, wa mir alles einfach zesummefaassen, kréie mir 6, awer vum Tablet liesen mir nëmmen 3! CTE Scan liest näischt vun iwwerall, awer schafft direkt mam Prozess Memory. Dat heescht, hei ass kloer eppes falsch!

Tatsächlech stellt sech eraus, datt hei all déi 3 Säiten mat Daten sinn, déi vum Seq Scan ugefrot goufen, fir d'éischt 1 gefrot fir den 1. CTE Scan, an dann den 2., an 2 weider goufen him gelies, dat heescht, insgesamt 3 Säite goufen gelies Daten, net 6.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

An dëst Bild huet eis zum Verständnis gefouert datt d'Ausféierung vun engem Plang net méi e Bam ass, awer einfach eng Aart azyklesch Grafik. A mir hunn en Diagramm wéi dëst, sou datt mir verstoen "wat vu wou an der éischter Plaz koum." Dat heescht, hei hu mir en CTE aus pg_class erstallt, an zweemol gefrot, a bal all eis Zäit ass un der Branche verbruecht, wéi mer et déi 2. Kéier gefrot hunn. Et ass kloer datt d'Liesen vum 101. Entrée vill méi deier ass wéi just den 1. Entrée vum Tablet ze liesen.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Mir hunn eng Zäitchen ausgeotemt. Si soten: "Elo, Neo, Dir wësst Kung Fu! Elo ass eis Erfahrung direkt op Ärem Écran. Elo kënnt Dir et benotzen." [Artikel]

Log Konsolidéierung

Eis 1000 Entwéckler hunn eng Erliichterung opgehuewen. Awer mir hu verstanen datt mir nëmmen Honnerte vu "Kampf" Serveren hunn, an all dës "Copy-Paste" vun den Entwéckler ass guer net bequem. Mir hu gemierkt datt mir et selwer mussen sammelen.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Am Allgemengen gëtt et e Standardmodul deen Statistike sammele kann, awer et muss och an der Configuratioun aktivéiert ginn - dëst pg_stat_statements module. Awer hien huet eis net gepasst.

Als éischt gëtt et déiselwecht Ufroe mat verschiddene Schemaen an der selwechter Datebank zougewisen verschidde QueryIds. Dat ass, wann Dir éischt maachen SET search_path = '01'; SELECT * FROM user LIMIT 1;an dann SET search_path = '02'; an déi selwecht Ufro, da wäert d'Statistiken vun dësem Modul verschidden records hunn, an ech wäert net fäheg sinn allgemeng Statistiken speziell am Kader vun dëser Ufro Profil ze sammelen, ouni Rechnung huelen de Schemaen.

Den zweete Punkt deen eis verhënnert huet et ze benotzen ass Mangel u Pläng. Dat ass, et gëtt kee Plang, et gëtt nëmmen d'Demande selwer. Mir gesinn wat verlangsamt gouf, awer mir verstinn net firwat. An hei komme mer zréck op de Problem vun engem séier verännerende Datesaz.

An de leschte Moment - Mangel u "Fakten". Dat ass, Dir kënnt net eng spezifesch Instanz vun der Ufroausféierung adresséieren - et gëtt keng, et gëtt nëmmen aggregéiert Statistiken. Och wann et méiglech ass mat dësem ze schaffen, ass et just ganz schwéier.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Dofir hu mir décidéiert fir Copy-Paste ze kämpfen an ugefaang ze schreiwen Sammler.

De Sammler verbënnt iwwer SSH, stellt eng sécher Verbindung zum Server mat der Datebank mat engem Zertifikat, an tail -F "klemmt" drop an der Logdatei. Also an dëser Sëtzung mir kréien e komplette "Spigel" vun der ganzer Logdatei, deen de Server generéiert. D'Laascht op de Server selwer ass minimal, well mir do näischt parséieren, mir spigelen just de Traffic.

Well mir schonn ugefaang hunn den Interface an Node.js ze schreiwen, hu mir weider de Sammler dra geschriwwen. An dës Technologie huet sech gerechtfäerdegt, well et ganz bequem ass JavaScript ze benotzen fir mat schwaach formatéierten Textdaten ze schaffen, wat de Log ass. An d'Node.js Infrastruktur selwer als Backend Plattform erlaabt Iech einfach a bequem mat Netzwierkverbindungen ze schaffen, an zwar mat all Datenstroum.

Deementspriechend "strecken" mir zwee Verbindungen: déi éischt fir de Logbuch selwer ze "lauschteren" an eis selwer ze huelen, an déi zweet fir periodesch d'Basis ze froen. "Awer de Log weist datt d'Schëld mat OID 123 blockéiert ass," awer dëst heescht näischt fir den Entwéckler, an et wier flott d'Datebank ze froen: "Wat ass OID = 123 iwwerhaapt?" An dofir froe mir periodesch d'Basis wat mir nach net iwwer eis selwer wëssen.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

"Et gëtt nëmmen eng Saach, déi Dir net berücksichtegt hutt, et gëtt eng Aart vun Elefantähnleche Bienen! .." Mir hunn ugefaang dëse System z'entwéckelen, wéi mir 10 Serveren iwwerwaache wollten. Déi kriteschst an eisem Verständnis, wou e puer Problemer entstane sinn, déi schwéier ze këmmeren waren. Awer am éischte Véierel hu mir honnert fir d'Iwwerwaachung kritt - well de System funktionnéiert, jidderee wollt et, jidderee war bequem.

All dëst muss derbäigesat ginn, den Datefloss ass grouss an aktiv. Tatsächlech, wat mir iwwerwaachen, wat mir kënne beschäftegen, ass dat wat mir benotzen. Mir benotzen och PostgreSQL als Datelagerung. An näischt ass méi séier fir Daten dran ze "goen" wéi de Bedreiwer COPY Nach net.

Awer einfach Daten "goen" ass net wierklech eis Technologie. Well wann Dir ongeféier 50k Ufroen pro Sekonn op honnert Serveren hutt, da generéiert dëst 100-150GB Logbicher pro Dag. Dofir hu mir d'Basis suergfälteg "geschnidden".

Als éischt hu mir dat gemaach Dag opgedeelt, well iwwerhaapt keen un der Korrelatioun tëscht Deeg interesséiert ass. Wat fir en Ënnerscheed mécht dat wat Dir gëschter hat, wann Dir haut den Owend eng nei Versioun vun der Applikatioun ausgerullt hutt - a schonn e puer nei Statistiken.

Zweetens hu mir geléiert (gezwongen) ganz, ganz séier ze schreiwen benotzt COPY. Dat ass, net nëmmen COPYwell hien ass méi séier wéi INSERT, an nach méi séier.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Den drëtte Punkt - ech hu missen Ausléiser opginn, respektiv, an auslännesch Schlësselen. Dat heescht, mir hu guer keng referenziell Integritéit. Well wann Dir en Dësch hutt, deen e Paar FKs huet, an Dir seet an der Datebankstruktur datt "hei ass e Logbuch, dee vum FK referenzéiert gëtt, zum Beispill, op eng Grupp vun Opzeechnungen", dann, wann Dir se asetzt, PostgreSQL huet näischt méi wéi wéi et ze huelen an et éierlech ze maachen SELECT 1 FROM master_fk1_table WHERE ... mam Identifizéierer deen Dir probéiert anzeginn - just fir ze kontrolléieren ob dëse Rekord do ass, datt Dir dësen Auslännerschlëssel net mat Ärer Aféierung "ofbriechen".

Amplaz vun engem Rekord op d'Ziltabelle a seng Indizes, kréie mir den zousätzleche Virdeel vum Liesen vun all den Dëscher op déi se bezitt. Awer mir brauchen dat guer net - eis Aufgab ass sou vill wéi méiglech a sou séier wéi méiglech mat der mannst Belaaschtung opzehuelen. Also FK - erof!

Den nächste Punkt ass Aggregatioun an Hashing. Am Ufank hu mir se an der Datebank ëmgesat - schliisslech ass et praktesch direkt, wann e Rekord kënnt, et an enger Aart Tablet ze maachen "plus een" direkt am Ausléiser. Gutt, et ass bequem, awer déiselwecht schlecht Saach - Dir setzt ee Rekord un, awer sidd gezwongen eppes anescht aus engem aneren Dësch ze liesen an ze schreiwen. Ausserdeem liest a schreift Dir net nëmmen, Dir maacht et och all Kéier.

Stellt Iech elo vir datt Dir en Dësch hutt an deem Dir einfach d'Zuel vun den Ufroen zielt, déi duerch e spezifesche Host passéiert sinn: +1, +1, +1, ..., +1. An Dir, am Prinzip, braucht dëst net - et ass alles méiglech Zomm an Erënnerung op de Sammler a schéckt op d'Datebank an engem goen +10.

Jo, am Fall vun e puer Probleemer, kann Är logesch Integritéit "auserneen falen", awer dëst ass e bal onrealistesche Fall - well Dir en normale Server hutt, et huet eng Batterie am Controller, Dir hutt en Transaktiounsprotokoll, e Log op der Dateisystem ... Am Allgemengen ass et net wäert. De Verloscht vun der Produktivitéit, déi Dir kritt vu Lafen Ausléiser / FK ass d'Käschte net wäert, déi Dir maacht.

Et ass d'selwecht mat Hashing. Eng gewëssen Ufro flitt op Iech, Dir berechent e bestëmmten Identifizéierer dovun aus an der Datebank, schreift se an d'Datebank a sot et dann jidderengem. Alles ass gutt bis zum Zäitpunkt vun der Opnam eng zweet Persoun bei Iech kënnt, déi datselwecht wëll ophuelen - an Dir sidd blockéiert, an dat ass scho schlecht. Dofir, wann Dir d'Generatioun vun e puer IDen un de Client transferéiere kënnt (relativ zu der Datebank), ass et besser dëst ze maachen.

Et war just perfekt fir eis MD5 aus dem Text ze benotzen - Ufro, Plang, Schabloun, ... Mir berechent et op der Sammlersäit, a "pour" déi fäerdeg ID an d'Datebank. D'Längt vun MD5 an deeglech Partitioning erlaben eis keng Suergen iwwer méiglech Kollisiounen.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Awer fir dat alles séier opzehuelen, musse mir d'Opnamprozedur selwer änneren.

Wéi schreift Dir normalerweis Daten? Mir hunn eng Zort Dataset, mir hunn et an e puer Dëscher opgedeelt, an dann COPY et - als éischt an déi éischt, dann an déi zweet, an déi drëtt ... Et ass onbequem, well mir schéngen een Datestroum an dräi Schrëtt ze schreiwen sequenziell. désagréabel. Kann et méi séier gemaach ginn? Kann!

Fir dëst ze maachen, ass et genuch just dës Flëss parallel mateneen ze zerstéieren. Et stellt sech eraus datt mir Feeler, Ufroen, Templates, Blockéierungen, ... an getrennten Threads fléien - a mir schreiwen alles parallel. Genuch fir dëst halen e COPY Kanal permanent oppen fir all eenzel Zil Dësch.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Dat heescht, beim Sammler et gëtt ëmmer e Stroum, an déi ech déi néideg Donnéeën schreiwen kann. Awer fir datt d'Datebank dës Donnéeën gesäit, an iergendeen net festhält fir op dës Donnéeën ze schreiwen, COPY muss a bestëmmten Intervalle ënnerbrach ginn. Fir eis war déi effektivste Period ongeféier 100ms - mir maachen et zou an oppen et direkt erëm op dee selwechten Dësch. A wa mir net genuch vun engem Flow während e puer Peaks hunn, da maache mir Pooling bis zu enger gewësser Limit.

Zousätzlech hu mir erausfonnt datt fir sou e Laaschtprofil all Aggregatioun, wann Rekorder a Chargen gesammelt ginn, béis ass. Klassesch Béisen ass INSERT ... VALUES a weider 1000 records. Well zu deem Zäitpunkt hutt Dir e Schreifpeak op de Medien, an all déi aner probéieren eppes op d'Disk ze schreiwen waarden.

Fir vun esou Anomalien lass ze ginn, aggregéiert einfach näischt, guer net puffer. A wann Puffer op Disk geschitt (glécklecherweis erlaabt de Stream API an Node.js Iech erauszefannen) - post dës Verbindung of. Wann Dir en Event kritt datt et erëm gratis ass, schreift et aus der cumuléierter Schlaang. A wann et beschäftegt ass, huelt déi nächst fräi aus dem Pool a schreift et.

Ier Dir dës Approche fir d'Datenopnam agefouert huet, hu mir ongeféier 4K Schreifops, an op dës Manéier hu mir d'Laascht ëm 4 Mol reduzéiert. Elo sinn se weider 6 Mol gewuess wéinst neie iwwerwaachte Datenbanken - bis zu 100MB / s. An elo späichere mir Logbicher fir déi lescht 3 Méint an engem Volume vun ongeféier 10-15TB, an der Hoffnung datt an nëmmen dräi Méint all Entwéckler fäeg sinn all Problem ze léisen.

Mir verstinn d'Problemer

Awer einfach all dës Donnéeën ze sammelen ass gutt, nëtzlech, relevant, awer net genuch - et muss verstane ginn. Well dëst sinn Millioune vu verschiddene Pläng pro Dag.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Awer Millioune sinn onmanéierbar, mir musse fir d'éischt "méi kleng" maachen. An, als éischt, musst Dir entscheeden wéi Dir dës "méi kleng" Saach organiséiert.

Mir hunn dräi Schlësselpunkte identifizéiert:

  • wien ass geschéckt dëser Demande
    Dat ass, vu wéi enger Applikatioun ass et "ukomm": Webinterface, Backend, Bezuelsystem oder soss eppes.
  • wou et ass geschitt
    Op wéi engem spezifesche Server? Well wann Dir e puer Serveren ënner enger Applikatioun hutt, an op eemol gëtt een "domm" (well de "Disk ass verrotten", "Erënnerung geleckt", en anere Problem), da musst Dir de Server speziell ugoen.
  • wéi de Problem huet sech op déi eng oder aner Manéier manifestéiert

Fir ze verstoen "wien" eis eng Ufro geschéckt huet, benotze mir e Standardinstrument - eng Sessiounsvariabel astellen: SET application_name = '{bl-host}:{bl-method}'; - Mir schécken den Numm vum Geschäftslogikhost, aus deem d'Ufro kënnt, an den Numm vun der Method oder der Applikatioun déi et initiéiert huet.

Nodeems mir de "Besëtzer" vun der Ufro passéiert hunn, muss et an de Logbuch erausginn - dofir konfiguréiere mir d'Variabel log_line_prefix = ' %m [%p:%v] [%d] %r %a'. Wien ass egal, vläicht kuckt am Handbuchwat heescht dat alles. Et stellt sech eraus datt mir am Logbuch gesinn:

  • время
  • Prozess- an Transaktiounsidentifizéierer
  • Datebank Numm
  • IP vun der Persoun déi dës Ufro geschéckt huet
  • an Method Numm

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Dunn hu mir gemierkt datt et net ganz interessant ass d'Korrelatioun fir eng Ufro tëscht verschiddene Serveren ze kucken. Et ass net dacks datt Dir eng Situatioun hutt wou eng Applikatioun hei an do gläich schrauwen. Awer och wann et d'selwecht ass, kuckt op eng vun dësen Serveren.

Also hei ass de Schnëtt "een Server - een Dag" et huet eis duergestallt fir all Analyse.

Déi éischt analytesch Sektioun ass déiselwecht "Probe" - eng verkierzte Form vun der Presentatioun vum Plang, geläscht vun all numereschen Indikatoren. Den zweeten Schnëtt ass d'Applikatioun oder d'Method, an den drëtten Schnëtt ass de spezifesche Plangknuet deen eis Probleemer verursaacht huet.

Wa mir vu spezifeschen Instanzen op Template geplënnert sinn, hu mir zwee Virdeeler gläichzäiteg:

  • Multiple Reduktioun vun der Unzuel vun Objekter fir Analyse
    Mir mussen de Problem analyséieren net méi duerch Dausende vu Ufroen oder Pläng, mee duerch Dosende vu Templates.
  • Zäitlinn
    Dat ass, andeems Dir d'"Fakten" an enger bestëmmter Rubrik resuméiert, kënnt Dir hir Erscheinung am Dag weisen. An hei kënnt Dir verstoen datt wann Dir e Muster hutt, dat geschitt, zum Beispill eemol d'Stonn, awer et sollt eemol am Dag geschéien, Dir sollt iwwerdenken wat falsch gaang ass - wien et verursaacht huet a firwat, vläicht sollt et hei sinn soll net. Dëst ass eng aner net-numeresch, reng visuell Method vun der Analyse.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Déi reschtlech Methoden baséieren op den Indikatoren, déi mir aus dem Plang extrahéieren: wéivill Mol esou e Muster geschitt ass, d'Gesamtzäit an d'Duerchschnëttszäit, wéi vill Daten aus der Disk gelies goufen a wéi vill aus der Erënnerung ...

Well, zum Beispill, Dir kommt op d'Analytik Säit fir den Host, kuckt - eppes fänkt ze vill op der Disk ze liesen. Den Disk um Server kann et net handhaben - wien liest dovun?

An Dir kënnt no all Kolonn zortéieren an entscheeden wat Dir grad elo beschäftegt - d'Laascht op de Prozessor oder d'Disk, oder d'total Unzuel vun Ufroen ... Mir hunn et zortéiert, déi "Top" gekuckt, fixéiert an eng nei Versioun vun der Applikatioun ausgerullt.
[Video Virtrag]

An direkt kënnt Dir verschidden Uwendungen gesinn, déi mat der selwechter Schabloun kommen aus enger Ufro wéi SELECT * FROM users WHERE login = 'Vasya'. Frontend, Backend, Veraarbechtung ... An Dir frot Iech firwat d'Veraarbechtung de Benotzer liest wann hien net mat him interagéiert.

De Géigendeel ass direkt vun der Applikatioun ze gesinn wat se mécht. Zum Beispill, de Frontend ass dëst, dëst, dëst, an dëst eemol d'Stonn (d'Timeline hëlleft). An d'Fro stellt sech direkt: et schéngt wéi wann et net d'Aarbecht vum Frontend ass eemol d'Stonn eppes ze maachen ...

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

No enger Zäit hu mir gemierkt datt et mir feelen aggregéiert Statistiken duerch Plannoden. Mir isoléiert aus de Pläng nëmmen déi Noden déi eppes mat den Daten vun den Dëscher selwer maachen (liesen / schreiwen se duerch Index oder net). Tatsächlech gëtt nëmmen een Aspekt par rapport zu der viregter Bild bäigefüügt - wéivill records huet dësen Node eis bruecht?, a wéi vill goufen verworf (Reihen geläscht duerch Filter).

Dir hutt net e passenden Index op der Plack, Dir maacht eng Ufro un, et flitt laanscht den Index, fällt an de Seq Scan ... Dir hutt all d'Records ausser ee gefiltert. Firwat braucht Dir 100M gefilterte records pro Dag? Ass et net besser den Index opzerollen?

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Nodeems mir all Pläng Node no Node analyséiert hunn, hu mir gemierkt datt et e puer typesch Strukturen an de Pläng sinn déi ganz wahrscheinlech verdächteg ausgesinn. An et wier flott dem Entwéckler ze soen: "Frënd, hei liest Dir als éischt duerch Index, dann sortéiert, an dann ofgeschnidden" - als Regel, gëtt et e Rekord.

Jiddereen, deen Ufroen geschriwwen huet, huet wahrscheinlech dëst Muster begéint: "Gitt mir déi lescht Bestellung fir Vasya, säin Datum." A wann Dir keen Index no Datum hutt, oder et ass keen Datum am Index deen Dir benotzt hutt, da wäert Dir Schrëtt op genee déi selwecht "Rake" .

Awer mir wëssen datt dëst e "Rake" ass - also firwat net direkt dem Entwéckler soen wat hie soll maachen. Deementspriechend, wann Dir e Plang elo opmaacht, gesäit eisen Entwéckler direkt e schéint Bild mat Tipps, wou se him direkt soen: "Dir hutt Problemer hei an do, awer se sinn esou an esou geléist."

Als Resultat ass d'Quantitéit un Erfahrung déi gebraucht gouf fir Problemer am Ufank ze léisen an elo däitlech erofgaang. Dëst ass d'Zort vun Tool déi mir hunn.

Bulk Optimiséierung vu PostgreSQL Ufroen. Kirill Borovikow (Tensor)

Source: will.com

Setzt e Commentaire