In Tarantool können Sie eine superschnelle Datenbank und eine Anwendung kombinieren, um damit zu arbeiten. Hier erfahren Sie, wie einfach es geht

Vor fünf Jahren habe ich versucht, mit Tarantool zu arbeiten, aber dann hat es bei mir nicht funktioniert. Aber kürzlich habe ich ein Webinar abgehalten, in dem ich über Hadoop und die Funktionsweise von MapReduce gesprochen habe. Dort stellten sie mir eine Frage: „Warum nicht Tarantool für diese Aufgabe verwenden?“

Aus Neugier beschloss ich, darauf zurückzukommen und die neueste Version zu testen – und dieses Mal gefiel mir das Projekt wirklich. Jetzt zeige ich Ihnen, wie Sie eine einfache Anwendung in Tarantool schreiben, sie laden und ihre Leistung überprüfen, und Sie werden sehen, wie einfach und cool alles ist.

In Tarantool können Sie eine superschnelle Datenbank und eine Anwendung kombinieren, um damit zu arbeiten. Hier erfahren Sie, wie einfach es geht

Was ist Tarantool?

Tarantool positioniert sich als ultraschnelle Datenbank. Sie können dort beliebige Daten eingeben. Replizieren Sie sie außerdem, sharden Sie sie, verteilen Sie also eine große Datenmenge auf mehrere Server und kombinieren Sie die daraus resultierenden Ergebnisse, um fehlertolerante Master-Master-Verbindungen herzustellen.

Zweitens ist dies ein Anwendungsserver. Sie können darauf Ihre Anwendungen schreiben, mit Daten arbeiten, zum Beispiel alte Datensätze im Hintergrund nach bestimmten Regeln löschen. Sie können direkt in Tarantula einen HTTP-Server schreiben, der mit Daten arbeitet: Geben Sie deren Menge aus, schreiben Sie dort neue Daten und reduzieren Sie alles auf den Master.

Ich habe einen Artikel darüber gelesen, wie die Jungs eine Nachrichtenwarteschlange mit 300 Zeilen erstellt haben, die einfach nur platzt und hektisch ist – sie haben eine Mindestleistung von 20 Nachrichten pro Sekunde. Hier können Sie wirklich umdrehen und eine sehr große Anwendung schreiben, und es wird kein Speicher wie in PostgreS sein.

Ich werde versuchen, in diesem Artikel so etwas wie diesen Server zu beschreiben, nur einfach.

Einstellung

Für den Test habe ich drei virtuelle Standardmaschinen gestartet – eine 20-GB-Festplatte, Ubuntu 18.04. 2 virtuelle CPUs und 4 GB Speicher.

Wir installieren Tarantool – führen das Bash-Skript aus oder fügen ein Repository hinzu und führen „apt get install Tarantool“ aus. Link zum Skript - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Wir haben Befehle wie:

tarantoolctl – der Hauptbefehl zur Verwaltung von Tarantula-Instanzen.
/etc/tarantool - hier ist die gesamte Konfiguration.
var/log/tarantool - Hier sind die Protokolle.
var/lib/tarantool – Die Daten liegen hier und werden dann in Instanzen unterteilt.

Es gibt die Ordner „instance-available“ und „instance-enable“ – sie enthalten, was gestartet wird – eine Instanzkonfigurationsdatei mit Lua-Code, der beschreibt, auf welchen Ports sie lauscht, welcher Speicher ihr zur Verfügung steht, Vinyl-Engine-Einstellungen und Code, der beim Start ausgeführt wird Server, Sharding, Warteschlangen, Löschen veralteter Daten usw.

Instanzen funktionieren wie in PostgreS. Sie möchten beispielsweise mehrere Kopien einer Datenbank ausführen, die an verschiedenen Ports hängt. Es stellt sich heraus, dass auf einem Server mehrere Datenbankinstanzen gestartet werden, die an unterschiedlichen Ports hängen. Sie können völlig unterschiedliche Einstellungen haben – eine Instanz implementiert eine Logik, die zweite eine andere.

Instanzverwaltung

Wir haben den Befehl tarantoolctl, mit dem Sie Tarantula-Instanzen verwalten können. Beispielsweise prüft tarantoolctl check example die Konfigurationsdatei und sagt: „Die Datei ist in Ordnung, wenn dort keine Syntaxfehler vorliegen.“

Sie können den Status der Instanz sehen – Beispiel für den Tarantoolctl-Status. Auf die gleiche Weise können Sie starten, stoppen und neu starten.

Sobald die Instanz ausgeführt wird, können Sie auf zwei Arten eine Verbindung zu ihr herstellen.

1. Verwaltungskonsole

Standardmäßig öffnet Tarantool einen Socket und normaler ASCII-Text wird dorthin gesendet, um Tarantool zu steuern. Die Verbindung zur Konsole erfolgt immer unter dem Admin-Benutzer, es erfolgt keine Authentifizierung, sodass für die Verwaltung von Tarantula keine Externalisierung des Konsolenports erforderlich ist.

Um eine Verbindung mit dieser Methode herzustellen, müssen Sie Tarantoolctl und den Instanznamen eingeben. Der Befehl startet die Konsole und stellt eine Verbindung als Admin-Benutzer her. Legen Sie den Konsolenanschluss niemals nach außen frei – es ist besser, ihn als Gerätebuchse zu belassen. Dann können sich nur diejenigen mit Schreibzugriff auf den Socket mit Tarantula verbinden.

Diese Methode wird für administrative Zwecke benötigt. Um mit Daten zu arbeiten, verwenden Sie die zweite Methode – das Binärprotokoll.

2. Verwenden eines Binärprotokolls zum Herstellen einer Verbindung zu einem bestimmten Port

Die Konfiguration enthält eine Listen-Direktive, die einen Port für externe Kommunikation öffnet. Dieser Port wird mit dem Binärprotokoll verwendet und dort ist die Authentifizierung aktiviert.

Für diese Verbindung wird tarantoolctl connect to port number verwendet. Damit können Sie eine Verbindung zu Remote-Servern herstellen, eine Authentifizierung nutzen und verschiedene Zugriffsrechte vergeben.

Datenaufzeichnungs- und Boxmodul

Da Tarantool sowohl eine Datenbank als auch ein Anwendungsserver ist, verfügt es über verschiedene Module. Uns interessiert das Box-Modul – es implementiert die Arbeit mit Daten. Wenn Sie etwas in die Box schreiben, schreibt Tarantool die Daten auf die Festplatte, speichert sie im Speicher oder macht etwas anderes damit.

Rekord

Wir gehen zum Beispiel in das Box-Modul und rufen die Funktion box.once auf. Dadurch wird Tarantool gezwungen, unseren Code auszuführen, wenn der Server initialisiert wird. Wir schaffen einen Raum, in dem unsere Daten gespeichert werden.

local function bootstrap()
    local space = box.schema.create_space('example')
    space:create_index('primary')
    box.schema.user.grant('guest', 'read,write,execute', 'universe')

    -- Keep things safe by default
    --  box.schema.user.create('example', { password = 'secret' })
    --  box.schema.user.grant('example', 'replication')
    --  box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end

Danach erstellen wir einen Primärindex – Primary – anhand dessen wir nach Daten suchen können. Wenn Sie keine Parameter angeben, wird standardmäßig das erste Feld in jedem Datensatz für den Primärindex verwendet.

Dann gewähren wir dem Gastbenutzer eine Gewährung, unter der wir uns über das Binärprotokoll verbinden. Wir ermöglichen das Lesen, Schreiben und Ausführen in der gesamten Instanz.

Im Vergleich zu herkömmlichen Datenbanken ist hier alles recht einfach. Wir haben Platz – einen Bereich, in dem unsere Daten einfach gespeichert werden. Jeder Datensatz wird als Tupel bezeichnet. Es ist in MessagePack verpackt. Dies ist ein sehr cooles Format – es ist binär und nimmt weniger Platz ein – 18 Byte gegenüber 27.

In Tarantool können Sie eine superschnelle Datenbank und eine Anwendung kombinieren, um damit zu arbeiten. Hier erfahren Sie, wie einfach es geht

Es ist sehr bequem, mit ihm zusammenzuarbeiten. Fast jede Zeile, jeder Datensatz kann völlig unterschiedliche Spalten haben.

Wir können alle Räume mit dem Befehl Box.space anzeigen. Um eine bestimmte Instanz auszuwählen, schreiben Sie box.space example und erhalten Sie vollständige Informationen darüber.

Tarantool verfügt über zwei integrierte Engines: Memory und Vinyl. Der Speicher speichert alle Daten im Speicher. Daher funktioniert alles einfach und schnell. Die Daten werden auf der Festplatte gespeichert und es gibt auch einen Protokollmechanismus zum Vorausschreiben, sodass wir bei einem Serverabsturz nichts verlieren.

Vinyl speichert Daten auf der Festplatte in einer für uns vertrauteren Form – das heißt, Sie können mehr Daten speichern, als wir Speicher haben, und Tarantula liest sie von der Festplatte.

Im Moment verwenden wir Memory.

unix/:/var/run/tarantool/example.control> box.space.example
---
- engine: memtx
  before_replace: 'function: 0x41eb02c8'
  on_replace: 'function: 0x41eb0568'
  ck_constraint: []
  field_count: 0
  temporary: false
  index:
    0: &0
      unique: true
      parts:
      - type: unsigned
        is_nullable: false
        fieldno: 1
      id: 0
      space_id: 512
      type: TREE
      name: primary
    primary: *0
  is_local: false
  enabled: true
  name: example
  id: 512
...

unix/:/var/run/tarantool/example.control>

Verzeichnis:

Für jeden Bereich muss ein Primärindex erstellt werden, denn ohne ihn geht nichts. Wie in jeder Datenbank erstellen wir das erste Feld – die Datensatz-ID.

Teilen:

Hier geben wir an, woraus unser Index besteht. Es besteht aus einem Teil – das erste Feld, das wir verwenden werden, ist vom Typ ohne Vorzeichen – einer positiven Ganzzahl. Soweit ich mich aus der Dokumentation erinnere, liegt die Höchstzahl bei 18 Trillionen. Das ist eine Menge.

Dann können wir Daten mit dem Befehl insert einfügen.

unix/:/var/run/tarantool/example.control> box.space.example:insert{1, 'test1', 'test2'}
---
- [1, 'test1', 'test2']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{2, 'test2', 'test3', 'test4'}
---
- [2, 'test2', 'test3', 'test4']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{3, 'test3'}
---
- [3, 'test3']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{4, 'test4'}
---
- [4, 'test4']
...

unix/:/var/run/tarantool/example.control>

Das erste Feld wird als Primärschlüssel verwendet und muss daher eindeutig sein. Wir sind nicht auf die Anzahl der Spalten beschränkt, sodass wir dort so viele Daten einfügen können, wie wir möchten. Sie werden im MessagePack-Format angegeben, das ich oben beschrieben habe.

Datenausgabe

Dann können wir die Daten mit dem Select-Befehl anzeigen.

Box.example.select mit der Taste {1} zeigt den gewünschten Eintrag an. Wenn wir die Taste senken, sehen wir alle Datensätze, die wir haben. Sie unterscheiden sich alle in der Anzahl der Spalten, hier gibt es jedoch grundsätzlich kein Spaltenkonzept, sondern Feldnummern.

Es kann absolut jede Datenmenge sein. Und zum Beispiel müssen wir nach dem zweiten Feld suchen. Dazu erstellen wir einen neuen Sekundärindex.


box.space.example:create_index( ‘secondary’, { type = ‘TREE’, unique = false, parts = {{field = 2, type =’string’} }}) 

Wir verwenden den Befehl Create_index.
Nennen wir es sekundär.

Danach müssen Sie die Parameter angeben. Der Indextyp ist TREE. Es ist möglicherweise nicht eindeutig. Geben Sie daher Unique = false ein.

Dann geben wir an, aus welchen Teilen unser Index besteht. Feld ist die Nummer des Feldes, an das wir den Index binden und den String-Typ angeben. Und so entstand es.

unix/:/var/run/tarantool/example.control> box.space.example:create_index('secondary', { type = 'TREE', unique = false, parts = {{field = 2, type = 'string'}}})
---
- unique: false
  parts:
  - type: string
    is_nullable: false
    fieldno: 2
  id: 1
  space_id: 512
  type: TREE
  name: secondary
...

unix/:/var/run/tarantool/example.control>

So können wir es nun nennen:

unix/:/var/run/tarantool/example.control> box.space.example.index.secondary:select('test1')
---
- - [1, 'test1', 'test2']
...

Erhaltung

Wenn wir die Instanz neu starten und erneut versuchen, die Daten aufzurufen, werden wir feststellen, dass sie nicht vorhanden sind – alles ist leer. Dies geschieht, weil Tarantool Prüfpunkte erstellt und die Daten auf der Festplatte speichert. Wenn wir jedoch bis zum nächsten Speichern aufhören zu arbeiten, verlieren wir alle Vorgänge, da wir vom letzten Prüfpunkt, der beispielsweise vor zwei Stunden lag, eine Wiederherstellung durchführen.

Es wird auch nicht funktionieren, jede Sekunde zu sparen, da es keine gute Idee ist, ständig 20 GB auf die Festplatte zu kopieren.

Zu diesem Zweck wurde das Konzept des Write-Ahead-Protokolls erfunden und implementiert. Mit seiner Hilfe wird für jede Änderung der Daten ein Eintrag in einer kleinen Write-Ahead-Logdatei erstellt.

In ihnen wird jeder Eintrag bis zum Kontrollpunkt gespeichert. Für diese Dateien legen wir die Größe fest – zum Beispiel 64 MB. Wenn es voll ist, beginnt die Aufnahme mit der zweiten Datei. Und nach dem Neustart wird Tarantool vom letzten Prüfpunkt wiederhergestellt und führt dann einen Rollover aller späteren Transaktionen durch, bis es stoppt.

In Tarantool können Sie eine superschnelle Datenbank und eine Anwendung kombinieren, um damit zu arbeiten. Hier erfahren Sie, wie einfach es geht

Um eine solche Aufzeichnung durchzuführen, müssen Sie die Option in den box.cfg-Einstellungen (in der Datei example.lua) angeben:

wal_mode = “write”;

Datenverbrauch

Mit dem, was wir jetzt geschrieben haben, können Sie Tarantula zum Speichern von Daten verwenden und es wird sehr schnell als Datenbank funktionieren. Und das Tüpfelchen auf dem i ist nun, was Sie daraus machen können.

Eine Bewerbung schreiben

Schreiben wir zum Beispiel die folgende Anwendung für Tarantula

Siehe die Anwendung unter dem Spoiler

box.cfg {
    listen = '0.0.0.0:3301';
    io_collect_interval = nil;
    readahead = 16320;
    memtx_memory = 128 * 1024 * 1024; -- 128Mb
    memtx_min_tuple_size = 16;
    memtx_max_tuple_size = 128 * 1024 * 1024; -- 128Mb
    vinyl_memory = 128 * 1024 * 1024; -- 128Mb
    vinyl_cache = 128 * 1024 * 1024; -- 128Mb
    vinyl_max_tuple_size = 128 * 1024 * 1024; -- 128Mb
    vinyl_write_threads = 2;
    wal_mode = "write";
    wal_max_size = 256 * 1024 * 1024;
    checkpoint_interval = 60 * 60; -- one hour
    checkpoint_count = 6;
    force_recovery = true;
    log_level = 5;
    log_nonblock = false;
    too_long_threshold = 0.5;
    read_only   = false
}

local function bootstrap()
    local space = box.schema.create_space('example')
    space:create_index('primary')

    box.schema.user.create('example', { password = 'secret' })
    box.schema.user.grant('example', 'read,write,execute', 'space', 'example')

    box.schema.user.create('repl', { password = 'replication' })
    box.schema.user.grant('repl', 'replication')
end

-- for first run create a space and add set up grants
box.once('replica', bootstrap)

-- enabling console access
console = require('console')
console.listen('127.0.0.1:3302')

-- http config
local charset = {}  do -- [0-9a-zA-Z]
    for c = 48, 57  do table.insert(charset, string.char(c)) end
    for c = 65, 90  do table.insert(charset, string.char(c)) end
    for c = 97, 122 do table.insert(charset, string.char(c)) end
end

local function randomString(length)
    if not length or length <= 0 then return '' end
    math.randomseed(os.clock()^5)
    return randomString(length - 1) .. charset[math.random(1, #charset)]
end

local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')

local httpd = http_server.new('0.0.0.0', 8080, {
    log_requests = true,
    log_errors = true
})

local router = http_router.new()

local function get_count()
 local cnt = box.space.example:len()
 return cnt
end

router:route({method = 'GET', path = '/count'}, function()
    return {status = 200, body = json.encode({count = get_count()})}
end)

router:route({method = 'GET', path = '/token'}, function()
    local token = randomString(32)
    local last = box.space.example:len()
    box.space.example:insert{ last + 1, token }
    return {status = 200, body = json.encode({token = token})}
end)

prometheus = require('prometheus')

fiber = require('fiber')
tokens_count = prometheus.gauge("tarantool_tokens_count",
                              "API Tokens Count")

function monitor_tokens_count()
  while true do
    tokens_count:set(get_count())
    fiber.sleep(5)
  end
end
fiber.create(monitor_tokens_count)

router:route( { method = 'GET', path = '/metrics' }, prometheus.collect_http)

httpd:set_router(router)
httpd:start()

Wir deklarieren eine Tabelle in Lua, die die Zeichen definiert. Diese Platte wird benötigt, um eine Zufallszeichenfolge zu erzeugen.

local charset = {}  do -- [0-9a-zA-Z]
    for c = 48, 57  do table.insert(charset, string.char(c)) end
    for c = 65, 90  do table.insert(charset, string.char(c)) end
    for c = 97, 122 do table.insert(charset, string.char(c)) end
end

Danach deklarieren wir die Funktion - randomString und geben den Längenwert in Klammern an.

local function randomString(length)
    if not length or length <= 0 then return '' end
    math.randomseed(os.clock()^5)
    return randomString(length - 1) .. charset[math.random(1, #charset)]
end

Dann verbinden wir den http-Router und den http-Server mit unserem Tarantula-Server, JSON, den wir an den Client senden.

local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')

Danach starten wir auf Port 8080 auf allen HTTP-Serverschnittstellen, der alle Anfragen und Fehler protokolliert.

local httpd = http_server.new('0.0.0.0', 8080, {
    log_requests = true,
    log_errors = true
})

Als nächstes deklarieren wir die Route, sodass wir die Funktion von einer Zeile aus aufrufen, wenn eine Anfrage mit der GET-Methode auf Port 8080 /count eintrifft. Es gibt den Status zurück – 200, 404, 403 oder jeden anderen, den wir angeben.

router:route({method = 'GET', path = '/count'}, function()
    return {status = 200, body = json.encode({count = get_count()})}
end)

Im Hauptteil geben wir json.encode zurück, darin geben wir count und getcount an, das aufgerufen wird und die Anzahl der Datensätze in unserer Datenbank anzeigt.

Die zweite Methode

router:route({method = 'GET', path = '/token'}, function() 
    local token = randomString(32) 
    local last = box.space.example:len() 
    box.space.example:insert{ last + 1, token } 
    return {status = 200, body = json.encode({token = token})}
end)

Wo in der Zeile router:route({method = 'GET', path = '/token'}, function() Wir rufen die Funktion auf und generieren ein Token.

String lokales Token = randomString(32) ist eine zufällige Zeichenfolge mit 32 Zeichen.
In der Reihe local last = box.space.example:len() Wir nehmen das letzte Element heraus.
Und in der Schlange box.space.example:insert{ last + 1, token } Wir schreiben die Daten in unsere Datenbank, das heißt, wir erhöhen einfach die ID um 1. Das geht übrigens nicht nur auf diese umständliche Art und Weise. Dafür gibt es Sequenzen in Tarantula.

Dort schreiben wir den Token.

Daher haben wir den Antrag in einer Datei geschrieben. Dort können Sie die Daten direkt manipulieren und das Box-Modul erledigt die ganze Drecksarbeit für Sie.

Es hört auf http und arbeitet mit Daten, alles ist in einer einzigen Instanz – sowohl die Anwendung als auch die Daten. Daher geht alles recht schnell.

Zunächst installieren wir das http-Modul:

Wie wir das machen, sehen Sie unter dem Spoiler

root@test2:/# tarantoolctl rocks install http
Installing http://rocks.tarantool.org/http-scm-1.src.rock
Missing dependencies for http scm-1:
   checks >= 3.0.1 (not installed)

http scm-1 depends on checks >= 3.0.1 (not installed)
Installing http://rocks.tarantool.org/checks-3.0.1-1.rockspec

Cloning into 'checks'...
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 28 (delta 1), reused 16 (delta 1), pack-reused 0
Receiving objects: 100% (28/28), 12.69 KiB | 12.69 MiB/s, done.
Resolving deltas: 100% (1/1), done.
Note: checking out '580388773ef11085015b5a06fe52d61acf16b201'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

No existing manifest. Attempting to rebuild...
checks 3.0.1-1 is now installed in /.rocks (license: BSD)

-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found TARANTOOL: /usr/include (found version "2.4.2-80-g18f2bc82d")
-- Tarantool LUADIR is /.rocks/share/tarantool/rocks/http/scm-1/lua
-- Tarantool LIBDIR is /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    version


-- Build files have been written to: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Scanning dependencies of target httpd
[ 50%] Building C object http/CMakeFiles/httpd.dir/lib.c.o
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: In function ‘tpl_term’:
/usr/include/tarantool/lauxlib.h:144:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
    (*(B)->p++ = (char)(c)))
    ~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: note: in expansion of macro ‘luaL_addchar’
       luaL_addchar(b, '\');
       ^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: note: here
      default:
      ^~~~~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: In function ‘tpe_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
    type = TPE_TEXT;
    ~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: note: here
   case TPE_LINECODE:
   ^~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: In function ‘httpfast_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 code = 0;
                 ~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: note: here
             case status:
             ^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 state = message;
                 ~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: note: here
             case message:
             ^~~~
[100%] Linking C shared library lib.so
[100%] Built target httpd
[100%] Built target httpd
Install the project...
-- Install configuration: "Debug"
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 is now installed in /.rocks (license: BSD)

root@test2:/#

Wir brauchen auch Prometheus, um Folgendes auszuführen:

root@test2:/# tarantoolctl rocks install prometheus
Installing http://rocks.tarantool.org/prometheus-scm-1.rockspec

Cloning into 'prometheus'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 19 (delta 2), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (19/19), 10.73 KiB | 10.73 MiB/s, done.
Resolving deltas: 100% (2/2), done.
prometheus scm-1 is now installed in /.rocks (license: BSD)

root@test2:/#

Wir starten und können auf die Module zugreifen

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"e2tPq9l5Z3QZrewRf6uuoJUl3lJgSLOI"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"fR5aCA84gj9eZI3gJcV0LEDl9XZAG2Iu"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/count
HTTP/1.1 200 Ok
Content-length: 11
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"count":2}root@test2:/#

/count gibt uns den Status 200.
/token stellt ein Token aus und schreibt dieses Token in die Datenbank.

Geschwindigkeit testen

Lassen Sie uns einen Benchmark für 50 Anfragen durchführen. Es wird 000 konkurrierende Anfragen geben.

root@test2:/# ab -c 500 -n 50000 http://127.0.0.1:8080/token
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests


Server Software:        Tarantool
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /token
Document Length:        44 bytes

Concurrency Level:      500
Time taken for tests:   14.578 seconds
Complete requests:      50000
Failed requests:        0
Total transferred:      7950000 bytes
HTML transferred:       2200000 bytes
Requests per second:    3429.87 [#/sec] (mean)
Time per request:       145.778 [ms] (mean)
Time per request:       0.292 [ms] (mean, across all concurrent requests)
Transfer rate:          532.57 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   10 103.2      0    3048
Processing:    12   69 685.1     15   13538
Waiting:       12   69 685.1     15   13538
Total:         12   78 768.2     15   14573

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     15
  75%     16
  80%     16
  90%     16
  95%     16
  98%     21
  99%     42
 100%  14573 (longest request)
root@test2:/#

Es werden Token ausgegeben. Und wir erfassen ständig Daten. 99 % der Anfragen wurden in 42 Millisekunden verarbeitet. Dementsprechend haben wir auf einer kleinen Maschine mit 3500 Kernen und 2 Gigabyte Speicher etwa 4 Anfragen pro Sekunde.

Sie können auch etwa 50000 Token auswählen und deren Wert sehen.

Sie können nicht nur http verwenden, sondern auch Hintergrundfunktionen ausführen, die Ihre Daten verarbeiten. Außerdem gibt es verschiedene Auslöser. Sie können beispielsweise Funktionen bei Updates aufrufen, etwas überprüfen – Konflikte beheben.

Sie können Skriptanwendungen direkt im Datenbankserver selbst schreiben und sind durch nichts eingeschränkt, können beliebige Module verbinden und beliebige Logik implementieren.

Der Anwendungsserver kann auf externe Server zugreifen, Daten abrufen und zu seiner Datenbank hinzufügen. Daten aus dieser Datenbank werden von anderen Anwendungen verwendet.

Tarantula erledigt dies selbst und Sie müssen keinen separaten Antrag schreiben.

Abschließend

Dies ist nur der erste Teil eines großen Werks. Der zweite wird sehr bald im Blog der Mail.ru Group veröffentlicht und wir werden in diesem Material auf jeden Fall einen Link dazu hinzufügen.

Wenn Sie daran interessiert sind, an Veranstaltungen teilzunehmen, bei denen wir diese Dinge online entwickeln und in Echtzeit Fragen stellen, dann melden Sie sich an Kanal DevOps von REBRAIN.

Wenn Sie in die Cloud wechseln müssen oder Fragen zu Ihrer Infrastruktur haben, Hinterlassen Sie gerne eine Anfrage.

PS: Wir bieten 2 kostenlose Audits pro Monat an, vielleicht gehört auch Ihr Projekt dazu.

Source: habr.com

Kommentar hinzufügen