In Tarantool puoi combinare un database super veloce e un'applicazione per lavorare con loro. Ecco quanto è facile da fare

Cinque anni fa ho provato a lavorare con Tarantool, ma poi non ha funzionato per me. Ma recentemente ho tenuto un webinar in cui ho parlato di Hadoop e di come funziona MapReduce. Lì mi hanno posto la domanda: “Perché non utilizzare il Tarantool per questo compito?”

Per curiosità, ho deciso di tornarci, testare l'ultima versione e questa volta il progetto mi è piaciuto molto. Ora ti mostrerò come scrivere una semplice applicazione in Tarantool, caricarla e verificarne le prestazioni, e vedrai quanto è facile e interessante tutto.

In Tarantool puoi combinare un database super veloce e un'applicazione per lavorare con loro. Ecco quanto è facile da fare

Cos'è il tarantolo

Tarantool si posiziona come un database ultraveloce. Puoi inserire tutti i dati che desideri lì. Inoltre, replicali, shard, ovvero dividi un'enorme quantità di dati su più server e combina i risultati da essi, crea connessioni master-master tolleranti agli errori.

In secondo luogo, questo è un server delle applicazioni. Puoi scrivere le tue applicazioni su di esso, lavorare con i dati, ad esempio, eliminare vecchi record in background secondo determinate regole. Puoi scrivere un server HTTP direttamente in Tarantula che funzionerà con i dati: distribuisci la loro quantità, scrivi lì nuovi dati e riduci tutto al master.

Ho letto un articolo su come i ragazzi hanno creato una coda di messaggi di 300 righe, che è semplicemente esplosiva e frenetica: hanno una prestazione minima di 20 messaggi al secondo. Qui puoi davvero girarti e scrivere un'applicazione molto grande, e non sarà archiviata, come in PostgreS.

Proverò a descrivere qualcosa di simile a questo server, solo semplice, in questo articolo.

Installazione

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

Installiamo Tarantool: esegui lo script bash o aggiungi un repository ed esegui apt get install Tarantool. Collegamento allo script - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Abbiamo comandi come:

tarantoolctl — il comando principale per la gestione delle istanze di Tarantula.
/etc/tarantool - ecco l'intera configurazione.
var/log/tarantool - ecco i registri.
var/lib/tarantool - i dati si trovano qui e poi sono divisi in istanze.

Sono presenti le cartelle istanza-disponibile e istanza-abilita - contiene ciò che verrà avviato - un file di configurazione dell'istanza con codice lua, che descrive su quali porte è in ascolto, quale memoria è disponibile, impostazioni del motore Vinyl, codice che viene eseguito all'avvio server, sharding, code, cancellazione di dati obsoleti e così via.

Le istanze funzionano come in PostgreS. Ad esempio, desideri eseguire diverse copie di un database bloccato su porte diverse. Si scopre che su un server vengono avviate diverse istanze del database, che si bloccano su porte diverse. Potrebbero avere impostazioni completamente diverse: un'istanza implementa una logica, la seconda un'altra.

Gestione delle istanze

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

Puoi vedere lo stato dell'istanza: esempio di stato tarantoolctl. Allo stesso modo puoi fare start, stop, restart.

Una volta che l'istanza è in esecuzione, puoi connetterti ad essa in due modi.

1. Console amministrativa

Per impostazione predefinita, Tarantool apre un socket, dove viene inviato il normale testo ASCII per controllare Tarantool. La connessione alla console avviene sempre sotto l'utente amministratore, non è prevista autenticazione, quindi non è necessario spostare la porta della console all'esterno per gestire Tarantula.

Per connettersi utilizzando questo metodo, è necessario inserire Tarantoolctl e inserire il nome dell'istanza. Il comando avvierà la console e si connetterà come utente amministratore. Non esporre mai la porta della console all'esterno: è meglio lasciarla come presa dell'unità. Quindi solo chi ha accesso in scrittura al socket potrà connettersi a Tarantula.

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

2. Utilizzo di un protocollo binario per connettersi a una porta specifica

La configurazione contiene una direttiva di ascolto, che apre una porta per le comunicazioni esterne. Questa porta viene utilizzata con il protocollo binario e lì viene abilitata l'autenticazione.

Per questa connessione viene utilizzato tarantoolctl connect to port number. Usandolo, puoi connetterti a server remoti, utilizzare l'autenticazione e concedere vari diritti di accesso.

Modulo di registrazione e box dati

Poiché Tarantool è sia un database che un server applicativo, dispone di vari moduli. Siamo interessati al modulo box: implementa il lavoro con i dati. Quando scrivi qualcosa su box, Tarantool scrive i dati su disco, li archivia in memoria o fa qualcos'altro con essi.

Record

Ad esempio, entriamo nel modulo box e chiamiamo la funzione box.once. Ciò obbligherà Tarantool a eseguire il nostro codice quando il server verrà inizializzato. Creiamo uno spazio in cui verranno 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')

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

Successivamente, creiamo un indice primario - primario - tramite il quale possiamo cercare i dati. Per impostazione predefinita, se non si specifica alcun parametro, per l'indice primario verrà utilizzato il primo campo di ciascun record.

Quindi concediamo una concessione all'utente ospite, in base alla quale ci colleghiamo tramite il protocollo binario. Permettiamo la lettura, la scrittura e l'esecuzione nell'intera istanza.

Rispetto ai database convenzionali, qui tutto è abbastanza semplice. Abbiamo spazio, un'area in cui i nostri dati vengono semplicemente archiviati. Ogni record è chiamato tupla. È confezionato in MessagePack. Questo è un formato molto interessante: è binario e occupa meno spazio: 18 byte contro 27.

In Tarantool puoi combinare un database super veloce e un'applicazione per lavorare con loro. Ecco quanto è facile da fare

È abbastanza conveniente lavorare con lui. Quasi ogni riga, ogni record di dati può avere colonne completamente diverse.

Possiamo visualizzare tutti gli spazi utilizzando il comando Box.space. Per selezionare un'istanza specifica, scrivi box.space example e ottieni informazioni complete al riguardo.

Tarantool ha due motori integrati: Memory e Vinyl. La memoria memorizza tutti i dati in memoria. Pertanto, tutto funziona in modo semplice e veloce. I dati vengono scaricati su disco ed è presente anche un meccanismo di registro di scrittura anticipata, quindi non perderemo nulla in caso di arresto anomalo del server.

Vinyl memorizza i dati su disco in una forma a noi più familiare, ovvero puoi memorizzare più dati di quanta ne abbiamo nella memoria e Tarantula li leggerà dal disco.

Per ora useremo 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>

Indice:

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

Parti:

Qui indichiamo in cosa consiste il nostro indice. Consiste di una parte - il primo campo che useremo è di tipo unsigned - un intero positivo. Per quanto ricordo dalla documentazione, il numero massimo che può essere è di 18 quintilioni. Questo è molto.

Quindi 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 viene utilizzato come chiave primaria, quindi deve essere univoco. Non siamo limitati dal numero di colonne, quindi possiamo inserire tutti i dati che vogliamo. Sono specificati nel formato MessagePack, che ho descritto sopra.

Uscita dati

Quindi possiamo visualizzare i dati utilizzando il comando select.

Box.example.select con il tasto {1} visualizzerà la voce desiderata. Se abbassiamo la chiave, vedremo tutti i record che abbiamo. Differiscono tutti nel numero di colonne, ma qui, in linea di principio, non esiste il concetto di colonne: ci sono numeri di campo.

Può esserci assolutamente qualsiasi quantità di dati. E ad esempio, dobbiamo cercarli nel secondo campo. Per fare ciò, creiamo un nuovo indice secondario.


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

Usiamo il comando Create_index.
Chiamiamolo secondario.

Successivamente è necessario specificare i parametri. Il tipo di indice è TREE. Potrebbe non essere univoco, quindi inserisci Unique = false.

Quindi indichiamo in quali parti è composto il nostro indice. Campo è il numero del campo a cui leghiamo l'indice e specifichiamo il tipo di stringa. E così è 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>

Ecco come possiamo chiamarlo:

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

conservazione

Se riavviamo l'istanza e proviamo a richiamare nuovamente i dati, vedremo che non ci sono: è tutto vuoto. Ciò accade perché Tarantool crea checkpoint e salva i dati su disco, ma se smettiamo di lavorare fino al salvataggio successivo, perderemo tutte le operazioni, perché recupereremo dall'ultimo checkpoint, ad esempio due ore fa.

Non funzionerà nemmeno salvare ogni secondo, perché scaricare costantemente 20 GB su disco non è una buona idea.

A questo scopo è stato inventato e implementato il concetto di log write-ahead. Con il suo aiuto, per ogni modifica dei dati, viene creata una voce in un piccolo file di registro write-ahead.

Ogni voce fino al checkpoint viene memorizzata in essi. Per questi file impostiamo la dimensione, ad esempio 64 MB. Quando è pieno, la registrazione inizia a passare al secondo file. E dopo il riavvio, Tarantool viene ripristinato dall'ultimo checkpoint e quindi ripristina tutte le transazioni successive fino all'arresto.

In Tarantool puoi combinare un database super veloce e un'applicazione per lavorare con loro. Ecco quanto è facile da fare

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

wal_mode = “write”;

utilizzo dei dati

Con quello che abbiamo scritto ora, puoi usare Tarantula per archiviare dati e funzionerà molto velocemente come database. E ora la ciliegina sulla torta è cosa puoi fare con tutto questo.

Scrivere un'applicazione

Ad esempio, scriviamo la seguente applicazione per Tarantula

Guarda l'applicazione sotto lo 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()

Dichiariamo una tabella in lua che definisce i caratteri. Questa piastra è 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

Successivamente, dichiariamo la funzione - randomString e forniamo il valore della lunghezza tra parentesi.

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

Quindi colleghiamo il router http e il server http al nostro server Tarantula, JSON, che invieremo al client.

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

Successivamente, iniziamo dalla porta 8080 su tutte le interfacce del server http, 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 route, in modo che se una richiesta con il metodo GET arriva sulla porta 8080 /count, chiamiamo la funzione da una riga. Restituisce lo stato: 200, 404, 403 o qualsiasi altro specificato.

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

Nel corpo restituiamo json.encode, in esso indichiamo count e getcount, che si chiama e mostra il numero di record nel nostro database.

Il 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 fila router:route({metodo = 'GET', percorso = '/token'}, funzione() chiamiamo la funzione e generiamo un token.

fila token locale = randomString(32) è una stringa casuale di 32 caratteri.
In linea local last = box.space.example:len() eliminiamo l'ultimo elemento.
E in linea box.space.example:inserisci{ ultimo + 1, token } scriviamo i dati nel nostro database, ovvero aumentiamo semplicemente l'ID di 1. Questo, tra l'altro, può essere fatto non solo in questo modo goffo. Ci sono sequenze per questo in Tarantula.

Scriviamo il token lì.

Pertanto, abbiamo scritto l'applicazione in un file. Puoi manipolare direttamente i dati lì e il modulo box farà tutto il lavoro sporco per te.

Ascolta http e funziona con i dati, tutto è in un'unica istanza, sia l'applicazione che i dati. Pertanto, tutto avviene abbastanza rapidamente.

Per iniziare installiamo il modulo http:

Come lo facciamo, guarda sotto lo 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:/#

Abbiamo anche bisogno di Prometeo per eseguire:

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:/#

Lanciamo 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 ci dà lo stato 200.
/token emette un token e scrive questo token nel database.

Velocità di prova

Eseguiamo un benchmark per 50 richieste. Ci saranno 000 richieste in competizione.

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:/#

Vengono emessi token. E registriamo costantemente dati. Il 99% delle richieste sono state elaborate in 42 millisecondi. Di conseguenza, su una piccola macchina con 3500 core e 2 gigabyte di memoria abbiamo circa 4 richieste al secondo.

Puoi anche selezionare circa 50000 token e vederne il valore.

Puoi utilizzare non solo http, ma anche eseguire funzioni in background che elaborano i tuoi dati. Inoltre ci sono vari trigger. Ad esempio, puoi chiamare funzioni sugli aggiornamenti, controllare qualcosa: correggere i conflitti.

Puoi scrivere applicazioni script direttamente nel server database stesso e non essere limitato da nulla, connettere qualsiasi modulo e implementare qualsiasi logica.

Il server delle applicazioni può accedere a server esterni, recuperare dati e aggiungerli al proprio database. I dati di questo database verranno utilizzati da altre applicazioni.

Tarantula lo farà da sola e non dovrai scrivere un'applicazione separata.

insomma

Questa è solo la prima parte di un grande lavoro. Il secondo sarà pubblicato molto presto sul blog del gruppo Mail.ru e aggiungeremo sicuramente un collegamento ad esso in questo materiale.

Se sei interessato a partecipare a eventi in cui creiamo queste cose online e poniamo domande in tempo reale, sintonizzati canale DevOps di REBRAIN.

Se devi passare al cloud o hai domande sulla tua infrastruttura, sentitevi liberi di lasciare una richiesta.

PS Abbiamo 2 audit gratuiti al mese, forse il tuo progetto sarà uno di questi.

Fonte: habr.com

Aggiungi un commento