Tarantool ۾، توهان گڏ ڪري سگهو ٿا هڪ سپر فاسٽ ڊيٽابيس ۽ انهن سان ڪم ڪرڻ لاءِ هڪ ايپليڪيشن. هتي اهو ڪيئن آسان آهي ڪرڻ آهي

پنج سال اڳ مون Tarantool سان ڪم ڪرڻ جي ڪوشش ڪئي، پر پوء اهو مون لاء ڪم نه ڪيو. پر تازو مون هڪ ويبينار منعقد ڪيو جتي مون Hadoop بابت ڳالهايو ۽ ڪيئن MapReduce ڪم ڪري ٿو. اتي هنن مون کان هڪ سوال پڇيو: ”ڇو نه هن ڪم لاءِ Tarantool استعمال ڪيو وڃي؟

تجسس کان ٻاهر، مون ان ڏانهن موٽڻ جو فيصلو ڪيو، تازو ورزن کي جانچيو - ۽ هن ڀيري مون واقعي پروجيڪٽ پسند ڪيو. ھاڻي مان توھان کي ڏيکاريندس ته Tarantool ۾ ھڪڙي سادي ايپليڪيشن ڪيئن لکجي، ان کي لوڊ ڪريو ۽ ان جي ڪارڪردگي چيڪ ڪريو، ۽ توھان ڏسندا ته سڀ ڪجھ ڪيترو آسان ۽ ٿڌو آھي.

Tarantool ۾، توهان گڏ ڪري سگهو ٿا هڪ سپر فاسٽ ڊيٽابيس ۽ انهن سان ڪم ڪرڻ لاءِ هڪ ايپليڪيشن. هتي اهو ڪيئن آسان آهي ڪرڻ آهي

Tarantool ڇا آهي

Tarantool پوزيشن پاڻ کي هڪ انتهائي تيز ڊيٽابيس جي طور تي. توهان ڪنهن به ڊيٽا کي توهان چاهيو ٿا اتي رکي سگهو ٿا. ان سان گڏ، انھن کي نقل ڪريو، شارڊ - اھو آھي، ڊيٽا جي وڏي مقدار کي ڪيترن ئي سرورن ۾ ورهايو ۽ انھن مان نتيجن کي گڏ ڪريو - غلطي برداشت ڪندڙ ماسٽر-ماسٽر ڪنيڪشن ٺاھيو.

ٻيو، هي هڪ ايپليڪيشن سرور آهي. توھان ان تي پنھنجيون ايپليڪيشنون لکي سگھو ٿا، ڊيٽا سان ڪم ڪري سگھو ٿا، مثال طور، ڪجھ ضابطن جي مطابق پس منظر ۾ پراڻا رڪارڊ ختم ڪريو. توھان لکي سگھوٿا ھڪڙو Http سرور سڌو Tarantula ۾ جيڪو ڪم ڪندو ڊيٽا سان: انھن جو مقدار ڏيو، اتي نئون ڊيٽا لکو ۽ اھو سڀ گھٽ ڪريو ماسٽر ڏانھن.

مون هڪ مضمون پڙهيو آهي ته ڪيئن ماڻهن 300 لائينن جي هڪ پيغام جي قطار ٺاهي آهي، جيڪا صرف فٽ ۽ جلدي آهي - انهن جي گهٽ ۾ گهٽ ڪارڪردگي آهي 20 پيغام في سيڪنڊ جي. هتي توهان واقعي ڦري سگهو ٿا ۽ هڪ تمام وڏي ايپليڪيشن لکي سگهو ٿا، ۽ اهو اسٽوريج نه هوندو، جيئن PostgreS ۾.

مان ڪوشش ڪندس ڪجھ بيان ڪرڻ جي هن سرور وانگر، صرف سادو، هن مضمون ۾.

تنصيب

ٽيسٽ لاءِ، مون ٽي معياري ورچوئل مشينون شروع ڪيون - هڪ 20 GB هارڊ ڊرائيو، Ubuntu 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 - ڊيٽا هتي آهي، ۽ پوء ان کي ورهايو ويو آهي مثالن ۾.

هتي فولڊر آهن مثال- دستياب ۽ مثال- فعال- ان ۾ شامل آهي جيڪو لانچ ڪيو ويندو- لوا ڪوڊ سان هڪ مثال جي ترتيب واري فائيل، جيڪا بيان ڪري ٿي ته اهو ڪهڙي بندرگاهن تي ٻڌندو آهي، ڪهڙي ميموري موجود آهي، ونائل انجڻ سيٽنگون، ڪوڊ جيڪو شروع ٿيڻ تي هلندو آهي سرور، شارڊنگ، قطار، ختم ٿيل ڊيٽا کي ختم ڪرڻ، وغيره.

مثالن وانگر ڪم ڪري ٿو PostgreS ۾. مثال طور، توهان هڪ ڊيٽابيس جون ڪيتريون ئي ڪاپيون هلائڻ چاهيو ٿا جيڪي مختلف بندرگاهن تي لٽڪيل آهن. اهو ظاهر ٿئي ٿو ته ڪيترن ئي ڊيٽابيس مثالن کي هڪ سرور تي شروع ڪيو ويو آهي، جيڪي مختلف بندرگاهن تي ٽنگيل آهن. اهي شايد مڪمل طور تي مختلف سيٽنگون هجن - هڪ مثال هڪ منطق لاڳو ڪري ٿو، ٻيو - ٻيو.

مثال جي انتظام

اسان وٽ tarantoolctl حڪم آهي، جيڪو توهان کي Tarantula مثالن کي منظم ڪرڻ جي اجازت ڏئي ٿو. مثال طور، tarantoolctl چيڪ مثال جي ترتيب واري فائل کي چيڪ ڪندي ۽ چوندا ته فائل ٺيڪ آهي جيڪڏهن اتي ڪو نحو غلطيون نه آهن.

توھان مثال جي حالت ڏسي سگھو ٿا - tarantoolctl status example. ساڳيء طرح توهان شروع ڪري سگهو ٿا، بند ڪريو، ٻيهر شروع ڪريو.

هڪ دفعو مثال هلي رهيو آهي، توهان ان کي ٻن طريقن سان ڳنڍي سگهو ٿا.

1. انتظامي ڪنسول

ڊفالٽ طور، Tarantool هڪ ساکٽ کوليندو آهي، عام ASCII متن اتي موڪليو ويندو آهي Tarantool کي ڪنٽرول ڪرڻ لاء. ڪنسول سان ڪنيڪشن هميشه منتظم صارف جي تحت ٿئي ٿو، اتي ڪا به تصديق نه آهي، تنهنڪري ٽرانٽلا کي منظم ڪرڻ لاءِ ڪنسول پورٽ کي ٻاهران ڪرڻ جي ڪا ضرورت ناهي.

ھن طريقي کي استعمال ڪندي ڳنڍڻ لاء، توھان کي داخل ڪرڻ جي ضرورت آھي Tarantoolctl داخل ڪريو مثال جو نالو. حڪم ڪنسول کي لانچ ڪندو ۽ منتظم صارف طور ڳنڍيندو. ڪڏهن به ڪنسول پورٽ کي ٻاهر نه ڪڍو - اهو بهتر آهي ته ان کي يونٽ ساکٽ جي طور تي ڇڏي ڏيو. پوءِ صرف اھي آھن جن کي ساکٽ تي لکڻ جي رسائي آھي Tarantula سان ڳنڍڻ جي قابل ٿي ويندا.

هن طريقي جي ضرورت آهي انتظامي شين لاء. ڊيٽا سان ڪم ڪرڻ لاء، ٻيو طريقو استعمال ڪريو - بائنري پروٽوڪول.

2. هڪ مخصوص پورٽ سان ڳنڍڻ لاء بائنري پروٽوڪول استعمال ڪندي

ٺاھ جوڙ ۾ ھڪ ٻڌڻ جي ھدايت شامل آھي، جيڪا خارجي رابطن لاءِ پورٽ کوليندي آھي. هي بندرگاهه بائنري پروٽوڪول سان استعمال ڪيو ويندو آهي ۽ تصديق اتي فعال آهي.

ھن ڪنيڪشن لاءِ، tarantoolctl connect سان پورٽ نمبر استعمال ڪيو ويندو آھي. ان کي استعمال ڪندي، توهان ريموٽ سرورز سان ڳنڍي سگهو ٿا، استعمال جي تصديق ۽ مختلف رسائي جا حق ڏيو.

ڊيٽا رڪارڊنگ ۽ باڪس ماڊل

جيئن ته Tarantool ٻئي هڪ ڊيٽابيس ۽ هڪ ايپليڪيشن سرور آهي، ان ۾ مختلف ماڊلز آهن. اسان باڪس ماڊل ۾ دلچسپي رکون ٿا - اهو ڊيٽا سان ڪم ڪرڻ کي لاڳو ڪري ٿو. جڏهن توهان باڪس ۾ ڪجهه لکندا آهيو، Tarantool ڊيٽا کي ڊسڪ ۾ لکندو آهي، ان کي ميموري ۾ ذخيرو ڪندو آهي، يا ان سان گڏ ٻيو ڪجهه ڪندو آهي.

رڪارڊ

مثال طور، اسان باڪس ماڊل ۾ وڃون ٿا ۽ box.once فنڪشن کي ڪال ڪريو. هي ٽرانٽول کي اسان جي ڪوڊ کي هلائڻ لاءِ مجبور ڪندو جڏهن سرور شروع ڪيو ويندو. اسان هڪ جاء ٺاهيندا آهيون جنهن ۾ اسان جي ڊيٽا محفوظ ڪئي ويندي.

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 ۾ ٻه ٺهيل انجڻيون آهن: ميموري ۽ ونائل. ميموري سڀني ڊيٽا کي ميموري ۾ محفوظ ڪري ٿو. تنهن ڪري، هر شيء آسان ۽ جلدي ڪم ڪري ٿو. ڊيٽا ڊسڪ تي ڊمپ ڪيو ويو آهي، ۽ اتي پڻ هڪ لکڻ جي اڳيان لاگ ميڪانيزم آهي، تنهنڪري اسان ڪجهه به نه وڃائينداسين جيڪڏهن سرور حادثو ٿئي.

Vinyl ڊسڪ تي ڊيٽا کي ذخيرو ڪري ٿو هڪ فارم ۾ جيڪو اسان کان وڌيڪ واقف آهي - اهو آهي، توهان اسان جي ميموري کان وڌيڪ ڊيٽا محفوظ ڪري سگهو ٿا، ۽ Tarantula ان کي ڊسڪ مان پڙهي سگهندو.

في الحال اسان ميموري استعمال ڪنداسين.

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:

ڪنهن به جاءِ لاءِ هڪ پرائمري انڊيڪس ٺاهيو وڃي، ڇاڪاڻ ته ان کان سواءِ ڪجهه به ڪم نه ڪندو. جيئن ڪنهن به ڊيٽابيس ۾، اسان پهريون فيلڊ ٺاهيو - رڪارڊ ID.

سڪندر:

هتي اسان اهو ظاهر ڪريون ٿا ته اسان جو انڊيڪس ڇا آهي. اھو ھڪڙو حصو تي مشتمل آھي - پھريون فيلڊ جيڪو اسين استعمال ڪنداسين قسم جي غير دستخط ٿيل آھي - ھڪڙو مثبت عدد. جيتري قدر مون کي دستاويزن مان ياد آهي، وڌ ۾ وڌ تعداد جيڪو ٿي سگهي ٿو 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 حڪم.
اچو ته ان کي ثانوي سڏين.

هن کان پوء توهان کي وضاحت ڪرڻ جي ضرورت آهي پيرا ميٽر. انڊيڪس جو قسم TREE آھي. اهو ٿي سگهي ٿو منفرد نه هجي، تنهنڪري داخل ڪريو Unique = غلط.

پوءِ اسان ظاھر ڪريون ٿا ته اسان جي انڊيڪس ڪھڙن حصن تي مشتمل آھي. فيلڊ فيلڊ جو تعداد آھي جنھن ۾ اسان انڊيڪس کي پابند ڪريون ٿا، ۽ اسٽرنگ جو قسم بيان ڪريو. ۽ ائين ئي پيدا ٿيو.

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 GB کي ڊسڪ تي ڊمپ ڪرڻ سٺو خيال ناهي.

هن مقصد لاء، لکڻ جي اڳيان لاگ جو تصور ايجاد ڪيو ويو ۽ لاڳو ڪيو ويو. ان جي مدد سان، ڊيٽا ۾ هر تبديليءَ لاءِ، هڪ ننڍي لکت-اڳتي لاگ فائل ۾ هڪ داخلا ٺاهي ويندي آهي.

چيڪ پوائنٽ تائين هر داخلا انهن ۾ ذخيرو ٿيل آهي. انهن فائلن لاء اسان سائيز مقرر ڪيو - مثال طور، 64 MB. جڏهن اهو مڪمل آهي، رڪارڊنگ شروع ٿئي ٿي ٻئي فائل ڏانهن وڃو. ۽ ٻيهر شروع ٿيڻ کان پوء، Tarantool کي آخري چيڪ پوائنٽ کان بحال ڪيو ويو آهي ۽ پوء سڀني بعد ۾ ٽرانزيڪشن کي ختم ڪيو وڃي جيستائين اهو بند نه ٿئي.

Tarantool ۾، توهان گڏ ڪري سگهو ٿا هڪ سپر فاسٽ ڊيٽابيس ۽ انهن سان ڪم ڪرڻ لاءِ هڪ ايپليڪيشن. هتي اهو ڪيئن آسان آهي ڪرڻ آهي

اهڙي رڪارڊنگ ڪرڻ لاءِ، توهان کي box.cfg سيٽنگن ۾ اختيار بيان ڪرڻ جي ضرورت آهي (مثال طور.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()

اسان لوا ۾ ڪجهه ٽيبل جو اعلان ڪريون ٿا جيڪي ڪردارن جي وضاحت ڪن ٿا. هي پليٽ هڪ بي ترتيب واري تار ٺاهڻ جي ضرورت آهي.

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

ان کان پوء، اسان سڀني http سرور انٽرنيٽ تي پورٽ 8080 تي شروع ڪندا آهيون، جيڪو سڀني درخواستن ۽ غلطين کي لاگ ان ڪندو.

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

اڳيون، اسان رستي جو اعلان ڪريون ٿا، انهي ڪري ته جيڪڏهن GET طريقي سان هڪ درخواست پورٽ 8080 / ڳڻپ تي اچي ٿي، پوء اسان هڪ لائن کان فنڪشن کي سڏيندا آهيون. اهو ڪيفيت واپس ڏئي ٿو - 200، 404، 403 يا ٻيو ڪو جيڪو اسان بيان ڪيو آهي.

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

جسم ۾ اسان json.encode واپس ڪريون ٿا، ان ۾ اسين ڳڻپ ۽ حاصل ڳڻپ جي نشاندهي ڪندا آهيون، جنهن کي سڏيو ويندو آهي ۽ اسان جي ڊيٽابيس ۾ رڪارڊ جو تعداد ڏيکاري ٿو.

ٻيو طريقو

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)

ڪٿي قطار ۾ روٽر: رستو ({طريقي = 'GET'، رستو = '/ ٽوڪن'}، فنڪشن () اسان فنڪشن کي سڏيندا آهيون ۽ هڪ ٽوڪن ٺاهيندا آهيون.

لڪير مقامي ٽوڪن = randomString (32) 32 اکرن جو هڪ بي ترتيب تار آهي.
قطار ۾ local last = box.space.example:len() اسان آخري عنصر ڪڍون ٿا.
۽ قطار ۾ box.space.example:insert{ last + 1, token } اسان ڊيٽا کي پنهنجي ڊيٽابيس ۾ لکون ٿا، يعني اسان صرف ID کي 1 تائين وڌايو. اهو نه صرف ان بي ترتيب انداز ۾ پر ڪري سگهجي ٿو. Tarantula ۾ ان لاءِ ترتيب ڏنل آهن.

اسان اتي ٽوڪن لکندا آهيون.

اهڙيء طرح، اسان هڪ فائل ۾ درخواست لکي. توھان سڌو سنئون ڊيٽا کي ھڙتال ڪري سگھو ٿا اتي، ۽ باڪس ماڊل توھان لاء تمام گندو ڪم ڪندو.

اهو ٻڌي ٿو http ۽ ڊيٽا سان ڪم ڪري ٿو، هر شيء هڪ واحد مثال ۾ آهي - ٻئي ايپليڪيشن ۽ ڊيٽا. تنهن ڪري، هر شيء بلڪل جلدي ٿئي ٿي.

شروع ڪرڻ لاءِ اسان انسٽال ڪريون ٿا http module:

اسان اهو ڪيئن ڪندا آهيون، اسپائلر جي هيٺان ڏسو

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.

جيڪڏھن توھان کي بادل ڏانھن منتقل ڪرڻ جي ضرورت آھي يا توھان جي انفراسٽرڪچر بابت سوال آھن، هڪ درخواست ڇڏڻ لاء آزاد محسوس ڪريو.

پي ايس اسان وٽ هر مهيني 2 مفت آڊٽ آهن، شايد توهان جو پروجيڪٽ انهن مان هڪ هوندو.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو