Sa Tarantool, maaari mong pagsamahin ang isang napakabilis na database at isang application upang gumana sa kanila. Narito kung gaano kadali itong gawin

Limang taon na ang nakalilipas sinubukan kong magtrabaho sa Tarantool, ngunit pagkatapos ay hindi ito gumana para sa akin. Ngunit kamakailan lamang ay nagsagawa ako ng webinar kung saan pinag-usapan ko ang tungkol sa Hadoop at kung paano gumagana ang MapReduce. Doon ay tinanong nila ako: "Bakit hindi gamitin ang Tarantool para sa gawaing ito?"

Dahil sa pag-usisa, nagpasya akong bumalik dito, subukan ang pinakabagong bersyon - at sa pagkakataong ito ay talagang nagustuhan ko ang proyekto. Ngayon ay ipapakita ko sa iyo kung paano magsulat ng isang simpleng application sa Tarantool, i-load ito at suriin ang pagganap nito, at makikita mo kung gaano kadali at cool ang lahat.

Sa Tarantool, maaari mong pagsamahin ang isang napakabilis na database at isang application upang gumana sa kanila. Narito kung gaano kadali itong gawin

Ano ang Tarantool

Pinoposisyon ng Tarantool ang sarili bilang isang napakabilis na database. Maaari mong ilagay ang anumang data na gusto mo doon. Dagdag pa, gayahin ang mga ito, shard - iyon ay, hatiin ang isang malaking halaga ng data sa ilang mga server at pagsamahin ang mga resulta mula sa kanila - gumawa ng fault-tolerant master-master na koneksyon.

Pangalawa, ito ay isang application server. Maaari mong isulat ang iyong mga application dito, magtrabaho kasama ang data, halimbawa, tanggalin ang mga lumang tala sa background ayon sa ilang mga patakaran. Maaari kang magsulat ng isang Http server nang direkta sa Tarantula na gagana sa data: ibigay ang kanilang dami, magsulat ng bagong data doon at bawasan ang lahat ng ito sa master.

Nabasa ko ang isang artikulo tungkol sa kung paano gumawa ang mga lalaki ng isang pila ng mensahe na 300 linya, na simpleng pumuputok at nagmamadali - mayroon silang minimum na pagganap na 20 mga mensahe bawat segundo. Dito maaari ka talagang tumalikod at magsulat ng isang napakalaking application, at hindi ito magiging storage, tulad ng sa PostgreS.

Susubukan kong ilarawan ang isang bagay tulad ng server na ito, simple lamang, sa artikulong ito.

Instalasyon

Para sa pagsubok, nagsimula ako ng tatlong karaniwang virtual machine - isang 20 GB hard drive, Ubuntu 18.04. 2 virtual na CPU at 4 na gig ng memorya.

Nag-i-install kami ng Tarantool - patakbuhin ang script ng bash o magdagdag ng isang repository at apt makakuha ng pag-install ng Tarantool. Link sa script - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Mayroon kaming mga utos tulad ng:

tarantoolctl — ang pangunahing utos para sa pamamahala ng mga pagkakataon ng Tarantula.
/etc/tarantool - narito ang buong configuration.
var/log/tarantool - narito ang mga tala.
var/lib/tarantool — ang data ay namamalagi dito, at pagkatapos ay nahahati ito sa mga pagkakataon.

May mga folder na instance-available at instance-enable - naglalaman ito ng kung ano ang ilulunsad - isang instance configuration file na may lua code, na naglalarawan kung saang port ito pinakikinggan, anong memory ang available dito, Vinyl engine settings, code na tumatakbo sa startup server, sharding, queues, pagtanggal ng hindi na ginagamit na data, at iba pa.

Gumagana ang mga pagkakataon tulad ng sa PostgreS. Halimbawa, gusto mong magpatakbo ng ilang kopya ng isang database na nakabitin sa iba't ibang port. Lumalabas na maraming mga database instance ang inilunsad sa isang server, na nakabitin sa iba't ibang port. Maaaring mayroon silang ganap na magkakaibang mga setting - ang isang pagkakataon ay nagpapatupad ng isang lohika, ang pangalawa - isa pa.

Pamamahala ng halimbawa

Mayroon kaming tarantoolctl command, na nagbibigay-daan sa iyo na pamahalaan ang mga pagkakataon ng Tarantula. Halimbawa, susuriin ng halimbawa ng tarantoolctl check ang configuration file at sasabihin - ok ang file kung walang mga syntax error doon.

Makikita mo ang status ng instance - halimbawa ng status ng tarantoolctl. Sa parehong paraan maaari mong simulan, ihinto, i-restart.

Kapag tumatakbo na ang instance, maaari kang kumonekta dito sa dalawang paraan.

1. Administrative console

Bilang default, ang Tarantool ay nagbubukas ng socket, ang normal na ASCII na teksto ay ipinadala doon upang kontrolin ang Tarantool. Ang koneksyon sa console ay palaging nangyayari sa ilalim ng admin user, walang pagpapatunay, kaya hindi na kailangang i-externalize ang console port upang pamahalaan ang Tarantula.

Upang kumonekta gamit ang paraang ito, kailangan mong ipasok ang Tarantoolctl enter instance name. Ilulunsad ng command ang console at kumonekta bilang admin user. Huwag kailanman ilantad ang console port sa labas - mas mahusay na iwanan ito bilang isang socket ng yunit. Kung gayon ang mga may access lamang na sumulat sa socket ang makakakonekta sa Tarantula.

Ang pamamaraang ito ay kailangan para sa mga bagay na pang-administratibo. Upang gumana sa data, gamitin ang pangalawang paraan - ang binary protocol.

2. Paggamit ng binary protocol para kumonekta sa isang partikular na port

Naglalaman ang configuration ng listen directive, na nagbubukas ng port para sa mga panlabas na komunikasyon. Ang port na ito ay ginagamit sa binary protocol at ang pagpapatunay ay pinagana doon.

Para sa koneksyon na ito, ginagamit ang tarantoolctl connect sa port number. Gamit ito, maaari kang kumonekta sa mga malalayong server, gumamit ng pagpapatunay at magbigay ng iba't ibang mga karapatan sa pag-access.

Pag-record ng Data at Box Module

Dahil ang Tarantool ay parehong database at application server, mayroon itong iba't ibang mga module. Interesado kami sa module ng kahon - ipinapatupad nito ang pagtatrabaho sa data. Kapag sumulat ka ng isang bagay sa kahon, isinusulat ng Tarantool ang data sa disk, iniimbak ito sa memorya, o may iba pang ginagawa dito.

Talaan

Halimbawa, pumunta kami sa box module at tawagan ang box.once function. Pipilitin nito ang Tarantool na patakbuhin ang aming code kapag nasimulan ang server. Lumilikha kami ng puwang kung saan iimbak ang aming data.

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

Pagkatapos nito, lumikha kami ng pangunahing index - pangunahin - kung saan maaari kaming maghanap ng data. Bilang default, kung hindi ka tumukoy ng anumang mga parameter, ang unang field sa bawat tala ay gagamitin para sa pangunahing index.

Pagkatapos ay gagawa kami ng grant sa guest user, kung saan kami kumonekta sa pamamagitan ng binary protocol. Pinapayagan namin ang pagbabasa, pagsusulat at pagpapatupad sa buong instance.

Kung ikukumpara sa mga nakasanayang database, ang lahat dito ay medyo simple. Mayroon kaming espasyo - isang lugar kung saan naka-imbak ang aming data. Ang bawat tala ay tinatawag na tuple. Ito ay nakabalot sa MessagePack. Ito ay isang napaka-cool na format - ito ay binary at tumatagal ng mas kaunting espasyo - 18 bytes kumpara sa 27.

Sa Tarantool, maaari mong pagsamahin ang isang napakabilis na database at isang application upang gumana sa kanila. Narito kung gaano kadali itong gawin

Medyo maginhawang magtrabaho kasama siya. Halos bawat linya, bawat talaan ng data ay maaaring magkaroon ng ganap na magkakaibang mga column.

Maaari naming tingnan ang lahat ng mga puwang gamit ang Box.space na utos. Para pumili ng partikular na instance, sumulat ng halimbawa ng box.space at kumuha ng kumpletong impormasyon tungkol dito.

Ang Tarantool ay may dalawang built-in na makina: Memory at Vinyl. Iniimbak ng memorya ang lahat ng data sa memorya. Samakatuwid, ang lahat ay gumagana nang simple at mabilis. Ang data ay itinapon sa disk, at mayroon ding write ahead log mechanism, kaya wala tayong mawawala kung mag-crash ang server.

Ang vinyl ay nag-iimbak ng data sa disk sa isang form na mas pamilyar sa amin - iyon ay, maaari kang mag-imbak ng higit pang data kaysa sa memorya namin, at babasahin ito ng Tarantula mula sa disk.

Sa ngayon ay gagamitin namin ang 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:

Ang isang pangunahing index ay dapat malikha para sa anumang espasyo, dahil kung wala ito walang gagana. Tulad ng sa anumang database, lumikha kami ng unang field - record ID.

Bahagi:

Dito ipinapahiwatig namin kung ano ang binubuo ng aming index. Binubuo ito ng isang bahagi - ang unang field na gagamitin namin ay may uri na unsigned - isang positive integer. Sa pagkakatanda ko mula sa dokumentasyon, ang maximum na bilang na maaaring maging ay 18 quintillion. Marami iyon.

Pagkatapos ay maaari tayong magpasok ng data gamit ang insert command.

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>

Ang unang field ay ginagamit bilang pangunahing susi, kaya dapat ito ay natatangi. Hindi kami nililimitahan ng bilang ng mga column, kaya maaari kaming magpasok ng maraming data hangga't gusto namin doon. Tinukoy ang mga ito sa format na MessagePack, na inilarawan ko sa itaas.

Output ng data

Pagkatapos ay maaari naming ipakita ang data gamit ang piliin na utos.

Box.example.select gamit ang {1} key ay magpapakita ng gustong entry. Kung ibababa natin ang susi, makikita natin ang lahat ng mga talaan na mayroon tayo. Lahat sila ay naiiba sa bilang ng mga haligi, ngunit dito, sa prinsipyo, walang konsepto ng mga haligi - mayroong mga numero ng field.

Maaaring mayroong ganap na anumang dami ng data. At halimbawa, kailangan nating hanapin ang mga ito sa pangalawang field. Para magawa ito, gumawa kami ng bagong pangalawang index.


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

Ginagamit namin ang utos na Create_index.
Tawagin natin itong Secondary.

Pagkatapos nito kailangan mong tukuyin ang mga parameter. Ang uri ng index ay TREE. Maaaring hindi ito natatangi, kaya ilagay ang Unique = false.

Pagkatapos ay ipinapahiwatig namin kung anong mga bahagi ang binubuo ng aming index. Ang patlang ay ang bilang ng patlang kung saan ibinubuklod namin ang index, at tinukoy ang uri ng string. At kaya ito ay nilikha.

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>

Ngayon ito ay kung paano natin ito matatawag:

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

Pangangalaga

Kung i-restart namin ang instance at subukang tawagan muli ang data, makikita namin na wala ito doon - lahat ay walang laman. Nangyayari ito dahil gumagawa ang Tarantool ng mga checkpoint at sine-save ang data sa disk, ngunit kung hihinto kami sa pagtatrabaho hanggang sa susunod na pag-save, mawawala ang lahat ng operasyon - dahil babawi kami mula sa huling checkpoint, na, halimbawa, dalawang oras na ang nakalipas.

Hindi rin gagana ang pag-save ng bawat segundo, dahil hindi magandang ideya ang patuloy na pagtatapon ng 20 GB sa disk.

Para sa layuning ito, naimbento at ipinatupad ang konsepto ng write-ahead log. Sa tulong nito, para sa bawat pagbabago sa data, isang entry ay nilikha sa isang maliit na write-ahead log file.

Ang bawat entry hanggang sa checkpoint ay naka-imbak sa kanila. Para sa mga file na ito, itinakda namin ang laki - halimbawa, 64 MB. Kapag puno na ito, magsisimulang mapunta ang pagre-record sa pangalawang file. At pagkatapos ng pag-restart, ang Tarantool ay naibalik mula sa huling checkpoint at pagkatapos ay i-roll sa lahat ng susunod na transaksyon hanggang sa ito ay huminto.

Sa Tarantool, maaari mong pagsamahin ang isang napakabilis na database at isang application upang gumana sa kanila. Narito kung gaano kadali itong gawin

Upang maisagawa ang naturang pag-record, kailangan mong tukuyin ang opsyon sa mga setting ng box.cfg (sa example.lua file):

wal_mode = “write”;

paggamit ng data

Sa kung ano ang isinulat namin ngayon, maaari mong gamitin ang Tarantula upang mag-imbak ng data at ito ay gagana nang napakabilis bilang isang database. At ngayon ang icing sa cake ay kung ano ang maaari mong gawin sa lahat ng ito.

Pagsusulat ng aplikasyon

Halimbawa, isulat natin ang sumusunod na aplikasyon para sa Tarantula

Tingnan ang application sa ilalim ng 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()

Idineklara namin ang ilang talahanayan sa lua na tumutukoy sa mga character. Ang plate na ito ay kinakailangan upang makabuo ng isang random na 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

Pagkatapos nito, ipinapahayag namin ang function - randomString at ibigay ang halaga ng haba sa mga panaklong.

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

Pagkatapos ay ikinonekta namin ang http router at http server sa aming Tarantula server, JSON, na ipapadala namin sa kliyente.

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

Pagkatapos nito, magsisimula kami sa port 8080 sa lahat ng interface ng http server, na magla-log sa lahat ng mga kahilingan at error.

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

Susunod, idineklara namin ang ruta, upang kung ang isang kahilingan na may pamamaraang GET ay dumating sa port 8080 /count, pagkatapos ay tatawagan namin ang function mula sa isang linya. Ibinabalik nito ang katayuan - 200, 404, 403 o anumang iba pang tinukoy namin.

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

Sa katawan ibinabalik namin ang json.encode, dito ipinapahiwatig namin ang count at getcount, na tinatawag at nagpapakita ng bilang ng mga tala sa aming database.

Ikalawang paraan

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)

Kung saan sa linya router:route({method = 'GET', path = '/token'}, function() tinatawag namin ang function at bumuo ng isang token.

Linya lokal na token = randomString(32) ay isang random na string ng 32 character.
Nasa linya lokal na huling = box.space.example:len() inalis namin ang huling elemento.
At sa linya box.space.example:insert{ last + 1, token } isinusulat namin ang data sa aming database, ibig sabihin, dinadagdagan lang namin ang ID ng 1. Ito ay maaaring gawin, sa pamamagitan ng paraan, hindi lamang sa ganitong clumsy na paraan. May mga sequence para dito sa Tarantula.

Sinusulat namin ang token doon.

Kaya, isinulat namin ang application sa isang file. Maaari mong direktang manipulahin ang data doon, at gagawin ng box module ang lahat ng maruming gawain para sa iyo.

Nakikinig ito sa http at gumagana sa data, ang lahat ay nasa isang pagkakataon - pareho ang application at ang data. Samakatuwid, ang lahat ay nangyayari nang mabilis.

Upang magsimula, i-install namin ang http module:

Kung paano natin ito gagawin, tingnan sa ilalim ng 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:/#

Kailangan din namin ang prometheus upang tumakbo:

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

Inilunsad namin at maaaring ma-access ang mga module

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"e2tPq9l5Z3QZrewRf6uuoJUl3lJgSLOI"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"fR5aCA84gj9eZI3gJcV0LEDl9XZAG2Iu"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/count
HTTP/1.1 200 Ok
Content-length: 11
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"count":2}root@test2:/#

Ang /count ay nagbibigay sa amin ng katayuan na 200.
Ang /token ay naglalabas ng token at isinusulat ang token na ito sa database.

Bilis ng pagsubok

Magpatakbo tayo ng benchmark para sa 50 kahilingan. Magkakaroon ng 000 nakikipagkumpitensyang kahilingan.

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

Ang mga token ay ibinibigay. At patuloy kaming nagre-record ng data. 99% ng mga kahilingan ay naproseso sa 42 millisecond. Alinsunod dito, mayroon kaming humigit-kumulang 3500 na kahilingan bawat segundo sa isang maliit na makina na may 2 core at 4 na gigabytes ng memorya.

Maaari ka ring pumili ng mga 50000 token at makita ang halaga nito.

Maaari mong gamitin hindi lamang ang http, ngunit magpatakbo din ng mga function sa background na nagpoproseso ng iyong data. Dagdag pa, mayroong iba't ibang mga pag-trigger. Halimbawa, maaari kang tumawag sa mga function sa mga update, suriin ang isang bagay - mga tamang salungatan.

Maaari kang magsulat ng mga application ng script nang direkta sa database server mismo, at hindi limitado sa anumang bagay, ikonekta ang anumang mga module at ipatupad ang anumang lohika.

Maaaring ma-access ng server ng application ang mga panlabas na server, kunin ang data at idagdag ito sa database nito. Ang data mula sa database na ito ay gagamitin ng iba pang mga application.

Gagawin ito ng Tarantula mismo, at hindi mo na kailangang magsulat ng isang hiwalay na aplikasyon.

Sa pagtatapos

Ito ay unang bahagi lamang ng isang malaking gawain. Ang pangalawa ay mai-publish sa lalong madaling panahon sa Mail.ru Group blog, at tiyak na magdaragdag kami ng isang link dito sa materyal na ito.

Kung interesado kang dumalo sa mga kaganapan kung saan binubuo namin ang mga bagay na ito online at nagtatanong nang real time, tumutok channel ng DevOps ng REBRAIN.

Kung kailangan mong lumipat sa cloud o may mga tanong tungkol sa iyong imprastraktura, huwag mag-atubiling mag-iwan ng kahilingan.

PS Mayroon kaming 2 libreng pag-audit bawat buwan, marahil ang iyong proyekto ay isa sa kanila.

Pinagmulan: www.habr.com

Magdagdag ng komento