در Tarantool می توانید یک پایگاه داده فوق سریع و یک برنامه کاربردی را برای کار با آنها ترکیب کنید. در اینجا این است که چگونه انجام آن آسان است

پنج سال پیش سعی کردم با Tarantool کار کنم، اما بعد از آن برای من کار نکرد. اما اخیرا یک وبینار برگزار کردم که در آن درباره Hadoop و نحوه عملکرد MapReduce صحبت کردم. در آنجا از من یک سوال پرسیدند: "چرا از Tarantool برای این کار استفاده نمی کنید؟"

از روی کنجکاوی، تصمیم گرفتم به آن برگردم، آخرین نسخه را آزمایش کنم - و این بار این پروژه را خیلی دوست داشتم. حالا من به شما نشان می دهم که چگونه یک برنامه ساده در Tarantool بنویسید، آن را بارگذاری کنید و عملکرد آن را بررسی کنید و خواهید دید که همه چیز چقدر آسان و جالب است.

در Tarantool می توانید یک پایگاه داده فوق سریع و یک برنامه کاربردی را برای کار با آنها ترکیب کنید. در اینجا این است که چگونه انجام آن آسان است

Tarantool چیست

Tarantool خود را به عنوان یک پایگاه داده فوق سریع معرفی می کند. شما می توانید هر داده ای را که می خواهید در آنجا قرار دهید. بعلاوه، تکثیر آنها، خرده - یعنی تقسیم حجم عظیمی از داده ها در چندین سرور و ترکیب نتایج حاصل از آنها - اتصالات کارشناسی ارشد مقاوم در برابر خطا ایجاد کنید.

در مرحله دوم، این یک سرور برنامه است. می توانید برنامه های خود را روی آن بنویسید، با داده ها کار کنید، به عنوان مثال، طبق قوانین خاصی رکوردهای قدیمی را در پس زمینه حذف کنید. می‌توانید مستقیماً یک سرور Http در Tarantula بنویسید که با داده‌ها کار می‌کند: مقدار آنها را ارائه دهید، داده‌های جدید را در آنجا بنویسید و همه آن‌ها را به Master کاهش دهید.

من مقاله ای را خواندم در مورد اینکه چگونه بچه ها یک صف پیام 300 خطی ایجاد کردند که فقط در حال انفجار و عجله است - آنها حداقل عملکرد 20 پیام در ثانیه دارند. در اینجا می توانید واقعاً بچرخید و یک برنامه بسیار بزرگ بنویسید و مانند PostgreS ذخیره سازی نخواهد بود.

من سعی خواهم کرد چیزی شبیه به این سرور را در این مقاله توضیح دهم.

نصب

برای آزمایش، من سه ماشین مجازی استاندارد را راه اندازی کردم - یک هارد دیسک 20 گیگابایتی، اوبونتو 18.04. 2 سی پی یو مجازی و 4 گیگ حافظه.

ما Tarantool را نصب می کنیم - اسکریپت bash را اجرا می کنیم یا یک مخزن اضافه می کنیم و apt دریافت Tarantool را نصب می کنیم. پیوند به اسکریپت - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). ما دستوراتی داریم مانند:

tarantoolctl - فرمان اصلی برای مدیریت نمونه های Tarantula.
/etc/tarantool - اینجا کل پیکربندی است.
var/log/tarantool - اینجا سیاههها هستند.
var/lib/tarantool - داده ها در اینجا قرار دارند و سپس به نمونه هایی تقسیم می شوند.

پوشه‌های instance-avail و instance-enable وجود دارد - حاوی مواردی است که راه‌اندازی می‌شود - یک فایل پیکربندی نمونه با کد lua، که توصیف می‌کند به چه پورت‌هایی گوش می‌دهد، چه حافظه‌ای در دسترس است، تنظیمات موتور وینیل، کدی که هنگام راه‌اندازی اجرا می‌شود. سرورها، اشتراک گذاری، صف ها، حذف داده های منسوخ و غیره.

نمونه ها مانند PostgreS کار می کنند. به عنوان مثال، شما می خواهید چندین نسخه از یک پایگاه داده را اجرا کنید که روی پورت های مختلف آویزان است. به نظر می رسد که چندین نمونه پایگاه داده روی یک سرور راه اندازی می شوند که در پورت های مختلف آویزان می شوند. آنها ممکن است تنظیمات کاملا متفاوتی داشته باشند - یک نمونه یک منطق را اجرا می کند، دومی - دیگری.

مدیریت نمونه

ما دستور tarantoolctl را داریم که به شما امکان می دهد نمونه های Tarantula را مدیریت کنید. به عنوان مثال، نمونه بررسی tarantoolctl فایل پیکربندی را بررسی می کند و می گوید - اگر هیچ خطای نحوی وجود نداشته باشد، فایل اوکی است.

می توانید وضعیت نمونه را مشاهده کنید - مثال وضعیت tarantoolctl. به همین ترتیب می توانید شروع، توقف، راه اندازی مجدد را انجام دهید.

هنگامی که نمونه اجرا می شود، می توانید از دو طریق به آن متصل شوید.

1. کنسول اداری

به طور پیش فرض، Tarantool یک سوکت را باز می کند و متن ASCII معمولی برای کنترل Tarantool به آنجا ارسال می شود. اتصال به کنسول همیشه توسط کاربر ادمین انجام می شود، هیچ احراز هویتی وجود ندارد، بنابراین برای مدیریت Tarantula نیازی به خارجی سازی پورت کنسول نیست.

برای اتصال با استفاده از این روش، باید نام نمونه Tarantoolctl را وارد کنید. این دستور کنسول را راه اندازی می کند و به عنوان کاربر مدیر متصل می شود. هرگز پورت کنسول را در معرض بیرون قرار ندهید - بهتر است آن را به عنوان سوکت واحد بگذارید. سپس فقط کسانی که دسترسی به نوشتن به سوکت دارند می توانند به Tarantula متصل شوند.

این روش برای امور اداری مورد نیاز است. برای کار با داده ها، از روش دوم - پروتکل باینری استفاده کنید.

2. استفاده از پروتکل باینری برای اتصال به یک پورت خاص

این پیکربندی شامل یک دستورالعمل گوش دادن است که یک پورت برای ارتباطات خارجی باز می کند. این پورت با پروتکل باینری استفاده می شود و احراز هویت در آنجا فعال است.

برای این اتصال از tarantoolctl connect to port number استفاده می شود. با استفاده از آن، می توانید به سرورهای راه دور متصل شوید، از احراز هویت استفاده کنید و حقوق دسترسی مختلف بدهید.

ماژول ضبط داده و جعبه

از آنجایی که 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. حافظه تمام داده ها را در حافظه ذخیره می کند. بنابراین، همه چیز به سادگی و به سرعت کار می کند. داده ها روی دیسک ریخته می شوند، و همچنین یک مکانیسم ثبت پیش از نوشتن وجود دارد، بنابراین در صورت خرابی سرور چیزی از دست نخواهیم داد.

وینیل داده ها را روی دیسک به شکلی که برای ما آشناتر است ذخیره می کند - یعنی شما می توانید داده های بیشتری از حافظه ما ذخیره کنید و Tarantula آن را از روی دیسک می خواند.

در حال حاضر از 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>

فهرست مطالب:

یک شاخص اولیه باید برای هر فضایی ایجاد شود، زیرا بدون آن هیچ چیز کار نخواهد کرد. مانند هر پایگاه داده، اولین فیلد را ایجاد می کنیم - شناسه رکورد.

بخش:

در اینجا ما نشان می دهیم که شاخص ما از چه چیزی تشکیل شده است. از یک قسمت تشکیل شده است - اولین فیلدی که استفاده خواهیم کرد از نوع بدون علامت است - یک عدد صحیح مثبت. تا جایی که من از مستندات به یاد دارم، حداکثر عددی که می تواند باشد 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 که در بالا توضیح دادم مشخص شده اند.

خروجی داده

سپس با استفاده از دستور select می توانیم داده ها را نمایش دهیم.

Box.example.select با کلید {1} ورودی مورد نظر را نمایش می دهد. اگر کلید را پایین بیاوریم، تمام رکوردهایی را که داریم می بینیم. همه آنها در تعداد ستون ها متفاوت هستند، اما در اینجا، در اصل، هیچ مفهومی از ستون ها وجود ندارد - اعداد فیلد وجود دارد.

مطلقاً هر مقدار داده می تواند وجود داشته باشد. و برای مثال باید آنها را با فیلد دوم جستجو کنیم. برای انجام این کار، یک شاخص ثانویه جدید ایجاد می کنیم.


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

ما از دستور Create_index استفاده می کنیم.
بیایید آن را ثانویه بنامیم.

پس از این باید پارامترها را مشخص کنید. نوع شاخص TREE است. ممکن است منحصر به فرد نباشد، بنابراین Unique = false را وارد کنید.

سپس نشان می دهیم که شاخص ما از چه قسمت هایی تشکیل شده است. فیلد تعداد فیلدی است که ایندکس را به آن متصل می کنیم و نوع رشته را مشخص می کنیم. و به این ترتیب ایجاد شد.

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”;

استفاده از داده

با آنچه اکنون نوشتیم، می توانید از Tarantula برای ذخیره داده ها استفاده کنید و خیلی سریع به عنوان یک پایگاه داده کار می کند. و حالا می توانید با همه اینها کاری انجام دهید.

نوشتن یک برنامه

برای مثال برنامه زیر را برای رتیل بنویسیم

اپلیکیشن زیر اسپویلر را ببینید

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

پس از این، ما در پورت 8080 در تمام رابط های سرور http شروع می کنیم، که تمام درخواست ها و خطاها را ثبت می کند.

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)

کجای صف router:route({method = 'GET', path = '/token'}, function() تابع را فراخوانی می کنیم و یک نشانه تولید می کنیم.

خط نشانه محلی = randomString (32) یک رشته تصادفی از 32 کاراکتر است.
در صف local last = box.space.example:len() ما آخرین عنصر را بیرون می آوریم.
و در خط box.space.example:insert{ last + 1, token } ما داده ها را در پایگاه داده خود می نویسیم، یعنی به سادگی شناسه را 1 افزایش می دهیم. اتفاقاً این کار را می توان نه تنها به این روش ناشیانه انجام داد. سکانس هایی برای این کار در Tarantula وجود دارد.

توکن را در آنجا می نویسیم.

بنابراین، ما برنامه را در یک فایل نوشتیم. شما می توانید مستقیماً داده ها را در آنجا دستکاری کنید و ماژول جعبه تمام کارهای کثیف را برای شما انجام می دهد.

به 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 درخواست رقابتی وجود خواهد داشت.

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 استفاده کنید، بلکه می توانید توابع پس زمینه ای را نیز اجرا کنید که داده های شما را پردازش می کنند. به علاوه محرک های مختلفی وجود دارد. به عنوان مثال، می توانید توابع را در به روز رسانی ها فراخوانی کنید، چیزی را بررسی کنید - تضادها را اصلاح کنید.

شما می توانید برنامه های اسکریپت را مستقیماً در خود سرور پایگاه داده بنویسید و با هیچ چیز محدود نشوید، ماژول ها را به هم متصل کنید و هر منطقی را پیاده سازی کنید.

سرور برنامه می تواند به سرورهای خارجی دسترسی پیدا کند، داده ها را بازیابی کرده و به پایگاه داده خود اضافه کند. داده های این پایگاه داده توسط برنامه های کاربردی دیگر استفاده خواهد شد.

Tarantula خود این کار را انجام می دهد و نیازی به نوشتن برنامه جداگانه ندارید.

در نتیجه

این تنها قسمت اول یک کار بزرگ است. دومین مورد به زودی در وبلاگ گروه Mail.ru منتشر خواهد شد و قطعاً پیوندی به آن در این مطالب اضافه خواهیم کرد.

اگر علاقه مند به شرکت در رویدادهایی هستید که در آن ما این موارد را به صورت آنلاین می سازیم و در زمان واقعی سؤال می پرسیم، هماهنگ کنید کانال DevOps توسط REBRAIN.

اگر نیاز به انتقال به ابر دارید یا در مورد زیرساخت خود سؤالی دارید، با خیال راحت درخواستی بگذارید.

PS ما 2 ممیزی رایگان در ماه داریم، شاید پروژه شما یکی از آنها باشد.

منبع: www.habr.com

اضافه کردن نظر