Trong Tarantool, bạn có thể kết hợp cơ sở dữ liệu siêu nhanh và một ứng dụng để làm việc với chúng. Đây là cách dễ dàng để làm

Năm năm trước, tôi đã thử làm việc với Tarantool nhưng sau đó nó không hiệu quả với tôi. Nhưng gần đây tôi đã tổ chức một hội thảo trực tuyến để nói về Hadoop và cách MapReduce hoạt động. Ở đó họ hỏi tôi một câu: “Tại sao không sử dụng Tarantool cho nhiệm vụ này?”

Vì tò mò, tôi quyết định quay lại, thử nghiệm phiên bản mới nhất - và lần này tôi thực sự thích dự án. Bây giờ tôi sẽ chỉ cho bạn cách viết một ứng dụng đơn giản trong Tarantool, tải nó và kiểm tra hiệu suất của nó, bạn sẽ thấy mọi thứ dễ dàng và thú vị như thế nào.

Trong Tarantool, bạn có thể kết hợp cơ sở dữ liệu siêu nhanh và một ứng dụng để làm việc với chúng. Đây là cách dễ dàng để làm

Tarantool là gì

Tarantool định vị mình là một cơ sở dữ liệu cực nhanh. Bạn có thể đặt bất kỳ dữ liệu nào bạn muốn ở đó. Ngoài ra, hãy sao chép chúng, phân đoạn - nghĩa là phân chia một lượng lớn dữ liệu trên một số máy chủ và kết hợp các kết quả từ chúng - tạo ra các kết nối chính-chính có khả năng chịu lỗi.

Thứ hai, đây là một máy chủ ứng dụng. Bạn có thể viết các ứng dụng của mình lên đó, làm việc với dữ liệu, chẳng hạn như xóa các bản ghi cũ ở chế độ nền theo các quy tắc nhất định. Bạn có thể viết một máy chủ Http trực tiếp trong Tarantula sẽ hoạt động với dữ liệu: đưa ra số lượng của chúng, ghi dữ liệu mới vào đó và giảm tất cả xuống bản gốc.

Tôi đã đọc một bài báo về cách những người này tạo một hàng đợi tin nhắn gồm 300 dòng, đơn giản là dồn dập và dồn dập - họ có hiệu suất tối thiểu là 20 tin nhắn mỗi giây. Ở đây bạn thực sự có thể quay lại và viết một ứng dụng rất lớn và nó sẽ không phải là bộ lưu trữ, như trong PostgreS.

Tôi sẽ cố gắng mô tả một cái gì đó giống như máy chủ này, chỉ đơn giản thôi, trong bài viết này.

Cài đặt

Để thử nghiệm, tôi đã khởi động ba máy ảo tiêu chuẩn - một ổ cứng 20 GB, Ubuntu 18.04. 2 CPU ảo và 4 gig bộ nhớ.

Chúng tôi cài đặt Tarantool - chạy tập lệnh bash hoặc thêm kho lưu trữ và thực hiện apt get install Tarantool. Liên kết tới tập lệnh - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Chúng tôi có các lệnh như:

tarantoolctl — lệnh chính để quản lý các phiên bản Tarantula.
/etc/tarantool - đây là toàn bộ cấu hình.
var/log/tarantool - đây là nhật ký.
var/lib/tarantool — dữ liệu nằm ở đây và sau đó được chia thành các trường hợp.

Có các thư mục có sẵn phiên bản và kích hoạt phiên bản - nó chứa những gì sẽ được khởi chạy - một tệp cấu hình phiên bản có mã lua, mô tả cổng nào nó nghe, bộ nhớ nào có sẵn cho nó, cài đặt công cụ Vinyl, mã chạy khi khởi động máy chủ, phân đoạn, hàng đợi, xóa dữ liệu lỗi thời, v.v.

Các phiên bản hoạt động giống như trong PostgreS. Ví dụ: bạn muốn chạy một số bản sao của cơ sở dữ liệu treo trên các cổng khác nhau. Hóa ra là một số phiên bản cơ sở dữ liệu được khởi chạy trên một máy chủ, treo trên các cổng khác nhau. Chúng có thể có các cài đặt hoàn toàn khác nhau - một phiên bản thực hiện một logic, phiên bản thứ hai - một logic khác.

Quản lý phiên bản

Chúng tôi có lệnh tarantoolctl, cho phép bạn quản lý các phiên bản Tarantula. Ví dụ: ví dụ kiểm tra tarantoolctl sẽ kiểm tra tệp cấu hình và nói - tệp vẫn ổn nếu không có lỗi cú pháp ở đó.

Bạn có thể xem trạng thái của phiên bản - ví dụ về trạng thái tarantoolctl. Theo cách tương tự, bạn có thể bắt đầu, dừng, khởi động lại.

Khi phiên bản đang chạy, bạn có thể kết nối với phiên bản đó theo hai cách.

1. Bảng điều khiển quản trị

Theo mặc định, Tarantool mở một socket và văn bản ASCII bình thường được gửi đến đó để điều khiển Tarantool. Kết nối với bảng điều khiển luôn diễn ra dưới quyền người dùng quản trị viên, không có xác thực nên không cần phải ra ngoài cổng bảng điều khiển để quản lý Tarantula.

Để kết nối bằng phương pháp này, bạn cần nhập Tarantoolctl enter instance name. Lệnh sẽ khởi chạy bảng điều khiển và kết nối với tư cách người dùng quản trị viên. Không bao giờ để cổng console ra bên ngoài - tốt hơn là để nó như một ổ cắm thiết bị. Sau đó, chỉ những người có quyền ghi vào ổ cắm mới có thể kết nối với Tarantula.

Phương pháp này là cần thiết cho những việc hành chính. Để làm việc với dữ liệu, hãy sử dụng phương pháp thứ hai - giao thức nhị phân.

2. Sử dụng giao thức nhị phân để kết nối với một cổng cụ thể

Cấu hình chứa lệnh lắng nghe, lệnh này mở ra một cổng để liên lạc bên ngoài. Cổng này được sử dụng với giao thức nhị phân và xác thực được kích hoạt ở đó.

Đối với kết nối này, tarantoolctl kết nối với số cổng được sử dụng. Sử dụng nó, bạn có thể kết nối với máy chủ từ xa, sử dụng xác thực và cấp nhiều quyền truy cập khác nhau.

Mô-đun ghi dữ liệu và hộp

Vì Tarantool vừa là cơ sở dữ liệu vừa là máy chủ ứng dụng nên nó có nhiều mô-đun khác nhau. Chúng tôi quan tâm đến mô-đun hộp - nó thực hiện làm việc với dữ liệu. Khi bạn ghi nội dung nào đó vào hộp, Tarantool ghi dữ liệu vào đĩa, lưu trữ vào bộ nhớ hoặc thực hiện thao tác khác với dữ liệu đó.

Ghi

Ví dụ: chúng ta vào mô-đun box và gọi hàm box.once. Điều này sẽ buộc Tarantool chạy mã của chúng tôi khi máy chủ được khởi chạy. Chúng tôi tạo ra một không gian trong đó dữ liệu của chúng tôi sẽ được lưu trữ.

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

Sau đó, chúng tôi tạo chỉ mục chính - chính - để chúng tôi có thể tìm kiếm dữ liệu. Theo mặc định, nếu bạn không chỉ định bất kỳ tham số nào thì trường đầu tiên trong mỗi bản ghi sẽ được sử dụng làm chỉ mục chính.

Sau đó, chúng tôi cấp quyền cho người dùng khách, theo đó chúng tôi kết nối thông qua giao thức nhị phân. Chúng tôi cho phép đọc, viết và thực thi trên toàn bộ phiên bản.

So với cơ sở dữ liệu thông thường, mọi thứ ở đây khá đơn giản. Chúng tôi có không gian - một khu vực trong đó dữ liệu của chúng tôi được lưu trữ đơn giản. Mỗi bản ghi được gọi là một tuple. Nó được đóng gói trong MessagePack. Đây là một định dạng rất thú vị - nó là định dạng nhị phân và chiếm ít không gian hơn - 18 byte so với 27 byte.

Trong Tarantool, bạn có thể kết hợp cơ sở dữ liệu siêu nhanh và một ứng dụng để làm việc với chúng. Đây là cách dễ dàng để làm

Làm việc với anh ấy khá thuận tiện. Hầu như mọi dòng, mọi bản ghi dữ liệu đều có thể có các cột hoàn toàn khác nhau.

Chúng ta có thể xem tất cả các khoảng trắng bằng lệnh Box.space. Để chọn một phiên bản cụ thể, hãy viết ví dụ về box.space và nhận thông tin đầy đủ về nó.

Tarantool có hai công cụ tích hợp: Bộ nhớ và Vinyl. Bộ nhớ lưu trữ tất cả dữ liệu trong bộ nhớ. Vì vậy, mọi thứ hoạt động đơn giản và nhanh chóng. Dữ liệu được đổ vào đĩa và cũng có cơ chế ghi nhật ký trước, vì vậy chúng tôi sẽ không mất bất cứ thứ gì nếu máy chủ gặp sự cố.

Vinyl lưu trữ dữ liệu trên đĩa ở dạng quen thuộc hơn với chúng ta - nghĩa là bạn có thể lưu trữ nhiều dữ liệu hơn mức chúng ta có bộ nhớ và Tarantula sẽ đọc dữ liệu đó từ đĩa.

Bây giờ chúng ta sẽ sử dụng 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>

Mục lục:

Chỉ mục chính phải được tạo cho bất kỳ không gian nào, vì nếu không có nó thì sẽ không có gì hoạt động. Như trong bất kỳ cơ sở dữ liệu nào, chúng tôi tạo trường đầu tiên – ID bản ghi.

Bộ phận:

Ở đây chúng tôi chỉ ra những gì chỉ mục của chúng tôi bao gồm. Nó bao gồm một phần - trường đầu tiên chúng ta sẽ sử dụng có kiểu không dấu - một số nguyên dương. Theo như tôi nhớ từ tài liệu, con số tối đa có thể là 18 triệu. Đó là rất nhiều.

Sau đó chúng ta có thể chèn dữ liệu bằng lệnh chèn.

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>

Trường đầu tiên được sử dụng làm khóa chính nên nó phải là duy nhất. Chúng tôi không bị giới hạn bởi số lượng cột nên có thể chèn bao nhiêu dữ liệu tùy thích vào đó. Chúng được chỉ định ở định dạng MessagePack mà tôi đã mô tả ở trên.

Đầu ra dữ liệu

Sau đó chúng ta có thể hiển thị dữ liệu bằng lệnh select.

Box.example.select bằng phím {1} sẽ hiển thị mục nhập mong muốn. Nếu hạ phím xuống, chúng ta sẽ thấy tất cả các bản ghi mà chúng ta có. Tất cả chúng đều khác nhau về số lượng cột, nhưng ở đây về nguyên tắc không có khái niệm về cột - có số trường.

Hoàn toàn có thể có bất kỳ lượng dữ liệu nào. Và ví dụ, chúng ta cần tìm kiếm chúng theo trường thứ hai. Để làm điều này, chúng tôi tạo một chỉ mục phụ mới.


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

Chúng tôi sử dụng lệnh Create_index.
Hãy gọi nó là Thứ cấp.

Sau này, bạn cần chỉ định các tham số. Loại chỉ mục là TREE. Nó có thể không phải là duy nhất nên hãy nhập Unique = false.

Sau đó, chúng tôi cho biết chỉ mục của chúng tôi bao gồm những phần nào. Trường là số trường mà chúng ta liên kết chỉ mục và chỉ định loại chuỗi. Và thế là nó đã được tạo ra.

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>

Bây giờ đây là cách chúng ta có thể gọi nó:

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

bảo quản

Nếu chúng ta khởi động lại phiên bản và cố gắng gọi lại dữ liệu, chúng ta sẽ thấy rằng nó không có ở đó - mọi thứ đều trống rỗng. Điều này xảy ra vì Tarantool tạo điểm kiểm tra và lưu dữ liệu vào đĩa, nhưng nếu chúng tôi ngừng hoạt động cho đến lần lưu tiếp theo, chúng tôi sẽ mất tất cả các thao tác - vì chúng tôi sẽ khôi phục từ điểm kiểm tra cuối cùng, chẳng hạn như hai giờ trước.

Việc tiết kiệm từng giây cũng sẽ không hiệu quả vì liên tục chuyển 20 GB vào đĩa không phải là một ý tưởng hay.

Với mục đích này, khái niệm nhật ký ghi trước đã được phát minh và triển khai. Với sự trợ giúp của nó, đối với mỗi thay đổi trong dữ liệu, một mục nhập sẽ được tạo trong một tệp nhật ký ghi trước nhỏ.

Mỗi mục nhập đến điểm kiểm tra đều được lưu trữ trong đó. Đối với những tệp này, chúng tôi đặt kích thước - ví dụ: 64 MB. Khi nó đầy, quá trình ghi bắt đầu chuyển sang tệp thứ hai. Và sau khi khởi động lại, Tarantool được khôi phục từ điểm kiểm tra cuối cùng và sau đó chuyển tiếp tất cả các giao dịch sau đó cho đến khi dừng lại.

Trong Tarantool, bạn có thể kết hợp cơ sở dữ liệu siêu nhanh và một ứng dụng để làm việc với chúng. Đây là cách dễ dàng để làm

Để thực hiện việc ghi như vậy, bạn cần chỉ định tùy chọn trong cài đặt box.cfg (trong tệp example.lua):

wal_mode = “write”;

sử dụng dữ liệu

Với những gì chúng tôi đã viết bây giờ, bạn có thể sử dụng Tarantula để lưu trữ dữ liệu và nó sẽ hoạt động rất nhanh như một cơ sở dữ liệu. Và bây giờ việc đóng băng trên bánh là những gì bạn có thể làm với tất cả.

Viết một ứng dụng

Ví dụ: hãy viết ứng dụng sau cho Tarantula

Xem ứng dụng dưới spoiler

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

Chúng ta khai báo một số bảng trong lua để xác định các ký tự. Tấm này là cần thiết để tạo ra một chuỗi ngẫu nhiên.

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

Sau đó, chúng ta khai báo hàm - RandomString và đưa ra giá trị độ dài trong ngoặc đơn.

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

Sau đó, chúng tôi kết nối bộ định tuyến http và máy chủ http với máy chủ Tarantula, JSON, mà chúng tôi sẽ gửi cho khách hàng.

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

Sau đó, chúng tôi bắt đầu trên cổng 8080 trên tất cả giao diện máy chủ http, cổng này sẽ ghi lại tất cả các yêu cầu và lỗi.

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

Tiếp theo, chúng ta khai báo tuyến đường để nếu một yêu cầu có phương thức GET đến trên cổng 8080 /count thì chúng ta gọi hàm từ một dòng. Nó trả về trạng thái - 200, 404, 403 hoặc bất kỳ trạng thái nào khác mà chúng tôi chỉ định.

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

Trong phần thân, chúng tôi trả về json.encode, trong đó chúng tôi biểu thị số lượng và getcount, được gọi và hiển thị số lượng bản ghi trong cơ sở dữ liệu của chúng tôi.

Phương pháp thứ hai

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)

Ở đâu trong dòng bộ định tuyến:route({method = 'GET', path = '/token'}, function() chúng tôi gọi hàm và tạo mã thông báo.

Chuỗi mã thông báo cục bộ = RandomString(32) là một chuỗi ngẫu nhiên gồm 32 ký tự.
Trong hàng local cuối cùng = box.space.example:len() chúng tôi loại bỏ phần tử cuối cùng.
Và trong dòng box.space.example:insert{ cuối cùng + 1, mã thông báo } chúng tôi ghi dữ liệu vào cơ sở dữ liệu của mình, nghĩa là chúng tôi chỉ cần tăng ID lên 1. Nhân tiện, điều này có thể được thực hiện không chỉ theo cách vụng về này. Có trình tự cho việc này ở Tarantula.

Chúng tôi viết mã thông báo ở đó.

Vì vậy, chúng tôi đã viết ứng dụng trong một tập tin. Bạn có thể trực tiếp thao tác dữ liệu ở đó và mô-đun hộp sẽ thực hiện tất cả công việc bẩn thỉu cho bạn.

Nó nghe http và hoạt động với dữ liệu, mọi thứ đều ở trong một phiên bản duy nhất - cả ứng dụng và dữ liệu. Vì vậy, mọi thứ diễn ra khá nhanh chóng.

Để bắt đầu, chúng tôi cài đặt mô-đun http:

Chúng ta làm điều này như thế nào, hãy nhìn vào phần spoiler

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

Chúng tôi cũng cần prometheus để chạy:

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

Chúng tôi khởi chạy và có thể truy cập các mô-đun

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 cho chúng ta trạng thái 200.
/token phát hành mã thông báo và ghi mã thông báo này vào cơ sở dữ liệu.

Kiểm tra tốc độ

Hãy chạy điểm chuẩn cho 50 yêu cầu. Sẽ có 000 yêu cầu cạnh tranh.

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

Token được phát hành. Và chúng tôi liên tục ghi lại dữ liệu. 99% yêu cầu được xử lý trong 42 mili giây. Theo đó, chúng tôi có khoảng 3500 yêu cầu mỗi giây trên một máy nhỏ có 2 lõi và 4 gigabyte bộ nhớ.

Bạn cũng có thể chọn khoảng 50000 token và xem giá trị của nó.

Bạn không chỉ có thể sử dụng http mà còn có thể chạy các chức năng nền xử lý dữ liệu của mình. Ngoài ra còn có nhiều tác nhân khác nhau. Ví dụ: bạn có thể gọi các chức năng khi cập nhật, kiểm tra nội dung nào đó - khắc phục xung đột.

Bạn có thể viết các ứng dụng tập lệnh trực tiếp trong chính máy chủ cơ sở dữ liệu và không bị giới hạn bởi bất kỳ điều gì, kết nối bất kỳ mô-đun nào và triển khai bất kỳ logic nào.

Máy chủ ứng dụng có thể truy cập các máy chủ bên ngoài, truy xuất dữ liệu và thêm nó vào cơ sở dữ liệu của nó. Dữ liệu từ cơ sở dữ liệu này sẽ được các ứng dụng khác sử dụng.

Tarantula sẽ tự làm việc này và bạn sẽ không phải viết một ứng dụng riêng.

Kết luận

Đây chỉ là phần đầu tiên của một công việc lớn. Cái thứ hai sẽ sớm được xuất bản trên blog của Nhóm Mail.ru và chúng tôi chắc chắn sẽ thêm một liên kết đến nó trong tài liệu này.

Nếu bạn muốn tham dự các sự kiện nơi chúng tôi xây dựng những điều này trực tuyến và đặt câu hỏi trong thời gian thực, hãy theo dõi kênh DevOps của REBRAIN.

Nếu bạn cần chuyển sang đám mây hoặc có thắc mắc về cơ sở hạ tầng của mình, vui lòng để lại yêu cầu.

Tái bút Chúng tôi có 2 đợt kiểm tra miễn phí mỗi tháng, có lẽ dự án của bạn sẽ là một trong số đó.

Nguồn: www.habr.com

Thêm một lời nhận xét