Avec Tarantool, vous pouvez associer une base de données super rapide et une application pour travailler avec celle-ci. Voici comment c'est fait simplement

Il y a cinq ans, j'ai essayĂ© de travailler avec Tarantool, mais cela ne m'a pas convaincu Ă  l'Ă©poque. RĂ©cemment, j'ai animĂ© un webinaire oĂč j'ai parlĂ© de Hadoop et du fonctionnement de MapReduce. On m'a alors posĂ© la question : « Pourquoi ne pas utiliser Tarantool pour cette tĂąche ? »

Par curiositĂ©, j'ai dĂ©cidĂ© de revenir Ă  Tarantool, de tester la derniĂšre version — et cette fois, le projet m'a beaucoup plu. Je vais maintenant vous montrer comment Ă©crire une application simple dans Tarantool, la solliciter et vĂ©rifier ses performances, et vous verrez Ă  quel point tout est facile et impressionnant.

Avec Tarantool, vous pouvez associer une base de données super rapide et une application pour travailler avec celle-ci. Voici comment c'est fait simplement

Qu'est-ce que Tarantool

Tarantool se positionne comme une base de donnĂ©es ultra-rapide. Vous pouvez y insĂ©rer n'importe quelles donnĂ©es que vous souhaitez. De plus, vous pouvez les rĂ©pliquer, les shardiser — c'est-Ă -dire rĂ©partir une grande quantitĂ© de donnĂ©es sur plusieurs serveurs et combiner les rĂ©sultats — crĂ©er des configurations rĂ©silientes comme des « maĂźtre-maĂźtre ».

En second lieu, c'est un serveur d'applications. Vous pouvez y écrire vos propres applications, travailler avec les données, par exemple, supprimer en arriÚre-plan les anciens enregistrements selon certaines rÚgles. Il est possible de créer directement dans Tarantool un serveur Http qui traitera les données : fournir leur quantité, y enregistrer de nouvelles données et réduire tout cela sur le maßtre.

J'ai lu un article sur la façon dont des dĂ©veloppeurs ont mis en place une file de messages en 300 lignes, qui fonctionne Ă  merveille — leur performance minimale est de 20 000 messages par seconde. Vous pouvez rĂ©ellement vous dĂ©ployer et Ă©crire une trĂšs grande application, contrairement aux solutions utilisĂ©es dans PostgreSQL.

Je vais essayer de décrire un serveur de ce type, mais de maniÚre simple, dans cet article.

Installation

Pour le test, j'ai créé trois machines virtuelles standard — un disque dur de 20 Go, Ubuntu 18.04, 2 CPU virtuels et 4 Go de mĂ©moire.

Nous installons Tarantool — soit nous lançons un script bash, soit nous ajoutons le dĂ©pĂŽt et faisons un apt get install Tarantool. Lien vers le script — (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Nous avons des commandes comme :

tarantoolctl — la commande principale pour gĂ©rer les instances de Tarantool.
/etc/tarantool — ici se trouve toute la configuration.
var/log/tarantool — ici se trouvent les journaux.
var/lib/tarantool — ici se trouvent les donnĂ©es, qui sont ensuite rĂ©parties par instances.

Il existe des dossiers instance-available et instance-enable : le premier contient ce qui va ĂȘtre exĂ©cutĂ© : un fichier de configuration de l'instance avec du code Lua, oĂč sont dĂ©crits les ports sur lesquels il Ă©coute, la mĂ©moire qui lui est allouĂ©e, les paramĂštres du moteur Vinyl, le code qui s'active au dĂ©marrage du serveur, le sharding, les files d'attente, la suppression des donnĂ©es obsolĂštes, etc.

Les instances fonctionnent comme dans PostgreS. Par exemple, vous souhaitez lancer plusieurs copies d'une base de donnĂ©es, qui se trouvent sur diffĂ©rents ports. Cela signifie que plusieurs instances de base de donnĂ©es sont lancĂ©es sur un mĂȘme serveur, chacune sur des ports diffĂ©rents. Elles peuvent avoir des configurations entiĂšrement diffĂ©rentes : une instance rĂ©alise une logique, l'autre en rĂ©alise une diffĂ©rente.

Gestion des instances

Nous avons la commande tarantoolctl, qui permet de gĂ©rer les instances de Tarantool. Par exemple, tarantoolctl check example vĂ©rifiera le fichier de configuration et indiquera — fichier is ok, s'il n'y a pas d'erreurs de syntaxe.

Vous pouvez voir le statut de l'instance avec tarantoolctl status example. De la mĂȘme maniĂšre, vous pouvez faire start, stop, restart.

Lorsque l'instance est lancée, il existe deux maniÚres de s'y connecter.

1. Console administrative

Par défaut, Tarantool ouvre un socket, cela transmet du texte ASCII standard pour gérer Tarantool. La connexion à la console se fait toujours sous l'utilisateur admin, il n'y a pas d'authentification, donc il n'est pas nécessaire d'exposer le port de la console pour gérer Tarantool à l'extérieur.

Pour se connecter de cette maniĂšre, vous devez entrer Tarantoolctl enter instance name. La commande lancera la console et se connectera en tant qu'utilisateur admin. Ne jamais exposer le port de la console Ă  l'extĂ©rieur — il vaut mieux le laisser en socket unit. Ainsi, seule les personnes ayant accĂšs en Ă©criture au socket pourront se connecter Ă  Tarantool.

Cette mĂ©thode est nĂ©cessaire pour les opĂ©rations administratives. Pour travailler avec les donnĂ©es, utilisez la seconde mĂ©thode — le protocole binaire.

2. Utilisation du protocole binaire pour se connecter à un port spécifique

Dans la configuration, il existe une directive listen qui ouvre un port pour les communications externes. Ce port est utilisé avec le protocole binaire, et l'authentification y est activée.

Pour cette connexion, on utilise tarantoolctl connect to port number. En l'utilisant, on peut se connecter Ă  des serveurs distants, utiliser l'authentification et accorder divers droits d'accĂšs.

Enregistrement des données et module Box

Puisque Tarantool est Ă  la fois une base de donnĂ©es et un serveur d'applications, il possĂšde diffĂ©rents modules. Nous nous intĂ©ressons au module box — il implĂ©mente le travail avec les donnĂ©es. Lorsque vous Ă©crivez quelque chose dans box, Tarantool enregistre les donnĂ©es sur le disque, les conserve en mĂ©moire ou effectue d'autres opĂ©rations avec elles.

Écriture

Par exemple, nous allons dans le module box et appelons la fonction box.once. Cela va forcer Tarantool Ă  exĂ©cuter notre code lors de l'initialisation du serveur. Nous crĂ©ons un espace oĂč nos donnĂ©es seront stockĂ©es.

local function bootstrap()
    local space = box.schema.create_space('example')
    space:create_index('primary')
    box.schema.user.grant('guest', 'read,write,execute', 'universe')

    -- Garder les choses sécurisées par défaut
    --  box.schema.user.create('example', { password = 'secret' })
    --  box.schema.user.grant('example', 'replication')
    --  box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end

AprĂšs cela, nous crĂ©ons un index primaire — primary — qui pourra ĂȘtre utilisĂ© pour rechercher des donnĂ©es. Par dĂ©faut, si aucun paramĂštre n'est spĂ©cifiĂ©, le premier champ de chaque enregistrement sera utilisĂ© pour l'index primaire.

Nous faisons ensuite un grant à l'utilisateur guest, par lequel nous nous connectons via le protocole binaire. Nous autorisons la lecture, l'écriture et l'exécution dans toute l'instance.

ComparĂ© aux bases de donnĂ©es ordinaires, ici c'est assez simple. Nous avons un space – un domaine oĂč nos donnĂ©es sont simplement stockĂ©es. Chaque enregistrement est appelĂ© un tuple. Il est empaquetĂ© en MessagePack. C'est un format trĂšs intĂ©ressant — il est binaire et occupe moins d'espace – 18 octets contre 27.

Avec Tarantool, vous pouvez associer une base de données super rapide et une application pour travailler avec celle-ci. Voici comment c'est fait simplement

Il est assez pratique à manipuler. Presque chaque ligne, chaque enregistrement de données peut avoir des colonnes totalement différentes.

Nous pouvons voir tous les espaces avec la commande Box.space. Pour sĂ©lectionner une instance spĂ©cifique – nous Ă©crivons box.space example et obtenons des informations complĂštes Ă  son sujet.

Tarantool intÚgre deux types de moteurs : Memory et Vinyl. Memory stocke toutes les données en mémoire. C'est pourquoi tout fonctionne simplement et rapidement. Les données sont sauvegardées sur disque, et il existe également un mécanisme de journalisation anticipée, donc nous ne perdrons rien en cas de panne du serveur.

Vinyl stocke les donnĂ©es sur le disque de maniĂšre plus familiĂšre — cela signifie que l'on peut stocker plus de donnĂ©es que ce que nous avons en mĂ©moire, et Tarantool les lira depuis le disque.

Nous allons maintenant utiliser 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>

Index:

Un index primaire doit ĂȘtre créé pour tout espace, car sans lui, rien ne fonctionnera. Comme dans toute base de donnĂ©es, nous crĂ©ons le premier champ – l'ID de l'enregistrement.

Parts:

Ici, nous spĂ©cifions de quoi se compose notre index. Il se compose d'une seule partie – le premier champ que nous allons utiliser, de type unsigned — un entier positif. Si je me souviens bien de la documentation, le nombre maximum peut atteindre 18 quintillions. ÉnormĂ©ment.

Ensuite, nous pouvons insérer des données avec la commande 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>

Le premier champ est utilisĂ© comme clĂ© primaire, il doit donc ĂȘtre unique. Nous ne sommes pas limitĂ©s par le nombre de colonnes, donc nous pouvons y insĂ©rer autant de donnĂ©es que nous le souhaitons. Elles sont spĂ©cifiĂ©es au format MessagePack, que j'ai dĂ©crit ci-dessus.

Sortie des données

Ensuite, nous pouvons afficher les données avec la commande select.

Box.example.select en spĂ©cifiant la clĂ© {1} affichera l'enregistrement souhaitĂ©. Si nous omettons la clĂ©, nous verrons tous les enregistrements que nous avons. Ils varient en nombre de colonnes, mais ici, il n'y a pas vraiment de notion de colonnes – il y a des numĂ©ros de champ.

Il peut y avoir absolument autant de données que nécessaire. Et par exemple, nous devons les rechercher par le deuxiÚme champ. Pour cela, nous créons un nouvel index secondaire.


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

Utilisons la commande Create_index.
Nous l'appelons Secondary.

AprĂšs cela, nous devons spĂ©cifier les paramĂštres. Le type d'index — TREE. Il peut ne pas ĂȘtre unique, donc nous saisissons Unique = false.

Ensuite, nous spĂ©cifions de quelles parties notre index est composĂ©. Field — c'est le numĂ©ro du champ auquel nous attachons l'index, et nous indiquons le type string. Et voilĂ , il a Ă©tĂ© créé.

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>

Voici comment nous pouvons l'appeler :

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

Sauvegarde

Si nous redĂ©marrons l'instance et essayons Ă  nouveau d'appeler les donnĂ©es, nous verrons qu'elles sont absentes — tout est vide. C'est ainsi que cela se passe, car Tarantool effectue des checkpoints et enregistre les donnĂ©es sur le disque, mais si nous arrĂȘtons avant la derniĂšre sauvegarde, nous perdrons toutes les opĂ©rations — car nous restaurerons Ă  partir du dernier checkpoint, qui Ă©tait, par exemple, deux heures auparavant.

Sauvegarder chaque seconde n'est pas non plus possible — car dump sur le disque de 20 Go en continu n'est pas vraiment une bonne idĂ©e.

Pour cela, le concept de journalisation anticipée (write-ahead log) a été conçu et réalisé. Avec cela, une entrée est créée dans un petit fichier de journalisation anticipée pour chaque modification des données.

Chaque entrĂ©e jusqu'au checkpoint est enregistrĂ©e dans ces fichiers. Pour ces fichiers, nous dĂ©finissons une taille — par exemple, 64 Mo. Lorsqu'il est rempli, l'enregistrement commence dans un second fichier. Et aprĂšs le redĂ©marrage, Tarantool se restaure Ă  partir du dernier checkpoint puis applique toutes les transactions plus rĂ©centes jusqu'au moment de l'arrĂȘt.

Avec Tarantool, vous pouvez associer une base de données super rapide et une application pour travailler avec celle-ci. Voici comment c'est fait simplement

Pour permettre cette Ă©criture, une option doit ĂȘtre spĂ©cifiĂ©e dans les paramĂštres box.cfg (dans le fichier example.lua) :

wal_mode = “write”;

Utilisation des données

Avec ce que nous venons d'Ă©crire, vous pouvez utiliser Tarantool pour stocker des donnĂ©es, et il fonctionnera trĂšs rapidement comme une base de donnĂ©es. Et maintenant, la cerise sur le gĂąteau – ce que vous pouvez faire avec tout cela.

Nous écrivons une application

Par exemple, écrivons une telle application pour Tarantool.

Vous pouvez voir l'application sous spoiler.

box.cfg {
    listen = '0.0.0.0:3301';
    io_collect_interval = nil;
    readahead = 16320;
    memtx_memory = 128 * 1024 * 1024; -- 128Mo
    memtx_min_tuple_size = 16;
    memtx_max_tuple_size = 128 * 1024 * 1024; -- 128Mo
    vinyl_memory = 128 * 1024 * 1024; -- 128Mo
    vinyl_cache = 128 * 1024 * 1024; -- 128Mo
    vinyl_max_tuple_size = 128 * 1024 * 1024; -- 128Mo
    vinyl_write_threads = 2;
    wal_mode = "write";
    wal_max_size = 256 * 1024 * 1024;
    checkpoint_interval = 60 * 60; -- une heure
    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

-- pour la premiÚre exécution, créez un espace et configurez les autorisations
box.once('replica', bootstrap)

-- activation de l'accĂšs console
console = require('console')
console.listen('127.0.0.1:3302')

-- configuration http
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",
                              "Nombre de jetons API")

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

Nous déclarons un tableau en lua qui définit des caractÚres. Ce tableau est nécessaire pour générer une chaßne aléatoire.

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

Ensuite, nous dĂ©clarons la fonction – randomString et passons en paramĂštre la valeur de longueur.

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

Puis, nous connectons le routeur http et le serveur http Ă  notre serveur Tarantool, ainsi que le JSON que nous allons renvoyer au client.

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

Ensuite, nous dĂ©marrons le serveur http sur le port 8080 sur toutes les interfaces, qui enregistrera toutes les requĂȘtes et erreurs.

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

Ensuite, nous dĂ©clarons la route, pour que si une requĂȘte avec la mĂ©thode GET arrive sur le port 8080 /count, nous appelons une fonction en une ligne. Elle retourne un statut — 200, 404, 403 ou tout autre, selon ce que nous indiquerons.

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

Dans le corps, nous retournons json.encode, oĂč nous indiquons count et get_count, qui est appelĂ©e et montre le nombre d'enregistrements dans notre base.

DeuxiÚme méthode

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)

OĂč dans la ligne router:route({method = 'GET', path = ' /token'}, function() nous appelons une fonction et gĂ©nĂ©rons un token.

ChaĂźne local token = randomString(32) – c'est une chaĂźne alĂ©atoire de 32 caractĂšres.
Dans la ligne local last = box.space.example:len() nous récupérons le dernier élément.
Et dans la ligne box.space.example:insert{ last + 1, token } nous enregistrons les donnĂ©es dans notre base, c'est-Ă -dire que nous augmentons simplement l'ID de 1. Cela peut d'ailleurs ĂȘtre fait, non seulement de cette maniĂšre peu Ă©lĂ©gante. Dans Tarantool, il existe des sĂ©quences pour cela.

Nous y écrivons le token.

Ainsi, nous avons écrit une application dans un seul fichier. Nous pouvons immédiatement interagir avec les données, et le module box fera tout le travail pénible pour vous.

Il Ă©coute http et travaille avec les donnĂ©es, tout se trouve dans une seule instance — Ă  la fois l'application et les donnĂ©es. Donc tout se passe assez rapidement.

Pour démarrer, nous installons le module http :

Comment nous le faisons, regardez sous le spoiler

root@test2:/# tarantoolctl rocks install http
Installation de http/rocks.tarantool.org/http-scm-1.src.rock
Dépendances manquantes pour http scm-1 :
   checks >= 3.0.1 (non installé)

http scm-1 dépend de checks >= 3.0.1 (non installé)
Installation de http/rocks.tarantool.org/checks-3.0.1-1.rockspec

Clonage dans 'checks'...
remote: Enumeration des objets : 28, terminé.
remote: Comptage des objets : 100% (28/28), terminé.
remote: Compression des objets : 100% (19/19), terminé.
remote: Total 28 (delta 1), réutilisé 16 (delta 1), pack-réutilisé 0
Réception des objets : 100% (28/28), 12.69 KiB | 12.69 MiB/s, terminé.
Résolution des deltas : 100% (1/1), terminé.
Note : vérification de '580388773ef11085015b5a06fe52d61acf16b201'.

Vous ĂȘtes dans un Ă©tat 'HEAD dĂ©tachĂ©'. Vous pouvez explorer, apporter des modifications expĂ©rimentales et les valider, et vous pouvez annuler toute validation que vous effectuez dans cet Ă©tat sans impacter aucune branche en effectuant un autre checkout.

Si vous souhaitez créer une nouvelle branche pour conserver les validations que vous créez, vous pouvez le faire (maintenant ou plus tard) en utilisant -b avec la commande checkout à nouveau. Exemple :

  git checkout -b <nom-nouvelle-branche>

Aucun manifeste existant. Tentative de reconstruction...
checks 3.0.1-1 est maintenant installé dans /.rocks (license : BSD)

-- L'identification du compilateur C est GNU 7.5.0
-- Vérification du compilateur C fonctionnel : /usr/bin/cc
-- Vérification du compilateur C fonctionnel : /usr/bin/cc -- fonctionne
-- Détection des informations d'ABI du compilateur C
-- Détection des informations d'ABI du compilateur C - terminé
-- Détection des caractéristiques de compilation C
-- Détection des caractéristiques de compilation C - terminé
-- TARANTOOL trouvé : /usr/include (version trouvée "2.4.2-80-g18f2bc82d")
-- Tarantool LUADIR est /.rocks/share/tarantool/rocks/http/scm-1/lua
-- Tarantool LIBDIR est /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configuration terminée
-- Génération terminée
Avertissement CMake :
  Les variables spécifiées manuellement n'ont pas été utilisées par le projet :

    version


-- Les fichiers de construction ont été écrits dans : /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Analyse des dépendances de la cible httpd
[ 50%] Construction de l'objet C http/CMakeFiles/httpd.dir/lib.c.o
Dans le fichier inclus de /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0 :
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: Dans la fonction ‘tpl_term’ :
/usr/include/tarantool/lauxlib.h:144:15: avertissement : cette déclaration peut tomber à travers [-Wimplicit-fallthrough=]
    (*(B)->p++ = (char)(c)))
    ~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: note : dans l'expansion de la macro ‘luaL_addchar’
       luaL_addchar(b, '\');
       ^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: note : ici
      default:
      ^~~~~~~
Dans le fichier inclus de /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0 :
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: Dans la fonction ‘tpe_parse’ :
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: avertissement : cette déclaration peut tomber à travers [-Wimplicit-fallthrough=]
    type = TPE_TEXT;
    ~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: note : ici
   case TPE_LINECODE:
   ^~~~
Dans le fichier inclus de /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0 :
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: Dans la fonction ‘httpfast_parse’ :
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: avertissement : cette déclaration peut tomber à travers [-Wimplicit-fallthrough=]
                 code = 0;
                 ~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: note : ici
             case status:
             ^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: avertissement : cette déclaration peut tomber à travers [-Wimplicit-fallthrough=]
                 state = message;
                 ~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: note : ici
             case message:
             ^~~~
[100%] Lien de la bibliothÚque partagée C lib.so
[100%] Cible httpd construite
[100%] Cible httpd construite
Installer le projet...
-- Configuration d'installation : "Debug"
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installation : /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 est maintenant installé dans /.rocks (license : BSD)

root@test2:/#

Nous avons également besoin de prometheus pour démarrer :

root@test2:~# tarantoolctl rocks install prometheus
Installation de http://rocks.tarantool.org/prometheus-scm-1.rockspec

Clonage dans 'prometheus'...
remote: Enumération des objets : 19, fait.
remote: Comptage des objets : 100 % (19/19), fait.
remote: Compression des objets : 100 % (19/19), fait.
remote: Total 19 (delta 2), réutilisé 5 (delta 0), pack-réutilisé 0
Réception des objets : 100 % (19/19), 10.73 KiB | 10.73 MiB/s, fait.
Résolution des deltas : 100 % (2/2), fait.
prometheus scm-1 est maintenant installé dans /.rocks (licence : BSD)

root@test2:~#

Nous lançons et pouvons accéder aux modules

root@test2:~# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Serveur : 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
Serveur : 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
Serveur : Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection : keep-alive

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

/count ĐŸŃ‚ĐŽĐ°Đ”Ń‚ ĐœĐ°ĐŒ статус 200.
/token ĐČыЎаДт Ń‚ĐŸĐșĐ”Đœ Đž ЎДлаДт Đ·Đ°ĐżĐžŃŃŒ ŃŃ‚ĐŸĐłĐŸ Ń‚ĐŸĐșĐ”ĐœĐ° ĐČ Đ±Đ°Đ·Ńƒ.

Testons la vitesse

Lançons un benchmark avec 50 000 requĂȘtes. Le nombre de requĂȘtes concurrentes sera de 500.

root@test2:~# ab -c 500 -n 50000 http://127.0.0.1:8080/token
This is ApacheBench, Version 2.3 
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 (soyez patient)
5000 requĂȘtes terminĂ©es
10000 requĂȘtes terminĂ©es
15000 requĂȘtes terminĂ©es
20000 requĂȘtes terminĂ©es
25000 requĂȘtes terminĂ©es
30000 requĂȘtes terminĂ©es
35000 requĂȘtes terminĂ©es
40000 requĂȘtes terminĂ©es
45000 requĂȘtes terminĂ©es
50000 requĂȘtes terminĂ©es
50000 requĂȘtes finalisĂ©es


Logiciel serveur :        Tarantool
Nom d'hĂŽte serveur :        127.0.0.1
Port serveur :            8080

Chemin du document :          /token
Longueur du document :        44 octets

Niveau de concurrence :      500
Temps pris pour les tests :   14.578 secondes
RequĂȘtes complĂštes :      50000
RequĂȘtes Ă©chouĂ©es :        0
Total transféré :      7950000 octets
HTML transféré :       2200000 octets
RequĂȘtes par seconde :    3429.87 [# /sec] (moyenne)
Temps par requĂȘte :       145.778 [ms] (moyenne)
Temps par requĂȘte :       0.292 [ms] (moyenne, sur toutes les requĂȘtes concurrentes)
Taux de transfert :          532.57 [Ko/sec] reçu

Temps de connexion (ms)
              min  mean[+/-sd] median   max
Connexion :        0   10 103.2      0    3048
Traitement :    12   69 685.1     15   13538
Attente :       12   69 685.1     15   13538
Total :         12   78 768.2     15   14573

Pourcentage des requĂȘtes servies dans un certain temps (ms)
  50 %     15
  66 %     15
  75 %     16
  80 %     16
  90 %     16
  95 %     16
  98 %     21
  99 %     42
 100 %  14573 (requĂȘte la plus longue)
root@test2:~#

Les tokens sont gĂ©nĂ©rĂ©s. Nous enregistrons constamment des donnĂ©es. 99 % des requĂȘtes ont Ă©tĂ© traitĂ©es en 42 millisecondes. Cela nous donne environ 3500 requĂȘtes par seconde sur une petite machine avec 2 cƓurs et 4 Go de mĂ©moire.

Il est également possible de sélectionner un token de 50000 et de voir sa valeur.

Vous pouvez utiliser non seulement http, mais aussi exĂ©cuter des fonctions en arriĂšre-plan qui traitent vos donnĂ©es. De plus, il existe diffĂ©rents dĂ©clencheurs. Par exemple, vous pouvez appeler des fonctions lors de mises Ă  jour, vĂ©rifier certaines choses – corriger des conflits.

Il est possible d'écrire des applications scripts directement sur le serveur de la base de données, sans aucune limitation, en connectant n'importe quel module et en réalisant n'importe quelle logique.

Le serveur d'applications peut se connecter à des serveurs externes, récupérer des données et les stocker dans sa propre base. Ces données seront utilisées par d'autres applications.

C'est Tarantool qui s'en chargera, et il ne sera pas nécessaire d'écrire une application séparée.

En conclusion

Ce n'est que la premiÚre partie d'un grand travail. La deuxiÚme sera publiée trÚs bientÎt sur le blog de Mail.ru Group, et nous ajouterons certainement un lien vers celle-ci dans ce matériel.

Si vous ĂȘtes intĂ©ressĂ© Ă  participer Ă  des Ă©vĂ©nements oĂč nous crĂ©ons ce genre de choses en ligne et Ă  poser des questions en temps rĂ©el, rejoignez-nous sur la chaĂźne DevOps by REBRAIN.

Si vous avez besoin de passer au cloud ou si vous avez des questions sur votre infrastructure, n'hésitez pas à laisser une demande.

P.S. Nous avons 2 audits gratuits par mois, peut-ĂȘtre que votre projet sera l'un d'eux.

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster