In Tarantool puoi unire un database super veloce e un'applicazione per gestirli. Ecco quanto è semplice farlo.

Cinque anni fa ho provato a lavorare con Tarantool, ma non mi è piaciuto. Recentemente, ho tenuto un webinar in cui parlavo di Hadoop e di come funziona MapReduce. Durante l'incontro, qualcuno mi ha chiesto: «Perché non usare Tarantool per questa esigenza?».

Per curiosità ho deciso di tornare indietro, testare l'ultima versione, e questa volta il progetto mi è piaciuto molto. Ora vi mostrerò come scrivere una semplice applicazione in Tarantool, la caricherò e verificherò le prestazioni, e vedrete quanto sia facile e interessante.

In Tarantool puoi unire un database super veloce e un'applicazione per gestirli. Ecco quanto è semplice farlo.

Cos'è Tarantool

Tarantool si posiziona come un database super veloce. Puoi inserire qualsiasi dato tu voglia. Inoltre, puoi replicarli, shardizzarli, cioè distribuire una grande quantità di dati su più server e unire i risultati — creando configurazioni ad alta disponibilità di tipo «master-master».

In secondo luogo, c'è il server application. Puoi scrivere le tue applicazioni su di esso, lavorare con i dati, ad esempio, eliminare in background le vecchie registrazioni secondo determinate regole. È possibile scrivere direttamente in Tarantool un server Http che lavorerà con i dati: restituire il loro numero, registrare nuovi dati e ridurre tutto questo sul master.

Ho letto un articolo su come un team ha creato una coda di messaggi di 300 righe che si muove a grande velocità — hanno una performance minima di 20.000 messaggi al secondo. Qui puoi veramente sviluppare e scrivere un'applicazione molto grande, e queste non saranno solo memorizzazioni, come in PostgreS.

Cercherò di descrivere un server di questo tipo, solo che semplice, in questo articolo.

Installazione

Per il test, ho attivato tre macchine virtuali standard – un disco rigido da 20 gigabyte, Ubuntu 18.04, 2 CPU virtuali e 4 GB di memoria.

Installiamo Tarantool — eseguendo uno script bash oppure aggiungendo il repository e facendo apt get install Tarantool. Il link allo script è — (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Qui abbiamo comandi come:

tarantoolctl — il comando principale per gestire le istanze di Tarantool.
/etc/tarantool — qui si trova tutta la configurazione.
var/log/tarantool — qui ci sono i log.
var/lib/tarantool — qui sono memorizzati i dati, e poi sono suddivisi per istanze.

Ci sono le cartelle instance-available e instance-enable — in quest'ultima si trova ciò che verrà avviato — il file di configurazione dell'istanza con codice lua, dove sono descritti quali porte ascolta, quanta memoria ha a disposizione, le impostazioni del motore Vinyl, il codice che si attiva all'avvio del server, il partizionamento, le code, l'eliminazione dei dati obsoleti e così via.

Le istanze funzionano come in PostgreS. Ad esempio, si desidera avviare più copie di un database, che sono su porte diverse. Così, su un server ci sono più istanze di database che girano su porte diverse. Possono avere impostazioni completamente diverse — un'istanza implementa una logica, l'altra un'altra.

Gestione delle istanze

Abbiamo il comando tarantoolctl, che consente di gestire le istanze di Tarantool. Ad esempio, tarantoolctl check example controllerà il file di configurazione e dirà — il file è ok, se non ci sono errori di sintassi.

È possibile controllare lo stato dell'istanza — tarantoolctl status example. Allo stesso modo si possono utilizzare start, stop, restart.

Quando l'istanza è avviata, è possibile connettersi in due modi.

1. Console di amministrazione

Per impostazione predefinita, Tarantool apre un socket, dove viene trasmesso un testo ASCII normale per gestire Tarantool. La connessione alla console avviene sempre come utente admin, non ci sono autenticazioni, quindi non è necessario esporre il porto della console per la gestione di Tarantool all'esterno.

Per connettersi in questo modo, è necessario digitare Tarantoolctl enter nome dell'istanza. Il comando avvierà la console e si connetterà come utente admin. Non esponete mai il porto della console all'esterno; è meglio lasciarlo come socket unit. In questo modo, la possibilità di connettersi a Tarantool sarà riservata solo a coloro che hanno accesso in scrittura al socket.

Questo metodo è necessario per operazioni amministrative. Per lavorare con i dati, utilizzare il secondo metodo: il protocollo binario.

2. Utilizzo del protocollo binario per connettersi a una porta specifica

Nella configurazione c'è la direttiva listen, che apre una porta per comunicazioni esterne. Questa porta è utilizzata con il protocollo binario e l'autenticazione è attivata.

Per questa connessione si utilizza tarantoolctl connect to port number. Utilizzandolo, è possibile connettersi a server remoti, usare l'autenticazione e concedere diversi diritti di accesso.

Scrittura dei dati e modulo Box

Poiché Tarantool è sia un database che un server applicativo, dispone di vari moduli. Siamo interessati al modulo box: esso gestisce le operazioni con i dati. Quando scrivi qualcosa in box, Tarantool scrive i dati su disco, li memorizza in memoria o ne fa qualcos'altro.

Scrittura

Ad esempio, accediamo al modulo box e chiamiamo la funzione box.once. Questa farà sì che Tarantool esegua il nostro codice al momento dell'inizializzazione del server. Creiamo uno spazio in cui saranno archiviati i nostri dati.

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

    -- Mantieni le cose sicure per impostazione predefinita
    --  box.schema.user.create('example', { password = 'secret' })
    --  box.schema.user.grant('example', 'replication')
    --  box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end

Dopo di ciò, creiamo un indice primario – primary – per il quale sarà possibile cercare i dati. Di default, se non vengono specificati parametri, sarà utilizzato il primo campo di ogni record per l'indice primario.

Poi facciamo un grant all'utente guest, con cui ci connettiamo tramite il protocollo binario. Consentiamo la lettura, la scrittura e l'esecuzione in tutto l'istanza.

Se paragonato ai database tradizionali, qui tutto è piuttosto semplice. Abbiamo space – un'area dove i nostri dati vengono semplicemente memorizzati. Ogni record è chiamato tupla. Viene impacchettata in MessagePack. È un formato davvero interessante: è binario e occupa meno spazio – 18 byte contro 27.

In Tarantool puoi unire un database super veloce e un'applicazione per gestirli. Ecco quanto è semplice farlo.

È abbastanza comodo lavorarci. Quasi ogni riga, ogni record di dati può avere colonne completamente diverse.

Possiamo visualizzare tutti gli space con il comando Box.space. Per evidenziare un'istanza specifica, scriviamo box.space example e otteniamo tutte le informazioni su di essa.

Tarantool ha due tipi di motori integrati: Memory e Vinyl. Memory memorizza tutti i dati in memoria. Quindi tutto funziona in modo semplice e veloce. I dati vengono svuotati su disco e c'è anche un meccanismo di write ahead log, quindi non perderemo nulla in caso di crash del server.

Vinyl memorizza i dati su disco in un formato più familiare — il che significa che possiamo conservare più dati di quanti ne abbia la nostra memoria, e Tarantool li leggerà dal disco.

Adesso utilizzeremo la memoria.

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>

Indice:

È necessario creare un indice primario per ogni spazio, perché senza di esso nulla funzionerà. Come in qualsiasi database, creiamo il primo campo – l'ID del record.

Parti:

Qui specifichiamo di cosa è composto il nostro indice. È composto da una sola parte – il primo campo che utilizzeremo, di tipo unsigned – numero intero positivo. Da quanto ricordo dalla documentazione, il numero massimo può arrivare a 18 quintilioni. Davvero tantissimo.

Dopo possiamo inserire i dati utilizzando il comando insert.

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>

Il primo campo è usato come chiave primaria, quindi deve essere unico. Non ci sono limiti sul numero di colonne, quindi possiamo inserire quanti più dati possibile. Vengono specificati in formato MessagePack, che ho descritto in precedenza.

Uscita dei dati

Successivamente, possiamo visualizzare i dati con il comando select.

Box.example.select specificando la chiave {1} mostrerà il record desiderato. Se non specifichiamo la chiave, vedremo tutti i record disponibili. Essi variano per numero di colonne, ma qui in realtà il concetto di colonne non esiste: ci sono solo numeri di campo.

Possiamo avere un numero illimitato di dati. E ad esempio, se dobbiamo cercarli in base al secondo campo, creiamo un nuovo indice secondario.


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

Utilizziamo il comando Create_index.
Lo chiamiamo Secondario.

Dopo di che, è necessario specificare i parametri. Il tipo di indice è TREE. Può non essere unico, quindi impostiamo Unique = false.

Poi specifichiamo da quali parti è composto il nostro indice. Field è il numero del campo a cui colleghiamo l'indice, e indichiamo il tipo string. Ed ecco che è stato creato.

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>

Ora possiamo chiamarlo in questo modo:

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

Salvataggio

Se riavviamo l'istanza e proviamo di nuovo a richiamare i dati, vedremo che non ci sono — è tutto vuoto. Ciò accade perché Tarantool crea checkpoint e salva i dati su disco, ma se fermiamo il lavoro prima del salvataggio più vicino, perderemo tutte le operazioni — perché ci ripristineremo all'ultimo checkpoint, che era, ad esempio, due ore fa.

Non è fattibile nemmeno salvare ogni secondo — perché dumpare continuamente 20 GB su disco non è una buona idea.

A questo scopo è stata ideata e implementata la concezione del write-ahead log. Grazie a essa, per ogni modifica ai dati viene creata una registrazione in un piccolo file write-ahead log.

Ogni registrazione fino al checkpoint viene salvata in questi file. Per questi file impostiamo una dimensione — ad esempio, 64 MB. Quando si riempie, la registrazione inizia a finire nel secondo file. E dopo il riavvio, Tarantool si ripristina dall'ultimo checkpoint e poi applica tutte le transazioni più recenti fino al momento di arresto.

In Tarantool puoi unire un database super veloce e un'applicazione per gestirli. Ecco quanto è semplice farlo.

Per effettuare tale registrazione, è necessario specificare un'opzione nelle impostazioni di box.cfg (nel file example.lua):

wal_mode = "write";

Utilizzo dei dati

Con quanto abbiamo scritto finora, potete utilizzare Tarantool per memorizzare dati, e questo funzionerà molto rapidamente come database. E ora la vera ciliegina sulla torta – cosa si può fare con tutto questo.

Scriviamo un'applicazione

Ad esempio, scriviamo un'applicazione per Tarantool

L'applicazione la trovate sotto il 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; -- un'ora
    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

-- per la prima esecuzione crea uno spazio e imposta i permessi
box.once('replica', bootstrap)

-- abilitando l'accesso alla console
console = require('console')
console.listen('127.0.0.1:3302')

-- configurazione http
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",
                              "Conteggio dei Token API")

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()

Dichiaramo una tabella in lua che definisce i caratteri. Questa tabella è necessaria per generare una stringa casuale.

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

Dopo di che dichiariamo la funzione – randomString e le daremo come argomento il valore della lunghezza.

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

Poi colleghiamo il router http e il server http al nostro server Tarantool, JSON, che restituiremo al client.

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

Successivamente, avviamo il server http sulla porta 8080 su tutte le interfacce, che registrerà tutte le richieste e gli errori.

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

Successivamente dichiariamo una route, in modo che se sulla porta 8080 /count viene ricevuta una richiesta con il metodo GET, invochiamo una funzione in una linea. Essa restituisce uno stato — 200, 404, 403 o qualsiasi altro stato che specifichiamo.

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

Nel corpo restituiamo json.encode, in cui specifichiamo count e getcount, che viene chiamato e mostra il numero di record nel nostro database.

Secondo metodo

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)

Dove nella stringa router:route({method = ‘GET’, path = ‘/token’}, function() chiamiamo la funzione e generiamo il token.

Stringa local token = randomString(32) – è una stringa casuale di 32 caratteri.
Nella riga local last = box.space.example:len() estraiamo l'ultimo elemento.
E nella stringa box.space.example:insert{ last + 1, token } registriamo i dati nel nostro database, quindi aumentiamo semplicemente l'ID di 1. Questo, tra l'altro, si può fare non solo in questo modo sgraziato. In Tarantool ci sono sequenze per questo.

Registriamo lì il token.

In questo modo, abbiamo scritto l'applicazione in un unico file. È possibile accedere immediatamente ai dati, e il modulo box farà tutto il lavoro sporco per voi.

Ascolta http e lavora con i dati, tutto si trova in un'unica istanza — sia l'applicazione che i dati. Pertanto, tutto avviene abbastanza rapidamente.

Per avviare installiamo il modulo http:

Come lo facciamo, guarda sotto spoiler

root@test2:/# tarantoolctl rocks install http
Installazione di http://rocks.tarantool.org/http-scm-1.src.rock
Dipendenze mancanti per http scm-1:
   checks >= 3.0.1 (non installato)

http scm-1 dipende da checks >= 3.0.1 (non installato)
Installazione di http://rocks.tarantool.org/checks-3.0.1-1.rockspec

Clonazione in 'checks'...
remote: Enumerazione degli oggetti: 28, completato.
remote: Conteggio oggetti: 100% (28/28), completato.
remote: Compressione oggetti: 100% (19/19), completato.
remote: Totale 28 (delta 1), riutilizzati 16 (delta 1), pack-reused 0
Ricezione oggetti: 100% (28/28), 12.69 KiB | 12.69 MiB/s, completato.
Risoluzione dei delta: 100% (1/1), completato.
Nota: controllo di '580388773ef11085015b5a06fe52d61acf16b201'.

Sei in stato 'HEAD staccato'. Puoi guardarti intorno, apportare cambiamenti sperimentali
e impegnarli, e puoi scartare qualsiasi impegno fatto in questo
stato senza impattare su eventuali rami eseguendo un altro checkout.

Se desideri creare un nuovo ramo per mantenere gli impegni creati, puoi
dirlo (ora o più tardi) usando -b con il comando di checkout di nuovo. Esempio:

  git checkout -b 

Nessun manifesto esistente. Tentativo di ricostruire...
checks 3.0.1-1 è ora installato in /.rocks (licenza: BSD)

-- L'identificazione del compilatore C è GNU 7.5.0
-- Verifica di un compilatore C funzionante: /usr/bin/cc
-- Verifica di un compilatore C funzionante: /usr/bin/cc -- funziona
-- Rilevamento delle informazioni ABI del compilatore C
-- Rilevamento delle informazioni ABI del compilatore C - completato
-- Rilevamento delle caratteristiche di compilazione C
-- Rilevamento delle caratteristiche di compilazione C - completato
-- TARANTOOL trovato: /usr/include (versione trovata "2.4.2-80-g18f2bc82d")
-- La LUADIR di Tarantool è /.rocks/share/tarantool/rocks/http/scm-1/lua
-- La LIBDIR di Tarantool è /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configurazione completata
-- Generazione completata
Avviso di CMake:
  Le variabili specificate manualmente non sono state utilizzate dal progetto:

    version


-- I file di build sono stati scritti in: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Scansione delle dipendenze dell'obiettivo httpd
[ 50%] Compilazione dell'oggetto C http/CMakeFiles/httpd.dir/lib.c.o
Nel file incluso da /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: Nella funzione 'tpl_term':
/usr/include/tarantool/lauxlib.h:144:15: avviso: questa affermazione potrebbe cadere attraverso [-Wimplicit-fallthrough=]
    (*(B)->p++ = (char)(c)))
    ~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: nota: nell'espansione della macro 'luaL_addchar'
       luaL_addchar(b, '\');
       ^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: nota: qui
      default:
      ^~~~~~~
Nel file incluso da /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: Nella funzione 'tpe_parse':
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: avviso: questa affermazione potrebbe cadere attraverso [-Wimplicit-fallthrough=]
    type = TPE_TEXT;
    ~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: nota: qui
   case TPE_LINECODE:
   ^~~~
Nel file incluso da /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: Nella funzione 'httpfast_parse':
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: avviso: questa affermazione potrebbe cadere attraverso [-Wimplicit-fallthrough=]
                 code = 0;
                 ~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: nota: qui
             case status:
             ^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: avviso: questa affermazione potrebbe cadere attraverso [-Wimplicit-fallthrough=]
                 state = message;
                 ~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: nota: qui
             case message:
             ^~~~
[100%] Collegamento della libreria condivisa C lib.so
[100%] Obiettivo httpd costruito
[100%] Obiettivo httpd costruito
Installa il progetto...
-- Configurazione di installazione: "Debug"
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installazione: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 è ora installato in /.rocks (licenza: BSD)

root@test2:/#

Per avviare, ci servirà anche prometheus:

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

Clonazione in corso di '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
Ricezione oggetti: 100% (19/19), 10.73 KiB | 10.73 MiB/s, done.
Risoluzione dei deltas: 100% (2/2), done.
prometheus scm-1 è ora installato in /.rocks (license: BSD)

root@test2:/#

Avviamo e possiamo accedere ai moduli

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 отдает нам статус 200.
/token выдает токен и делает запись этого токена в базу.

Testiamo la velocità

Avviamo un benchmark con 50.000 richieste. Ci saranno 500 richieste concorrenti.

root@test2:/# ab -c 500 -n 50000 http://127.0.0.1:8080/token
Questa è ApacheBench, Version 2.3 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licenza a The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (abbi pazienza)
Completati 5000 richieste
Completati 10000 richieste
Completati 15000 richieste
Completati 20000 richieste
Completati 25000 richieste
Completati 30000 richieste
Completati 35000 richieste
Completati 40000 richieste
Completati 45000 richieste
Completati 50000 richieste
Finito 50000 richieste


Software del server:        Tarantool
Nome host del server:        127.0.0.1
Porta del server:            8080

Percorso documento:          /token
Lunghezza documento:        44 byte

Livello di concorrenza:      500
Tempo impiegato per i test:   14.578 secondi
Richieste complete:      50000
Richieste non riuscite:        0
Totale trasferito:      7950000 byte
HTML trasferito:       2200000 byte
Richieste al secondo:    3429.87 [#/sec] (media)
Tempo per richiesta:       145.778 [ms] (media)
Tempo per richiesta:       0.292 [ms] (media, su tutte le richieste concorrenti)
Tasso di trasferimento:          532.57 [Kbytes/sec] ricevuti

Tempi di connessione (ms)
              min  media[+/-sd] mediana   max
Collegamento:        0   10 103.2      0    3048
Elaborazione:    12   69 685.1     15   13538
Attesa:       12   69 685.1     15   13538
Totale:         12   78 768.2     15   14573

Percentuale delle richieste servite entro un certo tempo (ms)
  50%     15
  66%     15
  75%     16
  80%     16
  90%     16
  95%     16
  98%     21
  99%     42
 100%  14573 (richiesta più lunga)
root@test2:/#

I token vengono emessi. E stiamo continuamente registrando i dati. Il 99% delle richieste è stata elaborata in 42 millisecondi. Di conseguenza, abbiamo circa 3500 richieste al secondo su una piccola macchina, con 2 core e 4 gigabyte di memoria.

È inoltre possibile selezionare qualche token da 50000 e vedere il suo valore.

Puoi utilizzare non solo http, ma anche avviare funzionalità in background che elaborano i tuoi dati. Inoltre, ci sono diversi trigger. Ad esempio, puoi richiamare funzioni sugli aggiornamenti, controllare qualcosa e risolvere i conflitti.

Puoi scrivere script direttamente sul server del database, senza alcuna limitazione, collegando moduli e implementando qualsiasi logica.

Il server delle applicazioni può accedere a server esterni, prelevare dati e memorizzarli nel proprio database. Questi dati saranno utilizzati da altre applicazioni.

Questo sarà gestito da Tarantool, quindi non dovrai scrivere un'applicazione separata.

In conclusione

Questa è solo la prima parte di un grande lavoro. La seconda sarà pubblicata molto presto nel blog di Mail.ru Group, e aggiungeremo sicuramente un link a questa nella materia.

Se sei interessato a partecipare a eventi dove creiamo queste cose online e porre domande in tempo reale, collegati a canale DevOps by REBRAIN.

Se hai bisogno di migrare al cloud o hai domande sulla tua infrastruttura, non esitate a lasciare una richiesta.

P.S. Abbiamo 2 audit gratuiti al mese, e magari il tuo progetto sarà tra questi.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster