Tarantool'da, süper hızlı bir veritabanı ile bir uygulamayı onlarla çalışmak için birleştirebilirsiniz. İşte bunu yapmak ne kadar kolay

Beş yıl önce Tarantool ile çalışmayı denedim ama sonra işe yaramadı. Ancak yakın zamanda Hadoop ve MapReduce'un nasıl çalıştığı hakkında konuştuğum bir web semineri düzenledim. Orada bana bir soru sordular: "Neden bu görev için Tarantool kullanmıyorsunuz?"

Merakımdan ona geri dönmeye, en son sürümü test etmeye karar verdim - ve bu sefer projeyi gerçekten beğendim. Şimdi size Tarantool'da basit bir uygulamanın nasıl yazılacağını, yükleneceği ve performansının nasıl kontrol edileceğini göstereceğim ve her şeyin ne kadar kolay ve harika olduğunu göreceksiniz.

Tarantool'da, süper hızlı bir veritabanı ile bir uygulamayı onlarla çalışmak için birleştirebilirsiniz. İşte bunu yapmak ne kadar kolay

Tarantool nedir?

Tarantool kendisini ultra hızlı bir veritabanı olarak konumlandırıyor. Oraya istediğiniz veriyi koyabilirsiniz. Ayrıca bunları çoğaltın, parçalayın (yani büyük miktarda veriyi birkaç sunucuya bölün ve bunlardan elde edilen sonuçları birleştirin) hataya dayanıklı ana-ana bağlantılar yapın.

İkincisi, bu bir uygulama sunucusudur. Üzerine uygulamalarınızı yazabilir, verilerle çalışabilir, örneğin arka planda eski kayıtları belirli kurallara göre silebilirsiniz. Doğrudan Tarantula'ya verilerle çalışacak bir Http sunucusu yazabilirsiniz: miktarlarını verin, oraya yeni veriler yazın ve hepsini ana bilgisayara azaltın.

Adamların nasıl 300 satırlık bir mesaj kuyruğu oluşturduğuna dair bir makale okudum, bu sadece patlama ve aceleden ibarettir - saniyede minimum 20 mesaj performansına sahiptirler. Burada gerçekten geri dönüp çok büyük bir uygulama yazabilirsiniz ve bu, PostgreS'te olduğu gibi depolama olmayacaktır.

Bu yazıda bu sunucuya benzer bir şeyi çok basit bir şekilde anlatmaya çalışacağım.

Montaj

Test için üç standart sanal makine başlattım: 20 GB sabit sürücü, Ubuntu 18.04. 2 sanal CPU ve 4 gig bellek.

Tarantool'u kuruyoruz - bash betiğini çalıştırıyoruz veya bir depo ekliyoruz ve Tarantool'u apt get install yapıyoruz. Komut dosyasına bağlantı - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Şunun gibi komutlarımız var:

tarantoolctl — Tarantula örneklerini yönetmek için ana komut.
/etc/tarantool - işte tüm konfigürasyon.
var/log/tarantool - işte günlükler.
var/lib/tarantool — veriler burada yatıyor ve ardından örneklere bölünüyor.

Örnek olarak kullanılabilen ve örneğin etkinleştirilebilen klasörler vardır - nelerin başlatılacağını içerir - hangi bağlantı noktalarını dinlediğini, hangi belleğin kullanılabilir olduğunu, Vinil motor ayarlarını, başlangıçta çalışan kodu açıklayan lua kodlu bir örnek yapılandırma dosyası sunucular, parçalama, kuyruklar, eski verilerin silinmesi vb.

Örnekler PostgreS'deki gibi çalışır. Örneğin, farklı bağlantı noktalarında asılı olan bir veritabanının birkaç kopyasını çalıştırmak istiyorsunuz. Farklı bağlantı noktalarında asılı olan bir sunucuda birkaç veritabanı örneğinin başlatıldığı ortaya çıktı. Tamamen farklı ayarlara sahip olabilirler - bir örnek bir mantığı uygular, ikincisi - diğeri.

Örnek Yönetimi

Tarantula örneklerini yönetmenize olanak tanıyan tarantoolctl komutumuz var. Örneğin, tarantoolctl kontrol örneği, yapılandırma dosyasını kontrol edecek ve şunu söyleyecektir: eğer orada sözdizimi hatası yoksa dosya tamamdır.

Örneğin tarantoolctl durum örneğinin durumunu görebilirsiniz. Aynı şekilde başlatma, durdurma, yeniden başlatma işlemlerini de yapabilirsiniz.

Örnek çalışmaya başladıktan sonra ona iki şekilde bağlanabilirsiniz.

1. Yönetim konsolu

Varsayılan olarak, Tarantool bir soket açar ve Tarantool'u kontrol etmek için buraya normal ASCII metni gönderilir. Konsola bağlantı her zaman yönetici kullanıcı altında gerçekleşir, kimlik doğrulaması yoktur, dolayısıyla Tarantula'yı yönetmek için konsol bağlantı noktasını haricileştirmeye gerek yoktur.

Bu yöntemi kullanarak bağlanmak için Tarantoolctl'e örnek adını girmeniz gerekir. Komut konsolu başlatacak ve yönetici kullanıcı olarak bağlanacaktır. Konsol portunu asla dışarıya maruz bırakmayın; onu ünite soketi olarak bırakmak daha iyidir. O zaman yalnızca sokete yazma erişimi olan kişiler Tarantula'ya bağlanabilecek.

Bu yöntem idari işler için gereklidir. Verilerle çalışmak için ikinci yöntemi kullanın - ikili protokol.

2. Belirli bir bağlantı noktasına bağlanmak için ikili protokol kullanma

Yapılandırma, harici iletişim için bir bağlantı noktası açan bir dinleme yönergesi içerir. Bu bağlantı noktası ikili protokolle birlikte kullanılır ve kimlik doğrulama burada etkinleştirilir.

Bu bağlantı için tarantoolctl connect to port numarası kullanılır. Bunu kullanarak uzak sunuculara bağlanabilir, kimlik doğrulamayı kullanabilir ve çeşitli erişim hakları verebilirsiniz.

Veri Kayıt ve Kutu Modülü

Tarantool hem veritabanı hem de uygulama sunucusu olduğundan çeşitli modüllere sahiptir. Kutu modülüyle ilgileniyoruz - verilerle çalışmayı uyguluyor. Kutuya bir şey yazdığınızda, Tarantool verileri diske yazar, hafızada saklar veya onunla başka bir şey yapar.

Kayıt

Örneğin box modülüne girip box.once fonksiyonunu çağırıyoruz. Bu, sunucu başlatıldığında Tarantool'u kodumuzu çalıştırmaya zorlayacaktır. Verilerimizin saklanacağı bir alan yaratıyoruz.

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

Bundan sonra, veri arayabileceğimiz birincil bir dizin (birincil) oluşturuyoruz. Varsayılan olarak herhangi bir parametre belirtmezseniz, birincil dizin için her kayıttaki ilk alan kullanılır.

Daha sonra konuk kullanıcıya ikili protokol aracılığıyla bağlandığımız bir hibe veriyoruz. Tüm örnekte okuma, yazma ve çalıştırmaya izin veriyoruz.

Geleneksel veritabanlarıyla karşılaştırıldığında burada her şey oldukça basittir. Verilerimizin basitçe depolandığı bir alan olan alanımız var. Her kayda tuple denir. Mesaj Paketi'nde paketlenmiştir. Bu çok harika bir formattır - ikilitir ve daha az yer kaplar - 18 bayta karşı 27 bayt.

Tarantool'da, süper hızlı bir veritabanı ile bir uygulamayı onlarla çalışmak için birleştirebilirsiniz. İşte bunu yapmak ne kadar kolay

Onunla çalışmak oldukça uygun. Hemen hemen her satır, her veri kaydı tamamen farklı sütunlara sahip olabilir.

Box.space komutunu kullanarak tüm alanları görüntüleyebiliriz. Belirli bir örneği seçmek için box.space örneğini yazın ve onun hakkında tam bilgi edinin.

Tarantool'un iki yerleşik motoru vardır: Bellek ve Vinil. Bellek, tüm verileri bellekte saklar. Bu nedenle her şey basit ve hızlı çalışır. Veriler diske dökülür ve ayrıca bir önceden yazma günlüğü mekanizması da vardır, böylece sunucu çökerse hiçbir şey kaybetmeyiz.

Vinyl, verileri diskte bize daha tanıdık bir biçimde saklar - yani, hafızamızda olduğundan daha fazla veri saklayabilirsiniz ve Tarantula bunları diskten okuyacaktır.

Şimdilik Memory'i kullanacağız.

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>

Dizin:

Herhangi bir alan için birincil dizin oluşturulmalıdır çünkü o olmadan hiçbir şey çalışmaz. Herhangi bir veritabanında olduğu gibi, ilk alanı - kayıt kimliğini oluşturuyoruz.

Parçalar:

Burada endeksimizin nelerden oluştuğunu belirtiyoruz. Tek bölümden oluşur - kullanacağımız ilk alan imzasız türdendir - pozitif bir tamsayı. Belgelerden hatırladığım kadarıyla olabilecek maksimum sayı 18 kentilyon. Bu çok fazla.

Daha sonra insert komutunu kullanarak veri ekleyebiliriz.

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>

İlk alan birincil anahtar olarak kullanıldığından benzersiz olması gerekir. Sütun sayısıyla sınırlı olmadığımız için oraya istediğimiz kadar veri girebiliyoruz. Yukarıda anlattığım Mesaj Paketi formatında belirtilirler.

Veri çıkışı

Daha sonra select komutunu kullanarak verileri görüntüleyebiliriz.

{1} tuşuyla Box.example.select istenilen girişi görüntüleyecektir. Anahtarı indirirsek elimizdeki tüm kayıtları göreceğiz. Hepsi sütun sayısında farklılık gösterir, ancak burada prensip olarak sütun kavramı yoktur - alan numaraları vardır.

Kesinlikle herhangi bir miktarda veri olabilir. Mesela onları ikinci alana göre aramamız gerekiyor. Bunu yapmak için yeni bir ikincil dizin oluşturuyoruz.


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

Create_index komutunu kullanıyoruz.
Buna İkincil diyelim.

Bundan sonra parametreleri belirtmeniz gerekir. Dizin türü AĞAÇ'tır. Benzersiz olmayabilir, bu nedenle Benzersiz = yanlış değerini girin.

Daha sonra indeksimizin hangi kısımlardan oluştuğunu belirtiyoruz. Alan, dizini bağladığımız alanın numarasıdır ve dize türünü belirtir. Ve böylece yaratıldı.

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>

Şimdi bunu şu şekilde adlandırabiliriz:

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

koruma

Örneği yeniden başlatırsak ve verileri tekrar çağırmayı denersek, orada olmadığını göreceğiz - her şey boş. Bunun nedeni Tarantool'un kontrol noktaları oluşturması ve verileri diske kaydetmesidir, ancak bir sonraki kaydetmeye kadar çalışmayı bırakırsak tüm işlemleri kaybederiz - çünkü örneğin iki saat önceki son kontrol noktasından kurtuluruz.

Her saniyeden tasarruf etmek de işe yaramayacaktır çünkü sürekli olarak 20 GB'yi diske boşaltmak iyi bir fikir değildir.

Bu amaçla yazma öncesi log kavramı icat edildi ve uygulandı. Onun yardımıyla verilerdeki her değişiklik için küçük bir yazma öncesi günlük dosyasında bir giriş oluşturulur.

Kontrol noktasına kadar olan her giriş bunlarda saklanır. Bu dosyalar için boyutu ayarladık - örneğin 64 MB. Dolduğunda kayıt ikinci dosyaya gitmeye başlar. Yeniden başlatmanın ardından Tarantool, son kontrol noktasından geri yüklenir ve daha sonra durana kadar sonraki tüm işlemleri devreder.

Tarantool'da, süper hızlı bir veritabanı ile bir uygulamayı onlarla çalışmak için birleştirebilirsiniz. İşte bunu yapmak ne kadar kolay

Bu tür bir kaydı gerçekleştirmek için box.cfg ayarlarında (example.lua dosyasında) seçeneği belirtmeniz gerekir:

wal_mode = “write”;

Veri kullanımı

Şimdi yazacaklarımızla Tarantula'yı veri depolamak için kullanabilirsiniz ve veritabanı olarak çok hızlı çalışacaktır. Ve şimdi tüm bunlarla yapabileceğiniz şey pastanın üzerine krema koymak.

Başvuru yazma

Örnek olarak Tarantula için aşağıdaki uygulamayı yazalım.

Spoiler altındaki uygulamaya bakın

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'da karakterleri tanımlayan bir tablo tanımlıyoruz. Bu plaka rastgele bir dizi oluşturmak için gereklidir.

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

Bundan sonra - randomString fonksiyonunu bildiriyoruz ve uzunluk değerini parantez içinde veriyoruz.

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

Daha sonra http router ve http sunucusunu client’a göndereceğimiz Tarantula sunucumuz JSON’a bağlıyoruz.

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

Bundan sonra, tüm istekleri ve hataları günlüğe kaydedecek olan tüm http sunucu arayüzlerinde 8080 numaralı bağlantı noktasından başlıyoruz.

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

Daha sonra rotayı beyan ederiz, böylece 8080 /count numaralı bağlantı noktasına GET yöntemiyle bir istek gelirse, işlevi bir satırdan çağırırız. 200, 404, 403 veya belirttiğimiz herhangi bir durumu döndürür.

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

Gövdede json.encode'u döndürüyoruz, içinde adı verilen ve veritabanımızdaki kayıt sayısını gösteren count ve getcount'u belirtiyoruz.

Ikinci yöntem

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)

Hattın neresinde yönlendirici:rota({method = 'GET', yol = '/token'}, function() işlevi çağırıyoruz ve bir jeton oluşturuyoruz.

Hat yerel belirteç = randomString(32) 32 karakterden oluşan rastgele bir dizedir.
Çizgide yerel son = box.space.example:len() son unsuru çıkarıyoruz.
Ve çizgide box.space.example:insert{ son + 1, jeton } veri tabanımıza veri yazıyoruz, yani sadece ID'yi 1 artırıyoruz. Bu arada, bu sadece bu kadar beceriksiz bir şekilde yapılamaz. Tarantula'da bunun için diziler var.

Jetonumuzu oraya yazıyoruz.

Böylece uygulamayı tek dosyaya yazdık. Oradaki verileri doğrudan değiştirebilirsiniz ve box modülü tüm kirli işleri sizin için yapacaktır.

Http'yi dinler ve verilerle çalışır, her şey tek bir örnektedir - hem uygulama hem de veriler. Bu nedenle her şey oldukça hızlı gerçekleşir.

Başlamak için http modülünü kuruyoruz:

Bunu nasıl yapıyoruz, spoiler altına bakın

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

Çalıştırmak için ayrıca prometheus'a ihtiyacımız var:

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

Modülleri başlatıyoruz ve bunlara erişebiliyoruz

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 bize 200 durumunu verir.
/token bir belirteç yayınlar ve bu belirteci veritabanına yazar.

Hızın test edilmesi

50 istek için bir kıyaslama çalıştıralım. 000 yarışan istek olacak.

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

Jetonlar verilir. Ve sürekli veri kaydediyoruz. İsteklerin %99'u 42 milisaniyede işlendi. Buna göre 3500 çekirdekli ve 2 gigabayt belleğe sahip küçük bir makinede saniyede yaklaşık 4 istek alıyoruz.

Ayrıca yaklaşık 50000 jeton seçip değerini görebilirsiniz.

Yalnızca http'yi değil, verilerinizi işleyen arka plan işlevlerini de çalıştırabilirsiniz. Ayrıca çeşitli tetikleyiciler var. Örneğin, güncellemelerde işlevleri çağırabilir, bir şeyi kontrol edebilir, çakışmaları düzeltebilirsiniz.

Komut dosyası uygulamalarını doğrudan veritabanı sunucusunun kendisine yazabilir ve hiçbir şeyle sınırlandırılmadan, herhangi bir modülü bağlayabilir ve herhangi bir mantığı uygulayabilirsiniz.

Uygulama sunucusu harici sunuculara erişebilir, verileri alabilir ve veritabanına ekleyebilir. Bu veritabanındaki veriler diğer uygulamalar tarafından kullanılacaktır.

Tarantula bunu kendisi yapacak ve ayrıca bir uygulama yazmanıza gerek kalmayacak.

Sonuç olarak

Bu büyük bir çalışmanın sadece ilk kısmı. İkincisi çok yakında Mail.ru Group blogunda yayınlanacak ve bu materyale kesinlikle bir bağlantı ekleyeceğiz.

Bunları çevrimiçi olarak oluşturduğumuz etkinliklere katılmak ve gerçek zamanlı sorular sormak ilginizi çekiyorsa, bizi takip edin REBRAIN'den kanal DevOps.

Buluta geçmeniz gerekiyorsa veya altyapınızla ilgili sorularınız varsa, İstek göndermekten çekinmeyin.

Not: Ayda 2 ücretsiz denetimimiz vardır, belki sizin projeniz de bunlardan biri olabilir.

Kaynak: habr.com

Yorum ekle