跳转至

tarantool: 用于从 nginx 通过嵌入的 Lua 模块或 nginx-module-lua 连接 tarantool 的库

安装

如果您尚未设置 RPM 仓库订阅,请 注册。然后您可以继续以下步骤。

CentOS/RHEL 7 或 Amazon Linux 2

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lua-resty-tarantool

CentOS/RHEL 8+、Fedora Linux、Amazon Linux 2023

dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install lua5.1-resty-tarantool

要在 NGINX 中使用此 Lua 库,请确保已安装 nginx-module-lua

本文档描述了 lua-resty-tarantool v0.3,发布于 2015 年 10 月 21 日。


介绍

这是一个连接 tarantool NoSQL 数据库的库。该数据库具有非常有趣的特性,使其成为传统 SQL 数据库与文档导向存储(如 CouchDB)之间的桥梁。

它是另一个 项目 的分支,我对此不满意。它有丰富的文档,并且在 tarantool API 的更新方面非常及时。特别是支持 upsert 命令。

另一个需要注意的事情是,该库试图在使用 Lua 的控制台中发出 updateupsert 命令的方式与 API 的工作方式之间保持一致。尤其是字段编号。在控制台中,字段编号考虑了主索引作为第一个字段的存在。因此,任何后续字段的位置都会考虑到这一点。特别是在指定用于 updateupsert 操作的运算符时。

用法

创建连接

local tar = require 'resty.tarantool'

local tar, err = tnt:new({
    host = '127.0.0.1',
    port = 3301,
    user = 'luser',
    password = 'some password',
    socket_timeout = 2000,
})
上述代码创建了一个连接对象,该对象连接到在回环地址上运行的 tarantool 服务器实例,端口为 3301,用户为 luser,密码为 some password。有关如何设置用户和分配权限的详细信息,请参见 Tarantool 手册中的身份验证

套接字超时(接收和发送)为 2 秒(2000 毫秒)。

set_timeout

settimeout(<connection object>, <timeout in ms>)

为给定的套接字设置发送和接收超时(以毫秒为单位)。

tnt:set_timeout(5000) -- 5s timeout for send/receive operations

如果设置成功,函数返回 true;如果失败,则返回 nil。请注意,为了使超时生效,此函数需要在建立连接之前调用,即在调用 connect 函数之前。或者,可以在创建连接对象(cosocket)时指定超时。

connect

connect(<connection object>)

将上述创建的套接字连接到创建连接对象时指定的端口和地址。

tar:connect()
如果连接成功,函数返回 true;如果失败,则返回 nil

set_keepalive

set_keepalive(<connection object>)

将创建的连接推送到连接池,以便在多个请求之间保持连接活跃。

tar:set_keepalive()

如果套接字成功推送到连接池(设置保持活动状态),函数返回 true;如果失败,则返回 nil

disconnect

disconnect(<connection object>)

关闭与给定地址和端口上运行的 tarantool 服务器的连接。

tar:disconnect()

如果连接成功关闭,函数返回 true;如果失败,则返回 nil

ping

ping 命令用于监控 tarantool 服务器以查看其是否可用。如果可用于查询,则返回字符串 PONG

tar:ping()
-- returns PONG

select

select 操作查询给定数据库(空间)以检索记录。

select(<connection object>, <space name>, <index>, <key>, <options>)

其中 <options> 是一个可选参数,可以是一个表,包含以下键:

  • offset: 查询时要跳过的记录数。
  • limit: 返回的最大记录数。
  • iterator: 指定要使用的迭代器的数字。由表指定:

local iterator_keys = {
  EQ = 0, -- 相等
  REQ = 1, -- 反向相等
  ALL = 2, -- 索引中的所有元组
  LT = 3, -- 小于
  LE = 4, -- 小于或等于
  GE = 5, -- 大于或等于
  GT = 6, -- 大于
  BITSET_ALL_SET = 7, -- 位掩码中的所有位都设置
  BITSET_ANY_SET = 8, -- 位掩码中的任何位都设置
  BITSET_ALL_NOT_SET = 9, -- 位掩码中的没有位被设置
}
有关迭代器的更多详细信息,请参见 tarantool 手册

select 示例

查询 _space 空间(数据库)以获取 _index 空间的空间 ID。

local res, err = tar:select('_space', 'name', '_index')

-- response:
[2881,"_index","memtx",0,"",
  [{"name":"id","type":"num"},
   {"name":"iid","type":"num"},
   {"name":"name","type":"str"},
   {"name":"type","type":"str"},
   {"name":"opts","type":"array"},
   {"name":"parts","type":"array"}]]]
上述请求相当于控制台请求:

box.space._space.index.name:select{ '_index' }

查询空间 'activities' 中价格低于 300 的活动

-- 注意:price 是 activities 空间的一个索引。
local res, err = tar:select('activities', 'price', 300, { iterator = 'LT' })
上述请求相当于控制台请求:

box.space.activities.index.price:select({ 300 }, { iterator = 'LT' })

insert

insert(<connection object>, <space name>, <tuple>)

其中 <tuple> 是要插入到 <space> 中的元组,同时设置主索引(唯一)为元组中指定的值。

如果操作成功,函数返回 插入的 记录。

insert 示例

local res, err = tar:insert('activities', { 16, 120, { activity = 'surf', price = 121 } })

-- response:
[[16,120,{"activity":"surf","price":121}]]
上述请求相当于控制台请求:

box.space.activities:insert({16, 120, { activity = 'surf', price = 121 }})
16 是主索引的值。这意味着对于整数类型索引,这将是主索引为 16 的记录。

replace

replace(<connection object>, <space name>, <tuple>)

replace 命令在调用和签名上与 insert 命令相似。但现在我们要 替换 已存在的记录,而不是插入新记录。我们再次需要主唯一索引的值。但现在该值必须存在,操作才能成功。如果操作成功,将返回带有 替换 值的记录。

replace 示例

local res, err = tar:replace('activities', { 16, 120, { activity = 'surf', price = 120 } })
-- response:
[[16,120,{"activity":"surf","price":120}]]
在这里,我们将之前的 121 价格替换为 120。主索引的值 16 与我们之前插入的记录匹配。

上述请求相当于控制台请求:

box.space.activities:update({ 16, 120, { activity = 'surf', price = 120 }})

update

update(<connection object>, <space name>, <index>, <key>, <operator list>)

其中 <operator list> 是按照 tarantool 手册 中指定的运算符列表。对 (, ) 的组合唯一标识一条记录,即 <key> 是主(唯一) <index> 的值。

<operator list> 是以下形式的表:

{ <operator>, <field position>, <value> }
运算符包括:

  • + 用于向数字字段添加。
  • - 用于从数字字段中减去。
  • & 用于两个无符号整数之间的按位与操作。
  • | 用于两个无符号整数之间的按位或操作。
  • ^ 用于两个无符号整数之间的按位异或操作。
  • : 用于字符串拼接。
  • ! 用于字段插入。
  • # 用于字段删除。
  • = 用于将给定值分配给字段。

如果操作成功,返回 更新的 记录。

update 示例

local res, err = tar:update('activities', 'primary', 16, { { '=', 2, 341 }, { '=', 3,  { activity = 'kitesurfing', price = 341 }}} )
-- response:
[16,341,{"activity":"kitesurfing","price":341}]]
我们更新了之前插入的主索引为 16 的记录。

上述请求相当于控制台请求:

box.space.activities.index.primary({ 16 }, { { '=', 2, 341 }, { '=', 3,  { activity = 'kitesurfing', price = 341 }}})

upsert

upsert(<connection object>, <space name>, <key>, <operator list>, <new tuple>)

除了 <new tuple> 参数外,函数签名与 update 相似。实际上,upsert 是两个命令的结合。如果指定的记录由 (, ) 组合存在,则执行更新;如果不存在,则执行插入。键是主索引的值,即唯一的。<new tuple> 是在 <key> 值不存在于 <index> 中时要插入的元组。如果操作成功,返回一个空表 {}。如果操作不成功,则返回 nil

upsert 示例

一个 插入

local res, err = tar:upsert('activities', 17, { { '=', 2, 450 }, { '=', 3,  { activity = 'submarine tour 8', price = 450 }}}, { 17, 450, { activity = 'waterski', price = 365 }})
-- response:
{}
我们 插入 了一个主索引为 17 的新记录,来自元组:

{ 18, 450, { activity = 'waterski', price = 365 }}
上述请求相当于控制台请求:

box.space.activities:upsert({ 17 }, { { '=', 2, 450 }, { '=', 3,  { activity = 'submarine tour 8', price = 450 }}}, { 17, 450, { activity = 'waterski', price = 365 }})
一个 更新

local res, err = tar:upsert('activities', 17, { { '=', 2, 450 }, { '=', 3,  { activity = 'submarine tour 8', price = 450 }}}, { 18, 285, { activity = 'kitesurfing', price = 285 }})
-- response:
{}
现在我们对主索引(唯一)中的键 17 标识的记录执行更新。

delete

delete(<connection object>, <space>, <key>)

<space> 中删除唯一由 <key> 指定的记录。请注意,<key> 必须属于主(唯一)索引。如果操作成功,返回 删除的 记录。

delete 示例

local response, err = tar:delete('activities', 17)
-- response:
[17,450,{"activity":"waterski","price":365}]]
我们删除了在活动空间中由主索引键 17 唯一标识的记录。

上述请求相当于控制台请求:

box.space.activities:delete({ 17 })

call

call(<connection object>, <proc>, <args>)

在我们连接的 tarantool 服务器中调用一个 存储过程(Lua 函数)。它返回调用的 结果

call 示例

由于 tarantool 控制台是一个 Lua REPL,只要在环境中可用,任何函数都可以被调用。

local res, err = tar:call('table.concat', { {'hello', ' ', 'world' } })
-- response:
[["hello world"]]
我们调用了表库中的 table.concat 函数来连接表:

{'hello', ' ', 'world' }
上述请求相当于控制台请求:

table.concat({'hello', ' ', 'world' })

有关 tarantool 存储过程的更多示例,请参见该仓库;https://github.com/mailru/tarlua

hide_version_header

hide_version_header(<connection object>)

默认情况下,每个响应都会发送一个自定义 HTTPX-Tarantool-Version,其中包含 tarantool 服务器的版本。

X-Tarantool-Version: 1.6.6-191-g82d1bc3

调用 hide_version_header 将移除该头。

tar:hide_version_header()

它不返回任何值。

GitHub

您可以在 nginx-module-tarantool 的 GitHub 仓库 中找到此模块的其他配置提示和文档。