Met Tarantool kun je een super snelle database combineren met een applicatie om ermee te werken. Zo eenvoudig is het.

Vijf jaar geleden heb ik geprobeerd om met Tarantool te werken, maar het beviel me toen niet. Maar recentelijk hield ik een webinar waarin ik sprak over Hadoop en hoe MapReduce werkt. Daar kreeg ik de vraag: "Waarom gebruiken we Tarantool niet voor deze taak?"

Uit nieuwsgierigheid besloot ik om terug te keren, de laatste versie te testen — en dit keer beviel het project me erg goed. Nu ga ik laten zien hoe je een eenvoudige applicatie in Tarantool kunt schrijven, deze kunt belasten en de prestaties kunt controleren, en je zult zien hoe eenvoudig en geweldig het daar is.

Met Tarantool kun je een super snelle database combineren met een applicatie om ermee te werken. Zo eenvoudig is het.

Wat is Tarantool

Tarantool positioneert zichzelf als een ultranette database. Je kunt er allerlei gegevens in stoppen die je maar wilt. Bovendien kun je ze repliceren, sharden — dat wil zeggen, een enorme hoeveelheid gegevens verdelen over verschillende servers en de resultaten combineren — en robuuste configuraties maken zoals 'master-master'.

Ten tweede is het een applicatieserver. Je kunt er je eigen applicaties op schrijven, met gegevens werken, bijvoorbeeld oude records op de achtergrond verwijderen volgens bepaalde regels. Je kunt zelfs een Http-server direct in Tarantool schrijven die met data werkt: de hoeveelheid gegevens opleveren, nieuwe gegevens opslaan en dit alles reduceren naar de master.

Ik las een artikel over hoe jongens een berichtenwachtrij met 300 regels maakten, die werkelijk indruk maakt — zij hebben een minimale prestaties van 20.000 berichten per seconde. Hier kun je echt uit de voeten en een zeer grote applicatie schrijven, en dit zullen geen stored procedures zijn, zoals in PostgreSQL.

Ongeveer zo'n server, maar dan eenvoudig, ga ik in dit artikel proberen te beschrijven.

Installatie

Voor de test heb ik drie standaard virtuele machines aangemaakt – een harde schijf van 20 gigabyte, Ubuntu 18.04, 2 virtuele CPU's en 4 gigabyte RAM.

We installeren Tarantool — we starten een bash-script of voegen de repository toe en doen apt get install Tarantool. Link naar het script — (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). We krijgen deze commando's:

tarantoolctl — het hoofdcommando voor het beheren van Tarantool-instanties.
/etc/tarantool — hier bevindt zich alle configuratie.
var/log/tarantool — hier staan de logs.
var/lib/tarantool — hier bevinden zich de gegevens, en verder zijn ze verdeeld over de instanties.

Er zijn mappen instance-available en instance-enable — hierin bevindt zich wat gestart zal worden — het configuratiebestand van de instantie met lua-code, waarin staat op welke poorten het luistert, welke geheugenruimte beschikbaar is, instellingen van de Vinyl-engine, de code die wordt uitgevoerd bij het starten van de server, sharding, wachtrijen, het verwijderen van verouderde gegevens, enzovoort.

Instanties werken zoals in PostgreS. Bijvoorbeeld, als je meerdere kopieën van een database wilt starten die op verschillende poorten draait. Dat betekent dat op één server meerdere database-instanties draaien die op verschillende poorten hangen. Ze kunnen volkomen verschillende instellingen hebben — één instantie implementeert de ene logica, de tweede een andere.

Beheer van instanties

We hebben het commando tarantoolctl, waarmee je instanties van Tarantool kunt beheren. Bijvoorbeeld, tarantoolctl check example controleert het configuratiebestand en zegt — bestand is ok, als er geen syntactische fouten zijn.

Je kunt de status van de instantie bekijken — tarantoolctl status example. Op dezelfde manier kun je start, stop, restart uitvoeren.

Wanneer de instantie is gestart, kun je op twee manieren verbinding maken.

1. Administratieve console

Standaard opent Tarantool een socket, waarbij normaal ASCII-tekst wordt doorgegeven voor het beheer van Tarantool. Verbinden met de console gebeurt altijd als gebruiker admin, er is geen authenticatie, dus je hoeft de consolepoort voor beheer niet naar buiten toe te openen.

Om op deze manier verbinding te maken, voer je Tarantoolctl enter instance name in. Deze opdracht start de console en maakt verbinding als gebruiker admin. Stel de consolepoort nooit buiten open — het is beter deze als unit-socket te laten. Dan kunnen alleen degenen die toegang hebben tot het schrijven in de socket verbinding maken met Tarantool.

Deze manier is nodig voor administratieve zaken. Voor het werken met gegevens gebruik je de tweede manier — het binaire protocol.

2. Gebruik van het binaire protocol om verbinding te maken met een bepaalde poort

In de configuratie is er de directive listen, die een poort opent voor externe communicatie. Deze poort wordt gebruikt met het binaire protocol en daar is authenticatie ingeschakeld.

Voor deze verbinding wordt tarantoolctl connect to port number gebruikt. Hiermee kan je verbinding maken met externe servers, authenticatie gebruiken en verschillende toegangsrechten geven.

Gegevens schrijven en de Box-module

Aangezien Tarantool zowel een database als een applicatieserver is, zijn er verschillende modules. Wij zijn geïnteresseerd in de module box — deze houdt zich bezig met gegevensbeheer. Wanneer je iets in de box schrijft, schrijft Tarantool de gegevens naar de schijf, slaat ze in het geheugen op of doet er iets anders mee.

Schrijven

Bijvoorbeeld, we gaan naar de module box en roepen de functie box.once aan. Dit zorgt ervoor dat Tarantool onze code uitvoert bij de initialisatie van de server. We creëren een ruimte waar onze gegevens opgeslagen zullen worden.

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

    -- Houd dingen standaard veilig
    --  box.schema.user.create('example', { password = 'secret' })
    --  box.schema.user.grant('example', 'replication')
    --  box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end

Daarna creëren we een primaire index – primary – waarmee we gegevens kunnen opzoeken. Standaard, als er geen parameters worden opgegeven, wordt het eerste veld in elke record gebruikt voor de primaire index.

Vervolgens geven we rechten aan de gebruiker guest, waarmee we verbinding maken via het binaire protocol. We staan lezen, schrijven en uitvoeren toe in de gehele instantie.

Als we dit vergelijken met gewone databases, is het hier allemaal vrij eenvoudig. We hebben een space – een gebied waar onze gegevens gewoon worden opgeslagen. Elke record wordt een tuple genoemd. Deze wordt verpakt in MessagePack. Dit is een heel leuk formaat — het is binair en neemt minder ruimte in — 18 bytes in plaats van 27.

Met Tarantool kun je een super snelle database combineren met een applicatie om ermee te werken. Zo eenvoudig is het.

Het is heel prettig om mee te werken. Bijna elke regel, elke record kan absoluut verschillende kolommen hebben.

Alle spaces kunnen we bekijken met het commando Box.space. Om een specifieke instantie uit te lichten – schrijven we box.space example en krijgen we volledige informatie daarover.

Tarantool heeft twee soorten engines ingebouwd: Memory en Vinyl. Memory slaat alle gegevens in het geheugen op. Daardoor werkt alles gewoon en snel. Gegevens worden naar de schijf gedumpt, en er is ook een mechanisme voor write ahead log, zodat we niets verliezen bij een servercrash.

Vinyl slaat gegevens op de schijf op in een meer vertrouwde indeling — dat wil zeggen, je kunt meer gegevens opslaan dan er geheugen beschikbaar is, en Tarantool zal deze van de schijf lezen.

We gaan nu Memory gebruiken.

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:

Een primaire index moet worden aangemaakt voor elke space, omdat zonder deze niets zal werken. Net als in elke database creëren we het eerste veld – de record ID.

Onderdelen:

Hier geven we op waaruit onze index bestaat. Hij bestaat uit één onderdeel – het eerste veld dat we zullen gebruiken, type unsigned — een positief geheel getal. Voor zover ik uit de documentatie herinner, is het maximale getal dat mogelijk is – 18 quintiljoen. Heel veel.

Daarna kunnen we gegevens invoegen met het commando 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>

Het eerste veld wordt gebruikt als primaire sleutel, dus het moet uniek zijn. We zijn niet beperkt in het aantal kolommen, dus we kunnen zoveel gegevens invoegen als we willen. Deze worden opgegeven in het MessagePack-formaat, dat ik hierboven heb beschreven.

Gegevensuitvoer

Daarna kunnen we gegevens ophalen met het select-commando.

Box.example.select met de sleutel {1} geeft het benodigde record terug. Als we de sleutel weglaten, zien we alle records die we hebben. Ze verschillen allemaal in het aantal kolommen, maar hier is hetprincipieel geen concept van kolommen — er zijn veldnummers.

Er kunnen absoluut veel gegevens zijn. En bijvoorbeeld, als we ze op het tweede veld moeten zoeken. Hiervoor maken we een nieuwe secundaire index.


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

We gebruiken het commando Create_index.
We noemen het Secondary.

Daarna moeten we de parameters opgeven. Type index — TREE. Het kan niet uniek zijn, dus we geven Unique = false op.

Vervolgens geven we op uit welke onderdelen onze index bestaat. Field — dat is het veldnummer waarop we de index baseren, en we geven het type string op. En zo is hij gemaakt.

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>

Nu kunnen we het op deze manier aanroepen:

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

Opslaan

Als we de instance opnieuw opstarten en opnieuw proberen de gegevens op te vragen, zullen we zien dat ze er niet zijn - alles is leeg. Dit gebeurt omdat Tarantool checkpoints maakt en gegevens op de schijf opslaat, maar als we de werking vóór de laatste opslaan stoppen, verliezen we alle bewerkingen - omdat we herstellen vanaf de laatste checkpoint, die bijvoorbeeld twee uur geleden was.

Elk seconde opslaan lukt ook niet - omdat het continue dumpen van 20 GB naar de schijf geen goed idee is.

Daarom is het concept van de write-ahead log bedacht en geïmplementeerd. Hiermee wordt voor elke wijziging in gegevens een record gemaakt in een klein write-ahead log-bestand.

Elke record tot aan de checkpoint wordt daarin opgeslagen. Voor deze bestanden stellen we een grootte in - bijvoorbeeld 64 MB. Wanneer het vol is, begint de opname in een tweede bestand. En na een herstart herstelt Tarantool zich vanaf de laatste checkpoint en past vervolgens alle latere transacties toe tot het moment van stoppen.

Met Tarantool kun je een super snelle database combineren met een applicatie om ermee te werken. Zo eenvoudig is het.

Om dergelijke opnames uit te voeren, moet u een optie opgeven in de instellingen van box.cfg (in het bestand example.lua):

wal_mode = “write”;

Gebruik van gegevens

Met wat we nu hebben geschreven, kunt u Tarantool gebruiken om gegevens op te slaan, en het zal heel snel werken als een database. En nu het mooiste - wat je met dit alles kunt doen.

We schrijven een applicatie

Laten we bijvoorbeeld een applicatie voor Tarantool schrijven

Bekijk de applicatie onder de 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; -- een uur
    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

-- voor de eerste uitvoer een ruimte creëren en machtigingen instellen
box.once('replica', bootstrap)

-- console-toegang inschakelen
console = require('console')
console.listen('127.0.0.1:3302')

-- http-configuratie
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 Aantal")

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

We verklaren een tabel in lua die de tekens definieert. Deze tabel is nodig voor het genereren van een willekeurige string.

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

Daarna verklaren we de functie – randomString en geven we in de haakjes de lengtewaarde.

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

Vervolgens verbinden we de http-router en http-server met onze Tarantool-server, JSON die we aan de klant gaan geven.

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

Daarna starten we de HTTP-server op poort 8080 op alle interfaces, die alle verzoeken en fouten zal loggen.

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

Vervolgens declareren we een route, zodat als er een GET-verzoek op poort 8080 /count binnenkomt, we een functieroutine met één regel aanroepen. Deze retourneert een status — 200, 404, 403 of een andere die we aangeven.

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

In de body retourneren we json.encode, waarin we het aantal en get_count vermelden, dat wordt aangeroepen en het aantal records in onze database toont.

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

Waar in de regel router:route({method = ‘GET’, path = ‘\/token’}, function() roepen we een functie aan en genereren we een token.

String local token = randomString(32) – dat is een willekeurige string van 32 tekens.
In de regel local last = box.space.example:len() halen we het laatste element op.
En in de regel box.space.example:insert{ last + 1, token } schrijven we de gegevens in onze database, dat wil zeggen, we verhogen gewoon de ID met 1. Dit kan trouwens niet alleen op zo'n grove manier. In Tarantool zijn er sequenties voor dit soort werk.

We schrijven daar het token in.

Op deze manier hebben we in één bestand een applicatie geschreven. Je kunt direct met gegevens omgaan en de box-module doet al het vuile werk voor je.

Het luistert naar HTTP en werkt met gegevens, alles bevindt zich in één instantie — zowel de applicatie als de gegevens. Daarom verloopt alles vrij snel.

Voor de start installeren we de HTTP-module:

Hoe we dit doen, zie je onder de spoiler

root@test2:/$ tarantoolctl rocks install http
Installing http://rocks.tarantool.org/http-scm-1.src.rock
Vereiste afhankelijkheden voor http scm-1:
   checks >= 3.0.1 (niet geïnstalleerd)

http scm-1 is afhankelijk van checks >= 3.0.1 (niet geïnstalleerd)
Installing http://rocks.tarantool.org/checks-3.0.1-1.rockspec

Clonen naar 'checks'...
remote: Objecten tellen: 28, gedaan.
remote: Objecten tellen: 100% (28/28), gedaan.
remote: Objecten comprimeren: 100% (19/19), gedaan.
remote: Totaal 28 (delta 1), hergebruikt 16 (delta 1), pack-hergebruikt 0
Ontvangen objecten: 100% (28/28), 12.69 KiB | 12.69 MiB/s, gedaan.
Resolving deltas: 100% (1/1), gedaan.
Opmerking: checken '580388773ef11085015b5a06fe52d61acf16b201'.

Je bevindt je in 'detached HEAD' staat. Je kunt rondkijken, experimentele
wijzigingen aanbrengen en ze vastleggen, en je kunt alle vastleggingen die je in deze
staat maakt verwijderen zonder enige takken te beïnvloeden door opnieuw te checkouten.

Als je een nieuwe tak wilt aanmaken om de vastleggingen die je aanmaakt te behouden, kun je
dit doen (nu of later) met -b bij de checkout-opdracht opnieuw. Voorbeeld:

  git checkout -b 

Geen bestaand manifest. Poging om opnieuw op te bouwen...
checks 3.0.1-1 is nu geïnstalleerd in /.rocks (licentie: BSD)

-- De C-compilator identificatie is GNU 7.5.0
-- Controleren voor werkende C compilator: /usr/bin/cc
-- Controleren voor werkende C compilator: /usr/bin/cc -- werkt
-- Detecteren van C compilator ABI-informatie
-- Detecteren van C compilator ABI-informatie - gedaan
-- Detecteren van C compileer-functies
-- Detecteren van C compileer-functies - gedaan
-- Gevonden TARANTOOL: /usr/include (gevonden versie "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
-- Configureren gedaan
-- Genereren gedaan
CMake Waarschuwing:
  Handmatig opgegeven variabelen zijn niet gebruikt door het project:

    versie


-- Bouwbestanden zijn geschreven naar: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Scannen van afhankelijkheden van doel httpd
[ 50%] C-object http/CMakeFiles/httpd.dir/lib.c.o aan het bouwen
In bestand opgenomen vanuit /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: In functie ‘tpl_term’:
/usr/include/tarantool/lauxlib.h:144:15: waarschuwing: deze verklaring kan doorvallen [-Wimplicit-fallthrough=]
    (*(B)->p++ = (char)(c)))
    ~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: opmerking: bij uitbreiding van macro ‘luaL_addchar’
       luaL_addchar(b, '\');
       ^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: opmerking: hier
      standaard:
      ^~~~~~~
In bestand opgenomen vanuit /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: In functie ‘tpe_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: waarschuwing: deze verklaring kan doorvallen [-Wimplicit-fallthrough=]
    type = TPE_TEXT;
    ~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: opmerking: hier
   case TPE_LINECODE:
   ^~~~
In bestand opgenomen vanuit /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: In functie ‘httpfast_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: waarschuwing: deze verklaring kan doorvallen [-Wimplicit-fallthrough=]
                 code = 0;
                 ~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: opmerking: hier
             case status:
             ^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: waarschuwing: deze verklaring kan doorvallen [-Wimplicit-fallthrough=]
                 state = message;
                 ~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: opmerking: hier
             case message:
             ^~~~
[100%] Koppelen van C gedeelde bibliotheek lib.so
[100%] Doel httpd gebouwd
[100%] Doel httpd gebouwd
Installeer het project...
-- Installatie-configuratie: "Debug"
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installeren: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 is nu geïnstalleerd in /.rocks (licentie: BSD)

root@test2:/$

We also need prometheus to start:

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

We are starting and can access the modules

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

Testing speed

Let's run a benchmark with 50,000 requests. There will be 500 concurrent requests.

root@test2:~# ab -c 500 -n 50000 http://127.0.0.1:8080/token
This is ApacheBench, Version 2.3 
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:~#

Tokens are being issued. And we are continuously recording data. 99% of requests were processed in 42 milliseconds. Consequently, we have about 3500 requests per second on a small machine with 2 cores and 4 gigabytes of memory.

You can also select some token from 50,000 and check its value.

You can use not only http, but also run background functions that process your data. Plus, there are various triggers. For example, you can invoke functions on updates, check something - resolve conflicts.

Je kunt applicatiescripts direct in de database server schrijven, zonder enige beperkingen, en alle modules aansluiten en elke logica implementeren.

De applicatieserver kan externe servers aanspreken, gegevens ophalen en deze in zijn eigen database opslaan. Gegevens uit deze database zullen door andere applicaties worden gebruikt.

Dit zal Tarantool zelf doen, waardoor je geen aparte applicatie hoeft te schrijven.

Ter conclusie

Dit is slechts het eerste deel van een groot werk. Het tweede deel zal binnenkort op de Blog van Mail.ru Group worden gepubliceerd, en we zullen zeker een link naar dit materiaal aan toevoegen.

Als je geïnteresseerd bent in evenementen waar we dergelijke dingen online creëren en vragen in real-time kunt stellen, sluit je dan aan bij de DevOps by REBRAIN-kanaal.

Als je hulp nodig hebt bij een cloud migratie of vragen hebt over je infrastructuur, laat gerust een aanvraag achter.

P.S. We hebben 2 gratis audits per maand, misschien is jouw project wel een van hen.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster