{"id":79467,"date":"2020-04-27T07:42:23","date_gmt":"2020-04-27T05:42:23","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres"},"modified":"2020-04-27T07:42:23","modified_gmt":"2020-04-27T05:42:23","slug":"operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres","title":{"rendered":"Operativna analitika u mikroservisnoj arhitekturi: pomo\u0107i i savjetovati Postgres FDW","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Mikroservisna arhitektura, kao i sve u ovom svijetu, ima svoje prednosti i mane. Neki procesi postaju lak\u0161i, dok drugi postaju slo\u017eeniji. U korist brzine promjena i bolje skalabilnosti, mora se praviti odre\u0111ene \u017ertve. Jedna od njih je kompliciranje analitike. Dok se u monolitu sva operativna analitika mo\u017ee svesti na SQL upite prema analiti\u010dkoj replici, u mikroservisnoj arhitekturi svaka usluga ima svoju bazu i \u010dini se da se jednim upitom ne mo\u017ee pro\u0107i (a mo\u017eda i mo\u017ee?). Za one koje zanima kako smo rije\u0161ili problem operativne analitike u na\u0161oj tvrtki i kako smo nau\u010dili \u017eivjeti s tim rje\u0161enjem \u2014 dobrodo\u0161li.<\/p>\n<p><img decoding=\"async\" alt=\"Operativna analitika u mikroservisnoj arhitekturi: pomo\u0107i i savjetovati Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/4296389f06d488999cc023dcaa3027f7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nZovem se Pavel Siva\u0161, u DomKlika radim u timu koji je zadu\u017een za odr\u017eavanje analiti\u010dkog skladi\u0161ta podataka. Na\u0161a aktivnost se mo\u017ee okarakterizirati kao in\u017eenjering podataka, ali zapravo, spektar zadatka je mnogo \u0161iri. Tu su standardni zadaci za in\u017eenjering podataka ETL\/ELT, podr\u0161ka i adaptacija alata za analizu podataka kao i razvoj vlastitih alata. Konkretno, za operativno izvje\u0161tavanje odlu\u010dili smo se pretvarati da imamo monolit i dati analiti\u010darima jednu bazu u kojoj \u0107e biti svi potrebni podaci. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Uglavnom smo razmatrali razne opcije. Mogli smo izgraditi potpuno skladi\u0161te \u2014 \u010dak smo to i poku\u0161ali, ali, da budem iskren, nismo uspjeli uskladiti dovoljno \u010deste promjene u logici s prili\u010dno sporim procesom izgradnje skladi\u0161ta i uno\u0161enja promjena (ako je nekome to uspjelo, neka javi u komentarima kako). Mogli smo re\u0107i analiti\u010darima: \u201eDe\u010dki, u\u010dite Python i idite u analiti\u010dke replike\u201c, ali to je dodatni zahtjev za zapo\u0161ljavanje, i \u010dinilo se da bi to trebalo izbje\u0107i, ako je mogu\u0107e. Odlu\u010dili smo poku\u0161ati koristiti tehnologiju FDW (Foreign Data Wrapper): u su\u0161tini, to je standardni dblink koji postoji u SQL standardu, ali s puno prikladnijim su\u010deljem. Na temelju nje napravili smo rje\u0161enje koje je na kraju opstalo, na njemu smo se zaustavili. Njegovi detalji su tema zasebnog \u010dlanka, a mo\u017eda i nekoliko njih, jer se \u017eeli pri\u010dati o mnogo\u010demu: od sinhronizacije shema baza do upravljanja pristupom i anonymizacije osobnih podataka. Tako\u0111er treba napomenuti da ovo rje\u0161enje nije zamjena za stvarne analiti\u010dke baze i skladi\u0161ta, ve\u0107 rje\u0161ava samo specifi\u010dan zadatak.<\/p>\n<p>Na visokoj razini, to izgleda ovako:<\/p>\n<p><img decoding=\"async\" alt=\"Operativna analitika u mikroservisnoj arhitekturi: pomo\u0107i i savjetovati Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/574da29dfdb40706afe9e817e789a61b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nPostoji baza podataka PostgreSQL, gdje korisnici mogu pohraniti svoje radne podatke, a najva\u017enije \u2014 toj bazi su putem FDW povezane analiti\u010dke replike svih servisa. To omogu\u0107uje pisanje upita na nekoliko baza, nezavisno od toga \u0161to one bile: PostgreSQL, MySQL, MongoDB ili ne\u0161to drugo (datoteka, API, ako slu\u010dajno nema odgovaraju\u0107eg wrappera, mo\u017eemo napisati vlastiti). Pa, izgleda super! Idemo se razi\u0107i?<\/p>\n<p>Da je sve zavr\u0161ilo tako brzo i jednostavno, vjerojatno ne bi bilo ni ovog \u010dlanka.<\/p>\n<p>Va\u017eno je jasno shvatiti kako PostgreSQL obra\u0111uje upite na udaljenim serverima. To se \u010dini logi\u010dnim, me\u0111utim, \u010desto se na to ne obra\u0107a pa\u017enja: PostgreSQL dijeli upit na dijelove koji se izvr\u0161avaju na udaljenim serverima neovisno, prikuplja te podatke, a kona\u010dne izra\u010dune vr\u0161i ve\u0107 sam, stoga \u0107e brzina izvr\u0161avanja upita uvelike ovisiti o tome kako je napisan. Tako\u0111er treba napomenuti: kada podaci dolaze s udaljenog servera, oni ve\u0107 nemaju indekse, nemaju ni\u0161ta \u0161to bi pomoglo planerima, stoga mo\u017eemo pomo\u0107i i uputiti ga samo mi sami. O tome bi \u017eeleo govoriti detaljnije.<\/p>\n<h1>Jednostavni upit i plan s njim<\/h1>\n<p>\nDa bismo pokazali kako PostgreSQL izvr\u0161ava upit na tablici s 6 milijuna redaka na udaljenom <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/hr\/server\/dts-dronten\/\"   title=\"serveru\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2589\">serveru<\/a>, pogledajmo jednostavan plan.<\/p>\n<pre><code class=\"sql\">obja\u0161njenje analiza detaljno  \nSELECT count(1)\nFROM fdw_schema.table;\n\nAgregat  (tro\u0161ak=418383.23..418383.24 redova=1 \u0161irina=8) (stvarno vreme=3857.198..3857.198 redova=1 petlje=1)\n  Izlaz: count(1)\n  -&gt;  Strano skeniranje na fdw_schema.&quot;table&quot;  (tro\u0161ak=100.00..402376.14 redova=6402838 \u0161irina=0) (stvarno vreme=4.874..3256.511 redova=6406868 petlje=1)\n        Izlaz: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Udaljeni SQL: SELECT NULL FROM fdw_schema.table\nVreme planiranja: 0.986 ms\nVreme izvr\u0161enja: 3857.436 ms<\/code><\/pre>\n<p>\nKori\u0161tenje upute VERBOSE omogu\u0107ava da se vidi upit koji \u0107e biti poslan na udaljeni poslu\u017eitelj i rezultati koje \u0107emo dobiti za daljnju obradu (linija RemoteSQL).<\/p>\n<p>Idemo malo dalje i dodajmo u na\u0161 upit nekoliko filtara: jedan po <b>boolean<\/b> polju, jedan po uklju\u010divanju <b>timestamp<\/b> u intervalu i jedan po <b>jsonb<\/b>.<\/p>\n<pre><code class=\"sql\">obja\u0161njenje analiza detaljno\nSELECT count(1)\nFROM fdw_schema.table \nWHERE is_active is True\nAND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' \nAND CURRENT_DATE - INTERVAL '6 month'\nAND meta-&gt;&gt;'source' = 'test';\n\nAgregat  (tro\u0161ak=577487.69..577487.70 redova=1 \u0161irina=8) (stvarno vreme=27473.818..25473.819 redova=1 petlje=1)\n  Izlaz: count(1)\n  -&gt;  Strano skeniranje na fdw_schema.&quot;table&quot;  (tro\u0161ak=100.00..577469.21 redova=7390 \u0161irina=0) (stvarno vreme=31.369..25372.466 redova=1360025 petlje=1)\n        Izlaz: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Filter: ((&quot;table&quot;.is_active IS TRUE) AND ((&quot;table&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) AND (&quot;table&quot;.created_dt &gt;= (('now'::cstring)::date - '7 mons'::interval)) AND (&quot;table&quot;.created_dt &lt;= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))\n        Redovi uklonjeni prema filteru: 5046843\n        Udaljeni SQL: SELECT created_dt, is_active, meta FROM fdw_schema.table\nVreme planiranja: 0.665 ms\nVreme izvr\u0161enja: 27474.118 ms<\/code><\/pre>\n<p>\nOvdje le\u017ei trenutak na koji treba obratiti pa\u017enju prilikom pisanja upita. Filtar se nije prenio na udaljeni poslu\u017eitelj, \u0161to zna\u010di da PostgreSQL mora izvu\u0107i svih 6 milijuna redaka kako bi ih kasnije lokalno filtrirao (linija Filter) i izvr\u0161io agregaciju. Klju\u010d uspjeha je pisanje upita tako da se filtri prenose na udaljeni stroj, a mi dobivamo i agregiramo samo potrebne retke. <\/p>\n<h1>To je neka vrlo nejasna stvar s bool vrijednostima<\/h1>\n<p>\nS boolean poljima - sve je jednostavno. U izvornoj upitu problem se javljao zbog operatora <b>is<\/b>. Ako ga zamijenimo s <b>=<\/b>, dobit \u0107emo sljede\u0107i rezultat:<\/p>\n<pre><code class=\"sql\">obja\u0161njenje analiza detaljno\nSELECT count(1)\nFROM fdw_schema.table\nWHERE is_active = True\nAND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' \nAND CURRENT_DATE - INTERVAL '6 month'\nAND meta-&gt;&gt;'source' = 'test';\n\nAgregat  (tro\u0161ak=508010.14..508010.15 redova=1 \u0161irina=8) (stvarno vreme=19064.314..19064.314 redova=1 petlje=1)\n  Izlaz: count(1)\n  -&gt;  Strano skeniranje na fdw_schema.&quot;table&quot;  (tro\u0161ak=100.00..507988.44 redova=8679 \u0161irina=0) (stvarno vreme=33.035..18951.278 redova=1360025 petlje=1)\n        Izlaz: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Filter: (((&quot;table&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) AND (&quot;table&quot;.created_dt &gt;= (('now'::cstring)::date - '7 mons'::interval)) AND (&quot;table&quot;.created_dt &lt;= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))\n        Redovi uklonjeni prema filteru: 3567989\n        Udaljeni SQL: SELECT created_dt, meta FROM fdw_schema.table WHERE (is_active)\nVreme planiranja: 0.834 ms\nVreme izvr\u0161enja: 19064.534 ms<\/code><\/pre>\n<p>\nKao \u0161to vidite, filtriranje se prebacilo na udaljeni server, a vrijeme izvo\u0111enja se smanjilo sa 27 na 19 sekundi. <\/p>\n<p>Va\u017eno je napomenuti da se operator <b>is<\/b> razlikuje od operatora <b>=<\/b> time \u0161to mo\u017ee raditi s vrijedno\u0161\u0107u Null. To zna\u010di da <b>is not True<\/b> u filtrima ostavlja vrijednosti False i Null, dok <b>!= True<\/b> ostavlja samo vrijednosti False. Stoga, prilikom zamjene operatora <b>is not<\/b> treba u filtrima proslijediti dva uvjeta s operatorom OR, na primjer, <b>WHERE (col != True) OR (col is null)<\/b>.<\/p>\n<p>S boolean vrijednostima smo rije\u0161ili, idemo dalje. A za sada vra\u0107amo filter po boolean vrijednosti u prvobitno stanje kako bismo samostalno razmotrili utjecaj drugih promjena.<\/p>\n<h1>timestamptz? hz<\/h1>\n<p>\n\u010cesto je potrebno eksperimentirati s pisanjem upita koji uklju\u010duju udaljene poslu\u017eitelje i tek nakon toga tra\u017eiti obja\u0161njenja za\u0161to se to\u010dno doga\u0111a to \u0161to se doga\u0111a. Na internetu se mo\u017ee prona\u0107i vrlo malo informacija o tome. U eksperimentima smo otkrili da filter prema fiksnom datumu bez problema ide na udaljeni poslu\u017eitelj, dok kada dinami\u010dki postavljamo datum, poput now() ili CURRENT_DATE, to se ne doga\u0111a. U na\u0161em primjeru dodali smo takav filter kako bi stupac created_at sadr\u017eavao podatke za to\u010dno jedan mjesec u pro\u0161losti (BETWEEN CURRENT_DATE - INTERVAL '7 month' AND CURRENT_DATE - INTERVAL '6 month'). \u0160to smo u\u010dinili u ovom slu\u010daju?<\/p>\n<pre><code class=\"sql\">objasni analiziraj detaljno\nSELECT count(1)\nFROM fdw_schema.table \nWHERE is_active is True\nAND created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 mjeseci') \nAND created_dt &gt;'source' = 'test';\n\nAgregacija  (tro\u0161ak=306875.17..306875.18 redova=1 \u0161irina=8) (stvarno vrijeme=4789.114..4789.115 redova=1 petlje=1)\n  Izlaz: count(1)\n  InitPlan 1 (vra\u0107a $0)\n    -&gt;  Rezultat  (tro\u0161ak=0.00..0.02 redova=1 \u0161irina=8) (stvarno vrijeme=0.007..0.008 redova=1 petlje=1)\n          Izlaz: ((('sada'::cstring)::datum)::timestamp with time zone - '7 mj.'::interval)\n  InitPlan 2 (vra\u0107a $1)\n    -&gt;  Rezultat  (tro\u0161ak=0.00..0.02 redova=1 \u0161irina=8) (stvarno vrijeme=0.002..0.002 redova=1 petlje=1)\n          Izlaz: ((('sada'::cstring)::datum)::timestamp with time zone - '6 mj.'::interval)\n  -&gt;  Strani pregled na fdw_schema.\"table\"  (tro\u0161ak=100.02..306874.86 redova=105 \u0161irina=0) (stvarno vrijeme=23.475..4681.419 redova=1360025 petlje=1)\n        Izlaz: \"table\".id, \"table\".is_active, \"table\".meta, \"table\".created_dt\n        Filtriraj: ((\"table\".is_active IS TRUE) AND ((\"table\".meta -&gt;&gt; 'source'::text) = 'test'::text))\n        Redovi uklonjeni filtriranjem: 76934\n        Daljinski SQL: SELECT is_active, meta FROM fdw_schema.table WHERE ((created_dt &gt;= $1::timestamp with time zone)) AND ((created_dt &lt; $2::timestamp with time zone))\nVrijeme planiranja: 0.703 ms\nVrijeme izvr\u0161avanja: 4789.379 ms<\/code><\/pre>\n<p>\nUpravo smo savjetovali planerima da unaprijed izra\u010dunaju datum u podupitu i prenesu ve\u0107 pripremljenu varijablu u filtar. I taj savjet dao nam je odli\u010dan rezultat, upit je postao br\u017ei gotovo 6 puta!<\/p>\n<p>Opet, ovdje je va\u017eno biti pa\u017eljiv: tip podataka u podupitu mora biti identi\u010dan onom polju po kojem filtriramo, ina\u010de planer odlu\u010duje da su tipovi razli\u010diti i da je prvo potrebno izvu\u0107i sve podatke, a zatim ih lokalno filtrirati.<\/p>\n<p>Vratimo filtar po datumu na izvorno stanje.<\/p>\n<h1>Freddy protiv Jsonb<\/h1>\n<p>\nU su\u0161tini, bool polja i datumi su ve\u0107 dovoljno ubrzali na\u0161 upit, me\u0111utim, ostao je jo\u0161 jedan tip podataka. Borba s filtriranjem po njemu, iskreno, jo\u0161 uvijek nije zavr\u0161ena, premda su tu zabilje\u017eeni odre\u0111eni uspjesi. Dakle, ovako smo uspjeli prenijeti filtar po <b>jsonb<\/b> polju na udaljeni server.<\/p>\n<pre><code class=\"sql\">objasni analiziraj detaljno\nSELECT count(1)\nFROM fdw_schema.table \nWHERE is_active is True\nAND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 mjeseci' \nAND CURRENT_DATE - INTERVAL '6 mjeseci'\nAND meta @&gt; '{\"source\":\"test\"}'::jsonb;\n\nAgregacija  (tro\u0161ak=245463.60..245463.61 redova=1 \u0161irina=8) (stvarno vrijeme=6727.589..6727.590 redova=1 petlje=1)\n  Izlaz: count(1)\n  -&gt;  Strani pregled na fdw_schema.\"table\"  (tro\u0161ak=1100.00..245459.90 redova=1478 \u0161irina=0) (stvarno vrijeme=16.213..6634.794 redova=1360025 petlje=1)\n        Izlaz: \"table\".id, \"table\".is_active, \"table\".meta, \"table\".created_dt\n        Filtriraj: ((\"table\".is_active IS TRUE) AND (\"table\".created_dt &gt;= (('sada'::cstring)::datum - '7 mj.'::interval)) AND (\"table\".created_dt  '{\"source\": \"test\"}'::jsonb))\nVrijeme planiranja: 0.747 ms\nVrijeme izvr\u0161avanja: 6727.815 ms<\/code><\/pre>\n<p>\nUmjesto operatora filtriranja, potrebno je koristiti operator prisutnosti jednog <b>jsonb<\/b> u drugom. 7 sekundi umjesto izvornih 29. Ovo je za sada jedini uspje\u0161an na\u010din prijenosa filtera po <b>jsonb<\/b> na udaljeni server, ali ovdje je va\u017eno uzeti u obzir jednu ograni\u010denja: koristimo verziju baze 9.6, me\u0111utim do kraja travnja planiramo zavr\u0161iti posljednje testove i pre\u0107i na verziju 12. Kada se a\u017euriramo, javit \u0107emo kako je to utjecalo, jer promjena ima mnogo na koje se ra\u010duna: json_path, novo pona\u0161anje CTE, push down (postoje\u0107i od verzije 10). Stvarno \u017eelim \u0161to prije isprobati.<\/p>\n<h1>Finish him<\/h1>\n<p>\nProvjerili smo kako svaka promjena utje\u010de na brzinu upita zasebno. Sada pogledajmo \u0161to \u0107e se dogoditi kada budu sva tri filtera ispravno napisana.<\/p>\n<pre><code class=\"sql\">objasni analiziraj detaljno\nSELECT count(1)\nFROM fdw_schema.table \nWHERE is_active = True\nAND created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 mjeseci') \nAND created_dt  '{\"source\":\"test\"}'::jsonb;\n\nAgregat  (cijena=322041.51..322041.52 redaka=1 \u0161irina=8) (stvarno vrijeme=2278.867..2278.867 redaka=1 petlje=1)\n  Izlaz: count(1)\n  InitPlan 1 (vra\u0107a $0)\n    -&gt;  Rezultat  (cijena=0.00..0.02 redaka=1 \u0161irina=8) (stvarno vrijeme=0.010..0.010 redaka=1 petlje=1)\n          Izlaz: ((('sada'::cstring)::date)::timestamp with time zone - '7 mj'::interval)\n  InitPlan 2 (vra\u0107a $1)\n    -&gt;  Rezultat  (cijena=0.00..0.02 redaka=1 \u0161irina=8) (stvarno vrijeme=0.003..0.003 redaka=1 petlje=1)\n          Izlaz: ((('sada'::cstring)::date)::timestamp with time zone - '6 mj'::interval)\n  -&gt;  Strano skeniranje na fdw_schema.\"table\"  (cijena=100.02..322041.41 redaka=25 \u0161irina=0) (stvarno vrijeme=8.597..2153.809 redaka=1360025 petlje=1)\n        Izlaz: \"table\".id, \"table\".is_active, \"table\".meta, \"table\".created_dt\n        Udaljeni SQL: SELECT NULL FROM fdw_schema.table WHERE (is_active) AND ((created_dt &gt;= $1::timestamp with time zone)) AND ((created_dt  '{\"source\": \"test\"}'::jsonb))\nVrijeme planiranja: 0.820 ms\nVrijeme izvr\u0161enja: 2279.087 ms<\/code><\/pre>\n<p>\nDa, upit izgleda slo\u017eenije, to je nu\u017ena cijena, ali brzina izvr\u0161enja iznosi 2 sekunde, \u0161to je vi\u0161e od 10 puta br\u017ee! I to govorimo o jednostavnom upitu prema relativno malom skupu podataka. Na stvarnim upitima dobivali smo pobolj\u0161anje do nekoliko stotina puta.<\/p>\n<p>Zaklju\u010dimo: ako koristite PostgreSQL s FDW, uvijek provjerite \u0161aljete li svi filteri na udaljeni server, i bit \u0107e vam sre\u0107e\u2026 barem dok ne do\u0111ete do spojeva izme\u0111u tablica iz razli\u010ditih <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/hr\/server\/\"   title=\"poslu\u017eitelja\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1482\">poslu\u017eitelja<\/a>. No to je ve\u0107 pri\u010da za jo\u0161 jedan \u010dlanak.<\/p>\n<p>Hvala na pa\u017enji! Bit \u0107u sretan \u010duti pitanja, komentare, kao i pri\u010de o va\u0161em iskustvu u komentarima.<br \/>\n<br \/>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/498018\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0438\u0440\u0435, \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u0441\u0432\u043e\u0438 \u043c\u0438\u043d\u0443\u0441\u044b. \u041e\u0434\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0441 \u043d\u0435\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043f\u0440\u043e\u0449\u0435, \u0434\u0440\u0443\u0433\u0438\u0435 \u2014 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0418 \u0432 \u0443\u0433\u043e\u0434\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438 \u043b\u0443\u0447\u0448\u0435\u0439 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u043e\u0441\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u0436\u0435\u0440\u0442\u0432\u044b. \u041e\u0434\u043d\u0430 \u0438\u0437 \u043d\u0438\u0445 \u2014 \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438. \u0415\u0441\u043b\u0438 \u0432 \u043c\u043e\u043d\u043e\u043b\u0438\u0442\u0435 \u0432\u0441\u044e \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0432\u0435\u0441\u0442\u0438 \u043a SQL \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u043a \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0440\u0435\u043f\u043b\u0438\u043a\u0435, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":79468,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-79467","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0438\u0440\u0435, \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u0441\u0432\u043e\u0438 \u043c\u0438\u043d\u0443\u0441\u044b. \u041e\u0434\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0441 \u043d\u0435\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043f\u0440\u043e\u0449\u0435, \u0434\u0440\u0443\u0433\u0438\u0435 \u2014 \u0441\u043b\u043e\u0436\u043d\u0435\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u0432 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435: \u043f\u0336\u043e\u0336\u043d\u0336\u044f\u0336\u0442\u0336\u044c\u0336 \u0336\u0438\u0336 \u0336\u043f\u0336\u0440\u0336\u043e\u0336\u0441\u0336\u0442\u0336\u0438\u0336\u0442\u0336\u044c\u0336 \u043f\u043e\u043c\u043e\u0447\u044c \u0438 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u044c Postgres FDW | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0438\u0440\u0435, \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u0441\u0432\u043e\u0438 \u043c\u0438\u043d\u0443\u0441\u044b. \u041e\u0434\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0441 \u043d\u0435\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043f\u0440\u043e\u0449\u0435, \u0434\u0440\u0443\u0433\u0438\u0435 \u2014 \u0441\u043b\u043e\u0436\u043d\u0435\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-04-27T05:42:23+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-04-27T05:42:23+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Operativna analitika u mikroservisnoj arhitekturi: pomo\u0107i i savjetovati Postgres FDW | ProHoster","description":"Mikroservisna arhitektura, kao i sve u ovom svijetu, ima svoje prednosti i nedostatke. Neki procesi postaju jednostavniji, dok drugi postaju slo\u017eeniji.","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u0432 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435: \u043f\u0336\u043e\u0336\u043d\u0336\u044f\u0336\u0442\u0336\u044c\u0336 \u0336\u0438\u0336 \u0336\u043f\u0336\u0440\u0336\u043e\u0336\u0441\u0336\u0442\u0336\u0438\u0336\u0442\u0336\u044c\u0336 \u043f\u043e\u043c\u043e\u0447\u044c \u0438 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u044c Postgres FDW | ProHoster","og:description":"\u041c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430, \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u0432 \u044d\u0442\u043e\u043c \u043c\u0438\u0440\u0435, \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u043f\u043b\u044e\u0441\u044b \u0438 \u0441\u0432\u043e\u0438 \u043c\u0438\u043d\u0443\u0441\u044b. \u041e\u0434\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0441 \u043d\u0435\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043f\u0440\u043e\u0449\u0435, \u0434\u0440\u0443\u0433\u0438\u0435 \u2014 \u0441\u043b\u043e\u0436\u043d\u0435\u0435.","og:url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/operativnaya-analitika-v-mikroservisnoj-arhitekture-p%cc%b6o%cc%b6n%cc%b6ya%cc%b6t%cc%b6%cc%b6-%cc%b6i%cc%b6-%cc%b6p%cc%b6r%cc%b6o%cc%b6s%cc%b6t%cc%b6i%cc%b6t%cc%b6%cc%b6-pomoch-i-podskazat-postgres","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-04-27T05:42:23+00:00","article:modified_time":"2020-04-27T05:42:23+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"79467","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:37:24","updated":"2026-02-09 21:38:01","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/79467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=79467"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/79467\/revisions"}],"predecessor-version":[{"id":159871,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/79467\/revisions\/159871"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/79468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=79467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=79467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=79467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}