Dieser Artikel wird Ihnen helfen, die Master-Slave-Synchronisation in Redis zu verstehen und die beiden Strukturmodelle von Redis Master-Slave, den Aufbau der Master-Slave-Beziehung, die Master-Slave-Replikationsstrategie usw. vorzustellen es wird für alle hilfreich sein!
Die Eigenschaften und Kernprinzipien von Redis wurden im vorherigen Artikel ausführlich analysiert. Ausgehend von diesem Artikel werden wir die Bereitstellungsstruktur und den Betriebsmodus von Redis analysieren und interpretieren. In einer realen Produktionsumgebung verwenden wir grundsätzlich kein Single-Node-Redis zur Bereitstellung von Diensten, zumindest nicht den Sentinel- oder Cluster-Modus einer Master-Slave-Struktur, um die Zuverlässigkeit des Redis-Dienstes sicherzustellen. In diesem Artikel wird der Master-Slave-Synchronisationsmechanismus von Redis ausführlich erläutert. [Verwandte Empfehlungen: Redis-Video-Tutorial]
Die Replikationsstruktur von einem Master und N Slaves hat nur eine Ebene Dies ist auch die am häufigsten verwendete Form von Redis, die diese Replikationsstruktur verwendet, um die Verfügbarkeit von Diensten durch die Replikationsbeziehung der Slave-Knoten der ersten Ebene sicherzustellen in ungewöhnlichen Situationen.
Die Replikationsbeziehung der Kaskadenreplikationsstruktur kann mehrere Ebenen haben, und der Slave-Knoten eines Master-Knotens kann der Master-Knoten eines untergeordneten Slave-Knotens sein. Die Anwendung einer Kaskadenreplikationsstruktur ist relativ selten. Diese Struktur kann den Replikationsdruck des Masterknotens in einer Struktur mit mehreren Slaveknoten bis zu einem gewissen Grad verringern.
Die Master-Slave-Synchronisation von Redis beginnt mit dem Befehl SLAVEOF. Mit diesem Befehl kann das Verhalten dynamisch geändert werden der Replikationsfunktion, wenn Redis ausgeführt wird. Durch Ausführen des Host-Port-Befehls SLAVEOF können Sie den aktuellen Server in einen Slave-Server des angegebenen Servers verwandeln. Wenn der aktuelle Server bereits ein Slave-Server eines Master-Servers ist, führt die Ausführung des SLAVEOF-Host-Ports dazu, dass der aktuelle Server die Synchronisierung mit dem alten Master-Server beendet, den alten Datensatz verwirft und mit der Synchronisierung mit dem neuen Master-Server beginnt. Darüber hinaus führt die Ausführung des Befehls SLAVEOF NO ONE auf einem Slave-Server dazu, dass der Slave-Server die Replikationsfunktion deaktiviert und vom Slave-Server zurück zum Master-Server wechselt. Der ursprünglich synchronisierte Datensatz wird nicht verworfen. Unter Ausnutzung der Funktion von SLAVEOF NO ONE wird der synchronisierte Datensatz nicht verworfen, ohne dass Sentinels und Cluster eingerichtet werden müssen. Wenn der Master-Server ausfällt, kann der Slave-Server als neuer Master-Server verwendet werden, wodurch ein unterbrechungsfreier Betrieb gewährleistet wird.
Die folgende Abbildung zeigt den Prozess des Aufbaus einer Master-Slave-Beziehung:
Hinweis:
Gemäß dem obigen Ausführungsprozess gibt es einen Punkt, der Aufmerksamkeit erfordert, wenn wir den Befehl „slaveof“ ausführen Auf einem Knoten, der bereits über eine Master-Slave-Beziehung verfügt, wird die bestehende Master-Slave-Beziehung beendet und alle Daten unter dem Knoten gelöscht. Dies ist ein relativ bedrohlicher Vorgang in der Produktionsumgebung. Gibt es einen sichereren Weg? Bei der Einführung des Befehls „slaveof“ haben wir oben erwähnt, dass Sie den Parameter „NO ONE“ übergeben können, dh den Befehl „SLAVEOF NO ONE“ ausführen können. Dieser Befehl beendet nur die Master-Slave-Replikationsbeziehung und löscht die Daten nicht, was relativ sicherer ist .
Nachdem die Master-Slave-Beziehung hergestellt wurde, treten hier hauptsächlich drei Situationen auf Nach Abschluss der ersten Synchronisierungsphase gibt es zwei Szenarien für die vollständige und inkrementelle Synchronisierung.
Wenn der Slave-Knoten gestartet oder getrennt und erneut verbunden wird (die erneute Verbindung erfüllt nicht die Bedingungen für die inkrementelle Synchronisierung), wird der SYNC-Befehl an die Master-Datenbank gesendet.
Nach Erhalt des SYNC-Befehls beginnt der Masterknoten mit dem Speichern des Snapshots im Hintergrund (d. h. RDB-Persistenz, die RDB während der Master-Slave-Replikation bedingungslos auslöst) und speichert die während des Snapshot-Speicherns empfangenen Befehle zwischen .
Nachdem der Masterknoten die RDB-Persistenz abgeschlossen hat, sendet er Snapshot-RDB-Dateien an alle Slave-Knoten und zeichnet während des Snapshot-Versands weiterhin die ausgeführten Schreibbefehle auf.
Nach dem Empfang der Snapshot-Datei verwirft der Slave-Knoten alle alten Daten (alle Daten werden gelöscht) und lädt den empfangenen Snapshot.
Nachdem der Master-Knoten-Snapshot gesendet wurde und der Slave-Knoten den Snapshot lädt, beginnt der Master-Knoten, den Schreibbefehl im Puffer an den Slave-Knoten zu senden.
Der Slave-Knoten schließt das Laden des Snapshots ab, beginnt mit dem Empfang von Befehlsanfragen und führt Schreibbefehle aus dem Hauptdatenbankpuffer aus. (Initialisierung aus der Datenbank abgeschlossen)
Jedes Mal, wenn der Master-Knoten einen Schreibbefehl ausführt, sendet er denselben Schreibbefehl an den Slave-Knoten, und der Slave-Knoten empfängt den empfangenen Schreibbefehl und führt ihn aus. (Befehlsweitergabevorgang, Vorgang nach Abschluss der Initialisierung des Slave-Knotens)
Der vollständige Synchronisierungsprozess ist wie folgt:
Vor Redis2.8 verwendete der Slave-Knoten die vollständige Synchronisierung, unabhängig davon, ob er initialisiert oder getrennt und wieder verbunden wurde .-Methode: In Versionen nach 2.8 wird der Befehl PSYNC eingeführt und es wird beurteilt, ob die inkrementelle Synchronisierung verwendet werden soll, nachdem der Slave-Knoten getrennt und wieder verbunden wurde.
PSYNC verfügt über die Modi vollständige Datenresynchronisierung und inkrementelle Synchronisierung.
Vollständige Neusynchronisierung: Es ist im Grunde dasselbe wie die alte Version der Kopie und kann als „vollständige“ Kopie verstanden werden.
Teilweise Neusynchronisation: Wenn der Slave getrennt und wieder verbunden wird, müssen in der Befehlsausbreitungsphase nur die während der Trennung vom Master ausgeführten Befehle an den Slave gesendet werden, was als „inkrementelle“ Replikation verstanden werden kann .
Es gibt drei wichtige Konzepte im Ausführungsprozess von PSYNC: Runid, Offset (Kopieroffset) und Kopierrückstandspuffer.
1.runid
Jeder Redis-Server verfügt über eine ID, die seine Identität angibt. Die in PSYNC gesendete ID bezieht sich auf die ID des zuvor verbundenen Masters. Wenn diese ID nicht gespeichert wird, verwendet der PSYNC-Befehl die Form „PSYNC? -1“, um sie an den Master zu senden, was darauf hinweist, dass eine vollständige Kopie erforderlich ist.
2.Offset (Replikationsoffset)
Sowohl der Master als auch der Slave bei der Master-Slave-Replikation behalten jeweils einen Offset bei. Nachdem der Master den N-Byte-Befehl erfolgreich gesendet hat, wird der Offset im Master um N erhöht. Nachdem der Slave den N-Byte-Befehl empfangen hat, erhöht der Slave auch den Offset im Slave um N. Wenn der Status von Master und Slave konsistent ist, sollten auch ihre Offsets konsistent sein.
3. Kopier-Backlog-Puffer
Der Kopier-Backlog-Puffer ist eine zirkuläre Backlog-Warteschlange fester Länge, die vom Master verwaltet wird. Seine Funktion besteht darin, die weitergegebenen Befehle zwischenzuspeichern. Wenn der Master Befehle weitergibt, sendet er die Befehle nicht nur an alle Slaves, sondern schreibt die Befehle auch in den Replikations-Backlog-Puffer. Der Unterschied zwischen dem Ausführungsprozess von PSYNC und SYNC besteht darin, dass beim Herstellen einer Salve-Verbindung beurteilt wird, ob eine vollständige Synchronisierung erforderlich ist. Der logische Prozess der vollständigen Synchronisierung ist der gleiche wie der von SYNC. Die Ausführungsschritte von PSYNC lauten wie folgt:
Der Client sendet den SLAVEOF-Befehl an den Server. Wenn der Slave also eine Verbindungsanforderung an den Master initiiert, bestimmt der Slave anhand dessen, ob es sich um die erste Verbindung handelt speichert die Master-Runid.
Wenn es sich um die erste Synchronisierung handelt, wird der Befehl PSYNC ? -1 zur vollständigen Synchronisierung an den Master gesendet; wenn es sich um eine erneute Verbindung handelt, wird der Befehl PSYNC runid offset an den Master gesendet (runid ist die Identitäts-ID). des Masters und Offset ist die Synchronisation des Slave-Knotens (die globale Migrationsmenge des Befehls).
Nach dem Empfang des PSYNC-Befehls ermittelt der Master zunächst, ob die Runid mit der ID des lokalen Computers übereinstimmt. Wenn sie konsistent ist, ermittelt er erneut, ob der Offset-Offset und der Offset des lokalen Computers die Kopie überschreiten Wenn nicht, senden Sie CONTINUE an den Slave. Zu diesem Zeitpunkt muss der Slave nur darauf warten, dass der Master den während des Verbindungsverlusts verlorenen Befehl zurückgibt. Wenn die Runid nicht mit der lokalen ID übereinstimmt oder die Offset-Lücke die Puffergröße des Kopierrückstands überschreitet, wird der Runid-Offset FULLRESYNC zurückgegeben und der Slave speichert die Runid und führt eine vollständige Synchronisierung durch.
Wenn der Master-Knoten Befehle weitergibt, leitet die Master-Datenbank jeden Schreibbefehl an die Slave-Datenbank weiter und speichert gleichzeitig den Schreibbefehl in der Backlog-Warteschlange und zeichnet den globalen Offset des darin gespeicherten Befehls auf die aktuelle Backlog-Warteschlange. Wenn der Salve wieder eine Verbindung herstellt, findet der Master die während der Trennungsperiode ausgeführten Befehle basierend auf dem vom Slave-Knoten übergebenen Offset in der Ring-Backlog-Warteschlange und synchronisiert sie mit dem Salve-Knoten, um inkrementelle Synchronisationsergebnisse zu erzielen.
Der PSYNC-Ausführungsprozess ist wie folgt:
Aus dem obigen PSYNC-Ausführungsprozess können wir ersehen, dass beim Trennen und erneuten Verbinden des Slave-Knotens der Kern zur Bestimmung, ob inkrementelle Synchronisation verwendet werden soll, der Offset-Offset des Knotens ist Wenn die Differenz die Größe des Copy-Backlog-Puffers überschreitet, wird diese Größe durch die folgenden Parameter konfiguriert. Der Replikations-Backlog-Puffer ist im Wesentlichen eine zirkuläre Warteschlange mit fester Länge. Die Größe der Warteschlange kann über die Konfigurationsdatei festgelegt werden: Je größer die Backlog-Warteschlange Je länger die Master-Slave-Datenbank getrennt werden darf, desto länger dauert es. Redis gibt auch an, wie lange es dauert, die Ringwarteschlange freizugeben, wenn kein Slave vorhanden ist Verbindung, wie oft der Replikations-Backlog-Puffer freigegeben wird
repl-backlog-ttl 3600
Redis采用了乐观复制的策略,也就是在一定程度内容忍主从数据库的内容不一致,但是保持主从数据库数据的最终一致性。具体来说,Redis在主从复制的过程中,本身就是异步的,在主从数据库执行完客户端请求后会立即将结果返回给客户端,并异步的将命令同步给从数据库,但是这里并不会等待从数据库完全同步之后,再返回客户端。这一特性虽然保证了主从复制期间性能不受影响,但是也会产生一个数据不一致的时间窗口,如果在这个时间窗口期间网络突然断开连接,就会导致两者数据不一致。如果不在配置文件中添加其他策略,那就默认会采用这种方式。为了防止主从不一致不可控,redis提供了以下两个参数来做约束:
min-slaves-to-write 3 min-slaves-max-lag 10
当slave数量小于min-slaves-to-write,且延迟小于等于min-slaves-max-lag时,master停止写入操作。
还有一个参数也会影响主从之间的延时:
repl-disable-tcp-nodelay:
设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟,造成master与slave数据不一致。设置成no,则redis master会立即发送同步数据,几乎没有延迟。
Redis的主从同步无论那种场景可以抽象为以下七个步骤:
1.建立socket连接
从服务器根据设置的套接字创建连向主服务器的套接字连接,主服务器接收从服务器的套接字连接之后,为该套接字创建响应的客户端状态,并将此时的从服务器看做是主服务器的客户端,也就是该从服务器同时具备服务器与客户端两个身份。
2.发送PING命令
PING命令主要有两种作用:虽然建立了套接字连接,但是还未使用过,通过发送PING命令检查套接字的读写状态是否正常;通过发送PING命令检查主服务器能否正常处理命令请求,能处理主服务器回复PONG。
3.身份验证
从服务器接收到主服务器返回的“PONG”回复,接下来就需要考虑身份验证的事。如果从服务器设置了masterauth选项,那么进行身份验证,如果从服务器没有设置masterauth选项,那么不进行身份验证。
4.发送端口信息
在身份验证步骤之后,从服务器将执行命令REPLCONF listening-port ,向主服务器发送从服务器的监听端口号。
5.数据同步
从服务器向主服务器发送SYNC命令、PSYNC命令,执行同步操作。
6.命令传播
主从服务器就会进入命令传播阶段,主服务器只要将自己执行的写命令发送给从服务器,而从服务器只要一直执行并接收主服务器发来的写命令。
本篇详细介绍了redis主从同步机制,不同场景下同步策略的选择,这也是redis高可用的基石。在此基础上,下一篇将对redis高可用的实现来进行分析讲解。
更多编程相关知识,请访问:编程视频!!
Das obige ist der detaillierte Inhalt vonVertiefendes Verständnis des Master-Slave-Synchronisationsmechanismus in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!