{"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 in architettura a microservizi: aiutare e guidare Postgres FDW","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>L'architettura a microservizi, come tutto in questo mondo, ha i suoi pro e i suoi contro. Alcuni processi diventano pi\u00f9 semplici, altri pi\u00f9 complicati. E, in nome della rapidit\u00e0 nelle modifiche e di una migliore scalabilit\u00e0, \u00e8 necessario fare delle rinunce. Una di queste \u00e8 la complicazione dell'analisi. Se nel monolite tutta l'analisi operativa pu\u00f2 essere ridotta a query SQL sulla replica analitica, nella architettura a microservizi ogni servizio ha il proprio database e sembra che non possa bastare una sola query (o forse s\u00ec?). Per coloro che sono interessati a scoprire 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 in architettura a microservizi: aiutare e guidare Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/4296389f06d488999cc023dcaa3027f7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMi chiamo Pavel Sivas e lavoro in DomClick in un team che si occupa della gestione del data warehouse analitico. La nostra attivit\u00e0 pu\u00f2 essere considerata in parte ingegneria dei dati, ma, in realt\u00e0, l'ampiezza delle mansioni \u00e8 molto pi\u00f9 vasta. Ci sono compiti standard per l'ingegneria dei dati come ETL\/ELT, supporto e adattamento di strumenti per l'analisi dei dati e sviluppo di strumenti personalizzati. In particolare, per i report operativi abbiamo deciso di \"fingere\" di avere un monolite e di fornire agli analisti un unico database, contenente tutti i dati necessari. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>In generale, abbiamo considerato diverse opzioni. Avremmo potuto costruire un vero e proprio repository \u2014 abbiamo anche provato, ma, ad essere onesti, non siamo riusciti a integrare frequenti cambiamenti nella logica con un processo di costruzione e modifica del repository piuttosto lento (se qualcuno ci \u00e8 riuscito, sentitevi liberi di scrivere nei commenti come). Avremmo potuto dire agli analisti: \"Ragazzi, imparate Python e adattatevi alle repliche analitiche\", ma questo sarebbe stato un ulteriore requisito per il reclutamento del personale, e sembrava opportuno evitarlo, se possibile. Abbiamo deciso di provare a utilizzare la tecnologia FDW (Foreign Data Wrapper): in sostanza, \u00e8 un dblink standard, presente nello standard SQL, ma con un'interfaccia molto pi\u00f9 comoda. Su questa base, abbiamo creato una soluzione che alla fine ha preso piede, e ci siamo fermati su di essa. I dettagli della soluzione sono materia di un articolo a parte, e forse pi\u00f9 di uno, poich\u00e9 ci sono molte cose da raccontare: dalla sincronizzazione degli schemi dei database alla gestione degli accessi e all'anonimizzazione dei dati personali. Inoltre, \u00e8 necessario sottolineare che questa soluzione non \u00e8 una sostituzione di veri e propri database analitici e repository; risolve solo un compito specifico.<\/p>\n<p>A livello generale, appare cos\u00ec:<\/p>\n<p><img decoding=\"async\" alt=\"Analisi operativa in architettura a microservizi: aiutare e guidare 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 conservare i propri dati di lavoro, e la cosa pi\u00f9 importante \u00e8 che a questo database sono collegate tramite FDW repliche analitiche di tutti i servizi. Questo consente di scrivere query a pi\u00f9 database, non importa se siano PostgreSQL, MySQL, MongoDB o altro (file, API; se non c'\u00e8 un wrapper adatto, si pu\u00f2 scriverne uno proprio). Bene, sembra tutto! Possiamo andare?<\/p>\n<p>Se tutto finisse cos\u00ec in fretta e semplicemente, probabilmente non ci sarebbe nemmeno bisogno di questo articolo.<\/p>\n<p>\u00c8 importante comprendere chiaramente come PostgreSQL gestisce le richieste ai server remoti. Questo sembra logico, ma spesso non ci si fa caso: PostgreSQL divide la query in parti che vengono eseguite sui server remoti in modo indipendente, raccoglie questi dati e poi esegue i calcoli finali, quindi la velocit\u00e0 di esecuzione della query dipender\u00e0 molto da come \u00e8 scritta. \u00c8 importante sottolineare che quando i dati arrivano da un server remoto, non hanno pi\u00f9 indici, non c'\u00e8 niente che possa aiutare il pianificatore; quindi solo noi possiamo aiutarlo e guidarlo. Ed \u00e8 esattamente di questo che vorrei parlare in dettaglio.<\/p>\n<h1>Richiesta semplice e piano associato<\/h1>\n<p>\nPer illustrare come Postgres esegue una query 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>, esaminiamo un piano semplice.<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente  \nSELEZIONARE count(1)\nDA fdw_schema.tabella;\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;tabella&quot;  (costo=100.00..402376.14 righe=6402838 larghezza=0) (tempo effettivo=4.874..3256.511 righe=6406868 cicli=1)\n        Uscita: &quot;tabella&quot;.id, &quot;tabella&quot;.is_active, &quot;tabella&quot;.meta, &quot;tabella&quot;.created_dt\n        SQL Remoto: SELEZIONARE NULL DA fdw_schema.tabella\nTempo di pianificazione: 0.986 ms\nTempo di esecuzione: 3857.436 ms<\/code><\/pre>\n<p>\nL'uso dell'istruzione VERBOSE consente di visualizzare la query che sar\u00e0 inviata al server remoto e i cui risultati riceveremo per ulteriori elaborazioni (riga RemoteSQL).<\/p>\n<p>Andiamo un po' oltre e aggiungiamo alla nostra query alcuni filtri: uno per <b>booleano<\/b> campo, uno per corrispondenza <b>timestamp<\/b> in un intervallo e uno per <b>jsonb<\/b>.<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONARE count(1)\nDA fdw_schema.tabella \nDOVE is_active \u00e8 Vero\nE created_dt \u00c8 TRA CURRENT_DATE - INTERVAL '7 mesi' \nE CURRENT_DATE - INTERVAL '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;tabella&quot;  (costo=100.00..577469.21 righe=7390 larghezza=0) (tempo effettivo=31.369..25372.466 righe=1360025 cicli=1)\n        Uscita: &quot;tabella&quot;.id, &quot;tabella&quot;.is_active, &quot;tabella&quot;.meta, &quot;tabella&quot;.created_dt\n        Filtro: ((&quot;tabella&quot;.is_active \u00c8 VERO) E ((&quot;tabella&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) E (&quot;tabella&quot;.created_dt &gt;= (('ora'::cstring)::data - '7 mesi'::intervallo)) E (&quot;tabella&quot;.created_dt &lt;= ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)))\n        Righe rimosse dal filtro: 5046843\n        SQL remoto: SELEZIONARE created_dt, is_active, meta DA fdw_schema.tabella\nTempo di pianificazione: 0.665 ms\nTempo di esecuzione: 27474.118 ms<\/code><\/pre>\n<p>\nProprio qui si trova il punto su cui bisogna prestare attenzione nella scrittura delle query. I filtri non sono stati inviati al server remoto, il che significa che per l'esecuzione Postgres estrae tutti i 6 milioni di righe per poi filtrare localmente (riga Filtro) e produrre l'aggregazione. La chiave del successo \u00e8 scrivere la query in modo che i filtri vengano inviati alla macchina remota, consentendoci di ricevere e aggregare solo le righe necessarie. <\/p>\n<h1>Questo \u00e8 un vero booleanshit<\/h1>\n<p>\nCon i campi booleani \u2014 \u00e8 tutto semplice. Nel query originale il problema \u00e8 emerso a causa dell'operatore <b>\u00e8<\/b>. Se lo sostituiamo con <b>=<\/b>, otteniamo il seguente risultato:<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONARE count(1)\nDA fdw_schema.tabella\nDOVE is_active = Vero\nE created_dt \u00c8 TRA CURRENT_DATE - INTERVAL '7 mesi' \nE CURRENT_DATE - INTERVAL '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;tabella&quot;  (costo=100.00..507988.44 righe=8679 larghezza=0) (tempo effettivo=33.035..18951.278 righe=1360025 cicli=1)\n        Uscita: &quot;tabella&quot;.id, &quot;tabella&quot;.is_active, &quot;tabella&quot;.meta, &quot;tabella&quot;.created_dt\n        Filtro: (((&quot;tabella&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) E (&quot;tabella&quot;.created_dt &gt;= (('ora'::cstring)::data - '7 mesi'::intervallo)) E (&quot;tabella&quot;.created_dt &lt;= ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)))\n        Righe rimosse dal filtro: 3567989\n        SQL remoto: SELEZIONARE created_dt, meta DA fdw_schema.tabella DOVE (is_active)\nTempo di pianificazione: 0.834 ms\nTempo di esecuzione: 19064.534 ms<\/code><\/pre>\n<p>\nCome potete vedere, il filtro \u00e8 stato trasferito su un server remoto, e il tempo di esecuzione \u00e8 diminuito da 27 a 19 secondi. <\/p>\n<p>\u00c8 importante notare che l'operatore <b>\u00e8<\/b> \u00e8 diverso dall'operatore <b>=<\/b> nella misura in cui pu\u00f2 gestire il valore Null. Questo 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> \u00e8 necessario passare due condizioni nel filtro con l'operatore OR, ad esempio, <b>WHERE (col != True) OR (col is null)<\/b>.<\/p>\n<p>Con il booleano ci siamo chiariti, procediamo oltre. Ma per ora, ripristiniamo il filtro per il valore booleano alla sua forma originale, per esaminare indipendentemente l'effetto delle altre modifiche.<\/p>\n<h1>timestamptz? hz<\/h1>\n<p>\nSpesso \u00e8 necessario sperimentare su come scrivere correttamente una query che coinvolge server remoti e poi cercare di capire perch\u00e9 funziona in quel modo. Ci sono poche informazioni disponibili online riguardo a questo. Durante gli esperimenti, abbiamo notato che il filtro su una data fissa funziona bene, ma quando vogliamo usare una data dinamica, come now() o CURRENT_DATE, non succede lo stesso. Nel nostro caso, abbiamo aggiunto un filtro affinch\u00e9 la colonna created_at includes dati esattamente di 1 mese fa (BETWEEN CURRENT_DATE - INTERVAL '7 mesi' E CURRENT_DATE - INTERVAL '6 mesi'). Cosa abbiamo fatto in questo caso?<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONARE count(1)\nDA fdw_schema.tabella \nDOVE is_active \u00e8 Vero\nE created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 mesi') \nE created_dt &lt;(SELECT CURRENT_DATE::timestamptz - INTERVAL '6 mesi')\nE meta-&gt;&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  Uscita: 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          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 effettivo=0.002..0.002 righe=1 cicli=1)\n          Uscita: ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)\n  -&gt;  Scansione Remota su fdw_schema.&quot;tabella&quot;  (costo=100.02..306874.86 righe=105 larghezza=0) (tempo effettivo=23.475..4681.419 righe=1360025 cicli=1)\n        Uscita: &quot;tabella&quot;.id, &quot;tabella&quot;.is_active, &quot;tabella&quot;.meta, &quot;tabella&quot;.created_dt\n        Filtro: ((&quot;tabella&quot;.is_active \u00c8 VERO) E ((&quot;tabella&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text))\n        Righe rimosse dal filtro: 76934\n        SQL remoto: SELEZIONARE is_active, meta DA fdw_schema.tabella 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 passare la variabile gi\u00e0 pronta al filtro. E questo suggerimento ci ha dato un risultato eccezionale, la query \u00e8 diventata quasi sei volte pi\u00f9 veloce!<\/p>\n<p>Ancora una volta, \u00e8 importante prestare attenzione: il tipo di dato nella sottoquery deve essere lo stesso di quello del campo su cui stiamo filtrando, 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>Ripristiniamo il filtro sulla data al valore originale.<\/p>\n<h1>Freddy vs. Jsonb<\/h1>\n<p>\nIn effetti, i campi booleani e le date hanno gi\u00e0 accelerato notevolmente la nostra query, ma rimaneva un altro tipo di dato. La battaglia per la filtrazione su di esso, a dire il vero, non \u00e8 ancora finita, anche se ci sono stati dei progressi. Ecco quindi come siamo riusciti a passare il filtro su <b>jsonb<\/b> un campo al server remoto.<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONARE count(1)\nDA fdw_schema.tabella \nDOVE is_active \u00e8 Vero\nE created_dt \u00c8 TRA CURRENT_DATE - INTERVAL '7 mesi' \nE CURRENT_DATE - INTERVAL '6 mesi'\nE meta @&gt; '{&quot;source&quot;:&quot;test&quot;}'::jsonb;\n\nAggregato  (costo=245463.60..245463.61 righe=1 larghezza=8) (tempo effettivo=6727.589..6727.590 righe=1 cicli=1)\n  Uscita: count(1)\n  -&gt;  Scansione Remota su fdw_schema.&quot;tabella&quot;  (costo=1100.00..245459.90 righe=1478 larghezza=0) (tempo effettivo=16.213..6634.794 righe=1360025 cicli=1)\n        Uscita: &quot;tabella&quot;.id, &quot;tabella&quot;.is_active, &quot;tabella&quot;.meta, &quot;tabella&quot;.created_dt\n        Filtro: ((&quot;tabella&quot;.is_active \u00c8 VERO) E (&quot;tabella&quot;.created_dt &gt;= (('ora'::cstring)::data - '7 mesi'::intervallo)) E (&quot;tabella&quot;.created_dt &lt;= ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)))\n        Righe rimosse dal filtro: 619961\n        SQL remoto: SELEZIONARE created_dt, is_active DA fdw_schema.tabella DOVE ((meta @&gt; '{&quot;source&quot;: &quot;test&quot;}'::jsonb))\nTempo di pianificazione: 0.747 ms\nTempo di esecuzione: 6727.815 ms<\/code><\/pre>\n<p>\n\u00c8 necessario utilizzare l'operatore di esistenza invece degli operatori di filtraggio <b>jsonb<\/b> in un altro. 7 secondi invece dei 29 iniziali. Questo \u00e8 attualmente l'unico modo riuscito per trasferire i filtri. <b>jsonb<\/b> su un server remoto, ma qui c'\u00e8 un'importante limitazione: stiamo utilizzando la versione 9.6 del database, per\u00f2 entro la fine di aprile prevediamo di completare gli ultimi test e migrare alla versione 12. Non appena ci aggiorneremo, scriveremo come questa modifica ha influito, visto che ci sono molte speranze riguardo ai numerosi cambiamenti: json_path, il nuovo comportamento dei CTE, il push down (gi\u00e0 presente 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 richiesta singolarmente. Adesso vediamo cosa accade quando tutti e tre i filtri vengono scritti correttamente.<\/p>\n<pre><code class=\"sql\">spiegare analizzare dettagliatamente\nSELEZIONARE count(1)\nDA fdw_schema.tabella \nDOVE is_active = Vero\nE created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 mesi') \nE created_dt &lt;(SELECT CURRENT_DATE::timestamptz - INTERVAL '6 mesi')\nE meta @&gt; '{&quot;source&quot;:&quot;test&quot;}'::jsonb;\n\nAggregato  (costo=322041.51..322041.52 righe=1 larghezza=8) (tempo effettivo=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 effettivo=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 effettivo=0.003..0.003 righe=1 cicli=1)\n          Uscita: ((('ora'::cstring)::data)::timestamp con fuso orario - '6 mesi'::intervallo)\n  -&gt;  Scansione Remota su fdw_schema.&quot;tabella&quot;  (costo=100.02..322041.41 righe=25 larghezza=0) (tempo effettivo=8.597..2153.809 righe=1360025 cicli=1)\n        Uscita: &quot;tabella&quot;.id, &quot;tabella&quot;.is_active, &quot;tabella&quot;.meta, &quot;tabella&quot;.created_dt\n        SQL remoto: SELEZIONARE NULL DA fdw_schema.tabella DOVE (is_active) E ((created_dt &gt;= $1::timestamp con fuso orario)) E ((created_dt &lt; $2::timestamp con fuso orario)) E ((meta @&gt; '{&quot;source&quot;:&quot;test&quot;}'::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 inevitabile, 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 ottenuto un incremento fino a diverse 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 sarai fortunato... Almeno fino a quando non arriverai alle join tra tabelle di diversi <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 condivider\u00f2 storie sulla tua esperienza 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 4.9.10 - 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. \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,\" \/>\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) 4.9.10\" \/>\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. \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,\" \/>\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: \u0336c\u0336o\u0336n\u0336o\u0336s\u0336c\u0336e\u0336r\u0336e\u0336 \u0336e\u0336 \u0336s\u0336i\u0336mplificare\u0336 aiutare e suggerire Postgres FDW | ProHoster","description":"L'architettura a microservizi, come tutto in questo mondo, ha i suoi vantaggi e svantaggi. Alcuni processi diventano pi\u00f9 semplici, altri pi\u00f9 complessi. E per il bene della velocit\u00e0 dei cambiamenti e della migliore scalabilit\u00e0, \u00e8 necessario fare dei sacrifici. Uno di questi \u00e8 la complessit\u00e0 dell'analisi. Se nel monolite tutta l'analisi operativa pu\u00f2 essere ridotta a query SQL su una replica analitica,","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. \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,","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"},"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}]}}