Heim >Backend-Entwicklung >PHP-Tutorial >Verwenden Sie ngx_lua, um Anwendungen mit hoher Parallelität zu erstellen

Verwenden Sie ngx_lua, um Anwendungen mit hoher Parallelität zu erstellen

WBOY
WBOYOriginal
2016-07-30 13:31:381034Durchsuche

Dieser Artikel konzentriert sich hauptsächlich auf die nicht blockierende Kommunikation mit dem Backend-Memcached und Redis über ngx_lua.

1. Memcached

Der Zugriff auf Memcached erfordert Modulunterstützung. Hier ist HttpMemcModule ausgewählt, das eine nicht blockierende Kommunikation mit dem Back-End-Memcached durchführen kann. Wir wissen, dass Memcached offiziell bereitgestellt wird. Dieses Modul unterstützt nur Get-Vorgänge, während Memc die meisten Memcached-Befehle unterstützt.

Das Memc-Modul verwendet Eingabevariablen als zu übergebende Parameter. Alle Variablen mit dem Präfix $memc_ sind die Eingabevariablen von Memc. memc_pass verweist auf den Backend-Memcached-Server.

Konfiguration:

[einfache] Ansicht Klartext?

  1. #Use HttpMemcModule
  2. location = /memc {
  3. set $memc_cmd $arg_cmd;
  4. set $memc_key $arg_key; 🎜>
  5. set $memc_exptime $arg_exptime;
  6. }
  7. Ausgabe:
  8. [plain ] Sicht Klartext?
$ curl 'http://localhost/memc?cmd=set&key=foo&val=Hello'

$ GESPEICHERT

  1. $ curl 'http://localhost/memc?cmd=get&key=foo' $ Hallo
  2. Dies realisiert den Zugriff auf Memcached. Schauen wir uns an, wie man in Lua auf Memcached zugreift.
  3. Konfiguration:
  4. [einfache] Ansicht Klartext?

#Access Memcached in Lua

location = /memc {

  1. internal; #Nur interner Zugriff set $memc_cmd get;
  2. set $memc_key $arg_key; 🎜>
  3. memc_pass '127.0.0.1:11211';
  4. }
  5. location = /lua_memc { 🎜>
  6. content_by_lua '
  7. local res = ngx.location.capture("/memc", {
  8. args = { key = ngx.var.arg_key }
  9. })
  10. if res.status == 20 0 then
  11. ngx.say(res.body)
  12. end
  13. ';
  14. }
  15. Ausgabe:
  16. [einfache] Ansicht Klartext?
  17. $ curl 'http://localhost/lua_memc?key=foo'
$ Hallo

Der Zugriff auf Memcached über Lua wird hauptsächlich über Unteranfragen implementiert, ähnlich wie Funktionsaufrufe. Zunächst wird ein Memc-Speicherort für die Kommunikation über Backend-Memcached definiert, was dem Memcached-Speicher entspricht. Da das gesamte Memc-Modul nicht blockierend ist, ist auch ngx.location.capture nicht blockierend, sodass der gesamte Vorgang nicht blockierend ist.

2. Redis

Der Zugriff auf Redis erfordert die Unterstützung von HttpRedis2Module, das auch nicht blockierend mit Redis kommunizieren kann. Die Antwort von Redis2 ist jedoch die native Antwort von Redis. Bei Verwendung in Lua muss diese Antwort daher analysiert werden. LuaRedisModule kann verwendet werden. Dieses Modul kann die native Anfrage von Redis erstellen und die native Antwort von Redis analysieren.

Konfiguration:

[einfache] Ansicht Klartext?

  1. #Access Redis in Lua
  2. location = /redis {
  3. internal; #Nur interner Zugriff
  4. redis2_query get $arg_key;
  5. redis2_pass '127.0.0.1:6379' ; 🎜>
  6. }
  7. location = /lua_redis { #Requires LuaRedisParser
  8. content_by_lua '
  9. local parser = require("redis.parser")
  10. local res = ngx.location.capture("/redis", {
  11. args = { key = ngx.var.arg_key }
  12. })
  13. wenn res = 200 then >
  14. end 
  15.  '; Ausgabe:
  16. [plain] view Klartext?
  17. $ curl 'http://localhost/lua_redis?key=foo'
  18. $ Hallo
Ähnlich wie beim Zugriff auf Memcached müssen Sie einen Redis-Speicher speziell für die Abfrage von Redis bereitstellen und dann Redis über Unteranforderungen aufrufen.

3. Redis-Pipeline

Beim tatsächlichen Zugriff auf Redis kann es erforderlich sein, mehrere Schlüssel gleichzeitig abzufragen. Wir können ngx.location.capture_multi verwenden, um mehrere Unteranforderungen an den Redis-Speicher zu senden und dann den Antwortinhalt zu analysieren. Es gibt jedoch eine Grenze. Der Nginx-Kernel legt fest, dass die Anzahl der Unteranforderungen, die gleichzeitig initiiert werden können, 50 nicht überschreiten darf. Wenn die Anzahl der Schlüssel also 50 überschreitet, ist diese Lösung nicht mehr anwendbar.
    Glücklicherweise bietet Redis einen Pipeline-Mechanismus, der mehrere Befehle in einer Verbindung ausführen kann, wodurch die Umlaufverzögerung bei der mehrfachen Ausführung von Befehlen verringert werden kann. Nachdem der Client mehrere Befehle über die Pipeline gesendet hat, empfängt Redis diese Befehle nacheinander, führt sie aus und gibt dann die Ergebnisse der Befehle nacheinander aus. Wenn Sie eine Pipeline in Lua verwenden, müssen Sie redis2_raw_queries des Redis2-Moduls verwenden, um die nativen Anforderungsabfragen von Redis auszuführen.
  1. Konfiguration:
  2. [einfache] Ansicht Klartext?
    1. #Access Redis in Lua
    2. location = /redis {
    3. internal ; '127.0.0.1:6379';
    4. content_by_lua 'conf/pipeline.lua'; 🎜>
    5. pipeline .lua
    6. [einfache] Ansicht Klartext?
    7. -- conf/pipeline.lua-Datei
    8. local parser = require('redis.parser ')
    9. local reqs = {
    10. {'get', 'one'}, {'get', 'two'}
    11. }
    --Konstruieren Sie eine native Redis-Abfrage, erhalten Sie onernget twon

    local raw_reqs = { }

    1. for i, req in ipairs(reqs) do table.insert(raw_reqs, parser.build_query(req))
    2. end
    3. local res = ngx.location.capture('/redis?'..#reqs, { body = table.concat( raw_reqs , '') }) 
    4.                                                                                                       🎜>                                                                                                                                                        Antworten. in ipairs(replies) machen
    5. ngx.say(reply[1])
    6. Ende
    7. Ende
    8. Ausgabe:
    9. [einfache] Ansicht Klartext?
    10. $ curl 'http://localhost/pipeline'
    11. $ first
    12. Sekunde
    13. 4. Verbindungspool Im vorherigen Beispiel wird der Zugriff auf Redis und Memcached jedes Mal verarbeitet, wenn eine Anfrage verarbeitet wird , wird eine Verbindung mit dem Back-End-Server hergestellt und die Verbindung freigegeben, nachdem die Anfrage verarbeitet wurde. Bei diesem Prozess entsteht ein gewisser Overhead wie drei Handshakes und Wartezeiten, was für Anwendungen mit hoher Parallelität nicht tolerierbar ist. Um diesen Overhead zu eliminieren, wird hier der Verbindungspool eingeführt.
    14. Der Verbindungspool erfordert die Unterstützung des HttpUpstreamKeepaliveModule-Moduls. Konfiguration:
    15. [einfache] Ansicht Klartext?
      1. http {
      2. # Erfordert HttpUpstreamKeepaliveModule 🎜>
      3. Server 127.0.0.1:6379;
      4. # Verbindungspool, der 1024 Verbindungen aufnehmen kann
      5. keepalive 1024 single; 🎜 > location = /redis {
      6. redis2_pass redis_pool;
      7. } Dieses Modul stellt die Keepalive-Direktive und ihren Kontext bereit. Es ist vorgelagert. Wir wissen, dass Upstream verwendet wird, wenn Nginx als Reverse-Proxy verwendet wird. Tatsächlich bezieht sich Upstream auf „Upstream“. Dieser „Upstream“ kann einige Server wie Redis, Memcached oder MySQL sein. Upstream kann einen virtuellen Servercluster definieren, und diese Backend-Server können Lastausgleich genießen. Keepalive 1024 definiert die Größe des Verbindungspools. Wenn die Anzahl der Verbindungen diese Größe überschreitet, werden nachfolgende Verbindungen automatisch in kurze Verbindungen umgewandelt. Die Verwendung des Verbindungspools ist sehr einfach. Ersetzen Sie einfach die ursprüngliche IP- und Portnummer.
      8. Jemand hat einmal gemessen, dass beim Zugriff auf Memcached (mit dem vorherigen Memc-Modul) ohne Verwendung eines Verbindungspools die RPS 20.000 betrug. Nach Nutzung des Verbindungspools stiegen die RPS bis auf 140.000. In tatsächlichen Situationen kann eine so große Verbesserung möglicherweise nicht erreicht werden, aber grundsätzlich ist eine Verbesserung von 100–200 % immer noch möglich.
      9. 5. Zusammenfassung
      10. Hier ist eine Zusammenfassung des Zugriffs auf Memcached und Redis. 1. Nginx bietet ein leistungsstarkes Programmiermodell. Der Standort entspricht einer Funktion, eine Unteranforderung entspricht einem Funktionsaufruf, und der Standort kann auch Unteranforderungen an sich selbst senden und so ein rekursives Modell bilden Modell wird übernommen. Komplexe Geschäftslogik implementieren.
      11. 2. Die E/A-Vorgänge von Nginx müssen nicht blockierend sein. Wenn Nginx dort blockiert, wird die Leistung von Nginx erheblich beeinträchtigt. Daher müssen in Lua Unteranforderungen über ngx.location.capture ausgegeben werden, um diese E/A-Vorgänge an das Ereignismodell von Nginx zu delegieren. 3. Wenn Sie eine TCP-Verbindung verwenden müssen, versuchen Sie, den Verbindungspool zu verwenden. Dadurch entfällt ein großer Aufwand beim Herstellen und Lösen von Verbindungen.
      12. Das Obige stellt die Verwendung von ngx_lua zum Erstellen von Anwendungen mit hoher Parallelität vor, einschließlich einiger Aspekte des Inhalts. Ich hoffe, dass es für Freunde hilfreich sein wird, die sich für PHP-Tutorials interessieren.
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn