Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En su charla, Andrey Borodin te contará cómo tuvieron en cuenta la experiencia del escalado de PgBouncer a la hora de diseñar un pooler de conexiones. Odyssey, cómo lo implementaron en producción. Además, discutiremos qué funciones del pooler nos gustaría ver en nuevas versiones: para nosotros es importante no solo cubrir nuestras necesidades, sino también desarrollar la comunidad de usuarios. Одиссея.

Vídeo:

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

¡Hola a todos! Mi nombre es Andrew.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En Yandex, desarrollo bases de datos de código abierto. Y hoy tenemos un tema sobre conexiones de agrupadores de conexiones.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Si sabes cómo llamar al pool de conexiones en ruso, dímelo. Realmente quiero encontrar un buen término técnico que deba establecerse en la literatura técnica.

El tema es bastante complicado, porque en muchas bases de datos el pooler de conexiones está integrado y ni siquiera necesitas saberlo. Algunas configuraciones, por supuesto, están en todas partes, pero en Postgres esto no funciona. Y en paralelo (en HighLoad++ 2019) hay un informe de Nikolai Samokhvalov sobre la configuración de consultas en Postgres. Y entiendo que han venido personas que ya han configurado las solicitudes perfectamente, y estas son personas que se enfrentan a problemas más raros del sistema relacionados con la red y la utilización de recursos. Y en algunos lugares puede resultar bastante difícil en el sentido de que los problemas no son obvios.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Yandex tiene Postgres. Muchos servicios de Yandex se encuentran en Yandex.Cloud. Y tenemos varios petabytes de datos que generan al menos un millón de solicitudes por segundo en Postgres.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y proporcionamos un clúster bastante típico para todos los servicios: este es el nodo principal principal del nodo, las dos réplicas habituales (sincrónica y asíncrona), copia de seguridad y escalado de solicitudes de lectura en la réplica.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Cada nodo del clúster es Postgres, en el que, además de Postgres y los sistemas de monitoreo, también está instalado un agrupador de conexiones. El pooler de conexiones se utiliza para cercar y para su propósito principal.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

¿Cuál es el objetivo principal de un agrupador de conexiones?

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Postgres adopta un modelo de proceso para trabajar con una base de datos. Esto significa que una conexión es un proceso, un backend de Postgres. Y hay muchos cachés diferentes en este backend, que son bastante costosos de hacer diferentes para diferentes conexiones.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Además, hay una matriz en el código de Postgres llamada procArray. Contiene datos básicos sobre conexiones de red. Y casi todos los algoritmos de procesamiento de procArray tienen una complejidad lineal, se ejecutan en toda la gama de conexiones de red. Es un ciclo bastante rápido, pero con más conexiones de red entrantes, las cosas se vuelven un poco más caras. Y cuando las cosas se vuelven un poco más caras, terminas pagando un precio muy alto por una gran cantidad de conexiones de red.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Hay 3 enfoques posibles:

  • Del lado de la aplicación.
  • Del lado de la base de datos.
  • Y entre, es decir, todas las combinaciones posibles.

Desafortunadamente, el pooler integrado está actualmente en desarrollo. Los amigos de PostgreSQL Professional hacen esto principalmente. Cuándo aparecerá es difícil de predecir. Y de hecho, tenemos dos soluciones para la elección de arquitecto. Estos son el grupo del lado de la aplicación y el grupo de proxy.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

El grupo del lado de la aplicación es la forma más sencilla. Y casi todos los controladores de cliente le proporcionan una manera: representar millones de sus conexiones en el código como algunas docenas de conexiones a la base de datos.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Existe un problema con el hecho de que, en cierto punto, desea escalar el backend y desea implementarlo en muchas máquinas virtuales.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Entonces todavía te das cuenta de que tienes varias zonas de disponibilidad más, varios centros de datos. Y el enfoque de agrupación del lado del cliente genera grandes cifras. Los grandes tienen unas 10 conexiones. Esta es una ventaja que puede funcionar bien.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Si hablamos de agrupadores de proxy, entonces hay dos agrupadores que pueden hacer muchas cosas. No son sólo poolers. Son poolers + funcionalidades más interesantes. Este grupo de páginas и Proxy crujiente.

Pero, lamentablemente, no todo el mundo necesita esta funcionalidad adicional. Y esto lleva al hecho de que los poolers solo admiten la agrupación de sesiones, es decir, un cliente entrante y un cliente saliente a la base de datos.

Esto no es muy adecuado para nuestras tareas, por lo que utilizamos PgBouncer, que implementa la agrupación de transacciones, es decir, las conexiones del servidor se asignan a las conexiones del cliente solo durante la duración de la transacción.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y en nuestra carga, es verdad. Pero hay varios problemas..Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Los problemas comienzan cuando quieres diagnosticar una sesión, porque todas las conexiones entrantes son locales. Todos vinieron con loopback y de alguna manera resulta difícil rastrear la sesión.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Por supuesto que puedes usar application_name_add_host. Esta es la forma secundaria de Bouncer de agregar una dirección IP al nombre_aplicación. Pero el nombre_aplicación lo establece una conexión adicional.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En este gráfico, donde la línea amarilla son las solicitudes reales y donde la línea azul son las solicitudes que llegan a la base de datos. Y esta diferencia es precisamente la configuración de nombre_aplicación, que sólo es necesaria para el seguimiento, pero no es gratuita en absoluto.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Además, Bouncer no puede limitar un grupo, es decir, el número de conexiones de bases de datos por usuario, por base de datos.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

¿A qué conduce esto? Tienes un servicio cargado escrito en C++ y en algún lugar cercano un pequeño servicio en un nodo que no hace nada malo con la base, pero su controlador se vuelve loco. Abre 20 conexiones y todo lo demás esperará. Incluso tu código es correcto.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Por supuesto, escribimos un pequeño parche para Bouncer que agregó esta configuración, es decir, limitar los clientes al grupo.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Sería posible hacer esto en el lado de Postgres, es decir, limitar los roles en la base de datos al número de conexiones.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Pero luego pierde la capacidad de comprender por qué no tiene conexión con el servidor. PgBouncer no arroja un error de conexión, siempre devuelve la misma información. Y no puedes entender: tal vez tu contraseña ha cambiado, tal vez la base de datos simplemente dejó de funcionar, tal vez algo anda mal. Pero no hay ningún diagnóstico. Si no se puede establecer la sesión, no sabrá por qué no se puede realizar.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En cierto momento, miras los gráficos de la aplicación y ves que la aplicación no funciona.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Mire la parte superior y vea que Bouncer tiene un solo subproceso. Este es un punto de inflexión en la vida del servicio. Entiendes que te estabas preparando para escalar la base de datos en un año y medio y que necesitas escalar el pooler.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Hemos llegado a la conclusión de que necesitamos más PgBouncers.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

https://lwn.net/Articles/542629/

Bouncer ha sido ligeramente parcheado.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y lo hicieron para que se puedan levantar varios Bouncers con la reutilización del puerto TCP. Y el sistema operativo ya transfiere automáticamente las conexiones TCP entrantes entre ellos por turnos.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Esto es transparente para los clientes, es decir, parece que tiene un Bouncer, pero tiene fragmentación de conexiones inactivas entre Bouncers en ejecución.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y en algún momento, podrás notar que estos 3 Bouncers se comen cada uno su núcleo al 100%. Necesitas bastantes Bouncers. ¿Por qué?

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Porque tienes TLS. Tienes una conexión cifrada. Y si compara Postgres con y sin TLS, encontrará que la cantidad de conexiones establecidas se reduce en casi dos órdenes de magnitud con el cifrado habilitado, porque el protocolo de enlace TLS consume recursos de la CPU.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y en la parte superior puedes ver bastantes funciones criptográficas que se ejecutan durante una ola de conexiones entrantes. Dado que nuestro principal puede cambiar entre zonas de disponibilidad, una ola de conexiones entrantes es una situación bastante típica. Es decir, por alguna razón, el antiguo primario no estaba disponible y toda la carga se envió a otro centro de datos. Todos vendrán a saludar a TLS al mismo tiempo.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y es posible que una gran cantidad de apretones de manos TLS no saluden ya al Bouncer, sino que le aprieten la garganta. Es posible que una ola de conexiones entrantes no se amortigue debido al tiempo de espera. Si vuelve a intentar llegar a la base sin un retroceso exponencial, no volverán una y otra vez en una ola coherente.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

A continuación se muestra un ejemplo de 16 PgBouncers que cargan 16 núcleos al 100%.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Hemos llegado al PgBouncer en cascada. Esta es la mejor configuración que podemos lograr en nuestra carga Bouncer. Nuestros Bouncers externos sirven para el protocolo de enlace TCP y los Bouncers internos sirven para agrupaciones reales, a fin de no fragmentar en gran medida las conexiones externas.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En esta configuración, es posible un reinicio suave. Puedes reiniciar todos estos 18 Bouncers uno por uno. Pero mantener dicha configuración es bastante difícil. Los administradores de sistemas, DevOps y las personas realmente responsables de este servidor no estarán muy contentos con este esquema.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Parecería que todas nuestras mejoras se pueden promocionar en código abierto, pero Bouncer no lo soporta muy bien. Por ejemplo, la capacidad de ejecutar múltiples PgBouncers en el mismo puerto se comprometió hace un mes. Hace unos años se realizó una solicitud de extracción con esta función.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

https://www.postgresql.org/docs/current/libpq-cancel.html

https://github.com/pgbouncer/pgbouncer/pull/79

O un ejemplo más. En Postgres, puede cancelar una solicitud en ejecución enviando el secreto a otra conexión sin autenticación adicional. Pero algunos clientes simplemente envían un reinicio de TCP, es decir, interrumpen la conexión de red. ¿Qué hará Bouncer con esto? Él no hará nada. Continuará ejecutando la solicitud. Si ha recibido una gran cantidad de conexiones que han sentado la base con pequeñas solicitudes, entonces simplemente desconectar la conexión de Bouncer no será suficiente, aún debe completar aquellas solicitudes que se están ejecutando en la base de datos.

Esto ha sido solucionado y el problema aún no se ha fusionado con el flujo ascendente de Bouncer.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y así llegamos a la conclusión de que necesitamos nuestro propio pool de conexiones, que será desarrollado, parcheado, en el que será posible solucionar problemas rápidamente y que, por supuesto, debe ser multiproceso.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Establecimos el subproceso múltiple como la tarea principal. Necesitamos poder manejar bien la ola de conexiones TLS entrantes.

Para hacer esto, tuvimos que desarrollar una biblioteca separada llamada Machinarium, que está diseñada para describir los estados de la máquina de una conexión de red como un código de serie. Si observa el código fuente de libpq, verá llamadas bastante complejas que pueden devolverle un resultado y decir: "Llámame un poco más tarde. Ahora mismo tengo IO por ahora, pero cuando pasa el IO, tengo una carga en el procesador. Y este es un esquema de varios niveles. La interacción de la red generalmente se describe mediante una máquina de estados. Muchas reglas como "Si anteriormente recibí un encabezado de paquete de tamaño N, ahora estoy esperando N bytes", "Si envié un paquete SYNC, ahora estoy esperando un paquete con metadatos de resultados". Resulta un código bastante complicado y contrario a la intuición, como si el laberinto se hubiera convertido en un escaneo lineal. Lo hicimos de modo que, en lugar de una máquina de estados, el programador describiera la ruta de interacción principal en forma de código imperativo ordinario. Solo en este código imperativo, debe insertar lugares donde la secuencia de ejecución debe interrumpirse esperando datos de la red, pasando el contexto de ejecución a otra rutina (hilo verde). Este enfoque es similar al hecho de que escribimos el camino más esperado en el laberinto en una fila y luego le agregamos ramas.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Como resultado, tenemos un subproceso que hace que TCP acepte y el round-robin pasa una conexión TPC a muchos trabajadores.

En este caso, cada conexión de cliente siempre se ejecuta en un procesador. Y esto le permite hacerlo compatible con el caché.

Y además, hemos mejorado ligeramente la recopilación de paquetes pequeños en un paquete grande para descargar la pila TCP del sistema.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Además, hemos mejorado el pool transaccional en el sentido de que Odyssey, cuando está configurado, puede enviar CANCELAR y ROLLBACK en caso de una falla en la conexión de red, es decir, si nadie está esperando la solicitud, Odyssey le indicará a la base de datos que no intente cumplir. la solicitud que puede desperdiciar recursos preciosos.

Y siempre que sea posible, mantenemos conexiones con el mismo cliente. Esto evita tener que reinstalar application_name_add_host. Si es posible, entonces no tenemos un reinicio adicional de los parámetros necesarios para el diagnóstico.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Trabajamos en interés de Yandex.Cloud. Y si está utilizando PostgreSQL administrado y tiene instalado un agrupador de conexiones, puede crear una replicación lógica hacia afuera, es decir, dejarnos si lo desea, usando la replicación lógica. El rebotador fuera del flujo de replicación lógica no cederá.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Este es un ejemplo de configuración de replicación lógica.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Además, contamos con soporte para replicación física hacia afuera. En la nube, por supuesto, es imposible, porque entonces el clúster le dará demasiada información sobre sí mismo. Pero en tus instalaciones, si necesitas replicación física a través del pooler de conexiones en Odyssey, es posible.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Odyssey tiene monitoreo totalmente compatible con PgBouncer. Tenemos la misma consola que ejecuta casi todos los mismos comandos. Si falta algo, envía una solicitud de extracción, o al menos un problema en GitHub, completaremos los comandos necesarios. Pero ya tenemos la funcionalidad principal de la consola PgBouncer.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y por supuesto tenemos reenvío de errores. Devolveremos el error reportado por la base. Obtendrás información de por qué no estás en la base, no solo de que no estás en ella.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Esta función está deshabilitada en caso de que necesite 100% de compatibilidad con PgBouncer. Podemos comportarnos como Bouncer, por si acaso.

Desarrollo

Algunas palabras sobre el código fuente de Odyssey.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

https://github.com/yandex/odyssey/pull/66

Por ejemplo, existen comandos "Pausar/Reanudar". Suelen utilizarse para actualizar la base de datos. Si necesita actualizar Postgres, puede pausarlo en el grupo de conexiones, realizar pg_upgrade y luego reanudarlo. Y desde el lado del cliente, parecerá que la base de datos simplemente se está desacelerando. Esta funcionalidad nos la trajeron personas de la comunidad. Ella aún no ha muerto, pero pronto todo lo será. (Ya está muerto)

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

https://github.com/yandex/odyssey/pull/73 - Ya está muerto

Además, una de las nuevas características de PgBouncer es la compatibilidad con la autenticación SCRAM, que también nos trajo una persona que no trabaja en Yandex.Cloud. Ambas son funcionalidades complejas e importantes.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Por lo tanto, me gustaría contarte de qué está hecho Odyssey, en caso de que también quieras escribir algo de código ahora.

Tienes la base Odyssey original, que se basa en dos bibliotecas principales. La biblioteca Kiwi es una implementación del protocolo de mensajes de Postgres. Es decir, el proto 3 nativo de Postgres son mensajes estándar que los frontends y backends pueden intercambiar. Están implementados en la biblioteca Kiwi.

La biblioteca Machinarium es una biblioteca de implementación de subprocesos. Un pequeño fragmento de este Machinarium está escrito en ensamblador. Pero no te preocupes, sólo hay 15 líneas.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Arquitectura Odisea. Hay una máquina principal que ejecuta rutinas. Esta máquina implementa la aceptación de conexiones TCP entrantes y la distribución entre los trabajadores.

Dentro de un trabajador, puede trabajar un controlador para varios clientes. Y también en el hilo principal están girando la consola y el procesamiento de tareas de crone para eliminar conexiones que ya no son necesarias en el grupo.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Odyssey se prueba utilizando el conjunto de pruebas estándar de Postgres. Simplemente ejecutamos install-check a través de Bouncer y a través de Odyssey, obtenemos un div nulo. Hay varias pruebas relacionadas con el formato de fechas que fallan exactamente igual en Bouncer y Odyssey.

Además, hay muchos conductores que tienen sus propias pruebas. Y usamos sus pruebas para probar Odyssey.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Además, debido a nuestra configuración en cascada, tenemos que probar varios paquetes: Postgres + Odyssey, PgBouncer + Odyssey, Odyssey + Odyssey para estar seguros de que si Odyssey está en alguna de las partes de la cascada, también funcione como se esperaba. .

Rastrillo

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Usamos Odyssey en producción. Y no sería justo si dijera que todo simplemente funciona. No, es decir, sí, pero no siempre. Por ejemplo, en producción todo funcionó, luego vinieron nuestros amigos de PostgreSQL Professional y dijeron que teníamos una pérdida de memoria. Realmente lo eran, los arreglamos. Pero fue sencillo.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Luego descubrimos que el grupo de conexiones tiene conexiones TLS entrantes y conexiones TLS salientes. Y las conexiones necesitan certificados de cliente y certificados de servidor.

Los certificados de servidor Bouncer y Odyssey se vuelven a leer mediante pcache, pero no es necesario volver a leer los certificados de cliente desde pcache, porque nuestro Odyssey escalable eventualmente depende del rendimiento del sistema al leer este certificado. Esto nos sorprendió porque no descansó inmediatamente. Al principio escalaba linealmente y después de 20 conexiones entrantes simultáneas, este problema se manifestó.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

El método de autenticación conectable es la capacidad de autenticarse con herramientas integradas de Linux. En PgBouncer, está implementado de tal manera que hay un subproceso separado esperando una respuesta de PAM y hay un subproceso PgBouncer principal que sirve a la conexión actual y puede pedirles que vivan en el subproceso PAM.

No implementamos esto por una sencilla razón. Tenemos muchas corrientes. ¿Por qué lo necesitamos?

Como resultado, esto puede crear problemas en el sentido de que si tiene autenticación PAM y autenticación no PAM, una gran ola de autenticación PAM puede retrasar significativamente la autenticación no PAM. Es una de esas cosas que no hemos solucionado. Pero si quieres solucionarlo, puedes hacer esto.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Otro problema fue el hecho de que tenemos un hilo que acepta todas las conexiones entrantes. Y luego se transfieren al grupo de trabajadores, donde se llevará a cabo el protocolo de enlace TLS.

Como resultado, si tienes una ola coherente de 20 conexiones de red, todas serán aceptadas. Y en el lado del cliente, libpq comenzará a informar tiempos de espera. De forma predeterminada, son como 000 segundos allí.

Si no pueden ingresar todos a la base al mismo tiempo, entonces no pueden ingresar a la base, porque todo esto puede cubrirse mediante un reintento no exponencial.

Terminamos copiando el esquema PgBouncer aquí para limitar la cantidad de conexiones TCP que aceptamos.

Si vemos que estamos aceptando conexiones, pero al final no tienen tiempo de darse la mano, las ponemos en cola para que no consuman recursos de CPU. Esto lleva a que no se pueda realizar un protocolo de enlace simultáneo para todas las conexiones llegadas. Pero al menos alguien entrará en la base de datos, incluso si la carga es lo suficientemente fuerte.

Roadmap

¿Qué te gustaría ver en el futuro en Odyssey? ¿Qué estamos dispuestos a desarrollar nosotros mismos y qué esperamos de la comunidad?

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Para agosto de 2019.

Así era la hoja de ruta de Odyssey en agosto:

  • Queríamos autenticación SCRAM y PAM.
  • Queríamos reenviar las solicitudes de lectura al modo de espera.
  • Me gustaría reiniciar en línea.
  • Y la posibilidad de pausar en el servidor.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

La mitad de esta hoja de ruta la hemos hecho nosotros, y no nosotros. Y esto es bueno. Así que analicemos lo que queda y agreguemos más.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Respecto al reenvío de consultas de solo lectura al modo de espera? Disponemos de réplicas que, sin cumplir pedidos, simplemente calentarán el aire. Los necesitamos para proporcionar conmutación por error y conmutación. En caso de problemas en uno de los centros de datos, me gustaría ocuparlos con algún trabajo útil. Porque no podemos configurar los mismos procesadores centrales, la misma memoria de otra manera, porque de otra manera la replicación no funcionará.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En principio, en Postgres, a partir de 10, es posible especificar session_attrs al conectarse. Puede enumerar todos los hosts de bases de datos en la conexión y decir por qué va a la base de datos: escritura o solo lectura. Y el propio conductor elegirá el primer host de la lista que más le guste, que cumpla con los requisitos de session_attrs.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Pero el problema con este enfoque es que no controla el retraso de replicación. Es posible que tengas algún tipo de réplica que esté retrasada por un tiempo inaceptable para tu servicio. Para poder ejecutar solicitudes de lectura con todas las funciones en una réplica, de hecho, necesitamos admitir en Odyssey la capacidad de no funcionar cuando es imposible leer.

Odyssey tiene que ir a la base de datos de vez en cuando y preguntar por la distancia de replicación desde la primaria. Y si ha alcanzado el límite, no permita que entren nuevas solicitudes a la base de datos, dígale al cliente que necesita reiniciar las conexiones y, posiblemente, seleccione otro host para ejecutar las solicitudes. Esto permitirá que la base de datos restaure rápidamente el retraso de replicación y regrese nuevamente para responder con una consulta.

Es difícil nombrar las fechas de implementación porque es de código abierto. Pero espero que no dos años y medio como los colegas de PgBouncer. Esta es la característica que me gustaría ver en Odyssey.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

En la comunidad, la gente preguntó sobre el apoyo a las declaraciones preparadas.. Ahora puedes crear una declaración preparada de dos maneras. Primero, puede ejecutar un comando SQL, es decir, "preparado". Para comprender este comando SQL, debemos aprender a comprender SQL en el lado de Bouncer. Esto sería excesivo porque necesitamos todo el analizador. No podemos analizar todos los comandos SQL.

Pero hay una declaración preparada a nivel de protocolo de mensajes en proto3. Y este es el lugar donde la información que se está creando en la declaración preparada llega de forma estructurada. Y podríamos apoyar el entendimiento de que en alguna conexión de servidor el cliente solicitó crear declaraciones preparadas. E incluso si la transacción se cierra, aún necesitamos mantener conectados al servidor y al cliente.

Pero aquí surge una discrepancia en el diálogo, porque alguien dice que es necesario comprender qué declaraciones preparadas creó el cliente y compartir la conexión del servidor entre todos los clientes que crearon esta conexión al servidor, es decir, quién creó dicha declaración preparada.

Andrés Freund dijo que si llega a usted un cliente que ya había creado una declaración preparada en otra conexión de servidor, entonces créela para él. Pero parece un poco incorrecto ejecutar consultas en la base de datos en lugar del cliente, pero desde el punto de vista del desarrollador que escribe el protocolo para interactuar con la base de datos, sería conveniente si simplemente se le proporcionara una conexión de red. que tiene una solicitud tan preparada.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Y una característica más que debemos implementar. Ahora contamos con monitorización compatible con PgBouncer. Podemos devolver el tiempo promedio de ejecución de la consulta. Pero el tiempo promedio es la temperatura promedio en el hospital: alguien tiene frío, alguien tiene calor; en promedio, todos están sanos. No es cierto.

Necesitamos implementar soporte para percentiles, lo que indicaría que hay solicitudes lentas que consumen recursos y haría que el monitoreo sea más aceptable.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Lo más importante es que quiero la versión 1.0 (la versión 1.1 ya ha sido lanzada). El hecho es que ahora Odyssey está en la versión 1.0rc, es decir, versión candidata. Y todo el rastrillo que enumeré se solucionó exactamente con la misma versión, excepto la pérdida de memoria.

¿Qué significará la versión 1.0 para nosotros? Estamos implementando el Odyssey en nuestras bases. Ya se está ejecutando en nuestras bases de datos, pero cuando alcanza el punto de 1 de solicitudes por segundo, entonces podemos decir que esta es una versión de lanzamiento y esta es una versión que se puede llamar 000.

Varias personas en la comunidad han pedido más pausa y SCRAM en la versión 1.0. Pero esto significará que tendremos que implementar la próxima versión en producción, porque ni SCRAM ni la pausa se han fusionado todavía. Pero lo más probable es que este problema se resuelva con bastante rapidez.

Hoja de ruta de Odyssey: qué más queremos de un agrupador de conexiones. Andrei Borodin (2019)

Estoy esperando tu solicitud de extracción. Y también me gustaría saber qué problemas tienes con Bouncer. Discutamos sobre ellos. Quizás podamos implementar algunas funciones que necesite.

Con esto concluye mi parte, me gustaría saber de usted. ¡Gracias!

preguntas

Si pongo mi propio nombre_aplicación, ¿se lanzará correctamente, incluso en la agrupación de transacciones en Odyssey?

¿Odisea o gorila?

En Odisea. El saltador es arrojado.

Haremos un set.

Y si mi conexión real salta sobre otras conexiones, ¿se transmitirá?

Haremos un conjunto de todos los parámetros que se enumeran. No puedo saber si nombre_aplicación está en esta lista. Parece que lo vio allí. Estableceremos todos los mismos parámetros. Con una solicitud, el conjunto hará todo lo que instaló el cliente durante el inicio.

¡Gracias Andrey por el informe! ¡Buen informe! Me alegro de que Odyssey se desarrolle cada vez más rápido cada minuto. Me gustaría seguir igual. Ya le hemos pedido que tenga una conexión de múltiples fuentes de datos para que Odyssey pueda conectarse a diferentes bases de datos al mismo tiempo, es decir, al maestro esclavo, y luego conectarse automáticamente al nuevo maestro después de una conmutación por error.

Sí, creo recordar esa discusión. Ahora hay varios almacenes. Pero no hay cambio entre ellos. Por nuestra parte, debemos consultar al servidor que aún está vivo y entender que se ha producido una conmutación por error, quien llamará a pg_recovery. Tengo una forma estándar de entender que no llegamos al maestro. ¿Y debemos entender de alguna manera los errores o cómo? Es decir, la idea es interesante, se está discutiendo. Escribe más comentarios. Si tienes manos trabajando que conocen C, esto es generalmente maravilloso.

La cuestión del escalado entre réplicas también nos interesa, porque queremos que la adopción de clústeres replicados sea lo más sencilla posible para los desarrolladores de aplicaciones. Pero aquí me gustaría más comentarios, es decir, cómo hacerlo, cómo hacerlo bien.

La pregunta también se refiere a las réplicas. Resulta que tienes un maestro y varias réplicas. Y está claro que acuden con menos frecuencia a la réplica que al maestro para conectarse, porque pueden tener una diferencia. Usted dijo que la diferencia en los datos puede ser tal que su negocio no le satisfará y no irá allí hasta que se replique. Al mismo tiempo, si no fue allí durante mucho tiempo y luego comenzó a ir, los datos que necesita no estarán disponibles de inmediato. Es decir, si vamos constantemente al maestro, entonces el caché se calienta allí y el caché queda un poco atrás en la réplica.

Sí, es verdad. No habrá bloques de datos en pcache que desee, en caché real no habrá información sobre las tablas que desee, no habrá consultas analizadas en los planes, nada en absoluto.

Y cuando tienes algún tipo de clúster y agregas una nueva réplica allí, mientras se inicia, todo está mal en él, es decir, su caché aumenta.

Se me ocurrió la idea. El enfoque correcto sería ejecutar primero un pequeño porcentaje de consultas en la réplica, lo que calentaría el caché. A grandes rasgos, tenemos la condición de que no debemos estar a más de 10 segundos del maestro. Y esta condición no debería incluirse en una sola ola, sino sin problemas para algunos clientes.

Sí, aumenta de peso.

Esta es una buena idea. Pero primero debes implementar este cierre. Primero debemos apagarlo y luego pensaremos en cómo encenderlo. Esta es una gran característica para activar sin problemas.

nginx tiene esta opción slowly start en el clúster del servidor. Y poco a poco va aumentando la carga.

Sí, gran idea, la intentaremos cuando lleguemos a eso.

Fuente: habr.com

Añadir un comentario