Në Tarantool, ju mund të kombinoni një bazë të dhënash super të shpejtë dhe një aplikacion për të punuar me ta. Ja sa e lehtë është të bëhet

Pesë vjet më parë u përpoqa të punoja me Tarantool, por më pas nuk funksionoi për mua. Por kohët e fundit mbajta një webinar ku fola për Hadoop dhe si funksionon MapReduce. Atje më bënë një pyetje: "Pse të mos përdor Tarantool për këtë detyrë?"

Nga kurioziteti, vendosa t'i kthehem, të testoj versionin e fundit - dhe këtë herë më pëlqeu shumë projekti. Tani do t'ju tregoj se si të shkruani një aplikacion të thjeshtë në Tarantool, ta ngarkoni dhe kontrolloni performancën e tij dhe do të shihni se sa e lehtë dhe e lezetshme është gjithçka.

Në Tarantool, ju mund të kombinoni një bazë të dhënash super të shpejtë dhe një aplikacion për të punuar me ta. Ja sa e lehtë është të bëhet

Çfarë është Tarantool

Tarantool pozicionohet si një bazë të dhënash ultra e shpejtë. Ju mund të vendosni çdo të dhënë që dëshironi atje. Plus, replikojini ato, shard - domethënë, ndani një sasi të madhe të dhënash në disa serverë dhe kombinoni rezultatet prej tyre - krijoni lidhje master-master tolerante ndaj gabimeve.

Së dyti, ky është një server aplikacioni. Ju mund të shkruani aplikacionet tuaja në të, të punoni me të dhëna, për shembull, të fshini regjistrimet e vjetra në sfond sipas rregullave të caktuara. Ju mund të shkruani një server Http direkt në Tarantula që do të punojë me të dhënat: jepni sasinë e tyre, shkruani të dhëna të reja atje dhe reduktoni të gjitha në master.

Kam lexuar një artikull se si djemtë kanë krijuar një radhë mesazhesh prej 300 rreshtash, e cila thjesht shpërthen dhe nxiton - ata kanë një performancë minimale prej 20 mesazhesh në sekondë. Këtu mund të ktheheni vërtet dhe të shkruani një aplikacion shumë të madh, dhe nuk do të jetë memorie, si në PostgreS.

Do të përpiqem të përshkruaj diçka të tillë si ky server, vetëm i thjeshtë, në këtë artikull.

Instalim

Për provën, fillova tre makina virtuale standarde - një hard disk 20 GB, Ubuntu 18.04. 2 CPU virtuale dhe 4 giga memorie.

Ne instalojmë Tarantool - ekzekutojmë skriptin bash ose shtojmë një depo dhe bëjmë me vend instalimin e Tarantool. Lidhja me skriptin - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Ne kemi komanda të tilla si:

tarantoolctl — komanda kryesore për menaxhimin e rasteve të Tarantula.
/etc/tarantool - këtu është i gjithë konfigurimi.
var/log/tarantool - këtu janë shkrimet.
var/lib/tarantool — të dhënat qëndrojnë këtu dhe më pas ndahen në instanca.

Ka dosje të disponueshme dhe instance-enable - përmban atë që do të hapet - një skedar konfigurimi shembulli me kodin lua, i cili përshkruan në cilat porta dëgjon, çfarë memorie është në dispozicion për të, cilësimet e motorit Vinyl, kodi që funksionon në fillim serverët, ndarjet, radhët, fshirja e të dhënave të vjetruara, e kështu me radhë.

Instancat funksionojnë si në PostgreS. Për shembull, ju dëshironi të ekzekutoni disa kopje të një baze të dhënash që varet në porte të ndryshme. Rezulton se disa raste të bazës së të dhënave janë nisur në një server, të cilat varen në porte të ndryshme. Ata mund të kenë cilësime krejtësisht të ndryshme - një shembull zbaton një logjikë, e dyta - një tjetër.

Menaxhimi i shembullit

Ne kemi komandën tarantoolctl, e cila ju lejon të menaxhoni instancat e Tarantula. Për shembull, shembulli i kontrollit tarantoolctl do të kontrollojë skedarin e konfigurimit dhe do të thotë - skedari është në rregull nëse nuk ka gabime sintaksore atje.

Ju mund të shihni statusin e shembullit - shembulli i statusit tarantoolctl. Në të njëjtën mënyrë mund të bëni start, stop, restart.

Pasi shembulli të funksionojë, mund të lidheni me të në dy mënyra.

1. Konsola administrative

Si parazgjedhje, Tarantool hap një fole, teksti normal ASCII dërgohet atje për të kontrolluar Tarantool. Lidhja me tastierën ndodh gjithmonë nën përdoruesin e administratorit, nuk ka vërtetim, kështu që nuk ka nevojë të ekzistojë porti i konsolës për të menaxhuar Tarantula.

Për t'u lidhur duke përdorur këtë metodë, duhet të futni emrin e shembullit Tarantoolctl. Komanda do të nisë konsolën dhe do të lidhet si përdorues administratori. Asnjëherë mos e ekspozoni portin e konsolës nga jashtë - është më mirë ta lini atë si një prizë njësie. Atëherë vetëm ata që kanë akses për të shkruar në prizë do të mund të lidhen me Tarantula.

Kjo metodë është e nevojshme për gjërat administrative. Për të punuar me të dhëna, përdorni metodën e dytë - protokollin binar.

2. Përdorimi i një protokolli binar për t'u lidhur me një port specifik

Konfigurimi përmban një direktivë dëgjimi, e cila hap një port për komunikime të jashtme. Ky port përdoret me protokollin binar dhe autentikimi aktivizohet atje.

Për këtë lidhje, përdoret tarantoolctl connect me numrin e portit. Duke e përdorur atë, mund të lidheni me serverë të largët, të përdorni vërtetimin dhe të jepni të drejta të ndryshme aksesi.

Regjistrimi i të dhënave dhe moduli i kutisë

Meqenëse Tarantool është njëkohësisht një bazë të dhënash dhe një server aplikacioni, ai ka module të ndryshme. Ne jemi të interesuar për modulin e kutisë - ai zbaton punën me të dhëna. Kur shkruani diçka në kuti, Tarantool i shkruan të dhënat në disk, i ruan ato në memorie ose bën diçka tjetër me të.

Rekord

Për shembull, ne hyjmë në modulin e kutisë dhe thërrasim funksionin box.once. Kjo do të detyrojë Tarantool të ekzekutojë kodin tonë kur serveri të inicializohet. Ne krijojmë një hapësirë ​​në të cilën do të ruhen të dhënat tona.

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

Pas kësaj, ne krijojmë një indeks primar - primar - me të cilin mund të kërkojmë të dhëna. Si parazgjedhje, nëse nuk specifikoni asnjë parametër, fusha e parë në çdo rekord do të përdoret për indeksin primar.

Më pas ne i bëjmë një grant përdoruesit mysafir, sipas të cilit lidhemi nëpërmjet protokollit binar. Ne lejojmë leximin, shkrimin dhe ekzekutimin në të gjithë shembullin.

Krahasuar me bazat e të dhënave konvencionale, gjithçka këtu është mjaft e thjeshtë. Ne kemi hapësirë ​​- një zonë në të cilën të dhënat tona thjesht ruhen. Çdo rekord quhet tuple. Është paketuar në MessagePack. Ky është një format shumë i lezetshëm - është binar dhe merr më pak hapësirë ​​- 18 bajt kundrejt 27.

Në Tarantool, ju mund të kombinoni një bazë të dhënash super të shpejtë dhe një aplikacion për të punuar me ta. Ja sa e lehtë është të bëhet

Është mjaft e përshtatshme të punosh me të. Pothuajse çdo rresht, çdo regjistrim i të dhënave mund të ketë kolona krejtësisht të ndryshme.

Ne mund t'i shohim të gjitha hapësirat duke përdorur komandën Box.space. Për të zgjedhur një shembull specifik, shkruani shembull box.space dhe merrni informacion të plotë rreth tij.

Tarantool ka dy motorë të integruar: Memory dhe Vinyl. Memoria ruan të gjitha të dhënat në memorie. Prandaj, gjithçka funksionon thjesht dhe shpejt. Të dhënat hidhen në disk dhe ekziston gjithashtu një mekanizëm i regjistrit të shkrimit përpara, kështu që nuk do të humbasim asgjë nëse serveri prishet.

Vinyl ruan të dhënat në disk në një formë më të njohur për ne - domethënë, ju mund të ruani më shumë të dhëna sesa kemi memorie, dhe Tarantula do t'i lexojë ato nga disku.

Tani për tani ne do të përdorim 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>

Indeksi:

Duhet të krijohet një indeks primar për çdo hapësirë, sepse pa të asgjë nuk do të funksionojë. Si në çdo bazë të dhënash, ne krijojmë fushën e parë - ID e regjistrimit.

Pjesë:

Këtu tregojmë se nga çfarë përbëhet indeksi ynë. Ai përbëhet nga një pjesë - fusha e parë që do të përdorim është e llojit të panënshkruar - një numër i plotë pozitiv. Me sa mbaj mend nga dokumentacioni, numri maksimal që mund të jetë është 18 kuintilion. Eshte shume.

Më pas mund të fusim të dhëna duke përdorur komandën 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>

Fusha e parë përdoret si çelësi kryesor, prandaj duhet të jetë unik. Ne nuk jemi të kufizuar nga numri i kolonave, kështu që mund të fusim sa të dhëna të duam atje. Ato janë të specifikuara në formatin MessagePack, të cilin e përshkrova më lart.

Prodhimi i të dhënave

Më pas mund t'i shfaqim të dhënat duke përdorur komandën Select.

Box.example.select me tastin {1} do të shfaqë hyrjen e dëshiruar. Nëse e ulim çelësin, do të shohim të gjitha rekordet që kemi. Ata të gjithë ndryshojnë në numrin e kolonave, por këtu, në parim, nuk ka koncept të kolonave - ka numra fushash.

Mund të ketë absolutisht çdo sasi të dhënash. Dhe për shembull, ne duhet t'i kërkojmë ato nga fusha e dytë. Për ta bërë këtë, ne krijojmë një indeks të ri dytësor.


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

Ne përdorim komandën Create_index.
Le ta quajmë dytësore.

Pas kësaj ju duhet të specifikoni parametrat. Lloji i indeksit është PEMË. Mund të mos jetë unik, prandaj shkruani Unique = false.

Pastaj ne tregojmë se nga cilat pjesë përbëhet indeksi ynë. Fusha është numri i fushës me të cilën lidhim indeksin dhe specifikojmë llojin e vargut. Dhe kështu u krijua.

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>

Tani kështu mund ta quajmë:

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

ruajtje

Nëse e rifillojmë shembullin dhe përpiqemi të thërrasim përsëri të dhënat, do të shohim që nuk është aty - gjithçka është bosh. Kjo ndodh sepse Tarantool bën pika kontrolli dhe i ruan të dhënat në disk, por nëse ndalojmë së punuari deri në ruajtjen tjetër, do t'i humbim të gjitha operacionet - sepse do të rikuperojmë nga pika e fundit e kontrollit, e cila ishte, për shembull, dy orë më parë.

Nuk do të funksionojë as të kurseni çdo sekondë, sepse hedhja e vazhdueshme e 20 GB në disk nuk është një ide e mirë.

Për këtë qëllim, u shpik dhe u zbatua koncepti i regjistrit të shkrimit përpara. Me ndihmën e tij, për çdo ndryshim në të dhëna, krijohet një hyrje në një skedar të vogël regjistri të shkrimit përpara.

Çdo hyrje deri në pikën e kontrollit ruhet në to. Për këto skedarë ne vendosim madhësinë - për shembull, 64 MB. Kur mbushet, regjistrimi fillon të shkojë te skedari i dytë. Dhe pas rifillimit, Tarantool rikthehet nga pika e fundit e kontrollit dhe më pas kalon mbi të gjitha transaksionet e mëvonshme derisa të ndalojë.

Në Tarantool, ju mund të kombinoni një bazë të dhënash super të shpejtë dhe një aplikacion për të punuar me ta. Ja sa e lehtë është të bëhet

Për të kryer një regjistrim të tillë, duhet të specifikoni opsionin në cilësimet e box.cfg (në skedarin example.lua):

wal_mode = “write”;

përdorimi i të dhënave

Me atë që kemi shkruar tani, ju mund të përdorni Tarantula për të ruajtur të dhënat dhe do të funksionojë shumë shpejt si një bazë të dhënash. Dhe tani qershia mbi tortë është ajo që mund të bëni me të gjitha.

Shkrimi i një aplikacioni

Për shembull, le të shkruajmë aplikacionin e mëposhtëm për Tarantula

Shikoni aplikacionin nën 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()

Ne deklarojmë një tabelë në lua që përcakton karakteret. Kjo pllakë nevojitet për të krijuar një varg të rastësishëm.

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

Pas kësaj, ne deklarojmë funksionin - randomString dhe japim vlerën e gjatësisë në kllapa.

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

Më pas lidhim ruterin http dhe serverin http me serverin tonë Tarantula, JSON, të cilin do t'ia dërgojmë klientit.

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

Pas kësaj, ne fillojmë në portin 8080 në të gjitha ndërfaqet e serverit http, i cili do të regjistrojë të gjitha kërkesat dhe gabimet.

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

Më pas, ne deklarojmë rrugën, kështu që nëse një kërkesë me metodën GET arrin në portin 8080 /count, atëherë ne e thërrasim funksionin nga një linjë. Ai kthen statusin - 200, 404, 403 ose ndonjë tjetër që ne specifikojmë.

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

Në trup kthejmë json.encode, në të tregojmë count dhe getcount, i cili thirret dhe tregon numrin e regjistrimeve në bazën tonë të të dhënave.

Metoda e dytë

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)

Ku në radhë router:route({method = 'GET', shteg = '/token'}, funksion() ne thërrasim funksionin dhe gjenerojmë një shenjë.

rresht token lokal = randomString(32) është një varg i rastësishëm prej 32 karakteresh.
Në rradhë local last = box.space.example:len() nxjerrim elementin e fundit.
Dhe në rresht box.space.example:insert{ last + 1, token } ne i shkruajmë të dhënat në bazën tonë të të dhënave, domethënë thjesht e rrisim ID-në me 1. Kjo mund të bëhet, meqë ra fjala, jo vetëm në këtë mënyrë të ngathët. Ka sekuenca për këtë në Tarantula.

Ne shkruajmë shenjën atje.

Kështu, ne e kemi shkruar aplikacionin në një dosje. Ju mund të manipuloni drejtpërdrejt të dhënat atje dhe moduli i kutisë do të bëjë të gjithë punën e pistë për ju.

Ai dëgjon http dhe punon me të dhëna, gjithçka është në një shembull të vetëm - si aplikacioni ashtu edhe të dhënat. Prandaj, gjithçka ndodh mjaft shpejt.

Për të filluar instalojmë modulin http:

Si e bëjmë këtë, shikoni nën 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:/#

Ne gjithashtu kemi nevojë për Prometheus për të kandiduar:

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

Ne nisim dhe mund të aksesojmë modulet

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 na jep statusin 200.
/token lëshon një shenjë dhe e shkruan këtë shenjë në bazën e të dhënave.

Testimi i shpejtësisë

Le të bëjmë një pikë referimi për 50 kërkesa. Do të ketë 000 kërkesa konkurruese.

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

Shenjat lëshohen. Dhe ne vazhdimisht regjistrojmë të dhëna. 99% e kërkesave u përpunuan në 42 milisekonda. Prandaj, ne kemi rreth 3500 kërkesa në sekondë në një makinë të vogël me 2 bërthama dhe 4 gigabajt memorie.

Ju gjithashtu mund të zgjidhni rreth 50000 token dhe të shihni vlerën e tij.

Ju mund të përdorni jo vetëm http, por edhe funksionet e sfondit që përpunojnë të dhënat tuaja. Plus, ka nxitës të ndryshëm. Për shembull, mund të telefononi funksione në përditësime, të kontrolloni diçka - korrigjoni konfliktet.

Ju mund të shkruani aplikacione skripti direkt në vetë serverin e bazës së të dhënave, dhe të mos kufizoheni nga asgjë, të lidhni asnjë modul dhe të zbatoni çdo logjikë.

Serveri i aplikacionit mund të hyjë në serverë të jashtëm, të marrë të dhëna dhe t'i shtojë ato në bazën e të dhënave të tij. Të dhënat nga kjo bazë të dhënash do të përdoren nga aplikacione të tjera.

Tarantula do ta bëjë këtë vetë, dhe ju nuk do të duhet të shkruani një aplikim të veçantë.

Në përfundim

Kjo është vetëm pjesa e parë e një pune të madhe. E dyta do të publikohet shumë shpejt në blogun e Grupit Mail.ru, dhe ne patjetër do të shtojmë një lidhje për të në këtë material.

Nëse jeni të interesuar të merrni pjesë në ngjarje ku ne i ndërtojmë këto gjëra në internet dhe të bëni pyetje në kohë reale, akordohuni kanali DevOps nga REBRAIN.

Nëse keni nevojë të kaloni në cloud ose keni pyetje në lidhje me infrastrukturën tuaj, mos ngurroni të lini një kërkesë.

PS Ne kemi 2 auditime falas në muaj, ndoshta projekti juaj do të jetë njëri prej tyre.

Burimi: www.habr.com

Shto një koment