ใน Tarantool คุณสามารถรวมฐานข้อมูลความเร็วสูงและแอปพลิเคชันเพื่อทำงานร่วมกันได้ นี่เป็นวิธีที่ง่ายที่จะทำ

เมื่อห้าปีก่อน ฉันพยายามทำงานกับ Tarantool แต่แล้วมันก็ไม่ได้ผลสำหรับฉัน แต่เมื่อเร็วๆ นี้ ฉันจัดสัมมนาผ่านเว็บโดยพูดคุยเกี่ยวกับ Hadoop และวิธีการทำงานของ MapReduce ที่นั่นพวกเขาถามคำถามกับฉัน: "ทำไมไม่ใช้ Tarantool สำหรับงานนี้"

ด้วยความอยากรู้อยากเห็น ฉันจึงตัดสินใจกลับไปทดสอบเวอร์ชันล่าสุด - และครั้งนี้ฉันชอบโปรเจ็กต์นี้มาก ตอนนี้ฉันจะแสดงวิธีเขียนแอปพลิเคชันง่ายๆ ใน Tarantool โหลดและตรวจสอบประสิทธิภาพ แล้วคุณจะเห็นว่าทุกอย่างง่ายและเจ๋งแค่ไหน

ใน Tarantool คุณสามารถรวมฐานข้อมูลความเร็วสูงและแอปพลิเคชันเพื่อทำงานร่วมกันได้ นี่เป็นวิธีที่ง่ายที่จะทำ

ทารันทูลคืออะไร

Tarantool วางตำแหน่งตัวเองเป็นฐานข้อมูลที่รวดเร็วเป็นพิเศษ คุณสามารถใส่ข้อมูลใดก็ได้ที่คุณต้องการที่นั่น นอกจากนี้ ทำซ้ำการแบ่งส่วน นั่นคือ แบ่งข้อมูลจำนวนมหาศาลไปยังเซิร์ฟเวอร์หลายเครื่อง และรวมผลลัพธ์จากเซิร์ฟเวอร์เหล่านั้น สร้างการเชื่อมต่อหลัก-หลักที่ทนทานต่อข้อผิดพลาด

ประการที่สอง นี่คือแอปพลิเคชันเซิร์ฟเวอร์ คุณสามารถเขียนแอปพลิเคชันของคุณ ทำงานกับข้อมูล เช่น ลบบันทึกเก่าในพื้นหลังตามกฎบางอย่าง คุณสามารถเขียนเซิร์ฟเวอร์ Http ได้โดยตรงใน Tarantula ที่จะทำงานกับข้อมูล: แจกแจงปริมาณ เขียนข้อมูลใหม่ที่นั่น และลดขนาดทั้งหมดเป็นข้อมูลหลัก

ฉันอ่านบทความเกี่ยวกับวิธีที่พวกเขาสร้างคิวข้อความ 300 บรรทัดซึ่งเพียงแค่ระเบิดและเร่งรีบ - พวกเขามีประสิทธิภาพขั้นต่ำ 20 ข้อความต่อวินาที ที่นี่คุณสามารถพลิกกลับและเขียนแอปพลิเคชันที่มีขนาดใหญ่มากและจะไม่เป็นที่เก็บข้อมูลเหมือนใน PostgreS

ฉันจะพยายามอธิบายบางอย่างเช่นเซิร์ฟเวอร์นี้แบบง่ายๆ ในบทความนี้

การติดตั้ง

สำหรับการทดสอบ ฉันเริ่มใช้งานเครื่องเสมือนมาตรฐานสามเครื่อง - ฮาร์ดไดรฟ์ 20 GB, Ubuntu 18.04 CPU เสมือน 2 ตัวและหน่วยความจำ 4 กิ๊ก

เราติดตั้ง Tarantool - รันสคริปต์ทุบตีหรือเพิ่มพื้นที่เก็บข้อมูลและทำการติดตั้ง Tarantool ลิงก์ไปยังสคริปต์ - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E ทุบตี) เรามีคำสั่งเช่น:

tarantoolctl — คำสั่งหลักสำหรับจัดการอินสแตนซ์ของทารันทูล่า
/etc/tarantool - นี่คือการกำหนดค่าทั้งหมด
var/log/tarantool - นี่คือบันทึก
var/lib/tarantool — ข้อมูลอยู่ที่นี่ จากนั้นจะถูกแบ่งออกเป็นอินสแตนซ์

มีโฟลเดอร์ที่พร้อมใช้งานและเปิดใช้งานอินสแตนซ์ - ประกอบด้วยสิ่งที่จะเปิดตัว - ไฟล์การกำหนดค่าอินสแตนซ์พร้อมรหัส lua ซึ่งอธิบายว่าพอร์ตใดที่ฟังอยู่ หน่วยความจำใดบ้างที่พร้อมใช้งาน การตั้งค่ากลไกไวนิล รหัสที่ทำงานเมื่อเริ่มต้นระบบ เซิร์ฟเวอร์ การแบ่งส่วน คิว การลบข้อมูลที่ล้าสมัย และอื่นๆ

อินสแตนซ์ทำงานเหมือนใน PostgreS ตัวอย่างเช่น คุณต้องการเรียกใช้สำเนาหลายชุดของฐานข้อมูลที่ค้างอยู่บนพอร์ตที่แตกต่างกัน ปรากฎว่ามีการเปิดตัวอินสแตนซ์ฐานข้อมูลหลายรายการบนเซิร์ฟเวอร์เดียวซึ่งค้างอยู่บนพอร์ตที่ต่างกัน อาจมีการตั้งค่าที่แตกต่างกันโดยสิ้นเชิง - อินสแตนซ์หนึ่งใช้ตรรกะเดียว อินสแตนซ์ที่สอง - อีกอัน

การจัดการอินสแตนซ์

เรามีคำสั่ง tarantoolctl ซึ่งช่วยให้คุณจัดการอินสแตนซ์ Tarantula ได้ ตัวอย่างเช่น ตัวอย่างการตรวจสอบ tarantoolctl จะตรวจสอบไฟล์การกำหนดค่าและพูดว่า - ไฟล์นั้นใช้ได้หากไม่มีข้อผิดพลาดทางไวยากรณ์อยู่ที่นั่น

คุณสามารถดูสถานะของอินสแตนซ์ - ตัวอย่างสถานะ tarantoolctl ในทำนองเดียวกัน คุณสามารถเริ่ม หยุด และเริ่มต้นใหม่ได้

เมื่ออินสแตนซ์ทำงาน คุณสามารถเชื่อมต่อกับอินสแตนซ์ได้สองวิธี

1. คอนโซลผู้ดูแลระบบ

ตามค่าเริ่มต้น Tarantool จะเปิดซ็อกเก็ต ข้อความ ASCII ปกติจะถูกส่งไปที่นั่นเพื่อควบคุม Tarantool การเชื่อมต่อกับคอนโซลจะเกิดขึ้นภายใต้ผู้ใช้ผู้ดูแลระบบเสมอ ไม่มีการตรวจสอบสิทธิ์ ดังนั้นจึงไม่จำเป็นต้องเปลี่ยนพอร์ตคอนโซลภายนอกเพื่อจัดการทารันทูล่า

หากต้องการเชื่อมต่อโดยใช้วิธีนี้ คุณต้องป้อน Tarantoolctl ป้อนชื่ออินสแตนซ์ คำสั่งจะเปิดคอนโซลและเชื่อมต่อในฐานะผู้ใช้ผู้ดูแลระบบ อย่าให้พอร์ตคอนโซลออกสู่ภายนอก - ควรปล่อยไว้เป็นช่องเสียบยูนิตจะดีกว่า จากนั้นเฉพาะผู้ที่มีสิทธิ์เขียนลงในซ็อกเก็ตเท่านั้นจึงจะสามารถเชื่อมต่อกับทารันทูล่าได้

วิธีนี้จำเป็นสำหรับการบริหารงาน หากต้องการทำงานกับข้อมูลให้ใช้วิธีที่สอง - โปรโตคอลไบนารี่

2. การใช้โปรโตคอลไบนารี่เพื่อเชื่อมต่อกับพอร์ตเฉพาะ

การกำหนดค่าประกอบด้วยคำสั่งการฟังซึ่งจะเปิดพอร์ตสำหรับการสื่อสารภายนอก พอร์ตนี้ใช้กับโปรโตคอลไบนารีและเปิดใช้งานการรับรองความถูกต้องที่นั่น

สำหรับการเชื่อมต่อนี้ จะใช้ tarantoolctl เชื่อมต่อกับหมายเลขพอร์ต คุณสามารถเชื่อมต่อกับเซิร์ฟเวอร์ระยะไกล ใช้การตรวจสอบสิทธิ์ และให้สิทธิ์การเข้าถึงต่างๆ ได้

การบันทึกข้อมูลและโมดูลกล่อง

เนื่องจาก 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

หลังจากนี้ เราจะสร้างดัชนีหลัก - หลัก - ซึ่งเราสามารถค้นหาข้อมูลได้ ตามค่าเริ่มต้น หากคุณไม่ได้ระบุพารามิเตอร์ใดๆ ฟิลด์แรกในแต่ละเรคคอร์ดจะถูกใช้สำหรับดัชนีหลัก

จากนั้นเราจะให้สิทธิ์แก่ผู้ใช้ทั่วไป โดยที่เราเชื่อมต่อผ่านโปรโตคอลไบนารี่ เราอนุญาตให้อ่าน เขียน และดำเนินการทั่วทั้งอินสแตนซ์

เมื่อเปรียบเทียบกับฐานข้อมูลทั่วไป ทุกอย่างที่นี่ค่อนข้างเรียบง่าย เรามีพื้นที่ - พื้นที่สำหรับจัดเก็บข้อมูลของเรา แต่ละระเบียนเรียกว่าทูเพิล มันถูกบรรจุใน 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 ควินล้านล้าน นั่นเป็นจำนวนมาก

จากนั้นเราก็สามารถแทรกข้อมูลโดยใช้คำสั่ง 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 ซึ่งฉันได้อธิบายไว้ข้างต้น

เอาท์พุทข้อมูล

จากนั้นเราสามารถแสดงข้อมูลโดยใช้คำสั่งเลือก

Box.example.select ด้วยปุ่ม {1} จะแสดงรายการที่ต้องการ ถ้าเราลดคีย์ลงเราจะเห็นบันทึกทั้งหมดที่เรามี ทั้งหมดนี้แตกต่างกันในจำนวนคอลัมน์ แต่โดยหลักการแล้ว ไม่มีแนวคิดเรื่องคอลัมน์ - มีหมายเลขฟิลด์

อาจมีข้อมูลจำนวนเท่าใดก็ได้ ตัวอย่างเช่น เราต้องค้นหาโดยใช้ช่องที่สอง เพื่อทำเช่นนี้ เราสร้างดัชนีรองใหม่


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

เราใช้คำสั่ง Create_index
เรามาเรียกมันว่ารองกันดีกว่า

หลังจากนี้คุณจะต้องระบุพารามิเตอร์ ประเภทดัชนีคือ TREE อาจไม่ซ้ำกัน ดังนั้นให้ป้อน Unique = false

จากนั้นเราจะระบุว่าดัชนีของเราประกอบด้วยส่วนใดบ้าง Field คือหมายเลขของฟิลด์ที่เราผูกดัชนีและระบุประเภทสตริง และมันก็ถูกสร้างขึ้นมา

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 (ในไฟล์ 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 โดยในนั้นเราจะระบุจำนวนและ 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', path = '/token'}, function() เราเรียกใช้ฟังก์ชันและสร้างโทเค็น

เส้น โทเค็นท้องถิ่น = RandomString (32) เป็นสตริงสุ่มจำนวน 32 ตัวอักษร
ในสาย ท้องถิ่นสุดท้าย = box.space.example:len() เรานำองค์ประกอบสุดท้ายออกมา
และในสาย box.space.example:insert{ สุดท้าย + 1, โทเค็น } เราเขียนข้อมูลลงในฐานข้อมูลของเรานั่นคือเราเพียงเพิ่ม ID ขึ้น 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 คอร์และหน่วยความจำ 4 กิกะไบต์

คุณสามารถเลือกโทเค็นได้ 50000 โทเค็นและดูมูลค่าของมัน

คุณไม่เพียงแต่ใช้ http เท่านั้น แต่ยังเรียกใช้ฟังก์ชันพื้นหลังที่ประมวลผลข้อมูลของคุณได้อีกด้วย แถมยังมีทริกเกอร์ต่างๆ ตัวอย่างเช่นคุณสามารถเรียกใช้ฟังก์ชันในการอัพเดตตรวจสอบบางอย่าง - แก้ไขข้อขัดแย้ง

คุณสามารถเขียนแอปพลิเคชันสคริปต์ได้โดยตรงในเซิร์ฟเวอร์ฐานข้อมูลเอง และไม่ถูกจำกัดด้วยสิ่งใดๆ เชื่อมต่อโมดูลใดๆ และใช้ตรรกะใดๆ

แอปพลิเคชันเซิร์ฟเวอร์สามารถเข้าถึงเซิร์ฟเวอร์ภายนอก ดึงข้อมูล และเพิ่มลงในฐานข้อมูลได้ ข้อมูลจากฐานข้อมูลนี้จะถูกใช้โดยแอปพลิเคชันอื่น

ทารันทูล่าจะทำเช่นนี้เอง และคุณไม่จำเป็นต้องเขียนแอปพลิเคชันแยกต่างหาก

ในข้อสรุป

นี่เป็นเพียงส่วนแรกของงานใหญ่เท่านั้น ส่วนที่สองจะมีการเผยแพร่ในบล็อก Mail.ru Group เร็ว ๆ นี้ และเราจะเพิ่มลิงก์ไปยังเนื้อหานี้อย่างแน่นอน

หากคุณสนใจเข้าร่วมกิจกรรมที่เราสร้างสิ่งเหล่านี้ทางออนไลน์และถามคำถามแบบเรียลไทม์ โปรดติดตาม ช่อง DevOps โดย REBRAIN.

หากคุณต้องการย้ายไปยังระบบคลาวด์หรือมีคำถามเกี่ยวกับโครงสร้างพื้นฐานของคุณ รู้สึกอิสระที่จะออกคำขอ.

ป.ล. เรามีการตรวจสอบฟรี 2 ครั้งต่อเดือน บางทีโครงการของคุณอาจเป็นหนึ่งในนั้น

ที่มา: will.com

เพิ่มความคิดเห็น