tarantool: Biblioteca para trabajar con tarantool desde nginx con el módulo Lua embebido o con nginx-module-lua
Instalación
Si no has configurado la suscripción al repositorio RPM, regístrate. Luego puedes proceder con los siguientes pasos.
CentOS/RHEL 7 o 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
Para usar esta biblioteca Lua con NGINX, asegúrate de que nginx-module-lua esté instalado.
Este documento describe lua-resty-tarantool v0.3 lanzado el 21 de octubre de 2015.
Introducción
Esta es una biblioteca para conectarse a la base de datos NoSQL tarantool. Esta base de datos tiene características muy interesantes que la convierten en una especie de puente entre una base de datos tradicional basada en SQL y almacenes orientados a documentos como CouchDB.
Es un fork de otro proyecto con el que no estaba satisfecho. Está abundantemente documentado y se actualiza respecto a la API de tarantool. Notablemente con soporte para el comando upsert.
Otra cosa a tener en cuenta es que la biblioteca intenta ser consistente entre la forma en que se emiten los comandos update y upsert en la consola usando Lua y la forma en que funciona la API. Notablemente los números de campo. En la consola, un número de campo tiene en cuenta la existencia de un índice primario como el primer campo. Por lo tanto, cualquier campo que venga después tendrá una posición que lo considere. Específicamente al especificar los operadores a utilizar para las operaciones de update o upsert.
Uso
Creando una conexión
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,
})
luser con la contraseña some password. Consulta el manual de Tarantool sobre autenticación para obtener detalles sobre cómo configurar usuarios y asignarles privilegios.
El tiempo de espera del socket (recepción y envío) es de 2 segundos (2000 ms).
set_timeout
settimeout(<connection object>, <timeout in ms>)
Establece tanto los tiempos de espera de envío como de recepción en milisegundos para un socket dado.
tnt:set_timeout(5000) -- 5s timeout para operaciones de envío/recepción
La función devuelve true si la configuración tiene éxito, nil si no. Ten en cuenta que para que el tiempo de espera tenga efecto, esta función debe ser invocada antes de que se establezca la conexión, es decir, antes de invocar la función connect. Alternativamente, el tiempo de espera puede especificarse al crear el objeto de conexión (cosocket).
connect
connect(<connection object>)
Conecta el socket creado anteriormente al puerto y dirección especificados al crear el objeto de conexión.
tar:connect()
nil si no.
set_keepalive
set_keepalive(<connection object>)
Hace que la conexión creada se envíe a un grupo de conexiones para que la conexión se mantenga activa a través de múltiples solicitudes.
tar:set_keepalive()
La función devuelve true si el socket se envía correctamente al grupo de conexiones (mantener viva la conexión). nil si no.
disconnect
disconnect(<connection object>)
Cierra una conexión a un servidor tarantool dado que se ejecuta en una dirección y puerto específicos.
tar:disconnect()
La función devuelve true si la conexión se cierra correctamente. nil si no.
ping
El comando ping es útil para monitorear el servidor tarantool y ver si está disponible. Si está disponible para consultas, devuelve la cadena PONG.
tar:ping()
-- devuelve PONG
select
La operación select consulta una base de datos (espacio) dada para recuperar registros.
select(<connection object>, <space name>, <index>, <key>, <options>)
donde <options> es un argumento opcional que puede consistir en una tabla que puede tener las siguientes claves:
offset: número de registros a omitir al realizar la consulta.limit: el número máximo de registros a devolver.iterator: un número que especifica el iterador a utilizar. Especificado por la tabla:
local iterator_keys = {
EQ = 0, -- igualdad
REQ = 1, -- igualdad inversa
ALL = 2, -- todas las tuplas en un índice
LT = 3, -- menor que
LE = 4, -- menor o igual
GE = 5, -- mayor o igual
GT = 6, -- mayor que
BITSET_ALL_SET = 7, -- bits en la máscara de bits todos establecidos
BITSET_ANY_SET = 8, -- cualquiera de los bits en la máscara de bits están establecidos
BITSET_ALL_NOT_SET = 9, -- ninguno de los bits en la máscara de bits están establecidos
}
ejemplos de select
Consultar el espacio _space (DB) para obtener el id del espacio _index.
local res, err = tar:select('_space', 'name', '_index')
-- respuesta:
[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' }
Consultar el espacio 'activities' para las actividades con un price menor a 300
-- N.B. price es un índice del espacio 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>)
donde <tuple> es la tupla a insertar en <space> mientras se establece el índice primario, que es único, al valor especificado en la tupla.
La función devuelve el registro insertado si la operación tiene éxito.
ejemplos de insert
local res, err = tar:insert('activities', { 16, 120, { activity = 'surf', price = 121 } })
-- respuesta:
[[16,120,{"activity":"surf","price":121}]]
box.space.activities:insert({16, 120, { activity = 'surf', price = 121 }})
replace
replace(<connection object>, <space name>, <tuple>)
El comando replace es similar en la invocación y firma al comando insert. Pero ahora estamos buscando reemplazar un registro que ya existe en lugar de insertar uno nuevo. Necesitamos nuevamente el valor de un índice primario único. Pero ahora el valor debe existir para que la operación tenga éxito. Si la operación tiene éxito, se devuelve el registro con los valores reemplazados.
ejemplos de replace
local res, err = tar:replace('activities', { 16, 120, { activity = 'surf', price = 120 } })
-- respuesta:
[[16,120,{"activity":"surf","price":120}]]
La solicitud anterior es equivalente a la solicitud de consola:
box.space.activities:update({ 16, 120, { activity = 'surf', price = 120 }})
update
update(<connection object>, <space name>, <index>, <key>, <operator list>)
donde <operator list> es la lista de operadores como se especifica en el manual de tarantool. El par (<key> es un valor del índice primario (único) <index>.
<operator list> es una tabla de la forma:
{ <operator>, <field position>, <value> }
+para sumar a un campo numérico.-para restar a un campo numérico.¶ operación AND a nivel de bits entre dos enteros sin signo.|para operación OR a nivel de bits entre dos enteros sin signo.^para operación XOR a nivel de bits entre dos enteros sin signo.:para concatenación de cadenas.!para inserción de campo.#para eliminación de campo.=para asignar un valor dado a un campo.
devuelve el registro actualizado si la operación es exitosa.
ejemplos de update
local res, err = tar:update('activities', 'primary', 16, { { '=', 2, 341 }, { '=', 3, { activity = 'kitesurfing', price = 341 }}} )
-- respuesta:
[16,341,{"activity":"kitesurfing","price":341}]]
primary 16 que insertamos anteriormente fue actualizado.
La solicitud anterior es equivalente a la solicitud de consola:
box.space.activities.index.primary({ 16 }, { { '=', 2, 341 }, { '=', 3, { activity = 'kitesurfing', price = 341 }}})
upsert
upsert(<connection object>, <space name>, <key>, <operator list>, <new tuple>)
aparte del argumento <new tuple>, la firma de la función es similar a update. De hecho, upsert es dos comandos en uno. Actualiza si el registro especificado por el par (<new tuple> es la tupla que se insertará si el valor <key> no existe en el <index>. Devuelve una tabla vacía {} si la operación tiene éxito. Si la operación no tiene éxito, devuelve nil.
ejemplos de upsert
Un insert.
local res, err = tar:upsert('activities', 17, { { '=', 2, 450 }, { '=', 3, { activity = 'submarine tour 8', price = 450 }}}, { 17, 450, { activity = 'waterski', price = 365 }})
-- respuesta:
{}
{ 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 }})
-- respuesta:
{}
primary (único).
delete
delete(<connection object>, <space>, <key>)
elimina el registro especificado de manera única por <key> del <space>. Ten en cuenta que <key> debe pertenecer a un índice primario (único). Devuelve el registro eliminado si la operación tiene éxito.
ejemplos de delete
local response, err = tar:delete('activities', 17)
-- respuesta:
[17,450,{"activity":"waterski","price":365}]]
La solicitud anterior es equivalente a la solicitud de consola:
box.space.activities:delete({ 17 })
call
call(<connection object>, <proc>, <args>)
Invoca un procedimiento almacenado (función Lua) en el servidor tarantool al que estamos conectados. Devuelve los resultados de la invocación.
ejemplos de call
Dado que la consola de tarantool es un REPL de Lua, cualquier función puede ser invocada siempre que esté disponible en el entorno.
local res, err = tar:call('table.concat', { {'hello', ' ', 'world' } })
-- respuesta:
[["hello world"]]
table.concat de la biblioteca de tablas para concatenar la tabla:
{'hello', ' ', 'world' }
table.concat({'hello', ' ', 'world' })
Para muchos ejemplos de procedimientos almacenados de tarantool, consulta el repositorio; https://github.com/mailru/tarlua
hide_version_header
hide_version_header(<connection object>)
Por defecto, cada respuesta envía un encabezado HTTP personalizado X-Tarantool-Version con la versión del servidor tarantool.
X-Tarantool-Version: 1.6.6-191-g82d1bc3
Invocar hide_version_header elimina el encabezado.
tar:hide_version_header()
No devuelve valores.
GitHub
Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-tarantool.