V Tarantool lahko združite super hitro bazo podatkov in aplikacijo za delo z njo. Tako preprosto je to narediti.

Pred petimi leti sem poskusil delati s Tarantool, toda takrat mi ni bil všeč. Nedavno pa sem imel spletni seminar, kjer sem govoril o Hadoopu in o tem, kako deluje MapReduce. Tam so mi postavili vprašanje – 'Zakaj za to nalogo ne bi uporabili Tarantool?'.

Iz radovednosti sem se odločil vrniti k njemu, preizkusiti zadnjo različico – in tokrat mi je projekt resnično bil všeč. Zdaj vam bom pokazal, kako napisati preprosto aplikacijo v Tarantool, obremeniti jo in preveriti zmogljivost, in videli boste, kako enostavno in odlično je vse skupaj.

V Tarantool lahko združite super hitro bazo podatkov in aplikacijo za delo z njo. Tako preprosto je to narediti.

Kaj je Tarantool

Tarantool se pozicionira kot super hitra baza podatkov. Vanj lahko shranite kakršnekoli podatke, ki jih želite. Poleg tega lahko replikacije, sharding – torej razdelitev ogromne količine podatkov med več strežniki in združevanje rezultatov – izvajate odporne povezave vrste 'master-master'.

Kot drugo je to aplikacijski strežnik. Na njem lahko pišete svoje aplikacije, delate s podatki, na primer, brišete stare zapise v ozadju po določenih pravilih. Naravnost v Tarantoolu lahko napišete Http-strežnik, ki bo delal s podatki: izdajal njihovo število, zapisoval nove podatke in to vse reduciral na master.

Prebral sem članek, kako so fantje naredili sporočilno vrsto s 300 vrsticami, ki preprosto razbija in šiba – njihova zmanjšana zmogljivost je od 20.000 sporočil na sekundo. Tukaj se lahko resnično razmahnemo in napišemo zelo veliko aplikacijo, in te ne bodo shranjevale, kot v PostgreS.

Približno takšen strežnik, le da preprost, bom poskušal opisati v tem članku.

Namestitev

Za test sem postavil tri standardne virtualne stroje – trdi disk na 20 gigabajtov, Ubuntu 18.04, 2 virtualna CPU in 4 giga pomnilnika.

Namestimo Tarantool – zaženemo bash skripto ali dodamo repozitorij in naredimo apt get install Tarantool. Povezava na skripto – (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Imamo ukaze, kot so:

tarantoolctl – glavni ukaz za upravljanje z instancami Tarantoola.
/etc/tarantool – tukaj se nahaja vsa konfiguracija.
var/log/tarantool – tukaj so dnevniki.
var/lib/tarantool – tukaj so podatki, ki so nato še razdeljeni po instancah.

Obstajajo mape instance-available in instance-enable — v njej so tiste, ki bodo zagnane — datoteka s konfiguracijo instance z lua kodo, kjer je opisano, na katerih vratih posluša, kakšna je dostopna pomnilnik, nastavitve pogona Vinyl, koda, ki se izvaja ob zagonu strežnika, deljenje, čakalne vrste, odstranjevanje zastare in tako naprej.

Instance delujejo kot v PostgreS. Na primer, želite zagnati več kopij baze podatkov, ki deluje na različnih vratih. Tako se na enem strežniku zažene več instanc baz podatkov, ki delujejo na različnih vratih. Imajo lahko popolnoma različne nastavitve — ena instanca izvajajo eno logiko, druga — drugo.

Upravljanje instanc

Imamo ukaz tarantoolctl, ki omogoča upravljanje instanc Tarantula. Na primer, tarantoolctl check example bo preveril datoteko s konfiguracijo in povedal — datoteka je ok, če tam ni nobenih sintaktičnih napak.

Lahko si ogledate status instance — tarantoolctl status example. Na enak način lahko izvajate start, stop, restart.

Ko je instance zagnana, se lahko povežete na dva načina.

1. Administrativna konzola

Privzeto Tarantool odpre socket, kjer se prenaša običajen ASCII besedilo za upravljanje Tarantula. Povezava na konzolo se vedno zgodi pod uporabnikom admin, tam ni avtentikacije, zato port konzole za upravljanje Tarantula ni treba izstavljati navzven.

Za povezovanje na ta način je treba vpisati Tarantoolctl enter instance name. Ukaz bo zagnal konzolo in se povezal pod uporabnikom admin. Nikoli ne izpostavljajte konzolskega porta navzven — bolje je, da ga pustite kot unit-socket. Tako bo možnost povezovanja na Tarantula imela le tisti, ki imajo dostop za pisanje v socket.

Ta način je potreben za administrativne zadeve. Za delo s podatki uporabite drugi način — binarni protokol.

2. Uporaba binarnega protokola za povezovanje na določeno vrata

V konfiguraciji je direktiva listen, ki odpre vrata za zunanje komunikacije. Ta vrata uporabljate z binarnim protokolom, kjer je vključena avtentikacija.

Za to povezavo se uporablja tarantoolctl connect to port number. Z uporabo tega lahko dostopate do oddaljenih strežnikov, uporabljate avtentikacijo in podeljujete različna dovoljenja.

Zapis podatkov in modul Box

Ker Tarantool služi tako kot podatkovna baza kot tudi kot aplikacijski strežnik, ima različne module. Zanima nas modul box – ta skrbi za delo s podatki. Ko v box zapišete nekaj, Tarantool shranjuje podatke na disk, jih ohranja v pomnilniku ali z njimi izvaja še kaj drugega.

Zapis

Na primer, vstopimo v modul box in pokličemo funkcijo box.once. Ta prisili Tarantool, da ob zagonu strežnika izvede naš kodo. Ustvarimo prostor, v katerem bodo shranjeni naši podatki.

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

    -- Za zaščito stvari privzeto
    --  box.schema.user.create('example', { password = 'secret' })
    --  box.schema.user.grant('example', 'replication')
    --  box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end

Nato ustvarimo primarni indeks – primary – po katerem bomo lahko iskali podatke. Privzeto, če ne navedemo nobenih parametrov, se prvo polje v vsaki vnosu uporabi za primarni indeks.

Nato dodelimo pravice uporabniku guest, pod katerim se prijavimo prek binarnega protokola. Dovolimo branje, pisanje in izvajanje v celotnem instancu.

V primerjavi s običajnimi podatkovnimi bazami je tu vse precej preprosto. Imamo space – območje, v katerem so shranjeni naši podatki. Vsaka vnos se imenuje kaze. Pakuje se v MessagePack. To je zelo zanimiv format — je binaren in zasede manj prostora – 18 bajtov namesto 27.

V Tarantool lahko združite super hitro bazo podatkov in aplikacijo za delo z njo. Tako preprosto je to narediti.

Z njim je zelo enostavno delati. Skoraj vsaka vrstica, vsak vnos podatkov, lahko vsebuje popolnoma različne stolpce.

Vse prostore lahko vidimo s pomočjo ukaza Box.space. Da izpostavimo določen instančni prostor, vpišemo box.space example in dobimo popolne informacije o tem.

V Tarantoolu so vgrajeni dva tipa motorjev: Memory in Vinyl. Memory shranjuje vse podatke v pomnilniku. Zato je vse enostavno in hitro. Podatki se shranijo na disk, prav tako je na voljo mehanizem write ahead log, tako da nič ne izgubimo ob padcu strežnika.

Vinyl shranjuje podatke na disku v bolj običajni obliki — to pomeni, da lahko shranimo več podatkov, kot jih imamo v pomnilniku, in Tarantool jih bo bral z diska.

Zdaj bomo uporabljali 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>

Indeks:

Primarni indeks mora biti kreiran za svaki prostor, jer bez njega ništa neće raditi. Kao i u svakoj bazi, kreiramo prvo polje – ID zapisa.

Delovi:

Ovde navodimo od čega se sastoji naš indeks. Sastoji se od jednog dela – prvog polja koje ćemo koristiti, tip unsigned — pozitivni ceo broj. Koliko se sećam iz dokumentacije, maksimalni broj može biti – 18 kvintiliona. Zapanjujuće mnogo.

Zatim možemo unositi podatke pomoću komande 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>

Prvo polje se koristi kao primarni ključ, zato mora biti jedinstveno. Nema ograničenja u broju kolona, tako da možemo uneti neograničen broj podataka. Oni se navode u formatu MessagePack, koji sam opisao ranije.

Prikaz podataka

Zatim možemo prikazivati podatke komandom select.

Box.example.select sa navedenim ključem {1} prikazaće odgovarajući zapis. Ako izostavimo ključ, videćemo sve zapise koje imamo. Svi su različiti po broju kolona, ali ovde u suštini nema pojma kolona — postoje brojevi polja.

Podataka može biti neograničeno. Na primer, možda ćemo morati da ih pretražujemo po drugom polju. Za to pravimo novi sekundarni indeks.


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

Koristimo komandu Create_index.
Nazivamo ga Sekundarni.

Nakon toga treba navesti parametre. Tip indeksa — TREE. Može biti ne jedinstven, pa unosimo Unique = false.

Zatim navodimo od kojih delova se sastoji naš indeks. Field — to je broj polja na koje vezujemo indeks, i navodimo tip string. I tako je kreiran.

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>

Теперь вот таким образом мы можем его вызвать:

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

Сохранение

Если мы перезагрузим инстанс и снова попробуем вызвать данные — то увидим, что их нет — все пусто. Так происходит, поскольку Tarantool делает чекпоинты и сохраняет данные на диск, но если мы остановим работу до ближайшего сохранения, то потеряем все операции — потому что восстановимся с последнего чекпоинта, который был, например, два часа назад.

Сохранять каждую секунду тоже не получится — потому что постоянно дампить на диск по 20 Гб — так себе затея.

Для этого была придумана и реализована концепция write-ahead log. С её помощью на каждое изменение в данных создается запись в маленьком файле write-ahead log.

Каждая запись до чекпоинта сохраняется в них. Для этих файлов мы выставляем размер — например, 64 Мб. Когда он заполняется, запись начинает идти во второй файл. И после рестарта Tarantool восстанавливается из последнего чекпоинта и затем накатывает все более поздние транзакции до момента остановки.

V Tarantool lahko združite super hitro bazo podatkov in aplikacijo za delo z njo. Tako preprosto je to narediti.

Чтобы осуществлять такую запись, нужно указать опцию в настройках box.cfg (в файле example.lua):

wal_mode = “write”;

Использование данных

С тем, что мы написали сейчас, вы можете использовать Тарантул для хранения данных, и он будет очень быстро работать как БД. А теперь самая вишенка на торте – что можно с этим со всем делать.

Пишем приложение

Например, напишем для Тарантула такое приложение

Приложение смотрите под спойлером

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; -- одна часа
    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

-- для первого запуска создайте пространство и настройте права
box.once('replica', bootstrap)

-- включение доступа к консоли
console = require('console')
console.listen('127.0.0.1:3302')

-- 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",
                              "Количество 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()

Мы объявляем некоторый набор символов в Lua, который необходим для генерации случайной строки.

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

Затем мы объявляем функцию – randomString и передаем в скобках значение длины.

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

Далее мы подключаем http-роутер и http-сервер к нашему Tarantool-серверу, а также JSON, который будем отправлять клиенту.

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

Nato se zaženemo na portu 8080 na vseh vmesnikih http strežnika, ki bo beležil vse poizvedbe in napake.

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

Nato razglasimo route, da če na portu 8080 /count prejme poizvedbo z metodo GET, pokličemo funkcijo, ki vrne status — 200, 404, 403 ali katerikoli drug, ki ga navedemo.

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

V telesu vrnemo json.encode, v njej navedemo count in getcount, ki je poklicana in kaže število zapisov v naši bazi.

Druga metoda

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)

Kjer v vrstici router:route({method = 'GET', path = ' /token'}, function() pokličemo funkcijo in generiramo token.

Vrstica local token = randomString(32) – je naključna vrstica dolgosti 32 znakov.
V vrstici local last = box.space.example:len() pridobimo zadnji element.
In v vrstici box.space.example:insert{ last + 1, token } shranimo podatke v našo bazo, torej preprosto povečamo ID za 1. To lahko storimo, mimogrede, ne le na tak nečist način. V Tarantulu so za to sekvence.

Shranjujemo tam token.

Tako smo v eni datoteki napisali aplikacijo. V njej lahko takoj dostopate do podatkov, modul box pa opravi vse umazano delo za vas.

Sluša http in dela z podatki, vse je v enem instanci — tako aplikacija kot podatki. Zato se vse odvija dovolj hitro.

Za zagon namestimo http modul:

Kako to naredimo, si oglejte pod zavihkom

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 

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

Za zagon potrebujemo tudi prometheus:

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 je sedaj nameščen v /.rocks (license: BSD)

root@test2:~#

Začnemo in lahko dostopamo do modulov

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

Testiramo hitrost

Začnimo benchmark z 50.000 poizvedbami. Konkurentnih poizvedb bo 500.

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

Toki se izdajajo. Nenehno beležimo podatke. 99% poizvedb je bilo izvedenih v 42 milisekundah. Imamo približno 3500 poizvedb na sekundo na majhnem strežniku z 2 jedroma in 4 gigabajti pomnilnika.

Lahko izberemo tudi kakšno 50000-token in preverimo njegovo vrednost.

Lahko ne uporabljamo samo http, temveč tudi zagnamo funkcije v ozadju, ki obdelujejo vaše podatke. Poleg tega so na voljo različni sprožilci. Na primer, lahko kličete funkcije ob posodobitvah, preverite nekatere stvari – odpravite konflikte.

Možno písať aplikácie-skripty priamo v samotnom databázovom serveri a neobmedzovať sa, pripojiť akékoľvek moduly a realizovať ľubovoľnú logiku.

Aplikačný server môže komunikovať s externými servermi, získavať dáta a ukladať ich vo svojej databáze. Tieto dáta budú využívať iné aplikácie.

Toto bude robiť samotný Tarantool, a nebude potrebné písať samostatnú aplikáciu.

Na záver

Toto je len prvá časť veľkej práce. Druhá bude čoskoro publikovaná na blogu Mail.ru Group a určite pridáme odkaz na ňu do tohto materiálu.

Ak máte záujem navštevovať podujatia, kde vytvárame takéto veci online a klásť otázky v reálnom čase, pripojte sa k kanálu DevOps by REBRAIN.

Ak potrebujete presun do cloudu alebo máte otázky k vašej infraštruktúre, kľudne zanechajte žiadosť.

P.S. Máme 2 bezplatné audity mesačne, možno práve váš projekt bude v ich počte.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster