Tarantoolдо сиз супер тез маалымат базасын жана алар менен иштөө үчүн тиркемени айкалыштыра аласыз. Бул жерде муну жасоо канчалык оңой

Беш жыл мурун мен Тарантоол менен иштешкенге аракет кылдым, бирок андан кийин майнап чыккан жок. Бирок жакында мен вебинар өткөрдүм, анда мен Hadoop жөнүндө, MapReduce кантип иштеши жөнүндө сүйлөштүм. Ал жерде мага суроо берилди - "Эмне үчүн бул тапшырма үчүн Tarantool колдонбойт?".

Кызыгуу үчүн мен ага кайрылып, акыркы версиясын сынап көрүүнү чечтим - бул жолу долбоор мага абдан жакты. Эми мен Tarantoolдо жөнөкөй тиркемени кантип жазууну көрсөтөм, аны жүктөйм жана иштешин текшерем, ошондо сиз ал жерде бардыгы канчалык жеңил жана салкын экенин көрөсүз.

Tarantoolдо сиз супер тез маалымат базасын жана алар менен иштөө үчүн тиркемени айкалыштыра аласыз. Бул жерде муну жасоо канчалык оңой

Tarantool деген эмне

Tarantool өзүн абдан тез маалымат базасы катары көрсөтөт. Сиз каалаган маалыматты ал жерге киргизе аласыз. Мындан тышкары, аларды кайталаңыз, сынык - башкача айтканда, чоң көлөмдөгү маалыматтарды бир нече серверге бөлүп, алардын натыйжаларын бириктириңиз - катага чыдамдуу мастер-мастер шилтемелерин жасаңыз.

Экинчиден, бул колдонмо сервери. Сиз ага өзүңүздүн тиркемелериңизди жаза аласыз, маалыматтар менен иштей аласыз, мисалы, белгилүү бир эрежелерге ылайык фондо эски жазууларды жок кыла аласыз. Сиз Http серверин түз Тарантулага жазсаңыз болот, ал маалыматтар менен иштей алат: алардын номерин бериңиз, ал жерге жаңы маалыматтарды жазып, баарын мастерге азайтыңыз.

Мен балдар 300 саптык билдирүү кезегин кантип түзүшкөнү жөнүндө макаланы окуп чыктым, алар жөн гана тытышып, ыргытып жиберишет - алар секундасына 20 000 билдирүүлөрдү аткарышат. Бул жерде сиз чындап эле бурулуп, абдан чоң тиркемени жаза аласыз, жана алар PostgreSдегидей сакталбайт.

Болжол менен мындай сервер, жөнөкөй гана, мен бул макалада сүрөттөөгө аракет кылам.

жөндөө

Сыноо үчүн мен үч стандарттуу виртуалдык машинаны баштадым - 20 гигабайт катуу диск, Ubuntu 18.04. 2 виртуалдык CPU жана 4 гигабайт эстутум.

Биз Tarantoolду орнотобуз - bash скриптин иштетебиз же репозиторийди кошобуз жана Tarantool'ду орнотобуз. Скриптке шилтеме - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Бизде төмөнкүдөй буйруктар бар:

tarantoolctl Тарантула учурларын башкаруу үчүн негизги буйрук болуп саналат.
/etc/tarantool - бул жерде бүт конфигурация жатат.
var/log/tarantool - бул жерде журналдар.
var/lib/tarantool - бул жерде маалыматтар жатат, анан алар инстанцияларга бөлүнөт.

Инстанцияга жеткиликтүү жана инстанцияны иштетүүчү папкалар бар - анда эмне ишке ашырыла турганы камтылган - lua коду бар инстанция конфигурациялоо файлы, ал кайсы порттордо угарын, кандай эстутум бар экенин, Винил кыймылдаткычынын жөндөөлөрү, ишке киргизүүдө иштеген код. серверлер, бөлүү, кезектер, эскирген маалыматтарды жок кылуу ж.б.у.с.

Инстанциялар PostgreSдегидей иштешет. Мисалы, сиз ар кандай портторго илинип турган маалымат базасынын бир нече көчүрмөсүн иштеткиңиз келет. Көрсө, бир серверде бир нече маалыматтар базасынын инстанциялары ишке киргизилет, алар ар кандай портторго илинип турат. Алар такыр башка орнотууларга ээ болушу мүмкүн - бир инстанция бир логиканы ишке ашырат, экинчиси - башка.

Instance Management

Бизде Tarantula инстанцияларын башкарууга мүмкүндүк берген tarantoolctl буйругу бар. Мисалы, tarantoolctl текшерүү мисалы конфигурация файлын текшерет жана синтаксистик каталар жок болсо, файл жакшы деп айтат.

Сиз инстанциянын абалын көрө аласыз - tarantoolctl status example. Ошол сыяктуу эле, сиз баштоо, токтотуу, кайра баштоо мүмкүн.

Инстанция иштеп баштагандан кийин, ага туташуу үчүн эки жол бар.

1. Административдик консол

Демейки боюнча, Tarantool розетка ачып, Тарантуланы башкаруу үчүн жөнөкөй ASCII текстин жөнөтөт. Консолго туташуу ар дайым администратор колдонуучунун астында болот, аутентификация жок, андыктан Тарантуланы сырттан башкаруу үчүн консол портун чыгаруунун кереги жок.

Ушундай жол менен туташуу үчүн, Tarantoolctl инстанциянын атын киргизишиңиз керек. Буйрук консолду ишке киргизип, администратор колдонуучу катары туташат. Консолдун портун эч качан сыртка чыгарбаңыз - аны бирдик розетка катары калтырганыңыз жакшы. Ошондо розеткага жазуу мүмкүнчүлүгү бар адамдар гана Тарантулага туташа алышат.

Бул ыкма административдик иштер үчүн керек. Берилиштер менен иштөө үчүн экинчи ыкманы - бинардык протоколду колдонуңуз.

2. Белгилүү бир портко туташуу үчүн экилик протоколду колдонуу

Конфигурацияда тышкы байланыштар үчүн портту ачкан угуу директивасы бар. Бул порт бинардык протокол менен колдонулат жана ал жерде аутентификация иштетилген.

Бул байланыш үчүн, tarantoolctl порт номерине туташуу колдонулат. Аны колдонуу менен сиз алыскы серверлерге туташып, аутентификацияны колдоно аласыз жана ар кандай кирүү укуктарын бере аласыз.

Маалыматтарды жазуу жана куту модулу

Tarantool маалымат базасы жана колдонмо сервери болгондуктан, анын ар кандай модулдары бар. Бизди кутуча модулу кызыктырат - ал маалыматтар менен иштөөнү ишке ашырат. Сиз кутуга бир нерсе жазганда, Tarantool маалыматтарды дискке жазат, аны эстутумда сактайт же аны менен башка бир нерсе кылат.

жазуу

Мисалы, куту модулуна кирип, box.once функциясын чакырабыз. Сервер инициализацияланганда Tarantool биздин кодду иштетүүгө мажбурлайт. Биздин маалыматтар сактала турган мейкиндикти түзөбүз.

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

Андан кийин, биз маалыматтарды издей турган негизги индексти - негизги - түзөбүз. Демейки боюнча, эч кандай параметр көрсөтүлбөсө, праймер индекси үчүн ар бир жазуудагы биринчи талаа колдонулат.

Андан кийин биз конок колдонуучуга грант беребиз, анын алкагында биз бинардык протокол аркылуу байланышабыз. Биз бүт инстанцияда окууга, жазууга жана аткарууга уруксат беребиз.

Кадимки маалымат базаларына салыштырмалуу, бул жерде баары абдан жөнөкөй. Бизде мейкиндик бар - бул биздин маалыматтар жөн гана сакталган аймак. Ар бир жазуу кортеж деп аталат. Ал MessagePack пакетине салынган. Бул абдан сонун формат - ал бинардык жана азыраак орун ээлейт - 18ге каршы 27 байт.

Tarantoolдо сиз супер тез маалымат базасын жана алар менен иштөө үчүн тиркемени айкалыштыра аласыз. Бул жерде муну жасоо канчалык оңой

Аны менен иштөө абдан ыңгайлуу. Дээрлик ар бир сап, ар бир маалымат киргизүү такыр башка мамычаларды болушу мүмкүн.

Биз Box.space буйругун колдонуп бардык боштуктарды көрө алабыз. Белгилүү бир мисалды тандоо үчүн биз box.space мисалын жазып, ал боюнча толук маалымат алабыз.

Tarantoolга орнотулган кыймылдаткычтардын эки түрү бар: Memory жана Vinyl. Эс тутум бардык маалыматтарды эс тутумда сактайт. Ошондуктан, баары жөнөкөй жана тез иштейт. Маалыматтар дискке ташталат, ошондой эле алдын ала жазуу журналы механизми бар, андыктан сервер бузулуп калса, биз эч нерсе жоготпойбуз.

Винил дисктеги маалыматтарды көбүрөөк тааныш формада сактайт - башкача айтканда, сиз бизде эс тутумга караганда көбүрөөк маалыматтарды сактай аласыз жана Тарантула аны дисктен окуйт.

Эми биз эстутумду колдонобуз.

unix/:/var/run/tarantool/example.control> box.space.example
---
- engine: memtx
  before_replace: 'function: 0x41eb02c8'
  on_replace: 'function: 0x41eb0568'
  ck_constraint: []
  field_count: 0
  temporary: false
  index:
    0: &0
      unique: true
      parts:
      - type: unsigned
        is_nullable: false
        fieldno: 1
      id: 0
      space_id: 512
      type: TREE
      name: primary
    primary: *0
  is_local: false
  enabled: true
  name: example
  id: 512
...

unix/:/var/run/tarantool/example.control>

Index:

Кандайдыр бир мейкиндик үчүн негизги индекс түзүлүшү керек, анткени ансыз эч нерсе иштебейт. Ар кандай маалымат базасындагыдай эле, биз биринчи талааны түзөбүз - жазуу ID.

бөлүктөрү:

Бул жерде биз индексибиздин эмнеден тураарын аныктайбыз. Ал бир бөлүктөн турат - биз колдоно турган биринчи талаа, unsigned териңиз - оң бүтүн сан. Документациядан эсимде, максималдуу сан 18 квинтиллион болушу мүмкүн. Абдан сонун.

Андан кийин биз 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>

Биринчи талаа негизги ачкыч катары колдонулат, ошондуктан ал уникалдуу болушу керек. Биз мамычалардын саны менен чектелбейбиз, андыктан ал жерге каалагандай маалыматтарды киргизе алабыз. Алар мен жогоруда сүрөттөгөн MessagePack форматында көрсөтүлгөн.

Маалымат чыгаруу

Андан кийин биз тандоо буйругу менен маалыматтарды көрсөтө алабыз.

Box.example.select {1} баскычы менен керектүү жазууну көрсөтөт. Эгерде биз ачкычты калтырсак, бизде болгон бардык жазууларды көрөбүз. Алардын баары мамычалардын саны боюнча айырмаланат, бирок бул жерде, негизинен, мамычалар деген түшүнүк жок - талаа номерлери бар.

Сиз каалагандай көп маалымат болушу мүмкүн. Ал эми, мисалы, биз аларды экинчи талаадан издешибиз керек. Бул үчүн биз жаңы экинчи көрсөткүчтү түзөбүз.


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

Биз Create_index буйругун колдонобуз.
Биз аны экинчи деп атайбыз.

Андан кийин, сиз параметрлерди көрсөтүү керек. Индекс түрү TREE болуп саналат. Бул уникалдуу болбошу мүмкүн, ошондуктан биз Unique = false киргизебиз.

Андан кийин биздин индекс кандай бөлүктөрдөн тураарын көрсөтөбүз. Field - бул биз индексти байлаган талаанын номери жана саптын түрүн көрсөтөт. Ошентип, ал жаралган.

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 ГБ тынымсыз төгүү - бул идея.

Бул үчүн, алдын ала жазуу журналы түшүнүгү ойлоп табылган жана ишке ашырылган. Анын жардамы менен маалыматтардын ар бир өзгөрүүсү үчүн кичинекей алдын ала жазуу журналында жазуу түзүлөт.

Аларда өткөрүү пунктуна чейинки ар бир кирүү сакталат. Бул файлдар үчүн биз өлчөмүн койдук - мисалы, 64 мб. Ал толгондо, жазуу экинчи файлга өтө баштайт. Жана кайра күйгүзгөндөн кийин, Tarantool акыркы текшерүү пунктунан калыбына келип, андан кийин токтогонго чейин бардык кийинки транзакцияларды өткөрөт.

Tarantoolдо сиз супер тез маалымат базасын жана алар менен иштөө үчүн тиркемени айкалыштыра аласыз. Бул жерде муну жасоо канчалык оңой

Мындай жаздыруу үчүн, 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; -- 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()

Биз символдорду аныктаган 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 серверин биздин Кардарга бере турган Tarantula серверибизге, JSONга туташтырабыз.

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

Андан кийин биз бардык http сервер интерфейстеринде 8080 портунан баштайбыз, ал бардык сурамдарды жана каталарды журналга киргизет.

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

Андан кийин биз маршрутту жарыялайбыз, эгерде GET ыкмасы менен суроо 8080 /count портуна келсе, анда функцияны бир саптан чакырабыз. Ал статусту кайтарат - 200, 404, 403 же биз белгилеген нерсе.

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

Денеде биз json.encode кайтарып беребиз, биз ага count жана getcount көрсөтөбүз, ал чакырылат жана биздин базадагы жазуулардын санын көрсөтөт.

экинчи ыкма

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)

Кайсы жерде роутер:маршрут({метод = 'GET', жол = '/токен'}, функция() функцияны чакырабыз жана токенди түзөбүз.

Сап жергиликтүү токен = randomString(32) 32 белгиден турган туш келди сап болуп саналат.
Кезекте жергиликтүү акыркы = box.space.example:len() биз акыркы элементти чыгарабыз.
Жана сапта box.space.example:insert{ акыркы + 1, токен } биз маалымат базасына маалыматтарды жазабыз, башкача айтканда, биз жөн гана ID 1 ге көбөйтөт. Бул, демек, мындай олдоксон жол менен гана эмес, жасоого болот. Тарантула бул иш үчүн ырааттуулугу бар.

Токенди ошол жерге жазабыз.

Ошентип, биз бир файлга арыз жаздык. Маалыматтарга дароо кире аласыз жана куту модулу сиз үчүн бардык ыплас иштерди жасайт.

Ал http угат жана маалыматтар менен иштейт, бардыгы бир инстанцияда - тиркеме да, маалыматтар да. Ошондуктан, баары абдан тез болот.

Иштөө үчүн http модулун орнотобуз:

Муну кантип кылабыз, спойлердин астына караңыз

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

Бизге прометей да керек:

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

Биз баштайбыз жана модулдарга кире алабыз

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 токен чыгарат жана бул белгини маалымат базасына жазат.

Сыноо ылдамдыгы

Келгиле, 50 000 сурам үчүн эталон жүргүзөлү. Конкурстук өтүнүчтөр 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:/#

Токендер чыгарылат. Ал эми биз тынымсыз маалыматтарды жазып жатабыз. Сурамдардын 99% 42 миллисекундда аткарылган. Демек, бизде 3500 өзөк жана 2 гигабайт эстутум бар кичинекей машинада секундасына 4гө жакын суроо-талаптар бар.

Ошондой эле 50000 белгини тандап, анын баасын көрө аласыз.

Сиз http гана эмес, маалыматыңызды иштеткен фондо функцияларды колдоно аласыз. Мындан тышкары, ар кандай триггерлер бар. Мисалы, сиз жаңыртуулар боюнча функцияларды чакыра аласыз, бир нерсени текшере аласыз - чыр-чатактарды оңдоо.

Сиз скрипт тиркемелерин түздөн-түз маалымат базасынын серверинде жаза аласыз жана эч нерсе менен чектелбей, каалаган модулдарды туташтырсаңыз жана каалаган логиканы ишке ашыра аласыз.

Тиркеме сервери тышкы серверлерге кире алат, маалыматтарды чогултуп, аны өзүнүн маалымат базасына кошо алат. Бул маалымат базасынан алынган маалыматтар башка колдонмолор тарабынан колдонулат.

Муну Тарантула өзү жасайт, өзүнчө арыз жазуунун кереги жок.

Жыйынтык

Бул чоң иштин биринчи гана бөлүгү. Экинчиси жакында Mail.ru Group блогунда жарыяланат жана биз бул материалда ага шилтемени сөзсүз кошобуз.

Эгер сиз онлайн режиминде бул нерселерди жараткан иш-чараларга катышууга жана реалдуу убакыт режиминде суроолорду берүүгө кызыксаңыз, байланышыңыз REBRAIN каналынын DevOps.

Булутка өтүшүңүз керек болсо же инфраструктураңыз тууралуу суроолоруңуз болсо, Сураныч тапшыруудан тартынбаңыз.

PS Бизде айына 2 акысыз аудит бар, балким сиздин долбооруңуз алардын бири болушу мүмкүн.

Source: www.habr.com

Комментарий кошуу