Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

introducción

Hace algún tiempo, me dieron la tarea de desarrollar un clúster de conmutación por error para PostgreSQL, operando en varios centros de datos conectados por fibra dentro de la misma ciudad y capaz de resistir la falla (por ejemplo, un apagón) de un centro de datos. Como software responsable de la tolerancia a fallas, elegí Marcapasos, porque esta es la solución oficial de RedHat para crear clústeres de conmutación por error. Es bueno porque RedHat brinda soporte para él y porque esta solución es universal (modular). Con su ayuda, será posible proporcionar tolerancia a fallas no solo para PostgreSQL, sino también para otros servicios, ya sea utilizando módulos estándar o creándolos para necesidades específicas.

Ante esta decisión, surgió una pregunta razonable: ¿qué tan tolerante a fallas será un clúster de conmutación por error? Para investigar esto, desarrollé un banco de pruebas que simula varias fallas en los nodos del clúster, espera la recuperación, restaura el nodo fallido y continúa probando en un bucle. Inicialmente, este proyecto se llamaba hapgsql, pero con el tiempo me aburrí del nombre, que tiene una sola vocal. Por lo tanto, comencé a nombrar bases de datos tolerantes a fallas (y direcciones IP flotantes que apuntaban a ellas) krogan (un personaje de un juego de computadora, en el que se duplican todos los órganos importantes), y los nodos, los clústeres y el proyecto en sí son tuchanka (el planeta donde viven los krogans).

La gerencia ya ha aprobado abrir un proyecto para la comunidad de código abierto bajo la licencia MIT. El README pronto se traducirá al inglés (porque se espera que los desarrolladores de Pacemaker y PostgreSQL sean los principales consumidores), y decidí publicar la versión rusa antigua del README (parcialmente) en forma de este artículo.

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Los clústeres se implementan en máquinas virtuales VirtualBox. En total, se desplegarán 12 máquinas virtuales (36GiB en total), que forman 4 clústeres de conmutación por error (diferentes opciones). Los primeros dos clústeres consisten en dos servidores PostgreSQL ubicados en diferentes centros de datos y un servidor común Testigo c dispositivo de quórum (alojado en una máquina virtual barata en un tercer centro de datos) que resuelve la incertidumbre 50% / 50%emitiendo su voto. El tercer clúster en tres centros de datos: un maestro, dos esclavos, no dispositivo de quórum. El cuarto clúster consta de cuatro servidores PostgreSQL, dos por centro de datos: uno maestro, el resto son réplicas, y también utiliza Testigo c dispositivo de quórum. El cuarto sobrevive a la falla de dos servidores o un centro de datos. Esta solución se puede escalar a más réplicas si es necesario.

servicio de tiempo ntpd también reconfigurado para la tolerancia a fallos, pero utiliza el método de ntpd (modo huérfano). servidor compartido Testigo actúa como un servidor NTP central, distribuyendo su tiempo a todos los clústeres, sincronizando así todos los servidores entre sí. Si Testigo falla o resulta estar aislado, entonces uno de los servidores del clúster (dentro del clúster) comenzará a distribuir su tiempo. Almacenamiento en caché auxiliar HTTP Proxy también elevado a Testigo, con su ayuda, otras máquinas virtuales tienen acceso a los repositorios de Yum. En realidad, los servicios como la hora exacta y el proxy probablemente estarán alojados en servidores dedicados, y en el stand en el que están alojados. Testigo solo para ahorrar la cantidad de máquinas virtuales y espacio.

Versiones

v0. Funciona con CentOS 7 y PostgreSQL 11 en VirtualBox 6.1.

Estructura del clúster

Todos los clústeres están diseñados para estar ubicados en varios centros de datos, unidos en una red plana y deben soportar fallas o el aislamiento de la red de un centro de datos. Es por eso imposible usar para proteger contra cerebro dividido tecnología de marcapasos estándar llamada STONITH (Dispara al otro nodo en la cabeza) o esgrima. Su esencia: si los nodos en el clúster comienzan a sospechar que algo anda mal con algún nodo, no responde o se comporta de manera incorrecta, entonces lo apagan a la fuerza a través de dispositivos "externos", por ejemplo, una tarjeta de control IPMI o UPS. Pero esto solo funcionará en los casos en que, con una sola falla del servidor IPMI o UPS, continúan funcionando. También planea proteger contra una falla mucho más catastrófica, cuando todo el centro de datos falla (por ejemplo, se desactiva). Y con tal negativa, todo estonio-los dispositivos (IPMI, UPS, etc.) tampoco funcionarán.

En cambio, el sistema se basa en la idea de quórum. Todos los nodos tienen voz, y solo aquellos que ven más de la mitad de todos los nodos pueden trabajar. Este número "medio + 1" se llama quórum. Si no se alcanza el quórum, el nodo decide que está en aislamiento de red y debe apagar sus recursos, es decir, es así protección de cerebro dividido. Si el software responsable de este comportamiento no funciona, entonces debería funcionar un perro guardián, por ejemplo, basado en IPMI.

Si el número de nodos es par (un grupo en dos centros de datos), entonces puede surgir la llamada incertidumbre. 50% / 50% (cincuenta cincuenta) cuando el aislamiento de la red divide el clúster exactamente por la mitad. Por lo tanto, para un número par de nodos, se suma dispositivo de quórum - un demonio poco exigente que se puede ejecutar en la máquina virtual más barata del tercer centro de datos. Da su voto a uno de los segmentos (que ve) y, por lo tanto, resuelve la incertidumbre del 50%/50%. El servidor en el que se ejecutará el dispositivo de quórum, llamé Testigo (terminología de repmgr, me gustó).

Los recursos pueden moverse de un lugar a otro, por ejemplo, de servidores defectuosos a servidores reparables, o por orden de los administradores del sistema. Para que los clientes sepan dónde se encuentran los recursos que necesitan (¿dónde conectarse?), ip flotante (IP flotante). Estas son las IPs que Pacemaker puede mover entre los nodos (todo está en una red plana). Cada uno de ellos simboliza un recurso (servicio) y estará ubicado donde necesite conectarse para acceder a este servicio (en nuestro caso, la base de datos).

Tuchanka1 (esquema comprimido)

Estructura

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

La idea era que tenemos muchas bases de datos pequeñas con poca carga, por lo que no es rentable mantener un servidor esclavo dedicado en modo de espera caliente para transacciones de solo lectura (no hay necesidad de tal desperdicio de recursos).

Cada centro de datos tiene un servidor. Cada servidor tiene dos instancias de PostgreSQL (en la terminología de PostgreSQL, se denominan clústeres, pero para evitar confusiones, las llamaré instancias (por analogía con otras bases de datos), y solo llamaré clústeres de Pacemaker clusters). Una instancia funciona en modo maestro y solo proporciona servicios (solo la IP flotante conduce a ella). La segunda instancia funciona como esclavo del segundo centro de datos y solo brindará servicios si su maestro falla. Dado que la mayoría de las veces solo una de las dos instancias (la maestra) proporcionará servicios (realizará solicitudes), todos los recursos del servidor están optimizados para la maestra (la memoria se asigna para el caché shared_buffers, etc.), pero para que la segunda instancia también tiene suficientes recursos (aunque para un trabajo no óptimo a través del caché del sistema de archivos) en caso de falla de uno de los centros de datos. El esclavo no proporciona servicios (no ejecuta solicitudes de solo lectura) durante el funcionamiento normal del clúster, por lo que no hay guerra por los recursos con el maestro en la misma máquina.

En el caso de dos nodos, la tolerancia a fallas solo es posible con la replicación asíncrona, ya que con la replicación síncrona, la falla del esclavo conducirá a la parada del maestro.

falta de testimonio

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

falta de testimonio (dispositivo de quórum) Consideraré solo para el grupo Tuchanka1, la misma historia será con todos los demás. Si el testigo falla, nada cambiará en la estructura del clúster, todo seguirá funcionando de la misma manera que funcionó. Pero el quórum se convertirá en 2 de 3 y, por lo tanto, cualquier próxima falla será fatal para el clúster. Todavía hay que hacerlo con urgencia.

Rechazo Tuchanka1

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Fallo de uno de los centros de datos de Tuchanka1. En este caso Testigo emite su voto al segundo nodo en el segundo centro de datos. Allí, el antiguo esclavo se convierte en un maestro, como resultado, ambos maestros trabajan en el mismo servidor y ambas direcciones IP flotantes apuntan a ellos.

Tuchanka2 (clásica)

Estructura

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

El esquema clásico de dos nodos. El maestro trabaja en uno, el esclavo trabaja en el segundo. Ambos pueden ejecutar solicitudes (el esclavo solo es de lectura), por lo que ambos son señalados por IP flotante: krogan2 es el maestro, krogan2s1 es el esclavo. Tanto el maestro como el esclavo tendrán tolerancia a fallas.

En el caso de dos nodos, la tolerancia a fallas solo es posible con la replicación asíncrona, porque con la replicación síncrona, la falla del esclavo conducirá a la parada del maestro.

Rechazo Tuchanka2

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Si uno de los centros de datos falla Testigo vota por el segundo. En el único centro de datos en funcionamiento, se generará el maestro y ambas direcciones IP flotantes apuntarán a él: maestro y esclavo. Por supuesto, la instancia debe configurarse de tal manera que tenga suficientes recursos (límites de conexión, etc.) para aceptar simultáneamente todas las conexiones y solicitudes de la IP flotante maestra y esclava. Es decir, durante el funcionamiento normal, debe tener un margen suficiente para los límites.

Tuchanka4 (muchos esclavos)

Estructura

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Ya otro extremo. Hay bases de datos que tienen muchas solicitudes de solo lectura (un caso típico de un sitio muy cargado). Tuchanka4 es una situación en la que puede haber tres o más esclavos para manejar tales solicitudes, pero aún así no demasiados. Con una gran cantidad de esclavos, será necesario inventar un sistema de replicación jerárquico. En el caso mínimo (en la imagen), cada uno de los dos centros de datos tiene dos servidores, cada uno de los cuales tiene una instancia de PostgreSQL.

Otra característica de este esquema es que ya es posible organizar aquí una replicación síncrona. Está configurado para replicar, si es posible, a otro centro de datos y no a una réplica en el mismo centro de datos que el maestro. El maestro y cada esclavo se indican mediante una IP flotante. Para bien, entre los esclavos será necesario hacer algún tipo de equilibrio de solicitudes. proxy sql, por ejemplo, en el lado del cliente. Diferentes tipos de clientes pueden requerir diferentes tipos de proxy sql, y solo los desarrolladores del cliente saben quién necesita cuál. Esta funcionalidad puede ser implementada por un demonio externo o por una biblioteca cliente (grupo de conexiones), etc. Todo esto está más allá del alcance del clúster de conmutación por error de la base de datos (conmutación por error). servidor proxy SQL se puede implementar de forma independiente, junto con la conmutación por error del cliente).

Rechazo Tuchanka4

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Si un centro de datos (es decir, dos servidores) falla, el testigo vota por el segundo. Como resultado, dos servidores trabajan en el segundo centro de datos: el maestro trabaja en uno y la IP flotante maestra apunta a él (para recibir solicitudes de lectura y escritura); y un esclavo con replicación síncrona se está ejecutando en el segundo servidor, y una de las direcciones IP flotantes del esclavo apunta a él (para solicitudes de solo lectura).

Lo primero a tener en cuenta: no todas las IP flotantes esclavas funcionarán, sino solo una. Y para poder trabajar correctamente con él, será necesario que proxy sql redirigió todas las solicitudes a la única IP flotante restante; y si proxy sql no, puede enumerar todos los esclavos IP flotantes separados por comas en la URL de conexión. En ese caso, con libpq la conexión será a la primera IP que funcione, como se hace en el sistema de pruebas automáticas. Quizás en otras bibliotecas, por ejemplo, JDBC, esto no funcione y sea necesario proxy sql. Esto se hace porque se prohíbe que la IP flotante para los esclavos se eleve simultáneamente en un servidor, por lo que se distribuyen uniformemente entre los servidores esclavos si hay varios.

Segundo: incluso en caso de falla del centro de datos, se mantendrá la replicación síncrona. E incluso si ocurre una falla secundaria, es decir, uno de los dos servidores falla en el centro de datos restante, el clúster, aunque deja de brindar servicios, aún conservará información sobre todas las transacciones comprometidas para las que confirmó el compromiso (habrá no habrá información de pérdida en caso de fallo secundario).

Tuchanka3 (3 centros de datos)

Estructura

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Este es un clúster para una situación en la que hay tres centros de datos completamente funcionales, cada uno de los cuales tiene un servidor de base de datos completamente funcional. En este caso dispositivo de quórum innecesario. Un maestro trabaja en un centro de datos y los esclavos trabajan en los otros dos. La replicación es síncrona, tipo ANY (esclavo1, esclavo2), es decir, el cliente recibirá una confirmación de compromiso cuando alguno de los esclavos sea el primero en responder que ha aceptado el compromiso. Los recursos son señalados por una IP flotante para el maestro y dos para los esclavos. A diferencia de Tuchanka4, las tres IP flotantes son tolerantes a fallas. Para equilibrar consultas SQL de solo lectura, puede usar proxy sql (con tolerancia a fallas separada), o asigne una IP flotante esclava a la mitad de los clientes y la segunda a la otra mitad.

Rechazo Tuchanka3

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Si uno de los centros de datos falla, quedan dos. En uno, se generan la IP maestra y flotante del maestro, en el segundo, la IP flotante esclava y ambas esclavas (la instancia debe tener un margen de recursos doble para aceptar todas las conexiones de ambas IP flotantes esclavas). Replicación síncrona entre maestros y esclavos. Además, el clúster guardará información sobre transacciones comprometidas y confirmadas (no habrá pérdida de información) en caso de destrucción de dos centros de datos (si no se destruyen al mismo tiempo).

Decidí no incluir una descripción detallada de la estructura y el despliegue del archivo. Si quieres jugar, puedes leer todo esto en el LÉAME. Solo doy una descripción de las pruebas automáticas.

Sistema de prueba automático

Para verificar la tolerancia a fallas de los grupos con imitación de varias fallas, se realizó un sistema de prueba automático. Lanzado por un script test/failure. El script puede tomar como parámetros la cantidad de clústeres que desea probar. Por ejemplo, este comando:

test/failure 2 3

solo probará el segundo y tercer grupo. Si no se especifican los parámetros, se probarán todos los clústeres. Todos los clústeres se prueban en paralelo y el resultado se muestra en el panel tmux. Tmux usa un servidor tmux dedicado, por lo que el script se puede ejecutar desde el tmux predeterminado, lo que da como resultado un tmux anidado. Recomiendo usar la terminal en una ventana grande y con letra pequeña. Antes de comenzar la prueba, todas las máquinas virtuales se revierten a una instantánea en el momento en que finaliza el script. setup.

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

El terminal se divide en columnas según la cantidad de clústeres probados, por defecto (en la captura de pantalla) hay cuatro de ellos. Describiré el contenido de las columnas usando Tuchanka2 como ejemplo. Los paneles en la captura de pantalla están numerados:

  1. Aquí es donde se muestran las estadísticas de prueba. Altavoces:
    • el fracaso — el nombre de la prueba (función en el script) que emula la falla.
    • reacción — el tiempo medio aritmético en segundos durante el cual el clúster ha restablecido su rendimiento. Se mide desde el inicio del script que emula la falla, y hasta el momento en que el clúster restablece su salud y puede continuar brindando servicios. Si el tiempo es muy corto, por ejemplo, seis segundos (esto sucede en clústeres con varios esclavos (Tuchanka3 y Tuchanka4)), significa que el mal funcionamiento terminó en un esclavo asíncrono y no afectó el rendimiento de ninguna manera, no hubo interruptores de estado del clúster.
    • desviación - muestra la dispersión (precisión) del valor reacción por el método de la desviación estándar.
    • contar Cuántas veces se ha realizado esta prueba.
  2. Un breve registro le permite evaluar lo que está haciendo actualmente el clúster. Se muestran el número de iteración (prueba), la marca de tiempo y el nombre de la operación. Una ejecución demasiado larga (> 5 minutos) indica algún tipo de problema.
  3. corazón (corazón) es la hora actual. Para la evaluación del rendimiento visual maestros la hora actual se escribe constantemente en su tabla utilizando la IP flotante del maestro. Si tiene éxito, el resultado se muestra en este panel.
  4. golpear (pulso) - "hora actual", que fue previamente registrada por el guión corazón para dominar, ahora lee de esclavo a través de su IP flotante. Le permite evaluar visualmente el rendimiento de un esclavo y la replicación. No hay esclavos con IP flotante en Tuchanka1 (no hay esclavos que brinden servicios), pero hay dos instancias (DB), por lo que no se mostrará aquí golpearY corazón segunda instancia
  5. Monitoreo del estado del clúster usando la utilidad pcs mon. Muestra la estructura, distribución de recursos por nodos y otra información útil.
  6. Muestra la supervisión del sistema desde cada máquina virtual del clúster. Puede haber más paneles de este tipo: cuántas máquinas virtuales tiene el clúster. dos gráficos Carga de CPU (dos procesadores en máquinas virtuales), nombre de la máquina virtual, Carga del sistema (llamado Promedio de carga porque promedió durante 5, 10 y 15 minutos), datos de proceso y asignación de memoria.
  7. Seguimiento del script que realiza las pruebas. En caso de mal funcionamiento, una interrupción repentina del trabajo o un ciclo de espera interminable, aquí puede ver el motivo de este comportamiento.

La prueba se lleva a cabo en dos etapas. Primero, el script pasa por todo tipo de pruebas, eligiendo aleatoriamente una máquina virtual a la que se le debe aplicar esta prueba. Luego se realiza un ciclo de prueba sin fin, las máquinas virtuales y un mal funcionamiento se seleccionan aleatoriamente cada vez. La finalización repentina del script de prueba (panel inferior) o un ciclo de espera sin fin para algo (> 5 minutos para completar una operación, esto se puede ver en el seguimiento) indica que algunas de las pruebas en este clúster han fallado.

Cada prueba consta de las siguientes operaciones:

  1. Inicio de una función que emula un fallo.
  2. Ready? - esperando la restauración de la salud del clúster (cuando se prestan todos los servicios).
  3. Se muestra el tiempo de espera de recuperación del clúster (reacción).
  4. Fijar - el clúster está "reparado". Después de lo cual debería volver a un estado completamente operativo y listo para el próximo mal funcionamiento.

Aquí hay una lista de pruebas con una descripción de lo que hacen:

  • Tenedorbomba: Crea "Fuera de la memoria" con una bomba de horquilla.
  • Sin espacio: el disco duro está lleno. Pero la prueba es más bien simbólica, con la carga insignificante que se crea durante la prueba, cuando el disco duro se desborda, PostgreSQL no suele fallar.
  • Postgres-KILL: mata a PostgreSQL con el comando killall -KILL postgres.
  • postgres-DETENER: cuelga PostgreSQL con el comando killall -STOP postgres.
  • Apagado: "desenergiza" la máquina virtual con el comando VBoxManage controlvm "виртуалка" poweroff.
  • Reanudar: recarga la máquina virtual con el comando VBoxManage controlvm "виртуалка" reset.
  • DETENER SBD: suspende el demonio SBD con el comando killall -STOP sbd.
  • Apagado: a través de SSH envía un comando a la máquina virtual systemctl poweroff, el sistema se cierra correctamente.
  • desconectar: aislamiento de red, comando VBoxManage controlvm "виртуалка" setlinkstate1 off.

Finalice las pruebas con el comando tmux estándar "kill-window" ctrl-b&, o por comando "separar-cliente" ctrl-bd: al mismo tiempo, se completa la prueba, se cierra tmux, se apagan las máquinas virtuales.

Problemas identificados durante las pruebas

  • Actualmente perro guardián demonio sbd maneja la detención de los demonios observados, pero no los congela. Y, como resultado, las fallas se resuelven incorrectamente, lo que lleva a una congelación solo corosinc и Marcapasos, pero no colgando sbd. para cheque corosinc ya tengo PR # 83 (en GitHub en sbd), aceptado en la rama dominar. Prometieron (en PR#83) que habría algo similar para Pacemaker, espero que para RedHat 8 servirá. Pero tales "fallos" son especulativos, fáciles de imitar artificialmente usando, por ejemplo, killall -STOP corosyncpero nunca se encuentran en la vida real.

  • У Marcapasos en la versión para 7 CentOS configurado incorrectamente sincronización_tiempo de espera у dispositivo de quórum, como resultado si un nodo fallaba, el segundo nodo se reiniciaba con cierta probabilidad, a la que se suponía que el maestro se mudaría. Curado por aumento sincronización_tiempo de espera у dispositivo de quórum durante el despliegue (en script setup/setup1). Esta enmienda no fue aceptada por los desarrolladores. Marcapasos, en cambio, prometieron volver a trabajar en la infraestructura de tal manera (en un futuro indefinido) que este tiempo de espera se calcule automáticamente.

  • Si especificó durante la configuración de la base de datos que LC_MESSAGES (mensajes de texto) Unicode se puede utilizar, por ejemplo, ru_RU.UTF-8, luego al inicio Postgres en un entorno donde la configuración regional no es UTF-8, por ejemplo, en un entorno vacío (aquí marcapasos+pgsqlms(paf) comienza Postgres) entonces en el registro en lugar de letras UTF-8 habrá signos de interrogación. Los desarrolladores de PostgreSQL nunca acordaron qué hacer en este caso. Cuesta, hay que poner LC_MESSAGES=en_US.UTF-8 al configurar (crear) una instancia de base de datos.

  • Si se establece wal_receiver_timeout (de manera predeterminada, es 60 s), entonces, al probar PostgreSQL-STOP en el maestro en los clústeres tuchanka3 y tuchanka4 La replicación no se vuelve a conectar a un nuevo maestro. La replicación allí es sincrónica, por lo que no solo se detiene el esclavo, sino también el nuevo maestro. Se obtiene configurando wal_receiver_timeout=0 al configurar PostgreSQL.

  • Ocasionalmente observé que la replicación de PostgreSQL se colgaba en la prueba ForkBomb (desbordamiento de memoria). Después de ForkBomb, a veces los esclavos pueden no volver a conectarse al nuevo maestro. He visto esto solo en los clústeres tuchanka3 y tuchanka4, donde debido al hecho de que la replicación es síncrona, el maestro se colgó. El problema desapareció por sí solo, después de mucho tiempo (alrededor de dos horas). Se necesita más investigación para solucionar esto. Los síntomas son similares al error anterior, que se produce por una causa diferente, pero con las mismas consecuencias.

Foto de Krogan tomada de deviant Art con el permiso del autor:

Modelado de clústeres de conmutación por error basados ​​en PostgreSQL y Pacemaker

Fuente: habr.com

Añadir un comentario