Zum Inhalt

lrucache: Lua-Land LRU Cache basierend auf LuaJIT FFI

Installation

Wenn Sie noch kein RPM-Repository-Abonnement 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-lrucache

CentOS/RHEL 8+, Fedora Linux, Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-lrucache

Um diese Lua-Bibliothek mit NGINX zu verwenden, stellen Sie sicher, dass nginx-module-lua installiert ist.

Dieses Dokument beschreibt lua-resty-lrucache v0.15, das am 10. Oktober 2024 veröffentlicht wurde.


-- Datei myapp.lua: Beispiel "myapp" Modul

local _M = {}

-- alternativ: local lrucache = require "resty.lrucache.pureffi"
local lrucache = require "resty.lrucache"

-- Wir müssen den Cache auf Modulebene initialisieren, damit
-- er von allen Anfragen, die von jedem NGINX-Worker-Prozess bedient werden, geteilt werden kann:
local c, err = lrucache.new(200)  -- bis zu 200 Elemente im Cache zulassen
if not c then
    error("Fehler beim Erstellen des Caches: " .. (err or "unbekannt"))
end

function _M.go()
    c:set("dog", 32)
    c:set("cat", 56)
    ngx.say("dog: ", c:get("dog"))
    ngx.say("cat: ", c:get("cat"))

    c:set("dog", { age = 10 }, 0.1)  -- läuft nach 0.1 Sek ab
    c:delete("dog")

    c:flush_all()  -- alle zwischengespeicherten Daten löschen
end

return _M
## nginx.conf

http {
    # nur wenn keine offizielle OpenResty-Version verwendet wird
    server {
        listen 8080;

        location = /t {
            content_by_lua_block {
                require("myapp").go()
            }
        }
    }
}

Beschreibung

Diese Bibliothek implementiert einen einfachen LRU-Cache für OpenResty und das ngx_lua Modul.

Dieser Cache unterstützt auch Ablaufzeiten.

Der LRU-Cache befindet sich vollständig in der Lua-VM und unterliegt der Lua-GC. Daher sollten Sie nicht erwarten, dass er über die OS-Prozessgrenze hinweg geteilt wird. Der Vorteil ist, dass Sie beliebig komplexe Lua-Werte (wie tief verschachtelte Lua-Tabellen) ohne die Overhead-Kosten der Serialisierung (wie bei ngx_lua's shared dictionary API) zwischenspeichern können. Der Nachteil ist, dass Ihr Cache immer auf den aktuellen OS-Prozess (d.h. den aktuellen NGINX-Worker-Prozess) beschränkt ist. Es macht nicht wirklich viel Sinn, diese Bibliothek im Kontext von init_by_lua zu verwenden, da der Cache nicht von einem der Worker-Prozesse geteilt wird (es sei denn, Sie möchten den Cache nur mit vordefinierten Elementen "vorwärmen", die von den Workern über fork() geerbt werden).

Diese Bibliothek bietet zwei verschiedene Implementierungen in Form von zwei Klassen: resty.lrucache und resty.lrucache.pureffi. Beide implementieren die gleiche API. Der einzige Unterschied besteht darin, dass letztere eine reine FFI-Implementierung ist, die auch eine FFI-basierte Hashtabelle für die Cache-Suche implementiert, während erstere native Lua-Tabellen verwendet.

Wenn die Cache-Trefferquote relativ hoch ist, sollten Sie die Klasse resty.lrucache verwenden, die schneller ist als resty.lrucache.pureffi.

Wenn die Cache-Trefferquote jedoch relativ niedrig ist und es viele Variationen von Schlüsseln gibt, die in den Cache eingefügt und daraus entfernt werden, sollten Sie stattdessen resty.lrucache.pureffi verwenden, da Lua-Tabellen nicht gut darin sind, Schlüssel häufig zu entfernen. Sie würden wahrscheinlich sehen, dass der resizetab Funktionsaufruf zur LuaJIT-Laufzeit in on-CPU-Flame-Graphs sehr häufig ist, wenn Sie in einem solchen Anwendungsfall die Klasse resty.lrucache anstelle von resty.lrucache.pureffi verwenden.

Methoden

Um diese Bibliothek zu laden,

  1. verwenden Sie eine offizielle OpenResty-Version oder folgen Sie den Installationsanweisungen.
  2. verwenden Sie require, um die Bibliothek in eine lokale Lua-Variable zu laden:
local lrucache = require "resty.lrucache"

oder

local lrucache = require "resty.lrucache.pureffi"

new

syntax: cache, err = lrucache.new(max_items [, load_factor])

Erstellt eine neue Cache-Instanz. Bei einem Fehler wird nil und eine Zeichenfolge, die den Fehler beschreibt, zurückgegeben.

Das Argument max_items gibt die maximale Anzahl von Elementen an, die dieser Cache halten kann.

Das Argument load-factor bezeichnet den "Lastfaktor" der intern verwendeten FFI-basierten Hashtabelle von resty.lrucache.pureffi; der Standardwert ist 0.5 (d.h. 50%); wenn der Lastfaktor angegeben wird, wird er auf den Bereich von [0.1, 1] (d.h. wenn der Lastfaktor größer als 1 ist, wird er auf 1 gesättigt; ebenso, wenn der Lastfaktor kleiner als 0.1 ist, wird er auf 0.1 geklammert). Dieses Argument ist nur für resty.lrucache.pureffi von Bedeutung.

set

syntax: cache:set(key, value, ttl?, flags?)

Setzt einen Schlüssel mit einem Wert und einer Ablaufzeit.

Wenn der Cache voll ist, wird der Cache automatisch das am wenigsten kürzlich verwendete Element entfernen.

Das optionale Argument ttl gibt die Ablaufzeit an. Der Zeitwert ist in Sekunden, aber Sie können auch den Bruchteil angeben (z.B. 0.25). Ein nil ttl-Argument bedeutet, dass der Wert niemals abläuft (was der Standard ist).

Das optionale Argument flags gibt einen Benutzer-Flag-Wert an, der mit dem zu speichernden Element verknüpft ist. Er kann später zusammen mit dem Element abgerufen werden. Die Benutzer-Flags werden intern als 32-Bit-Unsigned-Integer gespeichert und müssen daher als Lua-Zahl angegeben werden. Wenn nicht angegeben, haben die Flags einen Standardwert von 0. Dieses Argument wurde in der Version v0.10 hinzugefügt.

get

syntax: data, stale_data, flags = cache:get(key)

Holt einen Wert mit dem Schlüssel. Wenn der Schlüssel nicht im Cache vorhanden ist oder bereits abgelaufen ist, wird nil zurückgegeben.

Seit v0.03 wird die veraltete Daten auch als zweiter Rückgabewert zurückgegeben, wenn verfügbar.

Seit v0.10 wird der Benutzer-Flag-Wert, der mit dem gespeicherten Element verknüpft ist, ebenfalls als dritter Rückgabewert zurückgegeben. Wenn keine Benutzer-Flags einem Element zugewiesen wurden, sind die Standardflags 0.

delete

syntax: cache:delete(key)

Entfernt ein durch den Schlüssel angegebenes Element aus dem Cache.

count

syntax: count = cache:count()

Gibt die Anzahl der derzeit im Cache gespeicherten Elemente einschließlich abgelaufener Elemente, falls vorhanden, zurück.

Der zurückgegebene count-Wert ist immer größer oder gleich 0 und kleiner oder gleich dem size-Argument, das an cache:new übergeben wurde.

Diese Methode wurde in der Version v0.10 hinzugefügt.

capacity

syntax: size = cache:capacity()

Gibt die maximale Anzahl von Elementen zurück, die der Cache halten kann. Der Rückgabewert ist derselbe wie das size-Argument, das an cache:new übergeben wurde, als der Cache erstellt wurde.

Diese Methode wurde in der Version v0.10 hinzugefügt.

get_keys

syntax: keys = cache:get_keys(max_count?, res?)

Holt die Liste der derzeit im Cache befindlichen Schlüssel bis zu max_count. Die Schlüssel werden in MRU-Reihenfolge (Most-Recently-Used-Schlüssel zuerst) angeordnet.

Diese Funktion gibt eine Lua (Array-)Tabelle (mit Ganzzahlen als Schlüsseln) zurück, die die Schlüssel enthält.

Wenn max_count nil oder 0 ist, werden alle Schlüssel (falls vorhanden) zurückgegeben.

Wenn ein res-Tabellenargument bereitgestellt wird, wird diese Funktion keine Tabelle zuweisen und stattdessen die Schlüssel in res einfügen, zusammen mit einem nachfolgenden nil-Wert.

Diese Methode wurde in der Version v0.10 hinzugefügt.

flush_all

syntax: cache:flush_all()

Löscht alle vorhandenen Daten (falls vorhanden) in der aktuellen Cache-Instanz. Dies ist eine O(1)-Operation und sollte viel schneller sein als das Erstellen einer brandneuen Cache-Instanz.

Beachten Sie jedoch, dass die Methode flush_all() von resty.lrucache.pureffi eine O(n)-Operation ist.

Voraussetzungen

nginx.conf

http {
    ...
}

und laden Sie dann die Bibliothek in Lua:lua local lrucache = require "resty.lrucache" ```

Siehe auch

GitHub

Sie finden möglicherweise zusätzliche Konfigurationstipps und Dokumentationen für dieses Modul im GitHub-Repository für nginx-module-lrucache.