redis: Lua redis-Clienttreiber für nginx-module-lua basierend auf der cosocket-API
Installation
Wenn Sie das RPM-Repository-Abonnement noch nicht eingerichtet haben, melden Sie sich an. Dann können Sie mit den folgenden Schritten fortfahren.
CentOS/RHEL 7 oder Amazon Linux 2
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-redis
CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-redis
Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.
Dieses Dokument beschreibt lua-resty-redis v0.33, das am 09. Juli 2025 veröffentlicht wurde.
Diese Lua-Bibliothek ist ein Redis-Clienttreiber für das ngx_lua-nginx-Modul:
https://github.com/openresty/lua-nginx-module/#readme
Diese Lua-Bibliothek nutzt die cosocket-API von ngx_lua, die 100% nicht blockierendes Verhalten gewährleistet.
Beachten Sie, dass mindestens ngx_lua 0.5.14 oder OpenResty 1.2.1.14 erforderlich ist.
Synopsis
# Sie benötigen die folgende Zeile nicht, wenn Sie das
# OpenResty-Bundle verwenden:
server {
location /test {
# Der Resolver muss angegeben werden, um den Hostnamen aufzulösen
resolver 8.8.8.8;
content_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 Sekunde
-- oder verbinden Sie sich mit einer Unix-Domain-Socket-Datei, die von einem Redis-Server gehört wird:
-- local ok, err = red:connect("unix:/path/to/redis.sock")
-- direkt über die IP-Adresse verbinden
local ok, err = red:connect("127.0.0.1", 6379)
-- oder über den Hostnamen verbinden, der Resolver muss wie oben angegeben werden
local ok, err = red:connect("redis.openresty.com", 6379)
if not ok then
ngx.say("Verbindung fehlgeschlagen: ", err)
return
end
ok, err = red:set("hund", "ein Tier")
if not ok then
ngx.say("Hund setzen fehlgeschlagen: ", err)
return
end
ngx.say("Setzergebnis: ", ok)
local res, err = red:get("hund")
if not res then
ngx.say("Hund abrufen fehlgeschlagen: ", err)
return
end
if res == ngx.null then
ngx.say("Hund nicht gefunden.")
return
end
ngx.say("Hund: ", res)
red:init_pipeline()
red:set("katze", "Marry")
red:set("pferd", "Bob")
red:get("katze")
red:get("pferd")
local results, err = red:commit_pipeline()
if not results then
ngx.say("Fehler beim Commit der pipelined-Anfragen: ", err)
return
end
for i, res in ipairs(results) do
if type(res) == "table" then
if res[1] == false then
ngx.say("Fehler beim Ausführen des Befehls ", i, ": ", res[2])
else
-- Verarbeiten Sie den Tabellenwert
end
else
-- Verarbeiten Sie den Skalarwert
end
end
-- in den Verbindungspool der Größe 100 einfügen,
-- mit maximal 10 Sekunden Leerlaufzeit
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.say("Fehler beim Setzen von Keepalive: ", err)
return
end
-- oder schließen Sie die Verbindung sofort:
-- local ok, err = red:close()
-- if not ok then
-- ngx.say("Fehler beim Schließen: ", err)
-- return
-- end
}
}
}
Methoden
Alle Redis-Befehle haben ihre eigenen Methoden mit demselben Namen, außer dass sie alle in Kleinbuchstaben sind.
Sie finden die vollständige Liste der Redis-Befehle hier:
Sie müssen dieses Redis-Befehl-Referenzdokument überprüfen, um zu sehen, welche Argumente die Redis-Befehle akzeptieren.
Die Argumente der Redis-Befehle können direkt in den entsprechenden Methodenaufruf eingegeben werden. Zum Beispiel akzeptiert der "GET"-Redis-Befehl ein einzelnes Schlüsselargument, dann können Sie einfach die "get"-Methode so aufrufen:
local res, err = red:get("key")
Ähnlich akzeptiert der "LRANGE"-Redis-Befehl drei Argumente, dann sollten Sie die "lrange"-Methode so aufrufen:
local res, err = red:lrange("nokey", 0, 1)
Zum Beispiel entsprechen die Befehle "SET", "GET", "LRANGE" und "BLPOP" den Methoden "set", "get", "lrange" und "blpop".
Hier sind einige weitere Beispiele:
-- HMGET myhash field1 field2 nofield
local res, err = red:hmget("myhash", "field1", "field2", "nofield")
-- HMSET myhash field1 "Hallo" field2 "Welt"
local res, err = red:hmset("myhash", "field1", "Hallo", "field2", "Welt")
Alle diese Befehlsmethoden geben ein einzelnes Ergebnis im Erfolgsfall und nil andernfalls zurück. Im Falle von Fehlern oder Misserfolgen wird auch ein zweiter Wert zurückgegeben, der eine Zeichenfolge beschreibt, die den Fehler beschreibt.
Eine Redis "Statusantwort" führt zu einem Rückgabewert vom Typ Zeichenfolge mit dem "+"-Präfix entfernt.
Eine Redis "Ganzzahlantwort" führt zu einem Rückgabewert vom Typ Lua-Zahl.
Eine Redis "Fehlerantwort" führt zu einem Wert von false und einer Zeichenfolge, die den Fehler beschreibt.
Eine nicht-nil Redis "Bulk-Antwort" führt zu einem Lua-String als Rückgabewert. Eine nil-Bulk-Antwort führt zu einem Rückgabewert von ngx.null.
Eine nicht-nil Redis "Multi-Bulk-Antwort" führt zu einer Lua-Tabelle, die alle zusammensetzenden Werte (falls vorhanden) enthält. Wenn einer der zusammensetzenden Werte ein gültiger Redis-Fehlerwert ist, wird es eine zweielementige Tabelle {false, err} sein.
Eine nil-Multi-Bulk-Antwort gibt einen Wert von ngx.null zurück.
Siehe http://redis.io/topics/protocol für Details zu den verschiedenen Redis-Antworttypen.
Zusätzlich zu all diesen Redis-Befehlsmethoden werden auch die folgenden Methoden bereitgestellt:
new
syntax: red, err = redis:new()
Erstellt ein Redis-Objekt. Im Falle von Fehlern gibt es nil und eine Zeichenfolge zurück, die den Fehler beschreibt.
connect
syntax: ok, err = red:connect(host, port, options_table?)
syntax: ok, err = red:connect("unix:/path/to/unix.sock", options_table?)
Versucht, eine Verbindung zum Remote-Host und -Port herzustellen, auf dem der Redis-Server lauscht, oder zu einer lokalen Unix-Domain-Socket-Datei, die vom Redis-Server gehört wird.
Bevor tatsächlich der Hostname aufgelöst und eine Verbindung zum Remote-Backend hergestellt wird, wird diese Methode immer den Verbindungspool nach passenden Leerlaufverbindungen durchsuchen, die durch vorherige Aufrufe dieser Methode erstellt wurden.
Das optionale Argument options_table ist eine Lua-Tabelle, die die folgenden Schlüssel enthält:
-
sslWenn auf true gesetzt, wird SSL verwendet, um sich mit Redis zu verbinden (standardmäßig false).
-
ssl_verifyWenn auf true gesetzt, wird die Gültigkeit des SSL-Zertifikats des Servers überprüft (standardmäßig false). Beachten Sie, dass Sie lua_ssl_trusted_certificate konfigurieren müssen, um das CA- (oder Server-)Zertifikat anzugeben, das von Ihrem Redis-Server verwendet wird. Möglicherweise müssen Sie auch lua_ssl_verify_depth entsprechend konfigurieren.
-
server_nameGibt den Servernamen für die neue TLS-Erweiterung Server Name Indication (SNI) an, wenn über SSL verbunden wird.
-
poolGibt einen benutzerdefinierten Namen für den verwendeten Verbindungspool an. Wenn weggelassen, wird der Name des Verbindungspools aus der Zeichenfolgenvorlage
<host>:<port>oder<unix-socket-path>generiert. -
pool_sizeGibt die Größe des Verbindungspools an. Wenn weggelassen und keine
backlog-Option angegeben wurde, wird kein Pool erstellt. Wenn weggelassen, aberbacklogangegeben wurde, wird der Pool mit einer Standardgröße erstellt, die dem Wert der lua_socket_pool_size-Direktive entspricht. Der Verbindungspool hält bis zupool_sizeaktive Verbindungen bereit, die von nachfolgenden Aufrufen von connect wiederverwendet werden können, aber beachten Sie, dass es keine obere Grenze für die Gesamtzahl der außerhalb des Pools geöffneten Verbindungen gibt. Wenn Sie die Gesamtzahl der geöffneten Verbindungen einschränken müssen, geben Sie diebacklog-Option an. Wenn der Verbindungspool seine Größenbeschränkung überschreiten würde, wird die am wenigsten kürzlich verwendete (keep-alive) Verbindung, die sich bereits im Pool befindet, geschlossen, um Platz für die aktuelle Verbindung zu schaffen. Beachten Sie, dass der cosocket-Verbindungspool pro Nginx-Worker-Prozess und nicht pro Nginx-Serverinstanz gilt, sodass die hier angegebene Größenbeschränkung auch für jeden einzelnen Nginx-Worker-Prozess gilt. Beachten Sie auch, dass die Größe des Verbindungspools nicht geändert werden kann, sobald er erstellt wurde. Beachten Sie, dass mindestens ngx_lua 0.10.14 erforderlich ist, um diese Optionen zu verwenden. -
backlogWenn angegeben, wird dieses Modul die Gesamtzahl der geöffneten Verbindungen für diesen Pool begrenzen. Es können zu keinem Zeitpunkt mehr Verbindungen als
pool_sizefür diesen Pool geöffnet werden. Wenn der Verbindungspool voll ist, werden nachfolgende Verbindungsoperationen in eine Warteschlange eingeordnet, die dem Wert dieser Option entspricht (die "backlog"-Warteschlange). Wenn die Anzahl der wartenden Verbindungsoperationen gleichbacklogist, schlagen nachfolgende Verbindungsoperationen fehl und geben nil plus die Fehlermeldung"zu viele wartende Verbindungsoperationen"zurück. Die wartenden Verbindungsoperationen werden fortgesetzt, sobald die Anzahl der Verbindungen im Pool kleiner alspool_sizeist. Die wartende Verbindungsoperation wird abgebrochen, sobald sie länger alsconnect_timeoutin der Warteschlange steht, die durch set_timeout gesteuert wird, und gibt nil plus die Fehlermeldung "Zeitüberschreitung" zurück. Beachten Sie, dass mindestens ngx_lua 0.10.14 erforderlich ist, um diese Optionen zu verwenden.
set_timeout
syntax: red:set_timeout(time)
Setzt den Timeout (in ms) für nachfolgende Operationen, einschließlich der connect-Methode.
Seit Version v0.28 dieses Moduls wird empfohlen, set_timeouts anstelle dieser Methode zu verwenden.
set_timeouts
syntax: red:set_timeouts(connect_timeout, send_timeout, read_timeout)
Setzt die Verbindungs-, Sende- und Lese-Timeout-Schwellenwerte (in ms) für nachfolgende Socket-Operationen. Das Setzen von Timeout-Schwellenwerten mit dieser Methode bietet mehr Granularität als set_timeout. Daher wird empfohlen, set_timeouts über set_timeout zu verwenden.
Diese Methode wurde in der Version v0.28 hinzugefügt.
set_keepalive
syntax: ok, err = red:set_keepalive(max_idle_timeout, pool_size)
Fügt die aktuelle Redis-Verbindung sofort in den ngx_lua-cosocket-Verbindungspool ein.
Sie können die maximale Leerlaufzeit (in ms) angeben, wenn sich die Verbindung im Pool befindet, und die maximale Größe des Pools für jeden Nginx-Worker-Prozess.
Im Erfolgsfall gibt es 1 zurück. Im Falle von Fehlern gibt es nil mit einer Zeichenfolge zurück, die den Fehler beschreibt.
Rufen Sie diese Methode nur an der Stelle auf, an der Sie stattdessen die close-Methode aufgerufen hätten. Das Aufrufen dieser Methode versetzt das aktuelle Redis-Objekt sofort in den closed-Zustand. Alle nachfolgenden Operationen, außer connect(), auf dem aktuellen Objekt geben den closed-Fehler zurück.
get_reused_times
syntax: times, err = red:get_reused_times()
Diese Methode gibt die (erfolgreich) wiederverwendeten Zeiten für die aktuelle Verbindung zurück. Im Falle eines Fehlers gibt es nil und eine Zeichenfolge zurück, die den Fehler beschreibt.
Wenn die aktuelle Verbindung nicht aus dem integrierten Verbindungspool stammt, gibt diese Methode immer 0 zurück, das heißt, die Verbindung wurde (noch) nie wiederverwendet. Wenn die Verbindung aus dem Verbindungspool stammt, ist der Rückgabewert immer ungleich null. Diese Methode kann also auch verwendet werden, um zu bestimmen, ob die aktuelle Verbindung aus dem Pool stammt.
close
syntax: ok, err = red:close()
Schließt die aktuelle Redis-Verbindung und gibt den Status zurück.
Im Erfolgsfall gibt es 1 zurück. Im Falle von Fehlern gibt es nil mit einer Zeichenfolge zurück, die den Fehler beschreibt.
init_pipeline
syntax: red:init_pipeline()
syntax: red:init_pipeline(n)
Aktiviert den Redis-Pipelining-Modus. Alle nachfolgenden Aufrufe der Redis-Befehlsmethoden werden automatisch zwischengespeichert und an den Server in einem Durchgang gesendet, wenn die Methode commit_pipeline aufgerufen wird, oder werden durch den Aufruf der Methode cancel_pipeline abgebrochen.
Diese Methode gelingt immer.
Wenn sich das Redis-Objekt bereits im Redis-Pipelining-Modus befindet, wird durch den Aufruf dieser Methode die vorhandenen zwischengespeicherten Redis-Abfragen verworfen.
Das optionale Argument n gibt die (ungefähre) Anzahl der Befehle an, die zu diesem Pipeline hinzugefügt werden sollen, was die Dinge etwas schneller machen kann.
commit_pipeline
syntax: results, err = red:commit_pipeline()
Verlässt den Pipelining-Modus, indem alle zwischengespeicherten Redis-Abfragen in einem einzigen Durchgang an den Remote-Server übermittelt werden. Alle Antworten auf diese Abfragen werden automatisch gesammelt und werden zurückgegeben, als ob es sich um eine große Multi-Bulk-Antwort auf der höchsten Ebene handelt.
Diese Methode gibt nil und eine Lua-Zeichenfolge zurück, die den Fehler im Falle von Fehlern beschreibt.
cancel_pipeline
syntax: red:cancel_pipeline()
Verlässt den Pipelining-Modus, indem alle vorhandenen zwischengespeicherten Redis-Befehle seit dem letzten Aufruf der Methode init_pipeline verworfen werden.
Diese Methode gelingt immer.
Wenn sich das Redis-Objekt nicht im Redis-Pipelining-Modus befindet, ist diese Methode ein No-Op.
hmset
syntax: res, err = red:hmset(myhash, field1, value1, field2, value2, ...)
syntax: res, err = red:hmset(myhash, { field1 = value1, field2 = value2, ... })
Spezialwrapper für den Redis-Befehl "hmset".
Wenn es nur drei Argumente gibt (einschließlich des "red"-Objekts selbst), muss das letzte Argument eine Lua-Tabelle sein, die alle Feld-/Wert-Paare enthält.
array_to_hash
syntax: hash = red:array_to_hash(array)
Hilfsfunktion, die eine array-ähnliche Lua-Tabelle in eine hash-ähnliche Tabelle umwandelt.
Diese Methode wurde erstmals in der Version v0.11 eingeführt.
read_reply
syntax: res, err = red:read_reply()
Liest eine Antwort vom Redis-Server. Diese Methode ist hauptsächlich nützlich für die Redis Pub/Sub API, zum Beispiel,
local cjson = require "cjson"
local redis = require "resty.redis"
local red = redis:new()
local red2 = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 Sekunde
red2:set_timeouts(1000, 1000, 1000) -- 1 Sekunde
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("1: Verbindung fehlgeschlagen: ", err)
return
end
ok, err = red2:connect("127.0.0.1", 6379)
if not ok then
ngx.say("2: Verbindung fehlgeschlagen: ", err)
return
end
local res, err = red:subscribe("hund")
if not res then
ngx.say("1: Abonnieren fehlgeschlagen: ", err)
return
end
ngx.say("1: abonnieren: ", cjson.encode(res))
res, err = red2:publish("hund", "Hallo")
if not res then
ngx.say("2: Veröffentlichen fehlgeschlagen: ", err)
return
end
ngx.say("2: veröffentlichen: ", cjson.encode(res))
res, err = red:read_reply()
if not res then
ngx.say("1: Antwort lesen fehlgeschlagen: ", err)
return
end
ngx.say("1: empfangen: ", cjson.encode(res))
red:close()
red2:close()
Wenn Sie dieses Beispiel ausführen, erhalten Sie eine Ausgabe wie diese:
1: abonnieren: ["subscribe","hund",1]
2: veröffentlichen: 1
1: empfangen: ["message","hund","Hallo"]
Die folgenden Klassenmethoden werden bereitgestellt:
add_commands
syntax: hash = redis.add_commands(cmd_name1, cmd_name2, ...)
WARNUNG Diese Methode ist jetzt veraltet, da wir bereits die automatische Lua-Methoden-Generierung für alle Redis-Befehle durchführen, die der Benutzer zu verwenden versucht, und wir daher diese nicht mehr benötigen.
Fügt neue Redis-Befehle zur resty.redis-Klasse hinzu. Hier ist ein Beispiel:
local redis = require "resty.redis"
redis.add_commands("foo", "bar")
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 Sekunde
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("Verbindung fehlgeschlagen: ", err)
return
end
local res, err = red:foo("a")
if not res then
ngx.say("Fehler bei foo: ", err)
end
res, err = red:bar()
if not res then
ngx.say("Fehler bei bar: ", err)
end
Redis-Authentifizierung
Redis verwendet den AUTH-Befehl zur Authentifizierung: http://redis.io/commands/auth
Für diesen Befehl gibt es nichts Besonderes im Vergleich zu anderen Redis-Befehlen wie GET und SET. Man kann also einfach die auth-Methode auf Ihrer resty.redis-Instanz aufrufen. Hier ist ein Beispiel:
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 Sekunde
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("Verbindung fehlgeschlagen: ", err)
return
end
local res, err = red:auth("foobared")
if not res then
ngx.say("Authentifizierung fehlgeschlagen: ", err)
return
end
Dabei gehen wir davon aus, dass der Redis-Server mit dem Passwort foobared in der redis.conf-Datei konfiguriert ist:
requirepass foobared
Wenn das angegebene Passwort falsch ist, gibt das obige Beispiel Folgendes an den HTTP-Client aus:
Authentifizierung fehlgeschlagen: ERR ungültiges Passwort
Redis-Transaktionen
Diese Bibliothek unterstützt die Redis-Transaktionen. Hier ist ein Beispiel:
local cjson = require "cjson"
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000) -- 1 Sekunde
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("Verbindung fehlgeschlagen: ", err)
return
end
local ok, err = red:multi()
if not ok then
ngx.say("Fehler beim Ausführen von multi: ", err)
return
end
ngx.say("multi antwort: ", cjson.encode(ok))
local ans, err = red:set("a", "abc")
if not ans then
ngx.say("Fehler beim Ausführen von sort: ", err)
return
end
ngx.say("set antwort: ", cjson.encode(ans))
local ans, err = red:lpop("a")
if not ans then
ngx.say("Fehler beim Ausführen von sort: ", err)
return
end
ngx.say("set antwort: ", cjson.encode(ans))
ans, err = red:exec()
ngx.say("exec antwort: ", cjson.encode(ans))
red:close()
Dann wird die Ausgabe sein:
multi antwort: "OK"
set antwort: "QUEUED"
set antwort: "QUEUED"
exec antwort: ["OK",[false,"ERR Operation gegen einen Schlüssel mit dem falschen Werttyp"]]
Redis-Modul
Diese Bibliothek unterstützt das Redis-Modul. Hier ist ein Beispiel mit dem RedisBloom-Modul:
local cjson = require "cjson"
local redis = require "resty.redis"
-- registrieren Sie das Modulpräfix "bf" für RedisBloom
redis.register_module_prefix("bf")
local red = redis:new()
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.say("Verbindung fehlgeschlagen: ", err)
return
end
-- rufen Sie den BF.ADD-Befehl mit dem Präfix 'bf' auf
res, err = red:bf():add("hund", 1)
if not res then
ngx.say(err)
return
end
ngx.say("empfangen: ", cjson.encode(res))
-- rufen Sie den BF.EXISTS-Befehl auf
res, err = red:bf():exists("hund")
if not res then
ngx.say(err)
return
end
ngx.say("empfangen: ", cjson.encode(res))
Lastenausgleich und Failover
Sie können Ihre eigene Redis-Lastenausgleichslogik in Lua ganz einfach implementieren. Halten Sie einfach eine Lua-Tabelle mit allen verfügbaren Redis-Backend-Informationen (wie Hostnamen und Portnummern) und wählen Sie einen Server gemäß einer Regel (wie Round-Robin oder schlüsselbasierte Hashing) aus der Lua-Tabelle bei jeder Anfrage aus. Sie können den aktuellen Regelstatus in den Daten Ihres eigenen Lua-Moduls verfolgen, siehe https://github.com/openresty/lua-nginx-module/#data-sharing-within-an-nginx-worker
Ähnlich können Sie eine automatische Failover-Logik in Lua mit großer Flexibilität implementieren.
Debugging
Es ist normalerweise praktisch, die lua-cjson-Bibliothek zu verwenden, um die Rückgabewerte der Redis-Befehlsmethoden in JSON zu kodieren. Zum Beispiel,
local cjson = require "cjson"
...
local res, err = red:mget("h1234", "h5678")
if res then
print("res: ", cjson.encode(res))
end
Automatische Fehlerprotokollierung
Standardmäßig protokolliert das zugrunde liegende ngx_lua-Modul Fehler, wenn Socket-Fehler auftreten. Wenn Sie bereits eine ordnungsgemäße Fehlerbehandlung in Ihrem eigenen Lua-Code durchführen, wird empfohlen, diese automatische Fehlerprotokollierung zu deaktivieren, indem Sie die lua_socket_log_errors-Direktive von ngx_lua deaktivieren, das heißt,
lua_socket_log_errors off;
Checkliste für Probleme
- Stellen Sie sicher, dass Sie die Größe des Verbindungspools richtig in der set_keepalive konfigurieren. Grundsätzlich, wenn Ihr Redis
ngleichzeitige Verbindungen verarbeiten kann und Ihr NGINXmWorker hat, sollte die Größe des Verbindungspools alsn/mkonfiguriert werden. Zum Beispiel, wenn Ihr Redis normalerweise 1000 gleichzeitige Anfragen verarbeitet und Sie 10 NGINX-Worker haben, sollte die Größe des Verbindungspools 100 betragen. Ähnlich, wenn Siepverschiedene NGINX-Instanzen haben, sollte die Größe des Verbindungspoolsn/m/pbetragen. - Stellen Sie sicher, dass die Backlog-Einstellung auf der Redis-Seite groß genug ist. Für Redis 2.8+ können Sie direkt den
tcp-backlog-Parameter in derredis.conf-Datei anpassen (und auch den KernelparameterSOMAXCONNentsprechend anpassen, mindestens unter Linux). Möglicherweise möchten Sie auch denmaxclients-Parameter in derredis.confanpassen. - Stellen Sie sicher, dass Sie in den set_timeout- oder set_timeouts-Methoden keine zu kurzen Timeout-Einstellungen verwenden. Wenn Sie müssen, versuchen Sie, die Operation bei einer Zeitüberschreitung erneut durchzuführen und die automatische Fehlerprotokollierung auszuschalten (da Sie bereits eine ordnungsgemäße Fehlerbehandlung in Ihrem eigenen Lua-Code durchführen).
- Wenn die CPU-Auslastung Ihrer NGINX-Worker-Prozesse unter Last sehr hoch ist, könnte die NGINX-Ereignisschleife durch die CPU-Berechnung zu stark blockiert sein. Versuchen Sie, ein C-land on-CPU Flame Graph und ein Lua-land on-CPU Flame Graph für einen typischen NGINX-Worker-Prozess zu erstellen. Sie können die CPU-gebundenen Dinge gemäß diesen Flame Graphs optimieren.
- Wenn die CPU-Auslastung Ihrer NGINX-Worker-Prozesse unter Last sehr niedrig ist, könnte die NGINX-Ereignisschleife durch einige blockierende Systemaufrufe (wie Datei-I/O-Systemaufrufe) blockiert sein. Sie können das Problem bestätigen, indem Sie das epoll-loop-blocking-distr-Tool gegen einen typischen NGINX-Worker-Prozess ausführen. Wenn dies tatsächlich der Fall ist, können Sie weiter ein C-land off-CPU Flame Graph für einen NGINX-Worker-Prozess erstellen, um die tatsächlichen Blockierer zu analysieren.
- Wenn Ihr
redis-server-Prozess nahe 100% CPU-Auslastung läuft, sollten Sie in Betracht ziehen, Ihr Redis-Backend auf mehrere Knoten zu skalieren oder das C-land on-CPU Flame Graph-Tool zu verwenden, um die internen Engpässe innerhalb des Redis-Serverprozesses zu analysieren.
Einschränkungen
- Diese Bibliothek kann nicht in Codekontexten wie init_by_lua, set_by_lua, log_by_lua und header_filter_by_lua verwendet werden, in denen die ngx_lua-cosocket-API nicht verfügbar ist.
- Die
resty.redis-Objektinstanz kann nicht auf Modulebene in einer Lua-Variablen gespeichert werden, da sie dann von allen gleichzeitigen Anfragen, die vom selben NGINX-Worker-Prozess verarbeitet werden, geteilt wird (siehe https://github.com/openresty/lua-nginx-module/#data-sharing-within-an-nginx-worker) und zu schlechten Race-Bedingungen führen kann, wenn gleichzeitige Anfragen versuchen, dieselberesty.redis-Instanz zu verwenden (Sie würden den "schlechten Antrag" oder "Socket beschäftigt"-Fehler von den Methodenaufrufen zurückbekommen). Sie sollten immerresty.redis-Objekte in lokalen Funktionsvariablen oder in derngx.ctx-Tabelle initiieren. Diese Orte haben alle ihre eigenen Datenkopien für jede Anfrage.
Klonen Sie die neueste Version, angenommen v0.29
wget https://github.com/openresty/lua-resty-redis/archive/refs/tags/v0.29.tar.gz
Entpacken
tar -xvzf v0.29.tar.gz
In das Verzeichnis wechseln
cd lua-resty-redis-0.29
export LUA_LIB_DIR=/usr/local/openresty/site/lualib
Kompilieren und Installieren
make install
Jetzt wird der kompilierte Pfad ausgegeben
/usr/local/lib/lua/resty = lua_package_path in nginx conf
```
Siehe auch
- das ngx_lua-Modul: https://github.com/openresty/lua-nginx-module/#readme
- die Redis-verdrahtete Protokollspezifikation: http://redis.io/topics/protocol
- die lua-resty-memcached-Bibliothek
- die lua-resty-mysql-Bibliothek
GitHub
Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-redis.