¿Qué estructura es más adecuada para la replicación maestro-esclavo de Redis?
Resumen resumen de replicación maestro-esclavo de Redis
¿Tema? Redis
La estrategia de replicación maestro-esclavo de Redis se implementa a través de su archivo rdb persistente. El proceso consiste en volcar el archivo rdb primero, transferir el archivo rdb por completo al servidor esclavo (esclavo) y luego Las operaciones volcadas. se sincronizan con el servidor esclavo en tiempo real. Haga que el servidor esclavo sea una réplica exacta del servidor maestro. El documento oficial ReplicationHowto menciona las siguientes funciones:
Un servidor maestro admite múltiples servidores esclavos. Un servidor esclavo puede aceptar conexiones de otros servidores esclavos y actuar como servidor maestro para otros servidores esclavos, formando así un servidor maestro. Estructura esclava multinivel
La función de replicación no bloquea el servidor maestro. Servidor: el servidor maestro puede continuar procesando solicitudes de comando incluso si uno o más servidores esclavos están en proceso de sincronización inicial. La replicación no bloquea al esclavo: con la configuración adecuada en el archivo redis.conf, el servidor puede usar versiones anteriores del conjunto de datos para procesar consultas de comandos incluso cuando el esclavo está en un estado de sincronización inicial. Sin embargo, cuando el conjunto de datos antiguo se elimina del servidor y se carga el nuevo conjunto de datos, la solicitud de conexión se bloquea.
La replicación se puede utilizar para proporcionar escalabilidad, como usar esclavos para redundancia de datos, enviar comandos largos (como ordenar) a algunos esclavos para evitar bloquear al maestro o usar Persistir desde el esclavo y tener el esclavo. realice la operación de persistencia simplemente comentando el comando de guardar en el archivo de configuración del maestro.
Redis utiliza replicación asincrónica. A partir de Redis 2.8, el esclavo informará el progreso del flujo de replicación al maestro una vez por segundo.
Implementación de la replicación
La replicación maestro-esclavo en Redis se divide en dos etapas:
1) Operación de sincronización: actualiza el estado de la base de datos del servidor esclavo a el maestro El estado actual de la base de datos del servidor.
2) Propagación de comandos: cuando se modifica el estado de la base de datos del servidor maestro, lo que hace que el estado de la base de datos del servidor maestro y el servidor esclavo sean inconsistentes, restaure el servidor maestro y el servidor esclavo a un estado consistente. estado.
Sincronización
Cuando el cliente envía el comando SLAVEOF al servidor esclavo y solicita al servidor esclavo que copie el servidor maestro, el servidor esclavo primero debe realizar una operación de sincronización, lo que significa que el estado de la base de datos del servidor se actualice al estado actual de la base de datos del servidor principal.
La sincronización del servidor esclavo con el servidor maestro se completa enviando el comando SYNC? al servidor maestro, de la siguiente manera:
El servidor esclavo envía SYNC? ?
Después de recibir el comando SYNC, el servidor principal ejecuta el comando BGSAVE, genera un archivo RDB en segundo plano y usa el búfer para registrar todos los comandos de escritura ejecutados a partir de ahora.
Después de que el servidor maestro ejecuta el comando BGSAVE, el servidor maestro envía el archivo RDB generado por el comando BGSAVE al servidor esclavo. El servidor esclavo recibe y carga el archivo RDB y actualiza su propio estado de base de datos. El servidor maestro ejecuta el comando BGSAVE del estado de la base de datos en ese momento.
El servidor maestro envía todos los comandos de escritura registrados en el búfer al servidor esclavo, y el servidor esclavo ejecuta estos comandos y actualiza el estado de su base de datos al de la base de datos del servidor maestro.
La siguiente figura muestra cómo el servidor maestro y el servidor esclavo se comunican durante la ejecución del comando SYNC:
Propagación del comando
Después de completar la operación de sincronización , el servidor maestro y el servidor esclavo La base de datos del servidor está en un estado consistente, pero esta consistencia no es estática. Cuando el servidor maestro ejecuta el comando de escritura enviado por el cliente, la base de datos del servidor maestro puede modificarse. En este momento, el servidor maestro y el servidor esclavo ya no están en un estado consistente. Para restaurar el servidor maestro y el servidor esclavo a un estado consistente, el servidor maestro necesita realizar una operación de propagación de comandos en el servidor esclavo: el servidor maestro enviará el comando de escritura que ejecuta (es decir, el comando que causa la El servidor maestro y el servidor esclavo son inconsistentes) al servidor esclavo para su ejecución. Cuando el servidor esclavo ejecuta el mismo comando de escritura, el servidor maestro y el servidor esclavo volverán a un estado consistente.
Cuando el servidor esclavo ejecuta el mismo comando de escritura, el servidor maestro y el servidor esclavo volverán a un estado consistente nuevamente. Sin embargo, esta característica de replicación tiene un defecto: cuando el servidor maestro y el servidor esclavo se desconectan y se vuelven a conectar para realizar una operación de sincronización, se genera un archivo RDB completo y se envía al servidor esclavo para su carga, pero las bases de datos del servidor maestro y el servidor esclavo El estado es básicamente consistente antes de la desconexión. La única inconsistencia es que el servidor principal ejecutó el comando para modificar la base de datos después de la desconexión. Por lo tanto, el comando SYNC es un desperdicio en este momento, porque generar archivos RDB requiere mucha CPU. Y la CPU es muy importante para el servidor maestro y el servidor esclavo. Los archivos RDB son un proceso que consume una gran cantidad de CPU, memoria y recursos de IO. El envío de archivos RDB al servidor esclavo ocupará muchos recursos de ancho de banda de la red y el servidor esclavo se bloqueará durante el proceso de carga del archivo RDB. responder a cualquier comando Por lo tanto, en la mayoría de los casos, no es necesario ejecutar el comando SYNC y es muy irrazonable hacerlo.
Para solucionar el problema de rendimiento del comando SYNC en versiones anteriores a la 2.8, diseñamos un nuevo comando PSYNC en la versión 2.8. El comando PSYNC se divide en ?resincronización completa? ¿Resincronización parcial? El proceso de resincronización completa se utiliza para la replicación inicial desde el servidor durante la inicialización. Es básicamente el mismo que el comando SYNC que se usa para la replicación repetida después de la desconexión. Cuando las condiciones lo permiten, no generará un archivo RDB. responder al servidor esclavo A + Continuar indica la ejecución de la parte de resincronización y envía el comando para modificar la base de datos ejecutada por el servidor maestro después de que el servidor esclavo se desconecta del servidor esclavo y es ejecutado por el servidor esclavo.
El servidor maestro envía estos comandos al servidor esclavo, y el servidor esclavo ejecuta estos comandos para sincronizar la base de datos.
La función de resincronización parcial consta de:
¿Desplazamiento de replicación para el maestro? Desplazamiento de replicación del servidor esclavo: cuando el servidor maestro sincroniza comandos con el servidor esclavo, el servidor maestro y el servidor esclavo registrarán un desplazamiento de replicación respectivamente. Cuando el estado de la base de datos del servidor maestro y el servidor esclavo son consistentes, los dos replican. las compensaciones son las mismas. Si las dos compensaciones son inconsistentes, significa que el estado actual del servidor maestro y el servidor esclavo son inconsistentes.
Búfer de trabajo pendiente de replicación en el servidor maestro: el búfer de trabajo pendiente de replicación es una cola de tamaño fijo de primero en entrar, primero en salir. Cuando la cola está llena, se expulsarán los primeros datos insertados. Cuando el servidor principal propaga un comando, también coloca el comando en un búfer, que contiene dos partes de datos: desplazamiento y bytes. Durante el proceso de replicación, el servidor esclavo informará el desplazamiento al servidor maestro, y el servidor maestro verificará si el desplazamiento actual todavía existe en el búfer y, si existe, realizará una resincronización parcial; de lo contrario, realizará una resincronización completa; . Debido a que el búfer de trabajo pendiente es una cola de tamaño fijo, cuando el esclavo está desconectado durante un período prolongado, es probable que el desplazamiento de replicación del esclavo ya no esté en el búfer y solo se puede realizar una resincronización completa.
¿El ID de ejecución del servidor? El maestro envía la ID al esclavo en la sincronización inicial, el esclavo guarda la ID del maestro, cuando se desconecta y se vuelve a conectar informará la ID del maestro guardada previamente al maestro, el maestro verificará la copia previamente copiada del esclavo. ¿Es la ID del servidor maestro la misma? como su propia ID? Si es el mismo, realice una resincronización parcial; si es diferente, significa que el estado registrado previamente por el servidor esclavo no es el mismo que el estado actual; si es diferente, significa que el estado; registrado previamente por el servidor esclavo es diferente del estado actual No es el mismo. Si el estado registrado previamente del servidor no es el estado del maestro actual, será necesario realizar una resincronización completa.
Ejecución del comando PSYNC
En la replicación inicial o cuando se ejecutó un comando SLAVEOF no one anterior, realice una resincronización completa: envíe el comando PSYNC ?-1 al maestro. Si el esclavo ya ha replicado un maestro, envíe el comando PSYNC
runid es el ID del servidor maestro de la última replicación y offset es el desplazamiento de replicación del servidor. El servidor maestro decide qué sincronización realizar en función de estos dos parámetros, determina si el ID del servidor es el mismo que el de la máquina local y si. el desplazamiento de replicación está en el medio del búfer. El servidor maestro tiene tres respuestas:
Respuesta+FULLRESYNC
Respuesta+CONTINUAR , lo que indica que se realiza una resincronización parcial y el servidor esclavo espera a que el servidor maestro envíe los datos perdidos
Respuesta -ERR, lo que indica que la versión del servidor maestro es inferior a 2.8 y no admite el comando PSYNC
Proceso de replicación de la nueva versión:
Establezca la dirección y el puerto del servidor maestro llamando al comando SAVEOF
Establecer una conexión de socket.
Envíe el comando PING para comprobar si el servidor maestro y el servidor esclavo pueden procesar el comando normalmente.
Se requiere autenticación si masterauth está configurado en el servidor esclavo y requirepass está configurado en el servidor maestro. O configura ambas opciones o ninguna. Si solo se configura un servidor esclavo, se informará un error al enviar comandos al servidor maestro.
Para enviar información del puerto, ejecute el comando REPLCONF listening-port
Durante la sincronización, el servidor esclavo envía un comando PSYNC al servidor maestro.
Propagación del comando: una vez completada la sincronización, el servidor maestro propagará el comando de escritura ejecutado posteriormente al servidor esclavo para garantizar que el servidor maestro y el servidor esclavo estén en el mismo estado.
Detección de latidos
En la fase de propagación del comando, el servidor esclavo envía el comando al servidor maestro a una frecuencia de una vez por segundo de forma predeterminada: REPLCONF ACK
Detectar el estado de la conexión de red del servidor esclavo y detectar si la conexión entre los servidores maestro y esclavo es normal. Si el servidor maestro no recibe el comando REPLCONF ACK del servidor esclavo durante más de un cierto período de tiempo, puede haber un problema con su conexión.
La implementación auxiliar de la opción min-slaves, las opciones min-slaves-to-write y min-slaves-max-lag evitan que el maestro ejecute comandos de escritura de manera insegura. min-slaves-to-write 3 min-slaves-max-lag 10 significa que si hay menos de tres esclavos, o la latencia de los tres esclavos es superior a 10 segundos, el maestro rechazará el comando de escritura.
Al detectar la pérdida de comando, el servidor maestro recibirá el comando REPLCONF ACK emitido por el servidor esclavo y verificará si el desplazamiento del servidor esclavo es el mismo que el del servidor maestro. voluntad Los comandos que siguen al desplazamiento del esclavo en el búfer de trabajo pendiente se envían al esclavo.
Seguridad de datos para la replicación cuando la persistencia maestra está desactivada
Al configurar la replicación de Redis, se recomienda encarecidamente activar la persistencia maestra. De lo contrario, los servicios implementados deberían evitar las recuperaciones automáticas debido a la latencia y otros problemas. Para ayudar a comprender los peligros de los pull-ups automáticos cuando el maestro desactiva la persistencia, considere el siguiente ejemplo, que resultará en una pérdida total de datos tanto en el servidor maestro como en el esclavo:
Supongamos que el nodo A es el maestro y la persistencia está desactivada. El nodo B y el nodo C están replicando datos del nodo A
El nodo A falló y el servicio de extracción automática lo reinició.
Dado que la persistencia está desactivada en el nodo A, no hay datos después del reinicio.
El nodo B y el nodo C están copiando datos del nodo A, pero el nodo A está vacío y ha eliminado su propia copia guardada de los datos. .
Incluso usar Sentinel para lograr la alta disponibilidad de Redis es muy peligroso cuando la persistencia está desactivada en el servidor maestro y el proceso de llamada automática está activado al mismo tiempo. Esto se debe a que el maestro puede activarse tan rápidamente que Sentinel no puede detectar que el maestro se ha reiniciado dentro del intervalo de latidos configurado y luego seguir realizando el proceso de pérdida de datos descrito anteriormente. La seguridad de los datos es extremadamente importante en todo momento, por lo que se debe desactivar la activación automática cuando el maestro desactiva la persistencia.
Servidor esclavo de solo lectura
A partir de Redis 2.6, el servidor esclavo admite el modo de solo lectura y lo utiliza como modo predeterminado del servidor esclavo.
El modo de solo lectura se controla mediante la opción "slave-read-only" en el archivo redis.conf, y también se puede activar o desactivar usando el comando "CONFIG SET".
Los dispositivos esclavos de solo lectura se niegan a ejecutar ningún comando de escritura, por lo que los datos no se pueden escribir por error en el dispositivo esclavo.
Incluso si el dispositivo esclavo es de solo lectura, los comandos administrativos como "DEBUG" y "CONFIG" aún están disponibles, y el servidor no debe estar expuesto a Internet ni a ninguna red que no sea de confianza. Sin embargo, puede aumentar la seguridad de los esclavos de solo lectura deshabilitando la ejecución de ciertos comandos usando la opción de cambio de nombre de comando en redis.conf.
Aún es posible almacenar datos temporales sin importancia en el servidor esclavo. Por ejemplo, un cliente puede almacenar la información de accesibilidad del maestro en el servidor esclavo para implementar una estrategia de conmutación por error. Así que todavía necesitas hacer que el esclavo sea escribible.
Configuración del servidor esclavo
Si el servidor maestro tiene una contraseña configurada usando la opción "requirepass", el servidor esclavo también debe estar autenticado para sincronizar.
Para un servidor en ejecución, puede utilizar el cliente para ingresar el siguiente comando:
config set masterauth
Para establecer esta contraseña de forma permanente, Puede agregar esto al archivo de configuración:
masterauth <.contraseña>
Para obtener más información, consulte el archivo redis.conf.example en el código fuente de Redis.
El servidor maestro solo realiza operaciones de escritura cuando hay al menos N servidores esclavos
A partir de Redis 2.8, es posible configurar el servidor maestro para que solo realice operaciones de escritura cuando hay al menos N servidores esclavos actualmente conectados para garantizar la seguridad de los datos. Sin embargo, dado que Redis utiliza replicación asincrónica, las operaciones de escritura enviadas por el servidor maestro no necesariamente son recibidas por el servidor esclavo, por lo que aún existe la posibilidad de pérdida de datos. Así es como funciona:
El servidor esclavo hace ping al servidor maestro cada segundo e informa sobre el procesamiento del flujo de replicación.
El servidor maestro registrará el último tiempo de ping de cada servidor esclavo.
Los usuarios pueden configurar la latencia máxima de la red ("min-slaves-max-lag") y el número mínimo de servidores esclavos necesarios para realizar operaciones de escritura ("min-slaves-to-write").
Si hay al menos servidores esclavos "min-slaves-to-write?" y la latencia de estos servidores es inferior a "min-slaves-max-lag?" realizar la operación de escritura solicitada por el cliente. Puede pensar en esta característica como una versión relajada de C en la teoría CAP: si bien no hay garantía de que las escrituras sean duraderas, al menos la ventana para perder datos está estrictamente limitada a un número específico de segundos.
Si no se cumplen las condiciones especificadas por "min-slaves-to-write" y "min-slaves-max-lag", la operación de escritura no se realizará y el servidor maestro volverá al cliente que solicita la operación de escritura.
Las siguientes son las dos opciones para esta función y sus parámetros requeridos:
min-slaves-to-write?
min-slaves-max-lag? Los detalles se pueden encontrar en el archivo de muestra redis.conf incluido con el código fuente de Redis. Construcción de clúster escalable de Redis 1. La replicación activa puede evitar los defectos de replicación de Redis. Dado que la replicación de Redis tiene fallas, también podríamos abandonar la replicación proporcionada por el propio Redis y usar la replicación activa para construir nuestro entorno de clúster. La llamada "replicación activa" significa que la parte comercial o mediante middleware proxy realiza escrituras dobles o múltiples en los datos almacenados en Redis y logra el mismo propósito que la replicación al almacenar múltiples copias de los datos. La replicación activa no se limita a. uso en clústeres de Redis, muchas empresas están utilizando actualmente tecnología de replicación activa para resolver el problema de replicación maestro-esclavo de la replicación retrasada en MySQL. Por ejemplo, Twitter también ha desarrollado una molleja de middleware especial para replicación y partición. Por ejemplo, Twitter desarrolló molleja (? /twitter/gizzard?). La replicación activa resuelve el problema de retraso de la replicación pasiva, pero también trae nuevos problemas, a saber, la coherencia de los datos. ¿Cómo garantizar la coherencia de múltiples copias de datos cuando los datos se escriben 2 o más veces? Si su aplicación tiene requisitos bajos de coherencia de datos y permite una coherencia eventual, entonces generalmente una solución simple es permitir que el cliente obtenga múltiples copias de los datos simultáneamente y los verifique mediante marcas de tiempo o relojes vectoriales, etc. Si su aplicación tiene requisitos muy altos de coherencia de datos, entonces debe introducir algunos algoritmos de coherencia complejos, como Paxos, para garantizar la coherencia de los datos, pero el rendimiento de escritura también será muy bajo. Con la replicación activa, ya no tenemos que preocuparnos de que Redis tenga un único punto de falla. Si un clúster de Redis falla, podemos cambiar rápidamente el negocio a otro clúster de Redis para reducir los riesgos comerciales. 2. Expansión en línea de Redis mediante fragmentación previa. Hemos resuelto el problema del punto único de falla de Redis con la replicación activa, por lo que hay otro problema importante que resolver: la planificación de capacidad y el escalado en línea. Hemos analizado antes que el escenario de aplicación de Redis es almacenar todos los datos en la memoria y que la capacidad de la memoria es limitada, por lo que primero debe realizar una planificación preliminar de la capacidad en función de la cantidad de datos comerciales. Por ejemplo, sus datos comerciales requieren 100G. de espacio de almacenamiento Suponiendo que la memoria del servidor sea 48G, se necesitan al menos de 3 a 4 servidores para el almacenamiento. En realidad, se trata de una planificación de capacidad basada en la situación empresarial existente. Si el negocio crece rápidamente, pronto descubrirá que la capacidad actual no es suficiente y los datos almacenados en Redis pronto excederán el tamaño de la memoria física. El autor de Redis propuso una solución llamada preparticionamiento para resolver el problema de la expansión dinámica y la partición de datos. De hecho, en el mismo servidor, con la misma memoria de servidor 48G, se necesitan al menos 3 o 4 servidores para almacenar datos. El autor de Redis propuso una solución llamada presharding para resolver los problemas de expansión dinámica y partición de datos. En realidad, implementa varias instancias de Redis en la misma máquina y luego divide las instancias en diferentes máquinas cuando la capacidad es insuficiente. efecto de expansión. El proceso de división es el siguiente: Inicie la instancia de Redis en la nueva máquina usando el puerto correspondiente. Configurar el nuevo puerto como puerto esclavo del puerto a migrar. Una vez completada la copia y sincronizada con el maestro, cambie todas las configuraciones del cliente a los puertos del nuevo esclavo. Configurar el dispositivo esclavo como nuevo dispositivo maestro. Eliminar la instancia del puerto antiguo. Repita el proceso anterior para migrar todos los puertos al servidor especificado. El proceso de división anterior es un proceso de migración fluido propuesto por el autor de Redis, pero este método de división aún depende en gran medida de la función de replicación del propio Redis. Si el archivo de datos de la instantánea principal es demasiado grande, este proceso de replicación. También será muy largo y también ejercerá presión sobre la base de datos principal. Por lo tanto, es mejor elegir un momento con un valor máximo más bajo para el proceso de división. Ideas de mejora de copia de Sina Weibo: Primero, escribimos el archivo AOF de Redis, dividimos y enrollamos automáticamente el archivo AOF según el tamaño del archivo, cerramos el comando Reescribir de Redis, Luego, tome una instantánea del almacenamiento de memoria durante las horas de menor actividad comercial y escriba la ubicación actual del archivo AOF junto con el archivo de instantánea, para que podamos tomar una instantánea de la ubicación actual del archivo AOF. Archivo de instantánea, para que la ubicación del archivo de instantánea y el archivo AOF puedan ser consistentes, de modo que podamos obtener una instantánea de la memoria del sistema en un momento determinado, y también conocer la ubicación del archivo AOF correspondiente a este momento, y luego, cuando la biblioteca esclava envía sincronización Al ordenar, primero enviaremos el archivo de instantánea a la biblioteca esclava, y luego la biblioteca esclava extraerá la ubicación del archivo AOF almacenado en el archivo de instantánea y enviará la ubicación a la biblioteca principal. La biblioteca esclava enviará esta posición a la biblioteca maestra, y luego la biblioteca maestra enviará todos los comandos después de esta posición, y todas las replicaciones futuras después de esta posición serán información incremental. La replicación de Redis utiliza la persistencia de instantáneas, por lo que si el método de persistencia de Redis es el método de archivo adjunto de registro (de), entonces el sistema puede escribir simultáneamente el archivo de registro aof en el disco y escribir la instantánea en este. tiempo, la velocidad de respuesta de Redis se verá afectada. Por lo tanto, si elige utilizar un método de persistencia, debe tener más cuidado al agregar dispositivos esclavos. Resumen Es mejor no realizar ningún trabajo de persistencia en el programa de control principal, incluidas las instantáneas de memoria y los archivos de registro AOF. En particular, no habilite las instantáneas de memoria para la persistencia. Si los datos son muy importantes, un esclavo específico abrirá AOF para hacer una copia de seguridad de los datos y la política es sincronizarlos una vez por segundo. Para mejorar la velocidad de replicación maestro-esclavo y la estabilidad de la conexión, es mejor que el dispositivo esclavo y el dispositivo maestro estén en la misma LAN. Trate de evitar agregar bases de datos esclavas a la base de datos maestra que está bajo mucha presión. Para garantizar la estabilidad del Maestro, no utilice una estructura gráfica para la replicación maestro-esclavo. Será más eficiente utilizar una estructura de lista enlazada unidireccional. Estable, es decir, la relación maestro-esclavo es: Maestro <-Esclavo1 <-Esclavo2 <-Esclavo3... Esta estructura también es conveniente para resolver. problema de punto único de falla y realice el reemplazo del Maestro por el Esclavo, es decir, si el Maestro cuelga, puede habilitar inmediatamente el Esclavo1 como Maestro, dejando todo lo demás sin cambios. Materiales de referencia: Diseño e implementación de Redis