في Tarantool ، يمكنك الجمع بين قاعدة بيانات فائقة السرعة وتطبيق للعمل معهم. إليك مدى سهولة القيام بذلك

منذ خمس سنوات حاولت العمل مع Tarantool، لكن الأمر لم ينجح معي. لكنني عقدت مؤخرًا ندوة عبر الإنترنت تحدثت فيها عن Hadoop وكيفية عمل MapReduce. هناك سألوني سؤالاً: "لماذا لا تستخدم Tarantool لهذه المهمة؟"

بدافع الفضول، قررت العودة إليه واختبار أحدث إصدار - وهذه المرة أحببت المشروع حقًا. سأوضح لك الآن كيفية كتابة تطبيق بسيط في Tarantool، وتحميله والتحقق من أدائه، وسترى مدى سهولة وروعة كل شيء.

في Tarantool ، يمكنك الجمع بين قاعدة بيانات فائقة السرعة وتطبيق للعمل معهم. إليك مدى سهولة القيام بذلك

ما هو تارانتوول

يضع Tarantool نفسه كقاعدة بيانات فائقة السرعة. يمكنك وضع أي بيانات تريدها هناك. بالإضافة إلى ذلك، قم بتكرارها، والجزء - أي تقسيم كمية هائلة من البيانات عبر عدة خوادم ودمج النتائج منها - قم بإجراء اتصالات رئيسية متسامحة مع الأخطاء.

ثانيا، هذا هو خادم التطبيقات. يمكنك كتابة تطبيقاتك عليها، والعمل مع البيانات، على سبيل المثال، حذف السجلات القديمة في الخلفية وفقا لقواعد معينة. يمكنك كتابة خادم Http مباشرة في Tarantula والذي سيعمل مع البيانات: قم بإعطاء كميتها، واكتب بيانات جديدة هناك واختصرها كلها إلى السيد.

قرأت مقالًا عن كيفية إنشاء الرجال لقائمة انتظار رسائل مكونة من 300 سطر، وهو ببساطة متقطع ومتسرع - لديهم الحد الأدنى من الأداء وهو 20 رسالة في الثانية. هنا يمكنك حقًا الالتفاف وكتابة تطبيق كبير جدًا، ولن يكون مخزنًا، كما هو الحال في PostgreS.

سأحاول وصف شيء مثل هذا الخادم، بشكل بسيط، في هذه المقالة.

تركيب

للاختبار، قمت بتشغيل ثلاثة أجهزة افتراضية قياسية - محرك أقراص ثابتة سعة 20 جيجابايت، Ubuntu 18.04. 2 وحدة معالجة مركزية افتراضية و4 جيجا بايت من الذاكرة.

نقوم بتثبيت Tarantool - قم بتشغيل البرنامج النصي bash أو أضف مستودعًا وقم بإجراء apt get install Tarantool. رابط إلى البرنامج النصي - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). لدينا أوامر مثل:

com.tarantooctl — الأمر الرئيسي لإدارة حالات الرتيلاء.
/etc/tarantool - هنا التكوين بأكمله .
var/log/tarantool - وهنا السجلات.
var/lib/tarantool — البيانات تكمن هنا، ومن ثم يتم تقسيمها إلى حالات.

هناك مجلدات متاحة للمثيلات ومثيلات ممكنة - تحتوي على ما سيتم تشغيله - ملف تكوين المثيل مع كود lua، الذي يصف المنافذ التي يستمع إليها، والذاكرة المتوفرة له، وإعدادات محرك الفينيل، والرمز الذي يتم تشغيله عند بدء التشغيل الخوادم، والتجزئة، وقوائم الانتظار، وحذف البيانات القديمة، وما إلى ذلك.

تعمل المثيلات كما هو الحال في PostgreS. على سبيل المثال، تريد تشغيل عدة نسخ من قاعدة بيانات معلقة على منافذ مختلفة. اتضح أنه يتم إطلاق العديد من مثيلات قاعدة البيانات على خادم واحد، والتي يتم تعليقها على منافذ مختلفة. قد يكون لديهم إعدادات مختلفة تماما - مثيل واحد يطبق منطق واحد، والثاني - آخر.

إدارة المثيل

لدينا الأمر Tarantooctl، الذي يسمح لك بإدارة مثيلات Tarantula. على سبيل المثال، سيتحقق مثال التحقق من Tarantoolctl من ملف التكوين ويقول - الملف على ما يرام إذا لم تكن هناك أخطاء في بناء الجملة هناك.

يمكنك رؤية حالة المثيل - مثال لحالة Tarantooctl. بنفس الطريقة يمكنك البدء والتوقف وإعادة التشغيل.

بمجرد تشغيل المثيل، يمكنك الاتصال به بطريقتين.

1. وحدة التحكم الإدارية

افتراضيًا، يفتح Tarantool مأخذ توصيل ويتم إرسال نص ASCII العادي هناك للتحكم في Tarantool. يحدث الاتصال بوحدة التحكم دائمًا تحت المستخدم الإداري، ولا توجد مصادقة، لذلك ليست هناك حاجة لإضفاء الطابع الخارجي على منفذ وحدة التحكم لإدارة Tarantula.

للاتصال باستخدام هذه الطريقة، تحتاج إلى إدخال Tarantoolctl وإدخال اسم المثيل. سيقوم الأمر بتشغيل وحدة التحكم والاتصال كمستخدم مسؤول. لا تعرض أبدًا منفذ وحدة التحكم للخارج - فمن الأفضل تركه كمقبس وحدة. عندها فقط أولئك الذين لديهم حق الوصول للكتابة إلى المقبس سيكونون قادرين على الاتصال بـ Tarantula.

هذه الطريقة مطلوبة للأمور الإدارية. للعمل مع البيانات، استخدم الطريقة الثانية - البروتوكول الثنائي.

2. استخدام بروتوكول ثنائي للاتصال بمنفذ معين

يحتوي التكوين على توجيه الاستماع، الذي يفتح منفذًا للاتصالات الخارجية. يتم استخدام هذا المنفذ مع البروتوكول الثنائي ويتم تمكين المصادقة هناك.

لهذا الاتصال، يتم استخدام اتصال Tarantooctl برقم المنفذ. باستخدامه، يمكنك الاتصال بالخوادم البعيدة واستخدام المصادقة ومنح حقوق الوصول المختلفة.

تسجيل البيانات ووحدة الصندوق

نظرًا لأن Tarantool عبارة عن قاعدة بيانات وخادم تطبيقات، فهو يحتوي على وحدات مختلفة. نحن مهتمون بوحدة الصندوق - فهي تنفذ العمل مع البيانات. عندما تكتب شيئًا ما في الصندوق، يكتب Tarantool البيانات على القرص، أو يخزنها في الذاكرة، أو يفعل شيئًا آخر بها.

سجل

على سبيل المثال، نذهب إلى الوحدة النمطية box ونستدعي الدالة 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

بعد ذلك نقوم بإنشاء فهرس أساسي - أساسي - نستطيع من خلاله البحث عن البيانات. افتراضيًا، إذا لم تقم بتحديد أية معلمات، فسيتم استخدام الحقل الأول في كل سجل للفهرس الأساسي.

ثم نقوم بتقديم منحة للمستخدم الضيف، والتي بموجبها نتصل عبر البروتوكول الثنائي. نحن نسمح بالقراءة والكتابة والتنفيذ عبر المثيل بأكمله.

بالمقارنة مع قواعد البيانات التقليدية، كل شيء هنا بسيط للغاية. لدينا مساحة - منطقة يتم فيها تخزين بياناتنا ببساطة. ويسمى كل سجل Tuple. يتم تعبئتها في messagePack. هذا تنسيق رائع جدًا - فهو ثنائي ويستهلك مساحة أقل - 18 بايت مقابل 27.

في Tarantool ، يمكنك الجمع بين قاعدة بيانات فائقة السرعة وتطبيق للعمل معهم. إليك مدى سهولة القيام بذلك

من المريح جدًا العمل معه. يمكن أن يحتوي كل سطر تقريبًا وكل سجل بيانات على أعمدة مختلفة تمامًا.

يمكننا عرض جميع المساحات باستخدام أمر Box.space. لتحديد مثيل معين، اكتب مثال box.space واحصل على معلومات كاملة عنه.

يحتوي Tarantool على محركين مدمجين: الذاكرة والفينيل. تقوم الذاكرة بتخزين جميع البيانات في الذاكرة. ولذلك، كل شيء يعمل ببساطة وبسرعة. يتم تفريغ البيانات على القرص، وهناك أيضًا آلية سجل للكتابة المسبقة، لذلك لن نفقد أي شيء في حالة تعطل الخادم.

يقوم الفينيل بتخزين البيانات على القرص بشكل مألوف بالنسبة لنا - أي أنه يمكنك تخزين بيانات أكثر مما لدينا من ذاكرة، وسيقوم الرتيلاء بقراءتها من القرص.

في الوقت الحالي سوف نستخدم الذاكرة.

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 كوينتيليون. هذا كثير.

ثم يمكننا إدراج البيانات باستخدام أمر الإدراج.

unix/:/var/run/tarantool/example.control> box.space.example:insert{1, 'test1', 'test2'}
---
- [1, 'test1', 'test2']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{2, 'test2', 'test3', 'test4'}
---
- [2, 'test2', 'test3', 'test4']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{3, 'test3'}
---
- [3, 'test3']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{4, 'test4'}
---
- [4, 'test4']
...

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

يتم استخدام الحقل الأول كمفتاح أساسي، لذا يجب أن يكون فريدًا. نحن لا نقتصر على عدد الأعمدة، حتى نتمكن من إدراج أكبر قدر ممكن من البيانات هناك. تم تحديدها بتنسيق messagePack الذي وصفته أعلاه.

إخراج البيانات

ثم يمكننا عرض البيانات باستخدام أمر التحديد.

Box.example.select باستخدام المفتاح {1} سيعرض الإدخال المطلوب. إذا خفضنا المفتاح، فسنرى جميع السجلات التي لدينا. إنهم جميعا يختلفون في عدد الأعمدة، ولكن هنا، من حيث المبدأ، لا يوجد مفهوم للأعمدة - هناك أرقام الحقول.

يمكن أن يكون هناك أي قدر من البيانات على الإطلاق. وعلى سبيل المثال، نحن بحاجة للبحث عنها عن طريق الحقل الثاني. للقيام بذلك، نقوم بإنشاء فهرس ثانوي جديد.


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

نستخدم الأمر Create_index.
دعنا نسميها الثانوية.

بعد ذلك تحتاج إلى تحديد المعلمات. نوع الفهرس هو شجرة. قد لا يكون فريدًا، لذا أدخل 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 لتخزين البيانات وستعمل بسرعة كبيرة كقاعدة بيانات. والآن أصبح التزيين على الكعكة هو ما يمكنك فعله بكل شيء.

كتابة طلب

على سبيل المثال، لنكتب التطبيق التالي لـ 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 في النص، ونشير فيه إلى العدد و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)

أين في السطر جهاز التوجيه: الطريق ({method = 'GET'، المسار = '/ الرمز المميز'}، وظيفة () نحن نسمي الوظيفة وننشئ رمزًا مميزًا.

صف الرمز المحلي = سلسلة عشوائية (32) عبارة عن سلسلة عشوائية مكونة من 32 حرفًا.
في النسق آخر محلي = box.space.example:len() نخرج العنصر الأخير.
وفي السطر box.space.example:insert{ last + 1, token } نكتب البيانات في قاعدة بياناتنا، أي أننا ببساطة نزيد المعرف بمقدار 1. وبالمناسبة، يمكن القيام بذلك ليس بهذه الطريقة الخرقاء فقط. هناك تسلسلات لهذا في الرتيلاء.

نكتب الرمز المميز هناك.

وهكذا قمنا بكتابة الطلب في ملف واحد. يمكنك معالجة البيانات مباشرة هناك، وستقوم وحدة الصندوق بكل الأعمال القذرة نيابةً عنك.

يستمع إلى http ويعمل مع البيانات، كل شيء في مثيل واحد - كل من التطبيق والبيانات. لذلك، كل شيء يحدث بسرعة كبيرة.

للبدء، نقوم بتثبيت وحدة http:

كيف نفعل هذا، انظر تحت المفسد

root@test2:/# tarantoolctl rocks install http
Installing http://rocks.tarantool.org/http-scm-1.src.rock
Missing dependencies for http scm-1:
   checks >= 3.0.1 (not installed)

http scm-1 depends on checks >= 3.0.1 (not installed)
Installing http://rocks.tarantool.org/checks-3.0.1-1.rockspec

Cloning into 'checks'...
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 28 (delta 1), reused 16 (delta 1), pack-reused 0
Receiving objects: 100% (28/28), 12.69 KiB | 12.69 MiB/s, done.
Resolving deltas: 100% (1/1), done.
Note: checking out '580388773ef11085015b5a06fe52d61acf16b201'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

No existing manifest. Attempting to rebuild...
checks 3.0.1-1 is now installed in /.rocks (license: BSD)

-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found TARANTOOL: /usr/include (found version "2.4.2-80-g18f2bc82d")
-- Tarantool LUADIR is /.rocks/share/tarantool/rocks/http/scm-1/lua
-- Tarantool LIBDIR is /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    version


-- Build files have been written to: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Scanning dependencies of target httpd
[ 50%] Building C object http/CMakeFiles/httpd.dir/lib.c.o
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: In function ‘tpl_term’:
/usr/include/tarantool/lauxlib.h:144:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
    (*(B)->p++ = (char)(c)))
    ~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: note: in expansion of macro ‘luaL_addchar’
       luaL_addchar(b, '\');
       ^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: note: here
      default:
      ^~~~~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: In function ‘tpe_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
    type = TPE_TEXT;
    ~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: note: here
   case TPE_LINECODE:
   ^~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: In function ‘httpfast_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 code = 0;
                 ~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: note: here
             case status:
             ^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 state = message;
                 ~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: note: here
             case message:
             ^~~~
[100%] Linking C shared library lib.so
[100%] Built target httpd
[100%] Built target httpd
Install the project...
-- Install configuration: "Debug"
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 is now installed in /.rocks (license: BSD)

root@test2:/#

نحتاج أيضًا إلى بروميثيوس لتشغيل:

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

Cloning into 'prometheus'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 19 (delta 2), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (19/19), 10.73 KiB | 10.73 MiB/s, done.
Resolving deltas: 100% (2/2), done.
prometheus scm-1 is now installed in /.rocks (license: BSD)

root@test2:/#

نطلق ويمكننا الوصول إلى الوحدات

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"e2tPq9l5Z3QZrewRf6uuoJUl3lJgSLOI"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"fR5aCA84gj9eZI3gJcV0LEDl9XZAG2Iu"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/count
HTTP/1.1 200 Ok
Content-length: 11
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

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

/count يعطينا الحالة 200.
/token يصدر رمزًا مميزًا ويكتب هذا الرمز المميز في قاعدة البيانات.

اختبار السرعة

لنقم بتشغيل معيار لـ 50 طلب. سيكون هناك 000 طلب متنافس.

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 جيجابايت.

يمكنك أيضًا تحديد حوالي 50000 رمز مميز ومعرفة قيمتها.

لا يمكنك استخدام http فحسب، بل يمكنك أيضًا تشغيل وظائف الخلفية التي تعالج بياناتك. بالإضافة إلى وجود مشغلات مختلفة. على سبيل المثال، يمكنك استدعاء الوظائف على التحديثات، والتحقق من شيء ما - التعارضات الصحيحة.

يمكنك كتابة تطبيقات البرامج النصية مباشرة في خادم قاعدة البيانات نفسه، وعدم التقيد بأي شيء، وتوصيل أي وحدات وتنفيذ أي منطق.

يمكن لخادم التطبيق الوصول إلى الخوادم الخارجية واسترداد البيانات وإضافتها إلى قاعدة البيانات الخاصة به. سيتم استخدام البيانات من قاعدة البيانات هذه بواسطة تطبيقات أخرى.

ستقوم الرتيلاء بذلك بنفسها، ولن تضطر إلى كتابة طلب منفصل.

في الختام

وهذا ليس سوى الجزء الأول من العمل الكبير. سيتم نشر الجزء الثاني قريبًا جدًا على مدونة Mail.ru Group، وسنضيف بالتأكيد رابطًا له في هذه المادة.

إذا كنت مهتمًا بحضور الأحداث التي نقوم فيها ببناء هذه الأشياء عبر الإنترنت وطرح الأسئلة في الوقت الفعلي، فاحرص على متابعتنا DevOps بواسطة قناة REBRAIN.

إذا كنت بحاجة إلى الانتقال إلى السحابة أو كانت لديك أسئلة حول بنيتك التحتية ، لا تتردد في تقديم طلب.

ملاحظة: لدينا عمليتا تدقيق مجانيتان شهريًا ، وربما يكون مشروعك أحدهما.

المصدر: www.habr.com

إضافة تعليق