{"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\/nl\/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":"Operationele analytics in microservicesarchitectuur: p\u0336e\u0336n\u0336d\u0336e\u0336n\u0336 \u0336e\u0336n\u0336 \u0336o\u0336p\u0336l\u0336e\u0336g\u0336g\u0336e\u0336n\u0336 helpen en adviseren Postgres FDW","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Microservicesarchitectuur heeft, net als alles in deze wereld, zijn voor- en nadelen. Sommige processen worden eenvoudiger, andere complexer. En omwille van de snelheid van veranderingen en een betere schaalbaarheid moeten er offers worden gebracht. Een daarvan is de complicatie van analytics. In een monolith kan alle operationele analytics worden teruggebracht tot SQL-query's naar de analytische replica, maar in een multi-service architectuur heeft elke service zijn eigen database, en het lijkt alsof je niet met \u00e9\u00e9n query kunt werken (of kun je dat misschien wel?). Voor degenen die ge\u00efnteresseerd zijn in hoe we het probleem van operationele analytics in ons bedrijf hebben opgelost en hoe we met deze oplossing hebben leren leven \u2014 welkom.<\/p>\n<p><img decoding=\"async\" alt=\"Operationele analytics in microservicesarchitectuur: p\u0336e\u0336n\u0336d\u0336e\u0336n\u0336 \u0336e\u0336n\u0336 \u0336o\u0336p\u0336l\u0336e\u0336g\u0336g\u0336e\u0336n\u0336 helpen en adviseren Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/4296389f06d488999cc023dcaa3027f7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMijn naam is Pavel Siva\u0161, bij DomClick werk ik in het team dat verantwoordelijk is voor het onderhoud van het analytische datawarehouse. We kunnen onze werkzaamheden ruwweg onderbrengen in data engineering, maar in werkelijkheid is het scala aan taken veel breder. Er zijn standaardtaken voor data engineering zoals ETL\/ELT, ondersteuning en aanpassing van tools voor data-analyse en de ontwikkeling van onze eigen tools. In het bijzonder hebben we voor operationele rapportage besloten 'te doen alsof' we een monolith hebben en de analisten \u00e9\u00e9n database te geven waarin alle benodigde gegevens staan. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Over het algemeen hebben we verschillende opties overwogen. We hadden een volledige opslag kunnen opzetten \u2014 we hebben het zelfs geprobeerd, maar eerlijk gezegd is het ons niet gelukt om de vrij frequente wijzigingen in de logica te combineren met het vrij trage proces van het opbouwen van de opslag en het aanbrengen van wijzigingen (als iemand het gelukt is, laat dan in de reacties weten hoe). We hadden de analisten kunnen zeggen: \"Jongens, leer Python en ga naar de analytische replica's\", maar dat zou een extra vereiste voor het personeel zijn en het leek beter dit te vermijden, als dat mogelijk was. We besloten de technologie FDW (Foreign Data Wrapper) te gebruiken: in wezen is dit een standaard dblink die in de SQL-standaard voorkomt, maar met een veel gebruiksvriendelijker interface. Op basis daarvan hebben we een oplossing gemaakt die uiteindelijk is aangenomen en waar we op zijn teruggekomen. De details ervan zijn het onderwerp van een apart artikel, misschien zelfs meerdere, omdat we veel willen vertellen: van schema-synchronisatie tot toegangsbeheer en het anonimiseren van persoonsgegevens. Het moet ook worden opgemerkt dat deze oplossing geen vervanging is voor echte analytische databases en opslagplaatsen; het lost alleen een specifiek probleem op.<\/p>\n<p>Op hoofdlijnen ziet het er als volgt uit:<\/p>\n<p><img decoding=\"async\" alt=\"Operationele analytics in microservicesarchitectuur: p\u0336e\u0336n\u0336d\u0336e\u0336n\u0336 \u0336e\u0336n\u0336 \u0336o\u0336p\u0336l\u0336e\u0336g\u0336g\u0336e\u0336n\u0336 helpen en adviseren Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/574da29dfdb40706afe9e817e789a61b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nEr is een PostgreSQL-database, daar kunnen gebruikers hun werkgegevens opslaan, en het belangrijkste is dat deze database via FDW is gekoppeld aan de analytische replica's van alle diensten. Dit maakt het mogelijk om een query naar verschillende databases te schrijven, ongeacht of dit nu PostgreSQL, MySQL, MongoDB of iets anders is (een bestand, API; als er geen geschikte wrapper is, kan je zelf een schrijven). Nou, dat lijkt me alles, geweldig! Laten we het hierbij laten?<\/p>\n<p>Als alles zo snel en eenvoudig eindigde, zou er waarschijnlijk geen artikel zijn.<\/p>\n<p>Het is belangrijk om duidelijk te begrijpen hoe PostgreSQL verzoeken naar externe servers verwerkt. Dit lijkt logisch, maar wordt vaak over het hoofd gezien: PostgreSQL verdeeld een verzoek in delen die onafhankelijk op externe servers worden uitgevoerd, verzamelt deze gegevens en voert de uiteindelijke berekeningen zelf uit, waardoor de snelheid van de uitvoering van het verzoek sterk afhankelijk zal zijn van de manier waarop het is geschreven. Het moet ook worden opgemerkt: wanneer gegevens van een externe server komen, zijn ze al zonder indexen, zonder iets dat de planner kan helpen, dus kunnen we hem alleen zelf helpen en aanwijzingen geven. En daarover wil ik graag meer zeggen.<\/p>\n<h1>Eenvoudig verzoek en plan daarmee<\/h1>\n<p>\nOm te laten zien hoe PostgreSQL een aanvraag uitvoert op een tabel met 6 miljoen regels op afstand <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/nl\/server\/dts-dronten\/\"   title=\"de server\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2589\">de server<\/a>, kijken we naar een eenvoudig plan.<\/p>\n<pre><code class=\"sql\">verklaar analyseer gedetailleerd  \nSELECT count(1)\nFROM fdw_schema.tabel;\n\nAggregaat  (kosten=418383.23..418383.24 rijen=1 breedte=8) (werkelijke tijd=3857.198..3857.198 rijen=1 loops=1)\n  Uitvoer: count(1)\n  -&gt;  Buitenlandse Scan op fdw_schema.&quot;tabel&quot;  (kosten=100.00..402376.14 rijen=6402838 breedte=0) (werkelijke tijd=4.874..3256.511 rijen=6406868 loops=1)\n        Uitvoer: &quot;tabel&quot;.id, &quot;tabel&quot;.is_active, &quot;tabel&quot;.meta, &quot;tabel&quot;.created_dt\n        Externe SQL: SELECT NULL FROM fdw_schema.tabel\nPlanningtijd: 0.986 ms\nUitvoeringstijd: 3857.436 ms<\/code><\/pre>\n<p>\nHet gebruik van de VERBOSE-instructie stelt ons in staat om de aanvraag te zien die naar de externe server wordt verzonden en waarvan we de resultaten krijgen voor verdere verwerking (regel RemoteSQL).<\/p>\n<p>Laten we iets verder gaan en enkele filters aan onze aanvraag toevoegen: een op <b>boolean<\/b> veld, een op aanwezigheid <b>timestamp<\/b> in het interval en een op <b>jsonb<\/b>.<\/p>\n<pre><code class=\"sql\">verklaar analyseer gedetailleerd\nSELECT count(1)\nFROM fdw_schema.tabel \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\nAggregaat  (kosten=577487.69..577487.70 rijen=1 breedte=8) (werkelijke tijd=27473.818..25473.819 rijen=1 loops=1)\n  Uitvoer: count(1)\n  -&gt;  Buitenlandse Scan op fdw_schema.&quot;tabel&quot;  (kosten=100.00..577469.21 rijen=7390 breedte=0) (werkelijke tijd=31.369..25372.466 rijen=1360025 loops=1)\n        Uitvoer: &quot;tabel&quot;.id, &quot;tabel&quot;.is_active, &quot;tabel&quot;.meta, &quot;tabel&quot;.created_dt\n        Filter: ((&quot;tabel&quot;.is_active IS TRUE) AND ((&quot;tabel&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) AND (&quot;tabel&quot;.created_dt &gt;= (('nu'::cstring)::date - '7 mons'::interval)) AND (&quot;tabel&quot;.created_dt &lt;= ((('nu'::cstring)::date)::timestamp with tijdzone - '6 mons'::interval)))\n        Rijen verwijderd door filter: 5046843\n        Externe SQL: SELECT created_dt, is_active, meta FROM fdw_schema.tabel\nPlanningtijd: 0.665 ms\nUitvoeringstijd: 27474.118 ms<\/code><\/pre>\n<p>\nHier ligt echt het punt dat je moet opmerken bij het schrijven van aanvragen. De filters werden niet doorgestuurd naar de externe server, wat betekent dat PostgreSQL alle 6 miljoen regels ophaalt om deze vervolgens lokaal te filteren (regel Filter) en aggregatie uit te voeren. Het geheim van succes is om de aanvraag zo te schrijven dat de filters naar de externe machine worden gestuurd, zodat we alleen de benodigde rijen ontvangen en aggregeren. <\/p>\n<h1>Dat is wat onzin<\/h1>\n<p>\nMet booleanvelden is alles eenvoudig. In de oorspronkelijke aanvraag ontstond het probleem door de operator <b>is<\/b>. Als we deze vervangen door <b>=<\/b>, krijgen we het volgende resultaat:<\/p>\n<pre><code class=\"sql\">verklaar analyseer gedetailleerd\nSELECT count(1)\nFROM fdw_schema.tabel\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\nAggregaat  (kosten=508010.14..508010.15 rijen=1 breedte=8) (werkelijke tijd=19064.314..19064.314 rijen=1 loops=1)\n  Uitvoer: count(1)\n  -&gt;  Buitenlandse Scan op fdw_schema.&quot;tabel&quot;  (kosten=100.00..507988.44 rijen=8679 breedte=0) (werkelijke tijd=33.035..18951.278 rijen=1360025 loops=1)\n        Uitvoer: &quot;tabel&quot;.id, &quot;tabel&quot;.is_active, &quot;tabel&quot;.meta, &quot;tabel&quot;.created_dt\n        Filter: (((&quot;tabel&quot;.meta -&gt;&gt; 'source'::text) = 'test'::text) AND (&quot;tabel&quot;.created_dt &gt;= (('nu'::cstring)::date - '7 mons'::interval)) AND (&quot;tabel&quot;.created_dt &lt;= ((('nu'::cstring)::date)::timestamp with tijdzone - '6 mons'::interval)))\n        Rijen verwijderd door filter: 3567989\n        Externe SQL: SELECT created_dt, meta FROM fdw_schema.tabel WHERE (is_active)\nPlanningtijd: 0.834 ms\nUitvoeringstijd: 19064.534 ms<\/code><\/pre>\n<p>\nZoals u kunt zien, is de filter naar de externe server gegaan en is de uitvoeringstijd verkort van 27 seconden naar 19 seconden. <\/p>\n<p>Het is belangrijk op te merken dat de operator <b>is<\/b> verschilt van de operator <b>=<\/b> op de manier dat deze null-waarden kan verwerken. Dit betekent dat <b>is not True<\/b> in de filter waarden False en Null behoudt, terwijl <b>!= True<\/b> alleen waarden False behoudt. Daarom, bij het vervangen van de operator <b>is not<\/b> moeten twee voorwaarden met de operator OR in de filter worden doorgegeven, bijvoorbeeld, <b>WHERE (col != True) OR (col is null)<\/b>.<\/p>\n<p>Met boolean hebben we een oplossing, laten we verder gaan. Laten we de filter voor de booleaanse waarde terugzetten naar zijn oorspronkelijke staat om het effect van andere veranderingen onafhankelijk te bekijken.<\/p>\n<h1>timestamptz? hz<\/h1>\n<p>\nEigenlijk is het vaak nodig om te experimenteren met hoe je een query correct schrijft die betrokken is bij externe servers, en daarna pas te zoeken naar een uitleg over waarom het zo gebeurt. Er is zeer weinig informatie hierover te vinden op het internet. Zo hebben we in onze experimenten ontdekt dat een filter op een vaste datum probleemloos naar de externe server gaat, maar als we een datum dynamisch willen instellen, bijvoorbeeld now() of CURRENT_DATE, dat gebeurt niet. In ons voorbeeld hebben we zo'n filter toegevoegd om ervoor te zorgen dat de kolom created_at gegevens bevat die precies 1 maand in het verleden liggen (BETWEEN CURRENT_DATE \u2014 INTERVAL &#8216;7 month&#8217; AND CURRENT_DATE \u2014 INTERVAL &#8216;6 month&#8217;). Wat hebben we in dit geval gedaan?<\/p>\n<pre><code class=\"sql\">leg het analyseren uit met gedetailleerde informatie\nSELECT count(1)\nFROM fdw_schema.tabel\nWHERE is_active is True\nAND created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 maanden')\nAND created_dt &gt;'source' = 'test';\n\nAggregaat  (kost=306875.17..306875.18 rijen=1 breedte=8) (werkelijke tijd=4789.114..4789.115 rijen=1 loops=1)\n  Uitvoer: count(1)\n  InitPlan 1 (geeft $0 terug)\n    -&gt;  Resultaat  (kost=0.00..0.02 rijen=1 breedte=8) (werkelijke tijd=0.007..0.008 rijen=1 loops=1)\n          Uitvoer: ((('nu'::cstring)::datum)::timestamp met tijdzone - '7 maanden'::interval)\n  InitPlan 2 (geeft $1 terug)\n    -&gt;  Resultaat  (kost=0.00..0.02 rijen=1 breedte=8) (werkelijke tijd=0.002..0.002 rijen=1 loops=1)\n          Uitvoer: ((('nu'::cstring)::datum)::timestamp met tijdzone - '6 maanden'::interval)\n  -&gt;  Buitenlandse Scan op fdw_schema.\"tabel\"  (kost=100.02..306874.86 rijen=105 breedte=0) (werkelijke tijd=23.475..4681.419 rijen=1360025 loops=1)\n        Uitvoer: \"tabel\".id, \"tabel\".is_active, \"tabel\".meta, \"tabel\".created_dt\n        Filter: ((\"tabel\".is_active IS TRUE) EN ((\"tabel\".meta -&gt;&gt; 'source'::tekst) = 'test'::tekst))\n        Rijen verwijderd door filter: 76934\n        Externe SQL: SELECT is_active, meta FROM fdw_schema.tabel WHERE ((created_dt &gt;= $1::timestamp met tijdzone)) EN ((created_dt &lt; $2::timestamp met tijdzone))\nPlannings tijd: 0.703 ms\nUitvoering tijd: 4789.379 ms<\/code><\/pre>\n<p>\nWe hebben de planner aangemoedigd om de datum in de subquery vooraf te berekenen en al een kant-en-klare variabele aan de filter door te geven. Dit advies leverde ons een prachtig resultaat op; de query werd bijna 6 keer sneller!<\/p>\n<p>Opnieuw is het belangrijk om voorzichtig te zijn: het datatypen in de subquery moet hetzelfde zijn als dat van het veld waarvoor we filteren, anders besluit de planner dat omdat de types verschillen, het eerst alle gegevens moet ophalen en deze lokaal moet filteren.<\/p>\n<p>Laten we de datumfilter terugzetten naar de oorspronkelijke waarde.<\/p>\n<h1>Freddy vs. Jsonb<\/h1>\n<p>\nOver het algemeen hebben booleaanse velden en data onze query al behoorlijk versneld, maar er blijft nog \u00e9\u00e9n datatype over. De strijd om de filtering daarop is, eerlijk gezegd, nog steeds niet voorbij, hoewel er ook hier successen zijn geboekt. Dus zo hebben we het filter doorgegeven op <b>jsonb<\/b> het veld naar de externe server.<\/p>\n<pre><code class=\"sql\">leg het analyseren uit met gedetailleerde informatie\nSELECT count(1)\nFROM fdw_schema.tabel\nWHERE is_active is True\nAND created_dt TUSSEN CURRENT_DATE - INTERVAL '7 maanden'\nAND CURRENT_DATE - INTERVAL '6 maanden'\nAND meta @&gt; '{\"source\":\"test\"}'::jsonb;\n\nAggregaat  (kost=245463.60..245463.61 rijen=1 breedte=8) (werkelijke tijd=6727.589..6727.590 rijen=1 loops=1)\n  Uitvoer: count(1)\n  -&gt;  Buitenlandse Scan op fdw_schema.\"tabel\"  (kost=1100.00..245459.90 rijen=1478 breedte=0) (werkelijke tijd=16.213..6634.794 rijen=1360025 loops=1)\n        Uitvoer: \"tabel\".id, \"tabel\".is_active, \"tabel\".meta, \"tabel\".created_dt\n        Filter: ((\"tabel\".is_active IS TRUE) EN (\"tabel\".created_dt &gt;= (('nu'::cstring)::datum - '7 maanden'::interval)) EN (\"tabel\".created_dt  '{\"source\": \"test\"}'::jsonb))\nPlannings tijd: 0.747 ms\nUitvoering tijd: 6727.815 ms<\/code><\/pre>\n<p>\nIn plaats van filteroperatoren moeten we de aanwezigheidsoperator gebruiken. <b>jsonb<\/b> in een andere. 7 seconden in plaats van de oorspronkelijke 29. Tot nu toe is dit de enige succesvolle manier om filters door te geven <b>jsonb<\/b> naar een externe server, maar hier moet men \u00e9\u00e9n beperking in gedachten houden: we gebruiken versie 9.6 van de database, maar we zijn van plan om tegen het einde van april de laatste tests te voltooien en over te stappen op versie 12. Zodra we zijn bijgewerkt, zullen we schrijven hoe dit van invloed was, want er zijn veel veranderingen waar we op hopen: json_path, nieuw gedrag voor CTE, push down (bestaande sinds versie 10). We willen het zo snel mogelijk uitproberen.<\/p>\n<h1>Finish him<\/h1>\n<p>\nWe hebben gecontroleerd hoe elke wijziging afzonderlijk invloed heeft op de snelheid van het verzoek. Laten we nu kijken naar wat er gebeurt als alle drie de filters correct zijn geschreven.<\/p>\n<pre><code class=\"sql\">leg uitleg analyseren gedetailleerd\nSELECT count(1)\nFROM fdw_schema.tabel \nWHERE is_active = True\nAND created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 maanden') \nAND created_dt  '{\"source\":\"test\"}'::jsonb;\n\nAggregaat  (kosten=322041.51..322041.52 rijen=1 breedte=8) (werkelijke tijd=2278.867..2278.867 rijen=1 lussen=1)\n  Uitvoer: count(1)\n  InitPlan 1 (geeft $0 terug)\n    -&gt;  Resultaat  (kosten=0.00..0.02 rijen=1 breedte=8) (werkelijke tijd=0.010..0.010 rijen=1 lussen=1)\n          Uitvoer: ((('nu'::cstring)::datum)::timestamp met tijdzone - '7 maanden'::interval)\n  InitPlan 2 (geeft $1 terug)\n    -&gt;  Resultaat  (kosten=0.00..0.02 rijen=1 breedte=8) (werkelijke tijd=0.003..0.003 rijen=1 lussen=1)\n          Uitvoer: ((('nu'::cstring)::datum)::timestamp met tijdzone - '6 maanden'::interval)\n  -&gt;  Buitenlandse scan op fdw_schema.\"tabel\"  (kosten=100.02..322041.41 rijen=25 breedte=0) (werkelijke tijd=8.597..2153.809 rijen=1360025 lussen=1)\n        Uitvoer: \"tabel\".id, \"tabel\".is_active, \"tabel\".meta, \"tabel\".created_dt\n        Externe SQL: SELECT NULL FROM fdw_schema.tabel WHERE (is_active) AND ((created_dt &gt;= $1::timestamp met tijdzone)) AND ((created_dt  '{\"source\": \"test\"}'::jsonb))\nPlanningsduur: 0.820 ms\nUitvoeringsduur: 2279.087 ms<\/code><\/pre>\n<p>\nJa, de aanvraag lijkt ingewikkelder, dat is een noodzakelijke prijs, maar de uitvoeringstijd bedraagt 2 seconden, wat meer dan 10 keer sneller is! En we hebben het hier over een eenvoudige aanvraag aan een relatief kleine dataset. Bij echte aanvragen hebben we een toename van honderden keren gezien.<\/p>\n<p>Laten we de balans opmaken: als je PostgreSQL met FDW gebruikt, controleer altijd of alle filters naar de externe server worden gestuurd, en je zult gelukkig zijn... Tenminste, totdat je bij joins tussen tabellen van verschillende <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/nl\/server\/\"   title=\"servers\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1482\">servers<\/a>. Maar dat is al een verhaal voor een ander artikel.<\/p>\n<p>Bedankt voor uw aandacht! Ik kijk ernaar uit om vragen, opmerkingen en verhalen over uw ervaringen in de reacties te horen.<br \/>\n<br \/>Bron: <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.3 - 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\/nl\/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.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\/nl\/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\udd47Operationele analytics in microservicesarchitectuur: begrijpen en vereenvoudigen met Postgres FDW | ProHoster","description":"Microservices-architectuur heeft, net als alles in deze wereld, zowel voor- als nadelen. Sommige processen worden gemakkelijker, andere moeilijker.","canonical_url":"https:\/\/prohoster.info\/nl\/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":"nl_NL","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\/nl\/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\/nl\/wp-json\/wp\/v2\/posts\/79467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=79467"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/79467\/revisions"}],"predecessor-version":[{"id":159871,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/79467\/revisions\/159871"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/79468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=79467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=79467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=79467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}