{"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\/it\/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":"Analisi operativa nell'architettura a microservizi: p\u0336o\u0336n\u0336ya\u0336t\u0336e\u0336 \u0336e\u0336 \u0336p\u0336r\u0336o\u0336s\u0336t\u0336i\u0336t\u0336e\u0336 aiutare e consigliare Postgres FDW","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>L'architettura a microservizi, come tutto nel mondo, ha i suoi pro e i suoi contro. Alcuni processi diventano pi\u00f9 semplici, altri pi\u00f9 complessi. E a favore della velocit\u00e0 dei cambiamenti e di una migliore scalabilit\u00e0, bisogna fare dei sacrifici. Uno di questi \u00e8 la complicazione dell'analisi. Se nel monolite tutta l'analisi operativa pu\u00f2 essere ridotta a query SQL su una replica analitica, nell'architettura a pi\u00f9 servizi ogni servizio ha il proprio database e sembra che una sola query non sia sufficiente (o forse lo \u00e8?). Per coloro che sono interessati a sapere come abbiamo risolto il problema dell'analisi operativa nella nostra azienda e come abbiamo imparato a convivere con questa soluzione \u2014 benvenuti.<\/p>\n<p><img decoding=\"async\" alt=\"Analisi operativa nell&#039;architettura a microservizi: p\u0336o\u0336n\u0336ya\u0336t\u0336e\u0336 \u0336e\u0336 \u0336p\u0336r\u0336o\u0336s\u0336t\u0336i\u0336t\u0336e\u0336 aiutare e consigliare Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/4296389f06d488999cc023dcaa3027f7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMi chiamo Pavel Sivash, in DomClick lavoro nel team che si occupa della gestione del data warehouse analitico. In un certo senso, la nostra attivit\u00e0 pu\u00f2 essere considerata ingegneria dei dati, ma in realt\u00e0, l'intera gamma di compiti \u00e8 molto pi\u00f9 ampia. Ci sono attivit\u00e0 standard per l'ingegneria dei dati come ETL\/ELT, supporto e adattamento degli strumenti per l'analisi dei dati e sviluppo dei nostri strumenti. In particolare, per la reportistica operativa abbiamo deciso di \"fingere\" di avere un monolite e di fornire agli analisti un'unica base in cui ci siano tutti i dati necessari. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>In generale, abbiamo considerato diverse opzioni. Si poteva costruire un deposito completo \u2014 abbiamo anche provato, ma, a essere sincero, non siamo riusciti a sincronizzare le frequenti modifiche nella logica con il processo piuttosto lento di costruzione del deposito e di implementazione delle modifiche (se qualcuno ci \u00e8 riuscito, scrivete nei commenti come). Avremmo potuto dire agli analisti: \u00abRagazzi, imparate Python e lavorate con le repliche analitiche\u00bb, ma si sarebbe trattato di una richiesta aggiuntiva nel reclutamento, e sembrava utile evitarla se possibile. Abbiamo deciso di provare a utilizzare la tecnologia FDW (Foreign Data Wrapper): in sostanza, \u00e8 un dblink standard che esiste nello standard SQL, ma con un'interfaccia molto pi\u00f9 comoda. Su questa base, abbiamo creato una soluzione che \u00e8 stata alla fine accettata, e su cui ci siamo fermati. I dettagli di questa soluzione sono il tema di un articolo separato, e forse anche di pi\u00f9 di uno, poich\u00e9 ci sono molte cose da raccontare: dalla sincronizzazione degli schemi delle basi all'amministrazione degli accessi e all'anonimizzazione dei dati personali. \u00c8 importante notare che questa soluzione non \u00e8 un sostituto delle reali basi analitiche e dei depositi, ma risolve solo un compito specifico.<\/p>\n<p>A un alto livello, appare cos\u00ec:<\/p>\n<p><img decoding=\"async\" alt=\"Analisi operativa nell&#039;architettura a microservizi: p\u0336o\u0336n\u0336ya\u0336t\u0336e\u0336 \u0336e\u0336 \u0336p\u0336r\u0336o\u0336s\u0336t\u0336i\u0336t\u0336e\u0336 aiutare e consigliare Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/574da29dfdb40706afe9e817e789a61b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nC'\u00e8 un database PostgreSQL, dove gli utenti possono memorizzare i propri dati di lavoro, e la cosa pi\u00f9 importante \u00e8 che a questo database sono collegate tramite FDW le repliche analitiche di tutti i servizi. Questo consente di scrivere una query su pi\u00f9 basi, indipendentemente dal fatto che siano: PostgreSQL, MySQL, MongoDB o altro (file, API, e se non c'\u00e8 un wrapper adatto, \u00e8 possibile scrivere il proprio). Bene, tutto qui, fantastico! Possiamo andare?<\/p>\n<p>Se tutto finisse cos\u00ec in fretta e facilmente, probabilmente non ci sarebbe nemmeno un articolo.<\/p>\n<p>\u00c8 importante comprendere chiaramente come PostgreSQL gestisce le query ai server remoti. Questo sembra logico, ma spesso non viene prestata attenzione: PostgreSQL divide la query in parti che vengono eseguite sui server remoti in modo indipendente, raccoglie questi dati e quindi esegue i calcoli finali, quindi la velocit\u00e0 di esecuzione della query dipender\u00e0 molto da come \u00e8 scritta. Va anche notato: quando i dati provengono da un server remoto, non hanno pi\u00f9 indici, non c'\u00e8 nulla che possa aiutare il pianificatore, quindi possiamo solo aiutare e suggerire a lui stessi. E proprio su questo vorrei parlare pi\u00f9 dettagliatamente.<\/p>\n<h1>Richiesta semplice e piano associato<\/h1>\n<p>\nPer dimostrare come PostgreSQL esegue una richiesta su una tabella di 6 milioni di righe su un server remoto <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/it\/server\/dts-dronten\/\"   title=\"server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2589\">server<\/a>, diamo un'occhiata a un piano semplice.<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente  \nSELEZIONA count(1)\nDA fdw_schema.table;\n\nAggregato  (costo=418383.23..418383.24 righe=1 larghezza=8) (tempo effettivo=3857.198..3857.198 righe=1 cicli=1)\n  Uscita: count(1)\n  -&gt;  Scansione remota su fdw_schema.&quot;table&quot;  (costo=100.00..402376.14 righe=6402838 larghezza=0) (tempo effettivo=4.874..3256.511 righe=6406868 cicli=1)\n        Uscita: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        SQL remoto: SELEZIONA NULL DA fdw_schema.table\nTempo di pianificazione: 0.986 ms\nTempo di esecuzione: 3857.436 ms<\/code><\/pre>\n<p>\nL'uso dell'istruzione VERBOSE permette di vedere la richiesta che sar\u00e0 inviata al server remoto e i risultati che riceveremo per ulteriori elaborazioni (riga RemoteSQL).<\/p>\n<p>Andiamo un po' oltre e aggiungiamo al nostro query alcuni filtri: uno per <b>campo<\/b> il campo, uno per la presenza <b>timestamp<\/b> in un intervallo e uno per <b>jsonb<\/b>.<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONA count(1)\nDA fdw_schema.table \nDOVE is_active \u00e8 Vero\nE created_dt TRA CURRENT_DATE - INTERVALLO '7 mesi' \nE CURRENT_DATE - INTERVALLO '6 mesi'\nE meta-&gt;&gt;'source' = 'test';\n\nAggregato  (costo=577487.69..577487.70 righe=1 larghezza=8) (tempo effettivo=27473.818..25473.819 righe=1 cicli=1)\n  Uscita: count(1)\n  -&gt;  Scansione remota su fdw_schema.&quot;table&quot;  (costo=100.00..577469.21 righe=7390 larghezza=0) (tempo effettivo=31.369..25372.466 righe=1360025 cicli=1)\n        Uscita: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Filtri: ((&quot;table&quot;.is_active \u00c8 VERO) E ((&quot;table&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) E (&quot;table&quot;.created_dt &gt;= (('now'::cstring)::data - '7 mesi'::intervallo)) E (&quot;table&quot;.created_dt &lt;= ((('now'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)))\n        Rigore rimossi dal filtro: 5046843\n        SQL remoto: SELEZIONA created_dt, is_active, meta DA fdw_schema.table\nTempo di pianificazione: 0.665 ms\nTempo di esecuzione: 27474.118 ms<\/code><\/pre>\n<p>\n\u00c8 proprio qui che risiede il punto su cui \u00e8 necessario prestare attenzione quando si scrivono le query. I filtri non sono stati trasferiti al server remoto, il che significa che PostgreSQL deve estrarre tutte e 6 milioni di righe per filtrare localmente (riga Filter) e quindi aggregare. La chiave del successo \u00e8 scrivere la query in modo tale che i filtri vengano passati alla macchina remota, cos\u00ec otteniamo e aggregiamo solo le righe di interesse. <\/p>\n<h1>\u00c8 davvero una booleansciocchezza<\/h1>\n<p>\nCon i campi booleani \u00e8 tutto semplice. Nel query originale, il problema si presentava a causa dell'operatore <b>is<\/b>. Se lo sostituiamo con <b>=<\/b>, otterremo il seguente risultato:<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONA count(1)\nDA fdw_schema.table\nDOVE is_active = Vero\nE created_dt TRA CURRENT_DATE - INTERVALLO '7 mesi' \nE CURRENT_DATE - INTERVALLO '6 mesi'\nE meta-&gt;&gt;'source' = 'test';\n\nAggregato  (costo=508010.14..508010.15 righe=1 larghezza=8) (tempo effettivo=19064.314..19064.314 righe=1 cicli=1)\n  Uscita: count(1)\n  -&gt;  Scansione remota su fdw_schema.&quot;table&quot;  (costo=100.00..507988.44 righe=8679 larghezza=0) (tempo effettivo=33.035..18951.278 righe=1360025 cicli=1)\n        Uscita: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Filtri: (((&quot;table&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) E (&quot;table&quot;.created_dt &gt;= (('now'::cstring)::data - '7 mesi'::intervallo)) E (&quot;table&quot;.created_dt &lt;= ((('now'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)))\n        Rigore rimossi dal filtro: 3567989\n        SQL remoto: SELEZIONA created_dt, meta DA fdw_schema.table DOVE (is_active)\nTempo di pianificazione: 0.834 ms\nTempo di esecuzione: 19064.534 ms<\/code><\/pre>\n<p>\nCome puoi vedere, il filtro \u00e8 andato sul server remoto, e il tempo di esecuzione \u00e8 diminuito da 27 a 19 secondi. <\/p>\n<p>Vale la pena notare che l'operatore <b>is<\/b> \u00e8 diverso dall'operatore <b>=<\/b> nel senso che pu\u00f2 lavorare con il valore Null. Ci\u00f2 significa che <b>is not True<\/b> nel filtro lascer\u00e0 valori False e Null, mentre <b>!= True<\/b> lascer\u00e0 solo valori False. Pertanto, quando si sostituisce l'operatore <b>is not<\/b> dovrebbero essere passate nel filtro due condizioni con l'operatore OR, per esempio, <b>DOVE (col != True) O (col \u00e8 null)<\/b>.<\/p>\n<p>Abbiamo chiarito il booleano, proseguiamo. Forse rimettiamo il filtro sul valore booleano nella sua forma originale, per esaminare indipendentemente l'effetto di altre modifiche.<\/p>\n<h1>timestamptz? hz<\/h1>\n<p>\nIn effetti, spesso \u00e8 necessario sperimentare su come scrivere correttamente una query con server remoti, e poi cercare spiegazioni sul perch\u00e9 succede proprio cos\u00ec. Ci sono poche informazioni all'argomento disponibili su Internet. Cos\u00ec, nei nostri esperimenti, abbiamo scoperto che il filtro su date fisse viene gestito senza problemi sul server remoto, mentre quando vogliamo impostare la data in modo dinamico, ad esempio, using now() o CURRENT_DATE, non funziona in questo modo. Nel nostro esempio, abbiamo aggiunto un filtro per far s\u00ec che la colonna created_at contenesse dati esattamente per il mese scorso (TRA CURRENT_DATE - INTERVALLO '7 mesi' E CURRENT_DATE - INTERVALLO '6 mesi'). Cosa abbiamo fatto in questo caso?<\/p>\n<pre><code class=\"sql\">spiegare analizzare in modo verbose\nSELEZIONA count(1)\nDA fdw_schema.table \nDOVE is_active \u00e8 Vero\nE created_dt &gt;= (SELEZIONA CURRENT_DATE::timestamptz - INTERVAL '7 mesi') \nE created_dt &gt;'source' = 'test';\n\nAggregato (costo=306875.17..306875.18 righe=1 larghezza=8) (tempo effettivo=4789.114..4789.115 righe=1 cicli=1)\n  Output: count(1)\n  InitPlan 1 (restituisce $0)\n    -&gt; Risultato (costo=0.00..0.02 righe=1 larghezza=8) (tempo effettivo=0.007..0.008 righe=1 cicli=1)\n          Output: ((('ora'::cstring)::data)::timestamp con fuso orario - '7 mesi'::intervallo)\n  InitPlan 2 (restituisce $1)\n    -&gt; Risultato (costo=0.00..0.02 righe=1 larghezza=8) (tempo effettivo=0.002..0.002 righe=1 cicli=1)\n          Output: ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)\n  -&gt; Scansione esterna su fdw_schema.\"table\" (costo=100.02..306874.86 righe=105 larghezza=0) (tempo effettivo=23.475..4681.419 righe=1360025 cicli=1)\n        Output: \"table\".id, \"table\".is_active, \"table\".meta, \"table\".created_dt\n        Filtro: ((\"table\".is_active \u00c8 VERO) E ((\"table\".meta -&gt;&gt; 'source'::testo) = 'test'::testo))\n        Righe rimosse dal filtro: 76934\n        SQL remoto: SELEZIONA is_active, meta DA fdw_schema.table DOVE ((created_dt &gt;= $1::timestamp con fuso orario)) E ((created_dt &lt; $2::timestamp con fuso orario))\nTempo di pianificazione: 0.703 ms\nTempo di esecuzione: 4789.379 ms<\/code><\/pre>\n<p>\nAbbiamo suggerito al pianificatore di calcolare in anticipo la data nella sottoquery e di trasmettere la variabile gi\u00e0 pronta nel filtro. E questo suggerimento ci ha dato un ottimo risultato, la query \u00e8 diventata quasi sei volte pi\u00f9 veloce!<\/p>\n<p>Ancora una volta, \u00e8 importante prestare attenzione: il tipo di dati nella sottoquery deve essere lo stesso di quello del campo su cui filtriamo, altrimenti il pianificatore decider\u00e0 che, poich\u00e9 i tipi sono diversi, \u00e8 necessario prima estrarre tutti i dati e poi filtrare localmente.<\/p>\n<p>Riportiamo il filtro sulla data al valore originale.<\/p>\n<h1>Freddy contro Jsonb<\/h1>\n<p>\nIn effetti, i campi booleani e le date hanno gi\u00e0 accelerato abbastanza la nostra query, tuttavia c'era ancora un altro tipo di dato. La battaglia con la filtrazione su di esso, onestamente, non \u00e8 ancora finita, anche se qui ci sono stati progressi. Quindi, ecco come siamo riusciti a trasmettere il filtro per <b>jsonb<\/b> il campo al server remoto.<\/p>\n<pre><code class=\"sql\">spiegare analizzare in modo verbose\nSELEZIONA count(1)\nDA fdw_schema.table \nDOVE is_active \u00e8 Vero\nE created_dt TRA CURRENT_DATE - INTERVAL '7 mesi' \nE CURRENT_DATE - INTERVAL '6 mesi'\nE meta @&gt; '{\"source\":\"test\"}'::jsonb;\n\nAggregato (costo=245463.60..245463.61 righe=1 larghezza=8) (tempo effettivo=6727.589..6727.590 righe=1 cicli=1)\n  Output: count(1)\n  -&gt; Scansione esterna su fdw_schema.\"table\" (costo=1100.00..245459.90 righe=1478 larghezza=0) (tempo effettivo=16.213..6634.794 righe=1360025 cicli=1)\n        Output: \"table\".id, \"table\".is_active, \"table\".meta, \"table\".created_dt\n        Filtro: ((\"table\".is_active \u00c8 VERO) E (\"table\".created_dt &gt;= (('ora'::cstring)::data - '7 mesi'::intervallo)) E (\"table\".created_dt  '{\"source\": \"test\"}'::jsonb))\nTempo di pianificazione: 0.747 ms\nTempo di esecuzione: 6727.815 ms<\/code><\/pre>\n<p>\nInvece degli operatori di filtraggio \u00e8 necessario utilizzare l'operatore di esistenza <b>jsonb<\/b> in un altro. 7 secondi invece dei 29 originali. Finora \u00e8 l'unica opzione di successo per la trasmissione dei filtri <b>jsonb<\/b> su un server remoto, ma qui \u00e8 importante tener conto di una limitazione: stiamo utilizzando la versione del database 9.6, tuttavia entro la fine di aprile pianifichiamo di completare gli ultimi test e passare alla versione 12. Una volta aggiornati, scriveremo come questo ha influito, poich\u00e9 ci sono molte modifiche attese: json_path, un nuovo comportamento CTE, push down (che esiste dalla versione 10). Non vediamo l'ora di provare.<\/p>\n<h1>Finish him<\/h1>\n<p>\nAbbiamo verificato come ogni modifica influisce sulla velocit\u00e0 della query singolarmente. Adesso vediamo cosa succede quando tutti e tre i filtri sono scritti correttamente.<\/p>\n<pre><code class=\"sql\">spiega analizza dettagliatamente\nSELEZIONA count(1)\nDA fdw_schema.tabella \nDOVE is_active = Vero\nE created_dt &gt;= (SELEZIONA CURRENT_DATE::timestamptz - INTERVAL '7 mesi') \nE created_dt  '{\"source\":\"test\"}'::jsonb;\n\nAggregato  (costo=322041.51..322041.52 righe=1 larghezza=8) (tempo reale=2278.867..2278.867 righe=1 cicli=1)\n  Uscita: count(1)\n  InitPlan 1 (restituisce $0)\n    -&gt;  Risultato  (costo=0.00..0.02 righe=1 larghezza=8) (tempo reale=0.010..0.010 righe=1 cicli=1)\n          Uscita: ((('ora'::cstring)::data)::timestamp con fuso orario - '7 mesi'::intervallo)\n  InitPlan 2 (restituisce $1)\n    -&gt;  Risultato  (costo=0.00..0.02 righe=1 larghezza=8) (tempo reale=0.003..0.003 righe=1 cicli=1)\n          Uscita: ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)\n  -&gt;  Scansione esterna su fdw_schema.\"tabella\"  (costo=100.02..322041.41 righe=25 larghezza=0) (tempo reale=8.597..2153.809 righe=1360025 cicli=1)\n        Uscita: \"tabella\".id, \"tabella\".is_active, \"tabella\".meta, \"tabella\".created_dt\n        SQL remoto: SELEZIONA NULL DA fdw_schema.tabella DOVE (is_active) E ((created_dt &gt;= $1::timestamp con fuso orario)) E ((created_dt  '{\"source\": \"test\"}'::jsonb))\nTempo di pianificazione: 0.820 ms\nTempo di esecuzione: 2279.087 ms<\/code><\/pre>\n<p>\nS\u00ec, la query sembra pi\u00f9 complessa, \u00e8 un costo forzato, ma la velocit\u00e0 di esecuzione \u00e8 di 2 secondi, che \u00e8 pi\u00f9 di dieci volte pi\u00f9 veloce! E stiamo parlando di una semplice query su un insieme di dati relativamente piccolo. Su query reali abbiamo registrato un incremento di centinaia di volte.<\/p>\n<p>In sintesi: se utilizzi PostgreSQL con FDW, controlla sempre che tutti i filtri vengano inviati al server remoto, e vivrai felice\u2026 Fino a quando non arriverai ai join tra tabelle diverse <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/it\/server\/\"   title=\"server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1482\">server<\/a>. Ma questa \u00e8 gi\u00e0 una storia per un altro articolo.<\/p>\n<p>Grazie per l'attenzione! Sar\u00f2 felice di ricevere domande, commenti e storie sulle tue esperienze nei commenti.<br \/>\n<br \/>Fonte: <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.1.1 - 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\/it\/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<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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\/it\/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\udd47Analisi operativa nell'architettura a microservizi: aiutare e suggerire Postgres FDW | ProHoster","description":"L'architettura a microservizi, come tutto in questo mondo, ha i suoi pro e contro. Alcuni processi diventano pi\u00f9 semplici, altri pi\u00f9 complessi.","canonical_url":"https:\/\/prohoster.info\/it\/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":"it_IT","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\/it\/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\/it\/wp-json\/wp\/v2\/posts\/79467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=79467"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/79467\/revisions"}],"predecessor-version":[{"id":159871,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/79467\/revisions\/159871"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/79468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=79467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=79467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=79467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}