sql >> Base de Datos >  >> RDS >> PostgreSQL

Comparación de balanceadores de carga para PostgreSQL

El equilibrio de carga aumenta el rendimiento del sistema, especialmente desde el punto de vista de la aplicación, lo que permite que varias computadoras sirvan los mismos datos. Funciona de tal manera que la carga se distribuye entre las consultas de los clientes a los nodos de réplica además de su nodo principal o principal, mientras que las modificaciones de la base de datos se enrutan únicamente al nodo principal. Cualquier modificación en el nodo principal se propaga posteriormente a cada réplica mediante la replicación de transmisión de PostgreSQL.

¿Cómo pueden afectar los balanceadores de carga a PostgreSQL?

Utilizar el equilibrio de carga dirigirá las aplicaciones cliente para que se conecten al servidor de equilibrio de carga y distribuirá las conexiones iniciadas a los nodos de PostgreSQL disponibles según el tipo de solicitudes de consulta. Esto ayuda a estresar la carga pendiente en un servidor PostgreSQL en particular y promueve el equilibrio paralelo de carga entre los nodos disponibles dentro del clúster.

Usando PostgreSQL, ya hay un puñado de soluciones existentes para hacer que esto funcione. Estas soluciones pueden funcionar sin problemas o el balanceo de carga puede funcionar con la topología actual, con nodos primarios y de reserva, pero el balanceo de carga se implementa en la capa de la aplicación misma. El equilibrio de carga enfrenta desafíos con problemas de sincronización, que es la dificultad fundamental para que los servidores trabajen juntos. Debido a que no existe una solución única que elimine el impacto del problema de sincronización para todos los casos de uso, existen múltiples soluciones. Cada solución aborda este problema de una manera diferente y minimiza su impacto para una carga de trabajo específica.

En este blog, veremos esos balanceadores de carga comparándolos y lo beneficioso que es para su carga de trabajo de PostgreSQL.

Balance de carga HAProxy para PostgreSQL

HAProxy es un motor de no bloqueo controlado por eventos que combina un proxy con una capa de E/S muy rápida y un programador de subprocesos múltiples basado en prioridades. Como está diseñado con un objetivo de reenvío de datos en mente, su arquitectura está diseñada para operar en un proceso liviano que está optimizado para mover datos lo más rápido posible con la menor cantidad de operaciones posible. Se enfoca en optimizar la eficiencia de la memoria caché de la CPU manteniendo las conexiones en la misma CPU el mayor tiempo posible. Como tal, implementa un modelo en capas que ofrece mecanismos de derivación en cada nivel, lo que garantiza que los datos no alcancen niveles más altos a menos que sea necesario. La mayor parte del procesamiento se realiza en el kernel. HAProxy hace todo lo posible para ayudar al kernel a hacer el trabajo lo más rápido posible, dando algunas pistas o evitando ciertas operaciones cuando supone que podrían agruparse más tarde. Como resultado, las cifras típicas muestran el 15 % del tiempo de procesamiento invertido en HAProxy frente al 85 % en el kernel en modo de cierre TCP o HTTP, y alrededor del 30 % para HAProxy frente al 70 % para el kernel en modo HTTP keep-alive.

HAProxy también tiene características adicionales de equilibrio de carga. Por ejemplo, la función de proxy TCP nos permite usarla para conexiones de bases de datos, especialmente para PostgreSQL, utilizando su soporte de servicio de verificación integrado. Aunque hay soporte de servicio de base de datos, no es suficiente para la comprobación de estado deseada, especialmente para un tipo de clúster de replicación. El enfoque estándar cuando se implementa para producción es utilizar la comprobación de TCP y luego depender de xinetd con HAProxy.

Ventajas de usar HAProxy para PostgreSQL

Lo mejor de HAProxy es que es liviano, fácil de configurar y usar, y hace el trabajo como se esperaba. El uso de HAProxy en la parte superior de un clúster PostgreSQL se ha implementado y desplegado varias veces desde grandes organizaciones hasta varias SME/SMB para su uso en producción. Se ha probado durante mucho tiempo para producción y alta capacidad de carga de trabajo, no solo para bases de datos, sino incluso con otros servicios de red, como aplicaciones web o para equilibrio de carga geográfica (distribuir el tráfico entre múltiples centros de datos). Al contar con HAProxy sobre PostgreSQL, permite a los usuarios la capacidad de acelerar o limitar las respuestas para paralelizar y distribuir la carga correctamente a todos los nodos disponibles en el clúster. El mecanismo integrado con HAProxy también permite al usuario configurar una alta disponibilidad sin problemas y más fácil de escalar si se necesita carga y evitar el punto único de falla (SPOF).

Desventajas de usar HAProxy para PostgreSQL

HAProxy no proporciona filtrado de consultas ni análisis de consultas para identificar el tipo de declaraciones que se solicitan. Carece de la capacidad de realizar una división de lectura/escritura en un solo puerto. Configurar un equilibrador de carga sobre HAProxy requiere que al menos configure diferentes puertos para sus escrituras y diferentes para sus lecturas. Esto requiere cambios en la aplicación para satisfacer sus necesidades.

HAProxy también admite una característica muy simple con PostgreSQL para la verificación de estado, pero esto solo determina si el nodo está activo o no, como si solo estuviera haciendo ping al nodo y esperando una respuesta de recuperación. No identifica qué función tiene un nodo que intenta reenviar las conexiones solicitadas desde el cliente al nodo deseado. Por lo tanto, no comprende o no tiene ninguna función en HAProxy para comprender la topología de replicación. Aunque, un usuario puede crear oyentes separados basados ​​en diferentes puertos, pero aun así agrega cambios dentro de la aplicación para satisfacer las necesidades de balanceo de carga. Esto significa que el uso de un script externo con xinetd puede ser la solución para cumplir con los requisitos. Aún así, no está integrado a HAProxy y puede ser propenso a errores humanos.

Si un nodo o grupo de nodos debe colocarse en modo de mantenimiento, también deberá aplicar cambios a su HAProxy, de lo contrario, puede ser catastrófico.

Pgpool-II para equilibrar la carga de su PostgreSQL

Pgpool-II es un software de código abierto y es adoptado por la comunidad masiva de PostgreSQL para implementar el equilibrio de carga y usarlo para actuar como su middleware desde la aplicación hasta la capa de proxy, luego distribuye la carga después de haber analizado completamente el tipo de solicitud por consulta o conexión a la base de datos. Pgpool-II ha estado allí durante mucho tiempo desde 2003, que originalmente se llamó Pgpool hasta que se convirtió en Pgpool-II en 2006, lo que sirve como testimonio de una herramienta proxy muy estable no solo para el equilibrio de carga, sino también para toneladas de funciones interesantes. .

Pgpool-II es conocido como la navaja suiza para PostgreSQL y es un software proxy que se ubica entre los servidores PostgreSQL y un cliente de base de datos PostgreSQL. La idea básica de PgPool-II es que se asienta en el cliente, luego las consultas de lectura deben entregarse a los nodos en espera, mientras que la escritura o las modificaciones van directamente al primario. Es una solución de equilibrio de carga muy inteligente que no solo equilibra la carga, sino que también admite alta disponibilidad y proporciona agrupación de conexiones. El mecanismo inteligente permite equilibrar la carga entre maestros y esclavos. Por lo tanto, las escrituras se cargan en el maestro, mientras que las lecturas de procesamiento se dirigen a los servidores de solo lectura disponibles, que son sus nodos de espera supuestamente activos. Pgpool-II también proporciona replicación lógica. Si bien su uso e importancia han disminuido a medida que las opciones de replicación incorporadas mejoraron en el lado del servidor de PostgreSQL, esta sigue siendo una opción valiosa para las versiones anteriores de PostgreSQL. Además de todo esto, también proporciona agrupación de conexiones.

Pgpool-II tiene una arquitectura más complicada que PgBouncer para admitir todas las funciones que ofrece. Dado que ambos admiten la agrupación de conexiones, el último no tiene funciones de equilibrio de carga.

Pgpool-II puede administrar múltiples servidores PostgreSQL. El uso de la función de replicación permite crear una copia de seguridad en tiempo real en 2 o más discos físicos, de modo que el servicio pueda continuar sin detener los servidores en caso de falla del disco. Dado que Pgpool-II también es capaz de agrupar conexiones, puede proporcionar una limitación en las conexiones excedentes. Hay un límite en el número máximo de conexiones simultáneas con PostgreSQL y las conexiones se rechazan después de esta cantidad de conexiones. Sin embargo, establecer el número máximo de conexiones aumenta el consumo de recursos y afecta el rendimiento del sistema. pgpool-II también tiene un límite en el número máximo de conexiones, pero las conexiones adicionales se pondrán en cola en lugar de devolver un error inmediatamente.

En el equilibrio de carga, si se replica una base de datos, ejecutar una consulta SELECT en cualquier servidor devolverá el mismo resultado. pgpool-II aprovecha la función de replicación para reducir la carga en cada servidor PostgreSQL mediante la distribución de consultas SELECT entre varios servidores, lo que mejora el rendimiento general del sistema. En el mejor de los casos, el rendimiento mejora proporcionalmente a la cantidad de servidores PostgreSQL. El equilibrio de carga funciona mejor en una situación en la que muchos usuarios ejecutan muchas consultas al mismo tiempo.

Usando la función de consulta en paralelo, los datos se pueden dividir entre varios servidores, de modo que una consulta se puede ejecutar en todos los servidores al mismo tiempo para reducir el tiempo de ejecución general. La consulta en paralelo funciona mejor cuando se buscan datos a gran escala.

Ventajas de usar Pgpool para PostgreSQL

Es un tipo de software rico en funciones, no solo para equilibrar la carga. Las características principales y el soporte de esta herramienta son altamente bajo demanda, lo que proporciona agrupación de conexiones, una alternativa a PgBouncer, replicación nativa, recuperación en línea, almacenamiento en caché de consultas en memoria, conmutación por error automática y alta disponibilidad con su subproceso mediante vigilancia. Esta herramienta ha sido muy antigua y la comunidad de PostgreSQL la respalda continuamente de forma masiva, por lo que no puede ser difícil buscar ayuda para lidiar con los problemas. La documentación es su amigo aquí cuando busca preguntas, pero buscar ayuda en la comunidad no es difícil, y el hecho de que esta herramienta sea de código abierto puede usarla libremente siempre que cumpla con la licencia BSD.

Pgpool-II también tiene analizador SQL. Esto significa que puede analizar con precisión los SQL y reescribir la consulta. Esto permite que Pgpool-II aumente el paralelismo según la solicitud de consulta.

Desventajas de usar Pgpool para PostgreSQL

Pgpool-II no ofrece STONITH (dispara al otro nodo en la cabeza) que proporciona un mecanismo de cercado de nodos. Si el servidor PostgreSQL falla, mantiene la disponibilidad del servicio. Pgpool-II también puede ser el punto único de falla (SPOF). Una vez que el nodo deja de funcionar, la conectividad y disponibilidad de su base de datos se detiene desde ese punto. Aunque esto se puede solucionar teniendo redundancia con Pgpool-II y teniendo que utilizar el mecanismo de vigilancia para coordinar varios nodos de Pgpool-II, eso agrega trabajo adicional.

Para la agrupación de conexiones, desafortunadamente, para aquellos que se enfocan solo en la agrupación de conexiones, lo que Pgpool-II no hace muy bien es la agrupación de conexiones, especialmente para una pequeña cantidad de clientes. Debido a que cada proceso secundario tiene su propio grupo y no hay forma de controlar qué cliente se conecta a qué proceso secundario, se deja demasiado a la suerte cuando se trata de reutilizar conexiones.

Uso del controlador JDBC para equilibrar la carga de su PostgreSQL

Java Database Connectivity (JDBC) es una interfaz de programación de aplicaciones (API) para el lenguaje de programación Java, que define cómo un cliente puede acceder a una base de datos. Forma parte de la plataforma Java Standard Edition y proporciona métodos para consultar y actualizar datos en una base de datos, y está orientado a bases de datos relacionales.

El controlador JDBC de PostgreSQL (PgJDBC para abreviar) permite que los programas de Java se conecten a una base de datos de PostgreSQL utilizando un código Java independiente de la base de datos estándar. Es un controlador JDBC de código abierto escrito en Pure Java (Tipo 4) y se comunica en el protocolo de red nativo de PostgreSQL. Debido a esto, el controlador es independiente de la plataforma; una vez compilado, el controlador se puede utilizar en cualquier sistema.

No es comparable con las soluciones de balanceo de carga que hemos señalado anteriormente. Por lo tanto, esta herramienta es su API de interfaz de programación de aplicaciones que le permite conectarse desde su aplicación para cualquier tipo de lenguaje de programación escrito que admita JDBC o al menos tenga un adaptador para conectarse con JDBC. Por otro lado, es más favorable con aplicaciones Java.

El equilibrio de carga con JDBC es bastante ingenuo pero puede hacer el trabajo. Con los parámetros de conexión que pueden activar el mecanismo de equilibrio de carga que ofrece esta herramienta,

  • targetServerType:permite abrir conexiones solo a servidores con el estado/rol requerido de acuerdo con el factor de definición para los servidores PostgreSQL. Los valores permitidos son any, primario, maestro (obsoleto), esclavo (obsoleto), secundario, preferSlave y preferSecondary. El estado o rol se determina observando si el servidor permite escrituras o no.
  • hostRecheckSeconds:controla cuánto tiempo en segundos se almacena en caché el conocimiento sobre el estado de un host en la caché global amplia de JVM. El valor predeterminado es 10 segundos.
  • loadBalanceHosts:le permite configurar si siempre se prueba el primer host (cuando se establece en falso) o si las conexiones se eligen aleatoriamente (cuando se establece en verdadero)

Usando loadBalanceHosts que acepta un valor booleano. loadBalanceHosts está deshabilitado durante su modo predeterminado y los hosts están conectados en el orden dado. Si los hosts habilitados se eligen aleatoriamente del conjunto de candidatos adecuados. La sintaxis básica al conectarse a la base de datos usando jdbc es la siguiente,

  • jdbc:postgresql:base de datos
  • jdbc:postgresql:/
  • jdbc:postgresql://host/base de datos
  • jdbc:postgresql://host/
  • jdbc:postgresql://host:puerto/base de datos
  • jdbc:postgresql://host:puerto/

Dado que loadBalanceHosts y la conexión reciben múltiples hosts configurados como se muestra a continuación,

jdbc:postgresql://host1:port1,host2:port2,host3:port3/database

Esto permite que JDBC elija aleatoriamente del conjunto de candidatos adecuados.

Ventajas de usar PgJDBC para PostgreSQL

No es necesario requerir middleware o proxy como balanceadores de carga. Este proceso agrega más impulso de rendimiento desde la interfaz de la aplicación, ya que no hay una capa adicional para que pase cada solicitud. Si tiene aplicaciones listas y están escritas para admitir la interfaz con JDBC, esto puede ser ventajoso y si no necesita más middleware, especialmente si su presupuesto es ajustado y quiere limitar solo los procesos dedicados a su único propósito y función. A diferencia de las aplicaciones de alto tráfico y gran demanda, puede requerir servidores proxy que actúen como equilibradores de carga y puede exigir recursos adicionales para manejar correctamente las solicitudes de conexiones altas, lo que también requiere una demanda de CPU y procesamiento de memoria.

Desventajas de usar PgJDBC para PostgreSQL

Debe configurar su código para todas y cada una de las conexiones que se solicitarán. Es una interfaz de programación de aplicaciones, lo que significa que hay mucho trabajo por hacer, especialmente si su aplicación es muy exigente con cada solicitud que se envía a los servidores adecuados. No hay alta disponibilidad, escalabilidad automática y tiene un único punto de falla.

¿Qué hay de los contenedores o las herramientas implementadas con libpq para equilibrar la carga de su PostgreSQL?

libpq es la interfaz del programador de aplicaciones C para PostgreSQL. libpq es un conjunto de funciones de biblioteca que permite que los programas cliente pasen consultas al servidor backend de PostgreSQL y reciban los resultados de estas consultas.

libpq también es el motor subyacente para varias otras interfaces de aplicaciones de PostgreSQL, incluidas las escritas para C++, PHP, Perl, Python, Tcl, Swift y ECPG. Entonces, algunos aspectos del comportamiento de libpq serán importantes para usted si usa uno de esos paquetes.

libpq no automatiza el equilibrio de carga y no se debe considerar como una herramienta para soluciones de equilibrio de carga. Sin embargo, es capaz de conectarse a los siguientes servidores disponibles si fallan los servidores anteriores enumerados para la conexión. Por ejemplo, si tiene dos nodos de espera activa disponibles, si el primer nodo está demasiado ocupado y no responde al valor de tiempo de espera correspondiente, entonces se conecta al siguiente nodo disponible en la conexión dada. Depende del tipo de atributos de sesión que haya especificado. Esto se basa en el parámetro target_session_attrs.

El parámetro target_session_attrs acepta valores de lectura y escritura, y cualquiera que sea el valor predeterminado si no se especifica. Lo que hace el parámetro target_session_attrs es que, si se establece en lectura y escritura, solo se acepta una conexión en la que se aceptan transacciones de lectura y escritura durante la conexión. La consulta SHOW transaction_read_only se enviará en cualquier conexión exitosa. Si el resultado es activado, la conexión se cerrará, lo que significa que el nodo se identifica como una réplica o no procesa escrituras. Si se especificaron varios hosts en la cadena de conexión, los servidores restantes se probarán como si el intento de conexión hubiera fallado. El valor predeterminado de este parámetro, cualquiera, lo que significa que todas las conexiones son aceptables. Aunque confiar en target_session_attrs no es suficiente para equilibrar la carga, es posible que pueda simular una modalidad de turno rotativo. Vea mi ejemplo de código C a continuación usando libpq,

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <unistd.h>

#include <libpq-fe.h>




const char* _getRoundRobinConn() {

   char* h[2];

   h[0] = "dbname=node40 host=192.168.30.40,192.168.30.50";

   h[1] = "dbname=node50 host=192.168.30.50,192.168.30.40";



   time_t t;

   //srand((unsigned)time(&t));

   sleep(1.85);

   srand((unsigned)time(NULL));



   return h[rand() % 2];

}



void

_connect()

{

  PGconn *conn;

  PGresult *res;

  char strConn[120];




  snprintf(strConn, 1000, "user=dbapgadmin password=dbapgadmin %s target_session_attrs=any", _getRoundRobinConn());

  //printf("\nstrConn value is: %s\n", strConn);



  conn = PQconnectdb(strConn);



  res = PQexec(conn, "SELECT current_database(), inet_client_addr();");



  if ( PQresultStatus(res)==PGRES_TUPLES_OK )

  {

    printf("current_database = %s on %s\n", PQgetvalue(res, 0, 0),

PQhost(conn));

  } else {



    printf("\nFailed... Message Code is: %d\n", PQresultStatus(res));

  }



  PQclear(res);

  PQfinish(conn);



}



int main(void)

{

  int i;

  for (i=0 ; i<5 ; i++)

    _connect();



  return 0;

}

El resultado revela,

[email protected]:/home/vagrant# gcc -I/usr/include/postgresql -L/usr/lib/postgresql/12/lib libpq_conn.c -lpq -o libpq_conn; ./libpq_conn

current_database = node40 on 192.168.30.40

current_database = node40 on 192.168.30.40

current_database = node50 on 192.168.30.50

current_database = node40 on 192.168.30.40

current_database = node50 on 192.168.30.50

Tenga en cuenta que, si el nodo .40 (el nodo principal) falla, siempre dirigirá la conexión al .50 siempre que su valor target_session_attrs sea cualquiera.

En ese caso, simplemente puede crear el suyo propio libremente con la ayuda de libpq. Aunque el proceso de confiar en libpq y/o sus contenedores es demasiado simple para decir que esto puede proporcionar el mecanismo de equilibrio de carga deseado con una distribución uniforme a los nodos que tiene. Definitivamente, este enfoque y la codificación se pueden mejorar, pero la idea es que esto es gratuito y de código abierto, y puede codificar sin depender de middlewares y diseñar libremente la forma en que funcionará su equilibrio de carga.

Ventajas de usar libpq para PostgresQL

La biblioteca libpq es la interfaz de aplicación del programador construida en el lenguaje de programación C. Sin embargo, la biblioteca se ha implementado en varios idiomas como contenedores para que los programadores puedan comunicarse con la base de datos PostgreSQL utilizando sus idiomas favoritos. Puede crear directamente su propia aplicación utilizando sus idiomas favoritos y luego enumerar los servidores a los que desea que se envíen las consultas, pero solo después del otro, si falla o se agota el tiempo de espera, envíe su carga a los nodos disponibles a los que desea distribuir la carga. Está disponible en lenguajes como Python, Perl, PHP, Ruby, Tcl o Rust.

Desventajas de usar libpq para PostgresQL

La implementación sabia para el paralelismo de carga no es perfecta y debe escribir su propio mecanismo de balanceo de carga por código. No hay una configuración que pueda usar o personalizar, ya que es solo una interfaz de programación para la base de datos PostgreSQL con la ayuda del parámetro target_session_attrs. Eso significa que, al componer una conexión de base de datos, debe tener una serie de conexiones de lectura que vayan a sus nodos de réplica/en espera, luego escriba consultas que vayan al escritor o nodo principal en su código, ya sea en su aplicación o tiene que crear su propia API para administrar la solución de balanceo de carga.

Usar este enfoque definitivamente no necesita ni depende de un middleware desde la perspectiva de la aplicación frontal a la base de datos como backend. Por supuesto, eso es liviano, pero al enviar la lista de servidores al conectarse, no significa que la carga se comprenda y se envíe de manera uniforme a menos que tenga que agregar su código para este enfoque. Esto solo agrega molestias, sin embargo, ya existen soluciones, ¿por qué es necesario reinventar la rueda?

Conclusión

La implementación de sus balanceadores de carga con PostgreSQL puede ser exigente, pero depende del tipo de aplicación y el costo con el que esté tratando. A veces, para una alta demanda de carga, requiere la necesidad de un middleware que actúe como un proxy para distribuir correctamente la carga y también supervisa el estado o la salud de su nodo. Por otro lado, puede demandar recursos del servidor, ya sea que tenga que ejecutarse en un servidor dedicado o requiera CPU y memoria adicionales para satisfacer las necesidades y esto agrega costos. Por lo tanto, también hay una forma simple pero que requiere mucho tiempo pero que ofrece la distribución de la carga a los servidores disponibles que ya tiene. Sin embargo, requiere habilidades de programación y comprensión de la funcionalidad de la API.