{"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\/es\/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":"An\u00e1lisis operativo en arquitectura de microservicios: p\u0336u\u0336e\u0336d\u0336e\u0336 \u0336y\u0336 \u0336a\u0336y\u0336u\u0336d\u0336a\u0336 \u0336a\u0336 \u0336s\u0336u\u0336g\u0336e\u0336r\u0336i\u0336r\u0336 Postgres FDW","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>La arquitectura de microservicios, como todo en este mundo, tiene sus pros y sus contras. Algunos procesos se vuelven m\u00e1s sencillos con ella, otros m\u00e1s complejos. Y en aras de la velocidad de los cambios y una mejor escalabilidad, es necesario hacer sacrificios. Uno de ellos es la complejidad del an\u00e1lisis. Si en un monolito toda la anal\u00edtica operativa se puede reducir a consultas SQL a una r\u00e9plica de an\u00e1lisis, en una arquitectura de m\u00faltiples servicios cada servicio tiene su propia base de datos, y parece que no se puede hacer con una sola consulta (\u00bfo s\u00ed?). Para aquellos interesados en c\u00f3mo resolvimos el problema de la anal\u00edtica operativa en nuestra empresa y c\u00f3mo aprendimos a vivir con esta soluci\u00f3n, est\u00e1n todos invitados.<\/p>\n<p><img decoding=\"async\" alt=\"An\u00e1lisis operativo en arquitectura de microservicios: p\u0336u\u0336e\u0336d\u0336e\u0336 \u0336y\u0336 \u0336a\u0336y\u0336u\u0336d\u0336a\u0336 \u0336a\u0336 \u0336s\u0336u\u0336g\u0336e\u0336r\u0336i\u0336r\u0336 Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/4296389f06d488999cc023dcaa3027f7.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMe llamo Pavel Sivash, en DomClick trabajo en el equipo que se encarga del soporte del almac\u00e9n de datos anal\u00edticos. Nuestra actividad se puede clasificar, de forma general, como ingenier\u00eda de datos, pero en realidad, el espectro de tareas es mucho m\u00e1s amplio. Existen tareas est\u00e1ndar en la ingenier\u00eda de datos como ETL\/ELT, mantenimiento y adaptaci\u00f3n de herramientas para el an\u00e1lisis de datos y desarrollo de nuestras propias herramientas. En particular, para la generaci\u00f3n de informes operativos decidimos \u00abpretender\u00bb que tenemos un monolito y dar a los analistas una base de datos en la que estar\u00e1n todos los datos necesarios. <noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>En general, consideramos diferentes opciones. Podr\u00eda haberse construido un almacenamiento completo; incluso lo intentamos, pero, siendo honestos, no logramos mucho al intentar conciliar cambios frecuentes en la l\u00f3gica con un proceso de construcci\u00f3n de almacenamiento y modificaci\u00f3n de datos que resultaba bastante lento (si alguien lo consigui\u00f3, por favor comente c\u00f3mo). Podr\u00edamos haber dicho a los analistas: \"Chicos, aprendan python y utilicen r\u00e9plicas anal\u00edticas\", pero eso implica un requisito adicional para la selecci\u00f3n de personal, y parec\u00eda que era preferible evitarlo si era posible. Decidimos probar la tecnolog\u00eda FDW (Foreign Data Wrapper): en esencia, es un dblink est\u00e1ndar que existe en la norma SQL, pero con una interfaz mucho m\u00e1s conveniente. Bas\u00e1ndonos en esto, creamos una soluci\u00f3n que finalmente se arraig\u00f3 y en la que decidimos detenernos. Los detalles ser\u00edan tema de un art\u00edculo aparte, o tal vez varios, ya que hay mucho que contar: desde la sincronizaci\u00f3n de esquemas de bases hasta la gesti\u00f3n de acceso y la anonimizaci\u00f3n de datos personales. Tambi\u00e9n es necesario aclarar que esta soluci\u00f3n no reemplaza a las verdaderas bases de datos anal\u00edticas y almacenes de datos, solo resuelve una tarea espec\u00edfica.<\/p>\n<p>A nivel general, se ve as\u00ed:<\/p>\n<p><img decoding=\"async\" alt=\"An\u00e1lisis operativo en arquitectura de microservicios: p\u0336u\u0336e\u0336d\u0336e\u0336 \u0336y\u0336 \u0336a\u0336y\u0336u\u0336d\u0336a\u0336 \u0336a\u0336 \u0336s\u0336u\u0336g\u0336e\u0336r\u0336i\u0336r\u0336 Postgres FDW\" src=\"\/wp-content\/uploads\/2020\/04\/574da29dfdb40706afe9e817e789a61b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nHay una base de datos PostgreSQL donde los usuarios pueden almacenar sus datos de trabajo, y lo m\u00e1s importante es que a esta base est\u00e1n conectadas, a trav\u00e9s de FDW, r\u00e9plicas anal\u00edticas de todos los servicios. Esto permite realizar consultas a varias bases, sin importar si son: PostgreSQL, MySQL, MongoDB o cualquier otra cosa (archivo, API; si no hay un wrapper adecuado, se puede crear uno propio). Bueno, eso parece todo, \u00a1genial! \u00bfNos vamos?<\/p>\n<p>Si todo terminara tan r\u00e1pido y sencillo, probablemente no habr\u00eda art\u00edculo.<\/p>\n<p>Es importante entender claramente c\u00f3mo Postgres maneja las consultas a servidores remotos. Esto parece l\u00f3gico, sin embargo, a menudo se pasa por alto: Postgres divide la consulta en partes que se ejecutan en los servidores remotos de manera independiente, recopila esos datos y realiza los c\u00e1lculos finales por s\u00ed mismo, por lo que la velocidad de ejecuci\u00f3n de la consulta depender\u00e1 mucho de c\u00f3mo est\u00e9 escrita. Tambi\u00e9n cabe mencionar que cuando los datos llegan de un servidor remoto, ya no tienen \u00edndices, no hay nada que ayude al planificador, por lo tanto, solo nosotros mismos podemos ayudarlo y orientarlo. Y precisamente sobre esto es lo que me gustar\u00eda hablar con m\u00e1s detalle.<\/p>\n<h1>Consulta simple y plan asociado<\/h1>\n<p>\nPara mostrar c\u00f3mo Postgres ejecuta una consulta a una tabla de 6 millones de filas de forma remota <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/es\/server\/dts-dronten\/\"   title=\"servidor\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2589\">servidor<\/a>, observemos un plan sencillo.<\/p>\n<pre><code class=\"sql\">explicaci\u00f3n analizar detalladamente  \nSELECCIONAR count(1)\nDE fdw_schema.table;\n\nAgregado  (costo=418383.23..418383.24 filas=1 ancho=8) (tiempo real 3857.198..3857.198 filas=1 bucles=1)\n  Salida: count(1)\n  -&gt;  Exploraci\u00f3n Remota en fdw_schema.&quot;table&quot;  (costo=100.00..402376.14 filas=6402838 ancho=0) (tiempo real 4.874..3256.511 filas=6406868 bucles=1)\n        Salida: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        SQL Remoto: SELECCIONAR NULL DE fdw_schema.table\nTiempo de planificaci\u00f3n: 0.986 ms\nTiempo de ejecuci\u00f3n: 3857.436 ms<\/code><\/pre>\n<p>\nEl uso de la instrucci\u00f3n VERBOSE permite ver la consulta que se enviar\u00e1 al servidor remoto y los resultados que recibiremos para su procesamiento posterior (l\u00ednea RemoteSQL).<\/p>\n<p>Avancemos un poco m\u00e1s y a\u00f1adamos varios filtros a nuestra consulta: uno por <b>boolean<\/b> campo, uno por inclusi\u00f3n <b>timestamp<\/b> dentro de un intervalo y uno por <b>jsonb<\/b>.<\/p>\n<pre><code class=\"sql\">explicaci\u00f3n analizar detalladamente\nSELECCIONAR count(1)\nDE fdw_schema.table \nDONDE is_active es Verdadero\nY created_dt ENTRE CURRENT_DATE - INTERVALO '7 mes' \nY CURRENT_DATE - INTERVALO '6 mes'\nY meta-&gt;&gt;'source' = 'test';\n\nAgregado  (costo=577487.69..577487.70 filas=1 ancho=8) (tiempo real 27473.818..25473.819 filas=1 bucles=1)\n  Salida: count(1)\n  -&gt;  Exploraci\u00f3n Remota en fdw_schema.&quot;table&quot;  (costo=100.00..577469.21 filas=7390 ancho=0) (tiempo real 31.369..25372.466 filas=1360025 bucles=1)\n        Salida: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Filtro: ((&quot;table&quot;.is_active ES VERDADERO) Y ((&quot;table&quot;.meta -&gt;&gt; 'source'::texto) = 'test'::texto) Y (&quot;table&quot;.created_dt &gt;= (('ahora'::cstring)::fecha - '7 mons'::intervalo)) Y (&quot;table&quot;.created_dt &lt;= ((('ahora'::cstring)::fecha)::timestamp con zona horaria - '6 mons'::intervalo)))\n        Filas eliminadas por filtro: 5046843\n        SQL Remoto: SELECCIONAR created_dt, is_active, meta DE fdw_schema.table\nTiempo de planificaci\u00f3n: 0.665 ms\nTiempo de ejecuci\u00f3n: 27474.118 ms<\/code><\/pre>\n<p>\nAqu\u00ed es donde radica el punto que se debe tener en cuenta al escribir las consultas. Los filtros no se enviaron al servidor remoto, lo que significa que para su ejecuci\u00f3n, Postgres extrae todas las 6 millones de filas para luego filtrarlas localmente (l\u00ednea Filter) y realizar la agregaci\u00f3n. La clave del \u00e9xito es redactar la consulta de tal manera que los filtros se transfieran a la m\u00e1quina remota, y as\u00ed obtengamos y agreguemos solo las filas necesarias. <\/p>\n<h1>Eso es una tonter\u00eda booleana<\/h1>\n<p>\nCon los campos booleanos, es todo simple. La problem\u00e1tica en la consulta original surgi\u00f3 debido al operador <b>is<\/b>. Si lo reemplazamos por <b>=<\/b>, obtendremos el siguiente resultado:<\/p>\n<pre><code class=\"sql\">explicaci\u00f3n analizar detalladamente\nSELECCIONAR count(1)\nDE fdw_schema.table\nDONDE is_active = Verdadero\nY created_dt ENTRE CURRENT_DATE - INTERVALO '7 mes' \nY CURRENT_DATE - INTERVALO '6 mes'\nY meta-&gt;&gt;'source' = 'test';\n\nAgregado  (costo=508010.14..508010.15 filas=1 ancho=8) (tiempo real 19064.314..19064.314 filas=1 bucles=1)\n  Salida: count(1)\n  -&gt;  Exploraci\u00f3n Remota en fdw_schema.&quot;table&quot;  (costo=100.00..507988.44 filas=8679 ancho=0) (tiempo real 33.035..18951.278 filas=1360025 bucles=1)\n        Salida: &quot;table&quot;.id, &quot;table&quot;.is_active, &quot;table&quot;.meta, &quot;table&quot;.created_dt\n        Filtro: (((&quot;table&quot;.meta -&gt;&gt; 'source'::texto) = 'test'::texto) Y (&quot;table&quot;.created_dt &gt;= (('ahora'::cstring)::fecha - '7 mons'::intervalo)) Y (&quot;table&quot;.created_dt &lt;= ((('ahora'::cstring)::fecha)::timestamp con zona horaria - '6 mons'::intervalo)))\n        Filas eliminadas por filtro: 3567989\n        SQL Remoto: SELECCIONAR created_dt, meta DE fdw_schema.table DONDE (is_active)\nTiempo de planificaci\u00f3n: 0.834 ms\nTiempo de ejecuci\u00f3n: 19064.534 ms<\/code><\/pre>\n<p>\nComo pueden ver, el filtro se envi\u00f3 al servidor remoto, y el tiempo de ejecuci\u00f3n se redujo de 27 a 19 segundos. <\/p>\n<p>Vale la pena se\u00f1alar que el operador <b>is<\/b> se diferencia del operador <b>=<\/b> en que puede trabajar con el valor Null. Esto significa que <b>is not True<\/b> en el filtro dejar\u00e1 valores False y Null, mientras que <b>!= True<\/b> dejar\u00e1 solo valores False. Por lo tanto, al reemplazar el operador <b>is not<\/b> se deben pasar dos condiciones en el filtro con el operador OR, por ejemplo, <b>WHERE (col != True) OR (col is null)<\/b>.<\/p>\n<p>Ya hemos resuelto el booleano, sigamos adelante. Mientras tanto, volvamos a poner el filtro de valor booleano en su forma original para examinar independientemente el efecto de otros cambios.<\/p>\n<h1>timestamptz? hz<\/h1>\n<p>\nDe hecho, a menudo es necesario experimentar con c\u00f3mo redactar correctamente una consulta que involucra servidores remotos, y luego buscar una explicaci\u00f3n de por qu\u00e9 sucede as\u00ed. Hay muy poca informaci\u00f3n al respecto disponible en Internet. En nuestros experimentos descubrimos que el filtro por fecha fija se env\u00eda sin problemas al servidor remoto, mientras que cuando queremos establecer la fecha din\u00e1micamente, por ejemplo, now() o CURRENT_DATE, eso no ocurre. En nuestro ejemplo, agregamos dicho filtro para que la columna created_at contenga datos exactamente un mes en el pasado (BETWEEN CURRENT_DATE - INTERVAL '7 month' AND CURRENT_DATE - INTERVAL '6 month'). \u00bfQu\u00e9 hicimos en este caso?<\/p>\n<pre><code class=\"sql\">explicar analizar detalladamente\nSELECCIONAR contar(1)\nDE fdw_schema.tabla \nDONDE is_active es Verdadero\nY created_dt &gt;= (SELECCIONAR CURRENT_DATE::timestamptz - INTERVALO '7 meses') \nY created_dt &gt;'source' = 'test';\n\nAgregado  (costo=306875.17..306875.18 filas=1 ancho=8) (tiempo real 4789.114..4789.115 filas=1 ciclos=1)\n  Salida: contar(1)\n  InitPlan 1 (devuelve $0)\n    -&gt;  Resultado  (costo=0.00..0.02 filas=1 ancho=8) (tiempo real 0.007..0.008 filas=1 ciclos=1)\n          Salida: ((('ahora'::cstring)::date)::timestamp con zona horaria - '7 meses'::intervalo)\n  InitPlan 2 (devuelve $1)\n    -&gt;  Resultado  (costo=0.00..0.02 filas=1 ancho=8) (tiempo real 0.002..0.002 filas=1 ciclos=1)\n          Salida: ((('ahora'::cstring)::date)::timestamp con zona horaria - '6 meses'::intervalo)\n  -&gt;  Escaneo Externo en fdw_schema.\"tabla\"  (costo=100.02..306874.86 filas=105 ancho=0) (tiempo real 23.475..4681.419 filas=1360025 ciclos=1)\n        Salida: \"tabla\".id, \"tabla\".is_active, \"tabla\".meta, \"tabla\".created_dt\n        Filtro: ((\"tabla\".is_active ES VERDADERO) Y ((\"tabla\".meta-&gt;&gt;'source'::texto) = 'test'::texto))\n        Filas Eliminadas por el Filtro: 76934\n        SQL Remoto: SELECCIONAR is_active, meta DE fdw_schema.tabla DONDE ((created_dt &gt;= $1::timestamp con zona horaria)) Y ((created_dt &lt; $2::timestamp con zona horaria))\nTiempo de planificaci\u00f3n: 0.703 ms\nTiempo de ejecuci\u00f3n: 4789.379 ms<\/code><\/pre>\n<p>\nLe sugerimos al planificador que calculara de antemano la fecha en la subconsulta y pasar ya la variable lista al filtro. Y esta sugerencia nos dio un resultado excelente, la consulta se volvi\u00f3 casi 6 veces m\u00e1s r\u00e1pida.<\/p>\n<p>Nuevamente, aqu\u00ed es importante tener cuidado: el tipo de datos en la subconsulta debe ser el mismo que el del campo por el que filtramos, de lo contrario, el planificador decidir\u00e1 que como los tipos son diferentes, es necesario recuperar todos los datos primero y luego filtrarlos localmente.<\/p>\n<p>Volveremos a establecer el filtro por fecha en su valor original.<\/p>\n<h1>Freddy vs. Jsonb<\/h1>\n<p>\nEn general, los campos booleanos y las fechas ya aceleraron bastante nuestra consulta, sin embargo, a\u00fan quedaba otro tipo de datos. La batalla con la filtraci\u00f3n por \u00e9l, para ser honesto, todav\u00eda no ha terminado, aunque aqu\u00ed tambi\u00e9n hay algunos \u00e9xitos. As\u00ed que as\u00ed fue como logramos pasar el filtro por <b>jsonb<\/b> el campo al servidor remoto.<\/p>\n<pre><code class=\"sql\">explicar analizar detalladamente\nSELECCIONAR contar(1)\nDE fdw_schema.tabla \nDONDE is_active es Verdadero\nY created_dt ENTRE CURRENT_DATE - INTERVALO '7 meses' \nY CURRENT_DATE - INTERVALO '6 meses'\nY meta @&gt; '{\"source\":\"test\"}'::jsonb;\n\nAgregado  (costo=245463.60..245463.61 filas=1 ancho=8) (tiempo real 6727.589..6727.590 filas=1 ciclos=1)\n  Salida: contar(1)\n  -&gt;  Escaneo Externo en fdw_schema.\"tabla\"  (costo=1100.00..245459.90 filas=1478 ancho=0) (tiempo real 16.213..6634.794 filas=1360025 ciclos=1)\n        Salida: \"tabla\".id, \"tabla\".is_active, \"tabla\".meta, \"tabla\".created_dt\n        Filtro: ((\"tabla\".is_active ES VERDADERO) Y (\"tabla\".created_dt &gt;= (('ahora'::cstring)::date - '7 meses'::intervalo)) Y (\"tabla\".created_dt  '{\"source\": \"test\"}'::jsonb))\nTiempo de planificaci\u00f3n: 0.747 ms\nTiempo de ejecuci\u00f3n: 6727.815 ms<\/code><\/pre>\n<p>\nEn lugar de operadores de filtraci\u00f3n, es necesario usar el operador de existencia de uno. <b>jsonb<\/b> en otro. 7 segundos en lugar de los 29 originales. Hasta ahora, esta es la \u00fanica opci\u00f3n exitosa para la transmisi\u00f3n de filtros por <b>jsonb<\/b> a un servidor remoto, pero aqu\u00ed es importante tener en cuenta una limitaci\u00f3n: estamos usando la versi\u00f3n de la base 9.6, sin embargo, planeamos completar las \u00faltimas pruebas y migrar a la versi\u00f3n 12 antes de finales de abril. Una vez que hagamos la actualizaci\u00f3n, escribiremos sobre c\u00f3mo esto afect\u00f3, ya que hay muchas esperanzas puestas en los cambios: json_path, nuevo comportamiento de CTE, push down (existente desde la versi\u00f3n 10). Tenemos muchas ganas de probarlo pronto.<\/p>\n<h1>Finish him<\/h1>\n<p>\nHemos verificado c\u00f3mo cada cambio afecta la velocidad de la consulta por separado. Ahora veamos qu\u00e9 sucede cuando los tres filtros est\u00e1n bien escritos.<\/p>\n<pre><code class=\"sql\">explicar analizar detalladamente\nSELECT count(1)\nFROM fdw_schema.table \nWHERE is_active = True\nAND created_dt &gt;= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 month') \nAND created_dt  '{\"source\":\"test\"}'::jsonb;\n\nAgregado  (costo=322041.51..322041.52 filas=1 ancho=8) (tiempo real=2278.867..2278.867 filas=1 bucles=1)\n  Salida: count(1)\n  InitPlan 1 (devuelve $0)\n    -&gt;  Resultado  (costo=0.00..0.02 filas=1 ancho=8) (tiempo real=0.010..0.010 filas=1 bucles=1)\n          Salida: ((('ahora'::cstring)::date)::timestamp con zona horaria - '7 meses'::interval)\n  InitPlan 2 (devuelve $1)\n    -&gt;  Resultado  (costo=0.00..0.02 filas=1 ancho=8) (tiempo real=0.003..0.003 filas=1 bucles=1)\n          Salida: ((('ahora'::cstring)::date)::timestamp con zona horaria - '6 meses'::interval)\n  -&gt;  Escaneo Externo en fdw_schema.\"table\"  (costo=100.02..322041.41 filas=25 ancho=0) (tiempo real=8.597..2153.809 filas=1360025 bucles=1)\n        Salida: \"table\".id, \"table\".is_active, \"table\".meta, \"table\".created_dt\n        SQL Remoto: SELECT NULL FROM fdw_schema.table WHERE (is_active) AND ((created_dt &gt;= $1::timestamp con zona horaria)) AND ((created_dt  '{\"source\": \"test\"}'::jsonb))\nTiempo de planificaci\u00f3n: 0.820 ms\nTiempo de ejecuci\u00f3n: 2279.087 ms<\/code><\/pre>\n<p>\nS\u00ed, la consulta parece m\u00e1s compleja, es un coste forzado, pero la velocidad de ejecuci\u00f3n es de 2 segundos, \u00a1m\u00e1s de 10 veces m\u00e1s r\u00e1pida! Y estamos hablando de una consulta simple a un conjunto de datos relativamente peque\u00f1o. En consultas reales, hemos obtenido aumentos de hasta cientos de veces.<\/p>\n<p>Resumiendo: si est\u00e1s usando PostgreSQL con FDW, siempre verifica si se est\u00e1n enviando todos los filtros al servidor remoto, y te ir\u00e1 bien\u2026 al menos, hasta que llegues a los joins entre tablas de diferentes <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/es\/server\/\"   title=\"servidores\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1482\">servidores<\/a>. Pero esa ya es historia para otro art\u00edculo.<\/p>\n<p>\u00a1Gracias por su atenci\u00f3n! Estar\u00e9 encantado de escuchar preguntas, comentarios y tambi\u00e9n historias sobre su experiencia en los comentarios.<br \/>\n<br \/>Fuente: <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.2 - 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\/es\/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.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47Anal\u00edtica en tiempo real en arquitecturas de microservicios: entender y simplificar ayudar y asesorar Postgres FDW | ProHoster","description":"La arquitectura de microservicios, como todo en este mundo, tiene sus pros y sus contras. Algunos procesos se vuelven m\u00e1s simples, otros, m\u00e1s complejos.","canonical_url":"https:\/\/prohoster.info\/es\/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":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/79467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=79467"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/79467\/revisions"}],"predecessor-version":[{"id":159871,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/79467\/revisions\/159871"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/79468"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=79467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=79467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=79467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}