Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Redis-Transaktionen und lang andauernde Lua-Skripte

Redis bietet zwei Mechanismen zur Abwicklung von Transaktionen – MULTI/EXEC-basierte Transaktionen und Auswertung von Lua-Skripten. Redis Lua-Skripting ist der empfohlene Ansatz und wird ziemlich häufig verwendet.

Unsere Redis™-Kunden, die Lua-Skripte bereitgestellt haben, melden häufig diesen Fehler – „BUSY Redis ist damit beschäftigt, ein Skript auszuführen. Sie können nur SCRIPT KILL oder SHUTDOWN NOSAVE aufrufen “. In diesem Beitrag erklären wir die Redis-Transaktionseigenschaft von Skripts, was es mit diesem Fehler auf sich hat und warum wir auf Sentinel-verwalteten Systemen, die ein Failover ermöglichen, besonders vorsichtig sein müssen.

Transaktionscharakter von Redis Lua-Skripten

Redis „Transaktionen“ sind nicht wirklich Transaktionen im herkömmlichen Verständnis – im Falle von Fehlern gibt es kein Rollback der vom Skript vorgenommenen Schreibvorgänge.

„Atomizität“ von Redis-Skripten wird auf folgende Weise garantiert:

  • Sobald ein Skript mit der Ausführung beginnt, werden alle anderen Befehle/Skripte blockiert, bis das Skript abgeschlossen ist. Andere Clients sehen also entweder die vom Skript vorgenommenen Änderungen oder nicht. Dies liegt daran, dass sie nur entweder vor oder nach dem Skript ausgeführt werden können.
  • Redis führt jedoch keine Rollbacks durch, sodass bei einem Fehler in einem Skript alle bereits vom Skript vorgenommenen Änderungen beibehalten werden und zukünftige Befehle/Skripte diese teilweisen Änderungen sehen werden.
  • Da alle anderen Clients blockiert werden, während das Skript ausgeführt wird, ist es wichtig, dass das Skript sich gut verhält und rechtzeitig beendet wird.

Der „lua-time-limit“-Wert

Es wird dringend empfohlen, das Skript innerhalb eines Zeitlimits abzuschließen. Redis erzwingt dies auf schwache Weise mit dem Wert „lua-time-limit“. Dies ist die maximal zulässige Zeit (in ms), die das Skript ausgeführt werden darf. Der Standardwert ist 5 Sekunden. Dies ist eine wirklich lange Zeit für CPU-gebundene Aktivitäten (Skripte haben eingeschränkten Zugriff und können keine Befehle ausführen, die auf die Festplatte zugreifen).

Das Skript wird jedoch nicht beendet, wenn es nach dieser Zeit ausgeführt wird. Redis beginnt wieder mit der Annahme von Client-Befehlen, antwortet darauf jedoch mit einem BUSY-Fehler.

Wenn Sie das Skript an dieser Stelle beenden müssen, stehen zwei Optionen zur Verfügung:

  • SCRIPT KILL -Befehl kann verwendet werden, um ein Skript zu stoppen, das noch keine Schreibvorgänge ausgeführt hat.
  • Wenn das Skript bereits Schreibvorgänge auf dem Server ausgeführt hat und noch beendet werden muss, verwenden Sie SHUTDOWN NOSAVE um den Server komplett herunterzufahren.

Normalerweise ist es besser, einfach zu warten, bis das Skript seinen Vorgang abgeschlossen hat. Die vollständigen Informationen zu den Methoden zum Beenden der Skriptausführung und dem zugehörigen Verhalten finden Sie in der Dokumentation.

Redis-Transaktionen und langlaufende Lua-SkriptsClick To Tweet

Verhalten auf Sentinel-überwachten Hochverfügbarkeitssystemen

Sentinel-verwaltete Hochverfügbarkeitssysteme fügen dem einen neuen Aspekt hinzu. Tatsächlich gilt diese Diskussion für jedes System mit hoher Verfügbarkeit, das von der Abfrage der Integrität der Redis-Server abhängt:

  • Lange laufende Skripte blockieren zunächst Client-Befehle. Später, wenn das „lua-time-limit“ abgelaufen ist, beginnt der Server mit BUSY-Fehlern zu antworten.
  • Sentinels betrachten einen solchen Knoten als nicht verfügbar, und wenn dies über den auf den Sentinels konfigurierten Down-after-Millisekunden-Wert hinaus anhält, bestimmen sie, dass der Knoten ausgefallen ist.
  • Wenn ein solcher Knoten der Master ist, wird ein Failover initiiert. Ein Replikatknoten wird möglicherweise heraufgestuft und könnte beginnen, neue Verbindungen von Clients zu akzeptieren.
  • In der Zwischenzeit wird der ältere Master schließlich die Ausführung des Skripts abschließen und wieder online gehen. Sentinel konfiguriert es jedoch schließlich als Replikat neu und beginnt mit der Synchronisierung mit dem neuen Master. Alle vom Skript geschriebenen Daten gehen verloren.

Expertentipp

Um Hochverfügbarkeit (HA) zu erreichen, müssen Sie eine Master-Slave-Konfiguration bereitstellen. Erfahren Sie, wie Sie über einen einzigen Endpunkt eine Verbindung zu Redis-Servern in einer HA-Konfiguration herstellen.

Demonstration

Wir haben ein sensibles Hochverfügbarkeitssystem eingerichtet, um dieses Failover-Verhalten zu demonstrieren. Das Setup verfügt über 2 Redis-Server, die in einer Master/Replikat-Konfiguration ausgeführt werden, die von einem 3-Wächter-Quorum überwacht wird.

Der lua-time-limit-Wert wurde auf 500 ms festgelegt, damit es beginnt, auf Clients mit Fehlern zu reagieren, wenn ein Skript länger als 500 ms ausgeführt wird. Der Down-After-Millisekunden-Wert auf den Sentinels ist auf 5 Sekunden eingestellt, sodass ein Knoten, der Fehler meldet, nach 5 Sekunden als DOWN markiert wird.

Wir führen das folgende Lua-Skript auf dem Master aus:

local i = 0
while (true)
do
local key = "Key-" .. i
local value = "Value-" .. i
redis.call('set', key, value)
i = i + 1
redis.call('time')
end

Dies schreibt weiterhin Einträge in den Redis-Master. Wir abonnieren die Ereignisse auf einem der Sentinels, um das Verhalten zu beobachten.

Das Skript wird auf dem Master initiiert:

$ redis-cli -a  --eval test.lua
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

Hier ist eine verkürzte Abfolge von Aktivitäten, wie sie auf Sentinel zu sehen sind:

3) "+vote-for-leader"
4) "9096772621089bb885eaf7304a011d9f46c5689f 1"
1) "pmessage"
2) "*"
3) "+sdown" <<< master marked DOWN
4) "master test 172.31.2.48 6379"
1) "pmessage"
2) "*"
3) "+odown"
4) "master test 172.31.2.48 6379 #quorum 3/2"
1) "pmessage"
2) "*"
3) "-role-change" << role change initiated
4) "slave 172.31.28.197:6379 172.31.28.197 6379 @ test 172.31.2.48 6379 new reported role is master"
1) "pmessage"
2) "*"
3) "+config-update-from"
4) "sentinel 9096772621089bb885eaf7304a011d9f46c5689f 172.31.2.48 26379 @ test 172.31.2.48 6379"
1) "pmessage"
2) "*"
3) "+switch-master"
4) "test 172.31.2.48 6379 172.31.28.197 6379"

Später, wenn der alte Master online gebracht wird, wird er in eine Kopie geändert:

3) "-role-change"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is master"
1) "pmessage"
2) "*"
3) "-sdown"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379"
1) "pmessage"
2) "*"
3) "+role-change"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is slave"

Alle Daten, die über das Skript auf den alten Master geschrieben wurden, gehen verloren.

Empfehlungen

  • Sie müssen die Eigenschaften Ihrer langlaufenden Skripts im Voraus kennen, bevor Sie sie in der Produktion einsetzen.
  • Wenn Ihr Skript regelmäßig gegen das Lua-Zeitlimit verstößt, müssen Sie das Skript gründlich auf mögliche Optimierungen überprüfen. Sie können es auch in Teile aufteilen, die in akzeptabler Dauer abgeschlossen werden können.
  • Wenn Sie Skripte ausführen müssen, die das Lua-Zeitlimit überschreiten, ziehen Sie in Betracht, diese Skripte in Zeiten zu planen, in denen andere Client-Aktivitäten gering sind.
  • Der Wert des Lua-Zeitlimits kann auch erhöht werden. Dies wäre eine akzeptable Lösung, wenn andere Client-Anwendungen, die parallel zum Skript ausgeführt werden, es tolerieren können, extrem verzögerte Antworten zu erhalten, anstatt einen BUSY-Fehler zu erhalten und es später erneut zu versuchen.

Zusätzliche Überlegungen zu von Sentinel überwachten Hochverfügbarkeitssystemen:

  • Falls die Skripte nur Lesevorgänge ausführen und Sie Repliken zur Verfügung haben, können Sie diese Skripts in die Repliken verschieben.

Ändern Sie den Sentinel-Parameter down-after-milliseconds auf einen Wert, der sicherstellt, dass keine Failover initiiert werden. Sie dürfen dies nur nach sorgfältiger Überlegung tun, da eine drastische Erhöhung des Werts die Hochverfügbarkeitseigenschaften Ihres Systems beeinträchtigt. Dies könnte auch dazu führen, dass echte Serverausfälle ignoriert werden.

Weitere Tipps für Sie

Lernen Sie die Redis-Datenbank kennen:Iterieren über Schlüssel

Die Möglichkeit, kostengünstig über den Redis-Schlüsselraum zu iterieren, ist sehr wichtig, um sich mit den Datenbankinhalten vertraut zu machen. Lernen Sie die verschiedenen Schlüsselraum-Iterationsoptionen kennen, die in Redis verfügbar sind. Weitere Informationen

Top-Redis-Anwendungsfälle nach Kerndatenstrukturtypen

Redis kann wie eine Datenbank, ein Cache oder ein Nachrichtenbroker agieren und speichert keine Daten in wohldefinierten Datenbankschemata, die Tabellen, Zeilen und Spalten darstellen. Stattdessen speichert Redis Daten in Datenstrukturen, was die Verwendung sehr flexibel macht. Weitere Informationen

6 wichtige Kennzahlen zur Redis-Überwachung, die Sie im Auge behalten müssen

Wie stellen Sie sicher, dass Ihre Redis-Bereitstellung fehlerfrei ist und Ihre Anforderungen erfüllt? Sie müssen wissen, welche Überwachungsmetriken Sie beobachten müssen, und ein Tool zur Überwachung dieser kritischen Servermetriken, um deren Zustand sicherzustellen. Weitere Informationen