En Tarantool, vi povas kombini superrapidan datumbazon kaj aplikaĵon por labori kun ili. Jen kiel facile ĝi estas fari

Antaŭ kvin jaroj mi provis labori kun Tarantool, sed tiam ĝi ne funkciis por mi. Sed lastatempe mi okazigis retseminarion, kie mi parolis pri Hadoop, pri kiel funkcias MapReduce. Tie oni demandis min - "Kial ne uzi Tarantool por ĉi tiu tasko?".

Por scivolemo, mi decidis reveni al ĝi, testi la lastan version - kaj ĉi-foje mi tre ŝatis la projekton. Nun mi montros kiel skribi simplan aplikaĵon en Tarantool, ŝargi ĝin kaj kontroli la agadon, kaj vi vidos kiel facila kaj malvarmeta ĉio estas tie.

En Tarantool, vi povas kombini superrapidan datumbazon kaj aplikaĵon por labori kun ili. Jen kiel facile ĝi estas fari

Kio estas Tarantool

Tarantool poziciigas sin kiel ultra-rapida datumbazo. Vi povas meti ajnajn datumojn, kiujn vi volas. Plie, reproduktu ilin, shard - tio estas, dividu grandegan kvanton da datumoj tra pluraj serviloj kaj kombinu la rezultojn el ili - faru mistolerajn majstrajn ligojn.

Due, ĝi estas aplikaĵoservilo. Vi povas skribi viajn aplikojn sur ĝi, labori kun datumoj, ekzemple, forigi malnovajn enskribojn en la fono laŭ certaj reguloj. Vi povas skribi Http-servilon rekte en Tarantula, kiu funkcios kun datumoj: donu ilian numeron, skribu novajn datumojn tie kaj reduktu ĉion al majstro.

Mi legis artikolon pri kiel la uloj faris 300-linian mesaĝvicon, kiu nur ŝiras kaj draŝas - ili havas minimuman rendimenton de 20 000 mesaĝoj sekundo. Ĉi tie vi vere povas turni sin kaj skribi tre grandan aplikaĵon, kaj ĉi tiuj ne estos konservitaj, kiel en PostgreS.

Proksimume tian servilon, nur simplan, mi provos priskribi en ĉi tiu artikolo.

fikso

Por la testo, mi ekfunkciigis tri normajn virtualajn maŝinojn - 20 gigabajtan malmolan diskon, Ubuntu 18.04. 2 virtuala CPU kaj 4 gigabajtoj da memoro.

Ni instalas Tarantool - rulu bash-skripton aŭ aldonu deponejon kaj taŭgas instali Tarantool. Ligo al la skripto - (buklo -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Ni havas komandojn kiel:

tarantoolctl estas la ĉefa komando por administri Tarantula-instancojn.
/etc/tarantool - ĉi tie kuŝas la tuta agordo.
var/log/tarantool - jen la ŝtipoj.
var/lib/tarantool - ĉi tie kuŝas la datumoj, kaj poste ili estas dividitaj en okazojn.

Estas dosierujoj disponeblaj por petskriboj kaj ebligeblaj por petskriboj - ĝi enhavas tion, kio estos lanĉita - la instanca agorda dosiero kun lua kodo, kiu priskribas sur kiuj pordoj ĝi aŭskultas, kia memoro disponeblas al ĝi, Vinil-motoragordojn, kodon kiu funkcias ĉe ekfunkciigo. serviloj, sharding, vostoj, forigo de malnoviĝintaj datumoj ktp.

Okazaĵoj funkcias kiel en PostgreS. Ekzemple, vi volas ruli plurajn kopiojn de datumbazo kiu pendas sur malsamaj havenoj. Rezultas, ke pluraj datumbazaj petskriboj estas lanĉitaj sur unu servilo, kiuj pendas sur malsamaj havenoj. Ili povas havi tute malsamajn agordojn - unu kazo efektivigas unu logikon, la dua - alian.

Administrado de petskriboj

Ni havas la komandon tarantoolctl, kiu ebligas al ni administri Tarantula-instancojn. Ekzemple, tarantoolctl-kontrolo ekzemplo kontrolos la agordan dosieron kaj diros, ke la dosiero estas en ordo se ne estas sintaksaj eraroj.

Vi povas vidi la staton de la kazo - tarantoolctl status example. Same, vi povas komenci, halti, rekomenci.

Post kiam okazo funkcias, estas du manieroj konekti al ĝi.

1. Administra konzolo

Defaŭlte, Tarantool malfermas ingon kaj sendas simplan ASCII-tekston por kontroli la Tarantulon. Konekto al la konzolo ĉiam okazas sub la administra uzanto, ne ekzistas aŭtentigo, do vi ne bezonas eltiri la konzolan havenon por kontroli la Tarantulon ekstere.

Por konektiĝi tiamaniere, vi devas enigi Tarantoolctl enigi la instantan nomon. La komando lanĉos la konzolon kaj konektos kiel la administra uzanto. Neniam elmontru la konzolan havenon al la ekstero - estas pli bone lasi ĝin kiel unuokonekto. Tiam nur tiuj, kiuj havas skriban aliron al la ingo, povos konektiĝi al la Tarantulo.

Ĉi tiu metodo estas necesa por administraj aferoj. Por labori kun datumoj, uzu la duan metodon - la binaran protokolon.

2. Uzante binaran protokolon por konekti al specifa haveno

Estas aŭskulta direktivo en la agordo, kiu malfermas la havenon por eksteraj komunikadoj. Ĉi tiu haveno estas uzata kun binara protokolo kaj aŭtentigo estas ebligita tie.

Por ĉi tiu konekto, tarantoolctl connect to haveno numero estas uzata. Uzante ĝin, vi povas konektiĝi al foraj serviloj, uzi aŭtentikigon kaj doni diversajn alirrajtojn.

Datuma Registrado kaj Skatolo-Modulo

Ĉar Tarantool estas kaj datumbazo kaj aplikaĵoservilo, ĝi havas diversajn modulojn. Ni interesiĝas pri la kestomodulo - ĝi efektivigas laboron kun datumoj. Kiam vi skribas ion al skatolo, Tarantool skribas la datumojn al disko, konservas ĝin en memoro aŭ faras ion alian kun ĝi.

Registrado

Ekzemple, ni eniras la skatolan modulon kaj vokas la funkcion box.once. Ĝi devigos Tarantool ruli nian kodon kiam la servilo estas pravigita. Ni kreas spacon, kie niaj datumoj estos konservitaj.

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

Post tio, ni kreas primaran indekson - primaran - per kiu ni povas serĉi datumojn. Defaŭlte, se neniuj parametroj estas specifitaj, la unua kampo en ĉiu eniro por la komenca indekso estos uzata.

Poste ni donas subvencion al la gasto-uzanto, sub kiu ni konektas per binara protokolo. Ni permesas legi, skribi kaj ekzekuti en la tuta kazo.

Kompare kun konvenciaj datumbazoj, ĉio estas sufiĉe simpla ĉi tie. Ni havas spacon - areo en kiu niaj datumoj simple estas stokitaj. Ĉiu eniro estas nomita opo. Ĝi estas pakita en MessagePack. Ĉi tio estas tre bonega formato - ĝi estas duuma kaj okupas malpli da spaco - 18 bajtoj kontraŭ 27.

En Tarantool, vi povas kombini superrapidan datumbazon kaj aplikaĵon por labori kun ili. Jen kiel facile ĝi estas fari

Estas sufiĉe oportune labori kun li. Preskaŭ ĉiu linio, ĉiu eniro de datumoj povas havi tute malsamajn kolumnojn.

Ni povas vidi ĉiujn spacojn uzante la komandon Box.space. Por elekti specifan okazon, ni skribas box.space ekzemplon kaj ricevas plenajn informojn pri ĝi.

Estas du specoj de motoroj konstruitaj en Tarantool: Memoro kaj Vinilo. Memoro konservas ĉiujn datumojn en memoro. Tial ĉio funkcias simple kaj rapide. La datumoj estas forĵetitaj al disko, kaj ankaŭ ekzistas skriba antaŭregistra mekanismo, do ni nenion perdos se la servilo kraŝos.

Vinilo stokas datumojn sur disko en pli konata formo - tio estas, vi povas konservi pli da datumoj ol ni havas memoron, kaj Tarantula legos ĝin el disko.

Nun ni uzos Memoron.

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>

Indekso:

Primara indekso devas esti kreita por iu ajn spaco, ĉar nenio funkcios sen ĝi. Kiel en ĉiu datumbazo, ni kreas la unuan kampon - la rekordan ID.

Partoj:

Jen kie ni precizigas, el kio konsistas nia indekso. Ĝi konsistas el unu parto - la unua kampo, kiun ni uzos, tajpu sensigna - pozitiva entjero. Kiom mi memoras el la dokumentado, la maksimuma nombro kiu povas esti estas 18 kvintilionoj. Multe mirindaj.

Ni tiam povas enmeti datumojn uzante la enmeti komandon.

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>

La unua kampo estas uzata kiel ĉefa ŝlosilo, do ĝi devas esti unika. Ni ne estas limigitaj de la nombro da kolumnoj, do ni povas enmeti tiom da datumoj kiom ni volas tie. Ili estas specifitaj en la formato MessagePack, kiun mi priskribis supre.

Eligo de datumoj

Tiam ni povas montri la datumojn per la elekta komando.

Skatolo.ekzemplo.elekto per la klavo {1} montros la deziratan enskribon. Se ni preterlasas la ŝlosilon, ni vidos ĉiujn registrojn, kiujn ni havas. Ili ĉiuj estas malsamaj laŭ la nombro da kolumnoj, sed ĉi tie, principe, ne ekzistas koncepto de kolumnoj - estas kampaj nombroj.

Povas ekzisti absolute tiom da datumoj kiom vi ŝatas. Kaj ekzemple, ni devas serĉi ilin en la dua kampo. Por fari tion, ni faras novan sekundaran indekson.


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

Ni uzas la komandon Create_index.
Ni nomas ĝin Sekundara.

Post tio, vi devas specifi la parametrojn. La indeksa tipo estas ARBO. Ĝi eble ne estas unika, do ni eniras Unique = malvera.

Tiam ni indikas el kiuj partoj konsistas nia indekso. Kampo estas la nombro de la kampo al kiu ni ligas la indekson, kaj specifas la ĉenspecon. Kaj tiel ĝi estis kreita.

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>

Nun jen kiel ni povas nomi ĝin:

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

konservo

Se ni rekomencas la instancon kaj provos voki la datumojn denove, ni vidos, ke ili ne estas tie - ĉio estas malplena. Ĉi tio okazas ĉar Tarantool faras kontrolpunktojn kaj konservas la datumojn sur disko, sed se ni ĉesos labori antaŭ la sekva konservado, ni perdos ĉiujn operaciojn - ĉar ni resaniĝos de la lasta kontrolpunkto, kiu estis, ekzemple, antaŭ du horoj.

Ŝpari ĉiun sekundon ankaŭ ne funkcios - ĉar konstante forĵeti 20 GB al disko estas tiel tiel ideo.

Por tio, la koncepto de skrib-antaŭa protokolo estis inventita kaj efektivigita. Kun ĝia helpo, por ĉiu ŝanĝo en la datumoj, rekordo estas kreita en malgranda skriba protokolo-dosiero.

Ĉiu eniro ĝis la transirejo estas konservita en ili. Por ĉi tiuj dosieroj, ni fiksas la grandecon - ekzemple 64 mb. Kiam ĝi pleniĝas, la registrado komencas iri al la dua dosiero. Kaj post la rekomenco, Tarantool resaniĝas de la lasta kontrolpunkto kaj poste ruliĝas super ĉiuj postaj transakcioj ĝis ĝi ĉesas.

En Tarantool, vi povas kombini superrapidan datumbazon kaj aplikaĵon por labori kun ili. Jen kiel facile ĝi estas fari

Por fari tian registradon, vi devas specifi opcion en la agordoj box.cfg (en la dosiero example.lua):

wal_mode = “write”;

uzado de datumoj

Kun tio, kion ni skribis nun, vi povas uzi la Tarantulon por stoki datumojn kaj ĝi funkcios tre rapide kiel datumbazo. Kaj nun la ĉerizo sur la kuko - kion vi povas fari kun ĉio.

Skribante aplikaĵon

Ekzemple, ni skribu tian aplikaĵon por la Tarantulo

Vidu la aplikon sub la 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()

Ni deklaras ian tabelon en lua qua difinas simboloj. Ĉi tiu tabelo estas bezonata por generi hazardan ĉenon.

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

Post tio, ni deklaras funkcion - randomString kaj donas la longovaloron inter krampoj.

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

Poste ni konektas la http-enkursigilon kaj http-servilon al nia Tarantula servilo, JSON, kiun ni donos al la kliento.

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

Post tio, ni komencas sur la haveno 8080 sur ĉiuj http-servilaj interfacoj, kiuj ensalutos ĉiujn petojn kaj erarojn.

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

Poste, ni deklaras itineron, ke se peto kun la GET-metodo alvenas al la haveno 8080 /count, tiam ni vokas la funkcion de unu linio. Ĝi resendas statuson - 200, 404, 403 aŭ kion ajn ni specifas.

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

En la korpo, ni resendas json.encode, ni specifas count kaj getcount en ĝi, kiu estas nomita kaj montras la nombron da registroj en nia datumbazo.

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

Kie en la linio router:route({metodo = 'GET', vojo = '/token'}, funkcio () ni nomas la funkcion kaj generas ĵetonon.

Linio loka signo = randomString (32) estas hazarda ĉeno de 32 signoj.
En linio loka lasta = kesto.spaco.ekzemplo:len() ni eltiras la lastan elementon.
Kaj en la linio box.space.example:enmeti{ lasta + 1, signo } ni skribas la datumojn al nia datumbazo, tio estas, ni simple pliigas la ID per 1. Ĉi tio povas esti farita, cetere, ne nur tiel mallerte. Tarantulo havas sekvencojn por ĉi tiu kazo.

Ni skribas la ĵetonon tie.

Tiel, ni skribis aplikaĵon en unu dosiero. Vi povas aliri la datumojn tuj, kaj la kestomodulo faros la tutan malpuran laboron por vi.

Ĝi aŭskultas http kaj funkcias kun datumoj, ĉio estas en ununura kazo - kaj la aplikaĵo kaj la datumoj. Tial ĉio okazas sufiĉe rapide.

Por funkcii, ni instalas la http-modulon:

Kiel ni faras ĝin, vidu sub la 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:/#

Ni ankaŭ bezonas Prometeon por kuri:

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

Ni komencas kaj povas aliri modulojn

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

/kalkulo donas al ni statuson 200.
/token eldonas ĵetonon kaj skribas ĉi tiun ĵetonon al la datumbazo.

Prova rapideco

Ni faru komparnormon por 50 000 demandoj. Konkurencaj petoj estos 500.

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

Tokens estas eldonitaj. Kaj ni konstante registras datumojn. 99% de petoj estis kompletigitaj en 42 milisekundoj. Sekve, ni havas ĉirkaŭ 3500 petojn sekundo sur malgranda maŝino, kie estas 2 kernoj kaj 4 gigabajtoj da memoro.

Vi ankaŭ povas elekti 50000-ĵetonon kaj vidi ĝian valoron.

Vi povas uzi ne nur http, ruli fonajn funkciojn, kiuj prilaboras viajn datumojn. Krome estas diversaj ellasiloj. Ekzemple, vi povas voki funkciojn pri ĝisdatigoj, kontroli ion - ripari konfliktojn.

Vi povas skribi skripto-aplikaĵojn rekte en la datumbaza servilo mem, kaj ne esti limigita de io ajn, konekti iujn ajn modulojn kaj efektivigi ajnan logikon.

La aplikaĵoservilo povas aliri eksterajn servilojn, kolekti datumojn kaj aldoni ĝin al sia datumbazo. Datumoj de ĉi tiu datumbazo estos uzataj de aliaj aplikoj.

Ĉi tio estos farita de la Tarantulo mem, kaj ne necesas skribi apartan aplikaĵon.

En konkludo

Ĉi tio estas nur la unua parto de granda laboro. La dua estos publikigita tre baldaŭ en la blogo de Mail.ru Group, kaj ni certe aldonos ligilon al ĝi en ĉi tiu artikolo.

Se vi interesiĝas ĉeesti eventojn, kie ni kreas ĉi tiujn aferojn interrete kaj demandi demandojn en reala tempo, konektu al DevOps per kanalo REBRAIN.

Se vi bezonas translokiĝi al la nubo aŭ havas demandojn pri via infrastrukturo, Bonvolu sendi peton.

PS Ni havas 2 senpagajn reviziojn monate, eble via projekto estos unu el ili.

fonto: www.habr.com

Aldoni komenton