Acum cinci ani am încercat să lucrez cu Tarantool, dar nu m-a convins pe atunci. Recent, am susținut un webinar unde am vorbit despre Hadoop și despre cum funcționează MapReduce. Acolo mi s-a pus întrebarea - „De ce nu folosiți Tarantool pentru această sarcină?”.
Din curiozitate, am decis să mă întorc la el, să testez ultima versiune - și de data aceasta proiectul mi-a plăcut foarte mult. Acum vă voi arăta cum să scrieți o aplicație simplă în Tarantool, să o încarc și să verific performanța, și veți vedea cât de simplu și grozav este totul.

Ce este Tarantool
Tarantool se poziționează ca o bază de date extrem de rapidă. Puteți introduce orice fel de date doriți. În plus, le puteți replica, shardui - adică să împărțiți o cantitate uriașă de date pe mai multe servere și să combinați rezultatele de pe acestea - să creați combinații reziliente tip „master-master”.
În al doilea rând, este un server de aplicații. Puteți scrie aplicațiile dvs. pe el, lucra cu datele, de exemplu, să ștergeți în fundal înregistrările vechi conform unor reguli specifice. Puteți scrie direct în Tarantool un server Http care va lucra cu datele: va returna numărul acestora, va înregistra date noi și va reduce totul pe master.
Am citit un articol despre cum au realizat un sistem de mesagerie pe 300 de linii, care pur și simplu răstoarnă tot - au o performanță minimă de 20.000 de mesaje pe secundă. Aici se poate chiar dezvolta și scrie o aplicație foarte mare, care nu va fi ca în stocările din PostgreS.
Un server aproximativ de acest fel, doar simplificat, voi încerca să descriu în acest articol.
Instalare
Pentru test, am creat trei mașini virtuale standard - hard disk de 20 de gigaocteți, Ubuntu 18.04. 2 CPU virtuali și 4 giga de memorie.
Instalăm Tarantool - lansăm un script bash sau adăugăm depozitul și facem apt get install Tarantool. Linkul pentru script - (curl -L | VER=2.4 sudo -E bash). Ne apar comenzi precum:
tarantoolctl — comanda principală pentru gestionarea instanțelor de Tarantool.
/etc/tarantool — aici se află toată configurația.
var/log/tarantool — aici se află jurnalul.
var/lib/tarantool — aici se află datele, și mai departe sunt împărțite pe instanțe.
Există foldere instance-available și instance-enable — în acestea se află ceea ce va fi pornit — fișierul de configurare a instanței cu cod lua, care descrie pe ce porturi ascultă, ce memorie are disponibilă, setările motorului Vinyl, codul care se execută la pornirea serverului, shard-urile, coadă, eliminarea datelor vechi și așa mai departe.
Instanțele funcționează ca în PostgreS. De exemplu, doriți să porniți mai multe copiilor ale unei baze de date, care rulează pe porturi diferite. Astfel, pe un singur server sunt pornite mai multe instanțe de baze de date, care rulează pe porturi diferite. Acestea pot avea setări complet diferite — o instanță implementează o logică, iar cealaltă — alta.
Gestionarea instanțelor
Avem comanda tarantoolctl, care permite gestionarea instanțelor Tarantool. De exemplu, tarantoolctl check example va verifica fișierul de configurare și va spune — fișierul este ok, dacă nu există erori de sintaxă.
Se poate verifica starea instanței — tarantoolctl status example. În același mod se pot face start, stop, restart.
Când instanța este pornită, vă puteți conecta în două moduri.
1. Consola administrativă
În mod implicit, Tarantool deschide un socket, unde se transmite text ASCII obișnuit pentru gestionarea Tarantool-ului. Conexiunea la consolă se face întotdeauna sub utilizatorul admin, nu există autentificare, așa că nu trebuie să expuneți portul consolei pentru a gestiona Tarantool-ul.
Pentru a vă conecta prin acest mod, trebuie să introduceți Tarantoolctl enter instance name. Comanda va porni consola și se va conecta sub utilizatorul admin. Nu expuneți niciodată portul consolei în exterior — este mai bine să-l lăsați unit-socket. Atunci, posibilitatea de a se conecta la Tarantool va fi doar pentru cei care au acces la scriere pe socket.
Această metodă este destinată pentru lucruri administrative. Pentru a lucra cu date, utilizați a doua metodă — protocolul binar.
2. Utilizarea protocolului binar pentru a vă conecta la un port specific
În configurație există o directivă listen, care deschide un port pentru comunicații externe. Acest port este folosit cu protocolul binar, iar autentificarea este activată.
Pentru această conexiune se folosește tarantoolctl connect to port number. Folosind-o, vă puteți conecta la servere externe, utiliza autentificarea și acorda diferite drepturi de acces.
Scrierea datelor și modul Box
Deoarece Tarantool este atât o bază de date, cât și un server de aplicații, acesta are diferite module. Ne interesează modulul box — care implementează lucrul cu datele. Atunci când scrieți ceva în box, Tarantool scrie datele pe disc, le păstrează în memorie sau face altceva cu ele.
Scriere
De exemplu, intrăm în modulul box și apelăm funcția box.once. Aceasta va forța Tarantool să ruleze codul nostru la inițializarea serverului. Creăm un spațiu în care vor fi stocate datele noastre.
local function bootstrap()
local space = box.schema.create_space('example')
space:create_index('primary')
box.schema.user.grant('guest', 'read,write,execute', 'universe')
-- Păstrează lucrurile în siguranță prin default
-- box.schema.user.create('example', { password = 'secret' })
-- box.schema.user.grant('example', 'replication')
-- box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
endDupă aceasta, creăm un index primar – primary – după care vom putea căuta date. Implicit, dacă nu se specifică alți parametri, se va folosi primul câmp din fiecare înregistrare pentru indexul primar.
Apoi, acordăm drepturi utilizatorului guest, cu care ne conectăm prin protocolul binar. Permitem citirea, scrierea și executarea în întreaga instanță.
Comparativ cu bazele de date obișnuite, aici totul este destul de simplu. Avem un spațiu – o zonă în care sunt stocate datele noastre. Fiecare înregistrare se numește tuplu. Este ambalată în MessagePack. Acesta este un format foarte interesant — este binar și ocupă mai puțin spațiu – 18 bytes față de 27.

Este destul de ușor de lucrat cu el. Aproape fiecare linie, fiecare înregistrare de date poate avea coloane absolut diferite.
Toate spațiile le putem vizualiza folosind comanda Box.space. Pentru a evidenția o instanță specifică – scriem box.space example și obținem informații complete despre aceasta.
În Tarantool sunt încorporate două tipuri de motoare: Memory și Vinyl. Memory păstrează toate datele în memorie. De aceea, totul funcționează simplu și rapid. Datele sunt salvate pe disc, iar există și un mecanism de jurnal de scriere anticipată, așa că nu vom pierde nimic în caz de cădere a serverului.
Vinyl stochează datele pe disc într-o formă mai familiară pentru noi — adică putem stoca mai multe date decât avem memorie, iar Tarantool le va citi de pe disc.
Acum vom folosi 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>Index:
Trebuie să creăm un index primar pentru orice spațiu, deoarece fără el nimic nu va funcționa. La fel ca în orice bază de date, creăm primul câmp – ID-ul înregistrării.
Părți:
Aici specificăm din ce constă indexul nostru. Acesta constă dintr-o singură parte – primul câmp pe care îl vom folosi, de tip unsigned — număr întreg pozitiv. Din câte îmi amintesc din documentație, numărul maxim care poate fi utilizat este de 18 quintilioane. Foarte mult.
Apoi putem insera date folosind comanda 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>Primul câmp este folosit ca cheie primară, deci trebuie să fie unic. Nu există o limită a numărului de coloane, astfel că putem insera cât mai multe date dorim. Acestea sunt specificate în format MessagePack, pe care l-am descris mai sus.
Afișarea datelor
Apoi putem afișa datele folosind comanda select.
Box.example.select specificând cheia {1} va returna înregistrarea corectă. Dacă omitem cheia, vom vedea toate înregistrările pe care le avem. Acestea diferă în funcție de numărul coloanelor, dar în principiu nu există noțiunea de coloane – există numere de câmp.
Pot exista absolut oricât de multe date. De exemplu, dacă trebuie să le căutăm după al doilea câmp. În acest caz, facem un nou index secundar.
box.space.example:create_index( 'secondary', { type = 'TREE', unique = false, parts = {{field = 2, type ='string'} }}) Folosim comanda Create_index.
Îi dăm numele Secondary.
După aceea, trebuie să specificăm parametrii. Tipul indexului — TREE. Acesta poate să nu fie unic, așa că introducem Unique = false.
Apoi specificăm din ce părți constă indexul nostru. Field — este numărul câmpului la care legăm indexul, și specificăm tipul string. Și iată că s-a creat.
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>Acum putem să-l apelăm în acest mod:
unix/:/var/run/tarantool/example.control> box.space.example.index.secondary:select('test1')
---
- - [1, 'test1', 'test2']
...
Salvare
Dacă restartăm instanța și încercăm din nou să apelăm datele, vom vedea că acestea nu sunt disponibile — totul e gol. Acest lucru se întâmplă deoarece Tarantool face checkpoint-uri și salvează datele pe disc, dar dacă oprim funcționarea înainte de cea mai recentă salvare, pierdem toate operațiile — deoarece ne vom restaura de la ultimul checkpoint, care a fost, de exemplu, cu două ore în urmă.
Să salvăm în fiecare secundă nu va funcționa — deoarece a scurge constant 20 GB pe disc este o idee proastă.
Pentru aceasta a fost inventată și implementată concepția de write-ahead log. Cu ajutorul acesteia, pentru fiecare modificare a datelor se creează o înregistrare într-un mic fișier write-ahead log.
Fiecare înregistrare înainte de checkpoint este salvată în ele. Pentru aceste fișiere stabilim o dimensiune — de exemplu, 64 MB. Când acesta se umple, înregistrarea începe să se scrie în al doilea fișier. Și după restart, Tarantool se restaurează din ultimul checkpoint și apoi aplică toate tranzacțiile ulterioare până la momentul opririi.

Pentru a realiza o astfel de înregistrare, trebuie să specificați o opțiune în setările box.cfg (în fișierul example.lua):
wal_mode = “write”;Utilizarea datelor
Cu ceea ce am scris acum, puteți folosi Tarantool pentru a stoca date și va funcționa foarte rapid ca bază de date. Și acum, cireșa de pe tort – ce puteți face cu tot ceea ce există.
Scriem o aplicație
De exemplu, să scriem o aplicație pentru Tarantool
Aplicația poate fi vizualizată sub 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; -- o oră
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
-- pentru prima rulare se creează un spațiu și se adaugă permisiuni
box.once('replica', bootstrap)
-- activarea accesului la consolă
console = require('console')
console.listen('127.0.0.1:3302')
-- configurația 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",
"Numărul de Token-uri 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()Declarăm o tabelă în lua, care definește caracterele. Această tabelă este necesară pentru generarea unei șiruri aleatorii.
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
endDupă aceea, declarem funcția – randomString și îi vom atribui în paranteză valoarea lungimii.
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)]
endApoi conectăm http-router-ul și serverul http la serverul nostru Tarantool, JSON-ul pe care îl vom trimite clientului.
local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')După aceasta, pornim un server http pe portul 8080 pe toate interfețele, care va înregistra toate cererile și erorile.
local httpd = http_server.new('0.0.0.0', 8080, {
log_requests = true,
log_errors = true
})Apoi, declarăm un route, astfel încât dacă pe portul 8080 /count vine o cerere cu metoda GET, vom apela o funcție de o linie. Aceasta returnează un status — 200, 404, 403 sau orice altul, pe care îl specificăm.
router:route({method = 'GET', path = '\/count'}, function()
return {status = 200, body = json.encode({count = get_count()})}
end)În corp, returnăm json.encode, în care specificăm count și get_count, care este apelată și arată numărul de înregistrări din baza noastră de date.
A doua metodă
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)Unde în linia router:route({method = ‘GET’, path = ‘\/token’}, function() apelăm o funcție și generăm un token.
Șirul local token = randomString(32) – aceasta este un string aleatoriu de 32 de caractere.
În rândul local last = box.space.example:len() extragem ultimul element.
Iar în linia box.space.example:insert{ last + 1, token } înregistrăm datele în baza noastră, adică pur și simplu creștem ID-ul cu 1. Acest lucru se poate face, de altfel, nu doar într-un mod atât de incomod. În Tarantula sunt secvențe pentru aceasta.
Înscriem acolo token-ul.
Astfel, am scris o aplicație într-un singur fișier. În aceasta se poate interacționa cu datele, iar modulul box va face toată munca murdară pentru tine.
Ea ascultă http și lucrează cu datele, totul se află într-o singură instanță — atât aplicația, cât și datele. De aceea, totul se desfășoară destul de rapid.
Pentru a porni, instalăm modulul http:
Cum o facem, vedeți sub spoiler.
root@test2: /# tarantoolctl rocks install http
Instalare http://rocks.tarantool.org/http-scm-1.src.rock
Lipsesc dependențe pentru http scm-1:
checks >= 3.0.1 (neinstalat)
http scm-1 depinde de checks >= 3.0.1 (neinstalat)
Instalare http://rocks.tarantool.org/checks-3.0.1-1.rockspec
Clonare în 'checks'...
remote: Enumerarea obiectelor: 28, finalizat.
remote: Numărarea obiectelor: 100% (28/28), finalizat.
remote: Comprimarea obiectelor: 100% (19/19), finalizat.
remote: Total 28 (delta 1), reutilizat 16 (delta 1), pachet reutilizat: 0
Primirea obiectelor: 100% (28/28), 12.69 KiB | 12.69 MiB/s, finalizat.
Rezolvarea delta-urilor: 100% (1/1), finalizat.
Notă: verificând '580388773ef11085015b5a06fe52d61acf16b201'.
Te afli în starea 'HEAD detașat'. Poți explora, efectua modificări experimentale
și le poți salva, iar orice comit pe care îl faci în această
stare poate fi șters fără a afecta branch-urile printr-un alt checkout.
Dacă vrei să creezi un nou branch pentru a păstra comitele pe care le creezi, poți
asta (acum sau mai târziu) prin utilizarea -b cu comanda checkout din nou. Exemplu:
git checkout -b
Nu există un manifest existent. Încercăm să reconstruim...
checks 3.0.1-1 este acum instalat în /.rocks (licență: BSD)
-- Identificarea compilatorului C este GNU 7.5.0
-- Verificare pentru compilator C funcțional: /usr/bin/cc
-- Verificare pentru compilator C funcțional: /usr/bin/cc -- funcționează
-- Detectarea informațiilor ABI pentru compilator C
-- Detectarea informațiilor ABI pentru compilator C - finalizat
-- Detectarea caracteristicilor de compilare C
-- Detectarea caracteristicilor de compilare C - finalizat
-- Am găsit TARANTOOL: /usr/include (versiune găsită "2.4.2-80-g18f2bc82d")
-- Tarantool LUADIR este /.rocks/share/tarantool/rocks/http/scm-1/lua
-- Tarantool LIBDIR este /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configurarea a fost finalizată
-- Generarea a fost finalizată
Avertizare CMake:
Variabilele specificate manual nu au fost utilizate de proiect:
version
-- Fișierele de construire au fost scrise în: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Să scanăm dependențele țintei httpd
[ 50%] Crearea obiectului C http/CMakeFiles/httpd.dir/lib.c.o
În fișierul inclus din /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: În funcția 'tpl_term':
/usr/include/tarantool/lauxlib.h:144:15: avertizare: această declarație poate trece [-Wimplicit-fallthrough=]
(*(B)->p++ = (char)(c)))
~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: notă: în expansiunea macro-ului 'luaL_addchar'
luaL_addchar(b, '\');
^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: notă: aici
default:
^~~~~~~
În fișierul inclus din /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: În funcția 'tpe_parse':
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: avertizare: această declarație poate trece [-Wimplicit-fallthrough=]
type = TPE_TEXT;
~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: notă: aici
case TPE_LINECODE:
^~~~
În fișierul inclus din /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: În funcția 'httpfast_parse':
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: avertizare: această declarație poate trece [-Wimplicit-fallthrough=]
code = 0;
~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: notă: aici
case status:
^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: avertizare: această declarație poate trece [-Wimplicit-fallthrough=]
state = message;
~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: notă: aici
case message:
^~~~
[100%] Legarea bibliotecii partajate C lib.so
[100%] Ținta httpd construită
[100%] Ținta httpd construită
Instalați proiectul...
-- Configurația instalării: "Debug"
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Instalare: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 este acum instalat în /.rocks (licență: BSD)
root@test2: /#De asemenea, pentru a rula avem nevoie de prometheus:
root@test2:~# tarantoolctl rocks install prometheus
Instalare http://rocks.tarantool.org/prometheus-scm-1.rockspec
Clonare în '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.
Rezolvarea deltazilor: 100% (2/2), done.
prometheus scm-1 este acum instalat în /.rocks (licență: BSD)
root@test2:~#
Începem și putem să ne referim la module
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 выдает токен и делает запись этого токена в базу.
Testăm viteza
Hai să lansăm un benchmark pentru 50.000 de cereri. Cererile concurente vor fi 500.
root@test2:~# ab -c 500 -n 50000 http://127.0.0.1:8080/token
Aceasta este ApacheBench, Versiunea 2.3
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licențiat către Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (fii răbdător)
Finalizat 5000 cereri
Finalizat 10000 cereri
Finalizat 15000 cereri
Finalizat 20000 cereri
Finalizat 25000 cereri
Finalizat 30000 cereri
Finalizat 35000 cereri
Finalizat 40000 cereri
Finalizat 45000 cereri
Finalizat 50000 cereri
Finalizat 50000 cereri
Software Server: Tarantool
Hostname Server: 127.0.0.1
Port Server: 8080
Calea Documentului: /token
Lungimea Documentului: 44 bytes
Nivel Concurență: 500
Timp necesar pentru teste: 14.578 secunde
Cereri complete: 50000
Cereri eșuate: 0
Total transferat: 7950000 bytes
HTML transferat: 2200000 bytes
Cereri pe secundă: 3429.87 [#/sec] (medie)
Timp pe cerere: 145.778 [ms] (medie)
Timp pe cerere: 0.292 [ms] (medie, pentru toate cererile concurente)
Rată de transfer: 532.57 [Kbytes/sec] primite
Timpuri de Conexiune (ms)
min medie[+/-sd] median max
Conectare: 0 10 103.2 0 3048
Procesare: 12 69 685.1 15 13538
Așteptare: 12 69 685.1 15 13538
Total: 12 78 768.2 15 14573
Procentajul cererilor servite într-un anumit timp (ms)
50% 15
66% 15
75% 16
80% 16
90% 16
95% 16
98% 21
99% 42
100% 14573 (cea mai lungă cerere)
root@test2:~#Tokenurile sunt emise. Și noi continuăm să scriem datele. 99% din cereri au fost procesate în 42 de milisecunde. Astfel, avem aproximativ 3500 de cereri pe secundă pe o mașină mică, cu 2 nuclee și 4 gigabytes de memorie.
De asemenea, se poate selecta un token de 50000 și verifica valoarea acestuia.
Nu se poate folosi doar http, ci se pot rula funcții în fundal care prelucrează datele. De asemenea, există diverse trigger-uri. De exemplu, poți apela funcții la actualizări, pentru a verifica ceva - pentru a rezolva conflicte.
Puteți scrie aplicații-script direct pe serverul bazei de date, fără nicio restricție, conectând orice module și implementând orice logică.
Serverul de aplicații poate accesa servere externe, extrăgând date și stocându-le în baza sa de date. Acele date vor fi folosite de alte aplicații.
Aceasta va fi realizat de Tarantool, fără a fi nevoie să scrieți o aplicație separată.
În concluzie
Aceasta este doar prima parte a unei lucrări mari. Partea a doua va fi publicată foarte curând pe blogul Mail.ru Group, iar noi vom adăuga cu siguranță un link către aceasta în acest material.
Dacă sunteți interesat să participați la evenimente unde creăm astfel de lucruri online și să adresați întrebări în timp real, conectați-vă la.
Dacă aveți nevoie de migrare în cloud sau aveți întrebări despre infrastructura dumneavoastră, .
P.S. Avem 2 audituri gratuite pe lună, poate proiectul dumneavoastră va fi printre ele.
Sursa: habr.com
