En Tarantool, podes combinar unha base de datos superrápida e unha aplicación para traballar con elas. Velaquí o fácil que é facelo

Hai cinco anos tentei traballar con Tarantool, pero despois non me funcionou. Pero recentemente realicei un seminario web onde falei sobre Hadoop e como funciona MapReduce. Alí fixéronme unha pregunta: "Por que non usar Tarantool para esta tarefa?"

Por curiosidade, decidín volver a el, probar a última versión, e esta vez gustoume moito o proxecto. Agora mostrarei como escribir unha aplicación sinxela en Tarantool, cargala e comprobar o seu rendemento, e verás o sinxelo e xenial que é todo.

En Tarantool, podes combinar unha base de datos superrápida e unha aplicación para traballar con elas. Velaquí o fácil que é facelo

Que é Tarantool

Tarantool sitúase como unha base de datos ultrarrápida. Podes poñer alí os datos que queiras. Ademais, replícaos, fragmenta, é dicir, divide unha gran cantidade de datos en varios servidores e combina os resultados dos mesmos, fai conexións mestre-mestre tolerantes a fallos.

En segundo lugar, este é un servidor de aplicacións. Podes escribir as túas aplicacións nel, traballar con datos, por exemplo, eliminar rexistros antigos en segundo plano segundo determinadas regras. Podes escribir un servidor HTTP directamente en Tarantula que funcione con datos: dá a súa cantidade, escribe novos datos alí e redúceo todo ao mestre.

Lin un artigo sobre como os mozos fixeron unha fila de mensaxes de 300 liñas, que simplemente está a rebentar e apresurarse: teñen un rendemento mínimo de 20 mensaxes por segundo. Aquí pode realmente dar a volta e escribir unha aplicación moi grande, e non será almacenamento, como en PostgreS.

Tentarei describir algo como este servidor, só sinxelo, neste artigo.

Instalación

Para a proba, iniciei tres máquinas virtuais estándar: un disco duro de 20 GB, Ubuntu 18.04. 2 CPU virtuais e 4 gigas de memoria.

Instalamos Tarantool: executamos o script bash ou engadimos un repositorio e instalamos Tarantool. Ligazón ao guión - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Temos comandos como:

tarantoolctl — o comando principal para xestionar instancias de Tarantula.
/etc/tarantool - Aquí está a configuración completa.
var/log/tarantool - Aquí están os rexistros.
var/lib/tarantool - os datos están aquí, e despois divídese en instancias.

Hai cartafoles instance-available e instance-enable - contén o que se vai lanzar - un ficheiro de configuración de instancia co código lua, que describe en que portos escoita, que memoria ten dispoñible, configuración do motor de vinilo, código que se executa ao inicio servidores, fragmentación, colas, eliminación de datos obsoletos, etc.

As instancias funcionan como en PostgreS. Por exemplo, quere executar varias copias dunha base de datos que se colga en diferentes portos. Resulta que se lanzan varias instancias de base de datos nun servidor, que colgan en portos diferentes. Poden ter configuracións completamente diferentes: unha instancia implementa unha lóxica, a segunda, outra.

Xestión de instancias

Temos o comando tarantoolctl, que che permite xestionar instancias de Tarantula. Por exemplo, o exemplo de verificación tarantoolctl comprobará o ficheiro de configuración e dirá: o ficheiro está ben se non hai erros de sintaxe alí.

Podes ver o estado da instancia - exemplo de estado de tarantoolctl. Do mesmo xeito podes comezar, deter e reiniciar.

Unha vez que se executa a instancia, pode conectarse a ela de dúas formas.

1. Consola administrativa

Por defecto, Tarantool abre un socket, o texto normal ASCII envíase alí para controlar Tarantool. A conexión á consola sempre ocorre baixo o usuario administrador, non hai autenticación, polo que non é necesario externalizar o porto da consola para xestionar Tarantula.

Para conectarse usando este método, cómpre introducir Tarantoolctl e introducir o nome da instancia. O comando iniciará a consola e conectarase como usuario administrador. Nunca expoña o porto da consola ao exterior; é mellor deixalo como un enchufe da unidade. Entón só os que teñan acceso para escribir no socket poderán conectarse a Tarantula.

Este método é necesario para cousas administrativas. Para traballar con datos, use o segundo método: o protocolo binario.

2. Usando un protocolo binario para conectarse a un porto específico

A configuración contén unha directiva listen, que abre un porto para comunicacións externas. Este porto úsase co protocolo binario e alí está habilitada a autenticación.

Para esta conexión, utilízase a conexión tarantoolctl co número de porto. Usalo, pode conectarse a servidores remotos, usar a autenticación e dar varios dereitos de acceso.

Módulo de rexistro e caixa de datos

Xa que Tarantool é tanto unha base de datos como un servidor de aplicacións, ten varios módulos. Estamos interesados ​​no módulo de caixa: implementa o traballo con datos. Cando escribes algo na caixa, Tarantool escribe os datos no disco, gárdaos na memoria ou fai outra cousa con eles.

Rexistro

Por exemplo, entramos no módulo box e chamamos á función box.once. Isto obrigará a Tarantool a executar o noso código cando se inicialice o servidor. Creamos un espazo no que se almacenarán os nosos datos.

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

Despois diso, creamos un índice primario - primario - polo cal podemos buscar datos. Por defecto, se non especifica ningún parámetro, o primeiro campo de cada rexistro será usado para o índice primario.

A continuación, facemos unha subvención ao usuario convidado, baixo o cal nos conectamos mediante o protocolo binario. Permitimos ler, escribir e executar en toda a instancia.

Comparado coas bases de datos convencionais, todo aquí é bastante sinxelo. Temos espazo, unha área na que simplemente se almacenan os nosos datos. Cada rexistro chámase tupla. Está empaquetado en MessagePack. Este é un formato moi xenial - é binario e ocupa menos espazo - 18 bytes fronte a 27.

En Tarantool, podes combinar unha base de datos superrápida e unha aplicación para traballar con elas. Velaquí o fácil que é facelo

É moi cómodo traballar con el. Case todas as liñas, cada rexistro de datos pode ter columnas completamente diferentes.

Podemos ver todos os espazos usando o comando Box.space. Para seleccionar unha instancia específica, escribe box.space exemplo e obtén información completa sobre ela.

Tarantool ten dous motores incorporados: Memory e Vinyl. A memoria almacena todos os datos na memoria. Polo tanto, todo funciona de forma sinxela e rápida. Os datos bótanse ao disco e tamén hai un mecanismo de rexistro de escritura anticipada, polo que non perderemos nada se o servidor falla.

O vinilo almacena os datos no disco dunha forma máis familiar para nós, é dicir, podes almacenar máis datos dos que temos memoria, e Tarantula lerao desde o disco.

Polo de agora usaremos a Memoria.

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>

Índice:

Debe crearse un índice primario para calquera espazo, porque sen el nada funcionará. Como en calquera base de datos, creamos o primeiro campo: ID de rexistro.

Pezas:

Aquí indicamos en que consiste o noso índice. Consta dunha parte -o primeiro campo que utilizaremos é de tipo sen signo- un enteiro positivo. Segundo recordo da documentación, o número máximo que pode ser é de 18 quintillones. Iso é moito.

Despois podemos inserir datos usando o comando 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>

O primeiro campo úsase como clave principal, polo que debe ser único. Non estamos limitados polo número de columnas, polo que podemos inserir alí tantos datos como queiramos. Están especificados no formato MessagePack, que describín anteriormente.

Saída de datos

Despois podemos mostrar os datos usando o comando select.

Caixa.exemplo.seleccionar coa tecla {1} mostrará a entrada desexada. Se baixamos a tecla, veremos todos os rexistros que temos. Todos difiren no número de columnas, pero aquí, en principio, non hai ningún concepto de columnas: hai números de campo.

Pode haber absolutamente calquera cantidade de datos. E, por exemplo, necesitamos buscalos polo segundo campo. Para iso, creamos un novo índice secundario.


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

Usamos o comando Create_index.
Chamémoslle Secundaria.

Despois diso, cómpre especificar os parámetros. O tipo de índice é TREE. Pode que non sexa único, así que introduce Único = falso.

Despois indicamos en que partes está composto o noso índice. Campo é o número do campo ao que vinculamos o índice e especificamos o tipo de cadea. E así foi creado.

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>

Agora é como podemos chamalo:

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

Aforro

Se reiniciamos a instancia e tentamos chamar os datos de novo, veremos que non están alí: todo está baleiro. Isto ocorre porque Tarantool fai puntos de control e garda os datos no disco, pero se deixamos de traballar ata o seguinte gardado, perderemos todas as operacións, porque recuperaremos o último punto de control, que foi, por exemplo, hai dúas horas.

Tampouco funcionará para aforrar cada segundo, porque botar 20 GB constantemente no disco non é unha boa idea.

Para este fin, inventouse e implementouse o concepto de rexistro de escritura anticipada. Coa súa axuda, para cada cambio nos datos, créase unha entrada nun pequeno ficheiro de rexistro de escritura anticipada.

Cada entrada ata o punto de control almacénase neles. Para estes ficheiros definimos o tamaño, por exemplo, 64 MB. Cando estea cheo, a gravación comeza a ir ao segundo ficheiro. E despois do reinicio, Tarantool restablece desde o último punto de control e, a continuación, pasa por todas as transaccións posteriores ata que se detén.

En Tarantool, podes combinar unha base de datos superrápida e unha aplicación para traballar con elas. Velaquí o fácil que é facelo

Para realizar esa gravación, cómpre especificar a opción na configuración box.cfg (no ficheiro example.lua):

wal_mode = “write”;

uso de datos

Co que escribimos agora, podes usar Tarantula para almacenar datos e funcionará moi rapidamente como base de datos. E agora a guinda do bolo é o que podes facer con todo.

Redacción dunha aplicación

Por exemplo, escribamos a seguinte aplicación para Tarantula

Vexa a aplicación baixo o 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()

Declaramos algunha táboa en lua que define os caracteres. Esta placa é necesaria para xerar unha cadea aleatoria.

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

Despois diso, declaramos a función - randomString e damos o valor de lonxitude entre parénteses.

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

Despois conectamos o router http e o servidor http ao noso servidor Tarantula, JSON, que enviaremos ao cliente.

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

Despois diso, comezamos no porto 8080 en todas as interfaces do servidor http, que rexistrará todas as solicitudes e os erros.

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

A continuación, declaramos ruta, de xeito que se chega unha solicitude co método GET ao porto 8080 /count, chamamos á función desde unha liña. Devolve o estado: 200, 404, 403 ou calquera outro que especifiquemos.

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

No corpo devolvemos json.encode, nel indicamos count e getcount, que se chama e mostra o número de rexistros da nosa base de datos.

Segundo método

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)

Onde na liña router:route({método = 'GET', ruta = '/token'}, function() chamamos á función e xeramos un token.

Liña token local = randomString (32) é unha cadea aleatoria de 32 caracteres.
En liña local last = box.space.example:len() sacamos o último elemento.
E na liña caixa.espazo.exemplo:inserir{ último + 1, símbolo } escribimos os datos na nosa base de datos, é dicir, simplemente aumentamos o ID en 1. Isto pódese facer, por certo, non só deste xeito torpe. Hai secuencias para isto en Tarantula.

Escribimos a ficha alí.

Así, escribimos a aplicación nun ficheiro. Podes manipular directamente os datos alí, e o módulo de caixa fará todo o traballo sucio por ti.

Escoita http e funciona con datos, todo está nunha única instancia: tanto a aplicación como os datos. Polo tanto, todo ocorre con bastante rapidez.

Para comezar instalamos o módulo http:

Como facemos isto, mira debaixo do 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:/#

Tamén necesitamos de Prometheus para executar:

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

Lanzamos e podemos acceder aos módulos

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 dános o estado 200.
/token emite un token e escribe este token na base de datos.

Velocidade de proba

Imos realizar unha referencia para 50 solicitudes. Haberá 000 solicitudes concorrentes.

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

Emítense tokens. E estamos constantemente rexistrando datos. O 99 % das solicitudes procesáronse en 42 milisegundos. En consecuencia, temos unhas 3500 solicitudes por segundo nunha pequena máquina con 2 núcleos e 4 gigabytes de memoria.

Tamén podes seleccionar uns 50000 tokens e ver o seu valor.

Podes usar non só http, senón tamén executar funcións en segundo plano que procesan os teus datos. Ademais, hai varios disparadores. Por exemplo, pode chamar funcións sobre actualizacións, comprobar algo - corrixir conflitos.

Podes escribir aplicacións de script directamente no propio servidor de base de datos, e non estar limitado por nada, conectar calquera módulo e implementar calquera lóxica.

O servidor de aplicacións pode acceder a servidores externos, recuperar datos e engadilos á súa base de datos. Os datos desta base de datos serán utilizados por outras aplicacións.

Tarantula fará isto por si mesma e non terás que escribir unha aplicación separada.

En conclusión

Esta é só a primeira parte dun gran traballo. O segundo publicarase moi pronto no blog do Grupo Mail.ru e definitivamente engadiremos unha ligazón neste material.

Se estás interesado en asistir a eventos nos que creamos estas cousas en liña e en facer preguntas en tempo real, sintoniza canle DevOps de REBRAIN.

Se precisas pasar á nube ou tes dúbidas sobre a túa infraestrutura, non dubide en deixar unha solicitude.

PS Temos 2 auditorías gratuítas ao mes, quizais o teu proxecto sexa unha delas.

Fonte: www.habr.com

Engadir un comentario