导航

Qless 相关知识

Posted on 2015-02-24 09:03  蝈蝈俊  阅读(616)  评论(0编辑  收藏  举报

Qless是一个基于redis的分布式任务架构。相关代码在
https://github.com/seomoz/qless

它是完全有lua实现的,依靠 redis 对lua的支持,http://www.cnblogs.com/ghj1976/p/4298206.html 它实现了对redis的功能扩展。

有关lua的一些语法基础知识可以参考:http://www.cnblogs.com/ghj1976/p/4298178.html

https://github.com/seomoz/qless 这里我们可以看到下面文件,它们分别是下面功能:

base.lua -- 提前声明的部分和一些未分类的功能
config.lua -- 所有配置
job.lua -- 定时job类
recurring.lua -- 重复的job类
queue.lua -- 队列类
api.lua -- 客户端调用封装,这里做了一个非常轻量的封装

我们用的时候其实用的是 qless.lua 文件, 要用这个文件,需要用 make qless.lua 命令才产生:

image

在 qless.lua 的最后,我们可以看到下面一段代码,对这部分代码的解释如下:

if #KEYS > 0 then error('No Keys should be provided') end

local command_name = assert(table.remove(ARGV, 1), 'Must provide a command')
local command      = assert(
  QlessAPI[command_name], 'Unknown command ' .. command_name)

local now          = tonumber(table.remove(ARGV, 1))
local now          = assert(
  now, 'Arg "now" missing or not a number: ' .. (now or 'nil'))

return command(now, unpack(ARGV))

来自外部的调用,其实都被执行到 QlessAPI下的对应方法了, 外部调用传递进来的第1个参数是 QlessAPI 下对应的命令名字, 第二个是 这个命令的 now 参数,其他是其他参数。

 

在Redis中执行Lua的参数说明

在Redis中执行lua,我们最常用下面三个命令:EVAL、EVALSHA、SCRIPT LOAD

参考:http://www.cnblogs.com/ghj1976/p/4298206.html

以 eval 为例,它的参数如下,其他几个参数也类似:

EVAL script numkeys key [key ...] arg [arg ...]

script 参数是一段 Lua 5.1 脚本程序,它会被运行在 Redis 服务器上下文中,这段脚本不必(也不应该)定义为一个 Lua 函数。

numkeys 参数用于指定键名参数的个数。

键名参数 key [key ...]EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1]KEYS[2] ,以此类推)。

在命令的最后,那些不是键名参数的附加参数 arg [arg ...] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1]ARGV[2] ,诸如此类)。

上面这几段长长的说明可以用一个简单的例子来概括:

> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"

其中 "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 是被求值的 Lua 脚本,数字 2 指定了键名参数的数量, key1key2 是键名参数,分别使用 KEYS[1]KEYS[2] 访问,而最后的 firstsecond 则是附加参数,可以通过 ARGV[1]ARGV[2] 访问它们。

参考: http://redis.readthedocs.org/en/latest/script/eval.html#eval

 

table.remove

table 的默认初始索引一般以 1 开始

table.remove(table, pos)

table.remove()函数删除并返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起.

参考:http://dhq.me/lua-learning-notes-table

 

assert (v [, message])


功能:相当于C的断言,
参数:
v:当表达式v为nil或false将触发错误,
message:发生错误时返回的信息,默认为"assertion failed!"

 

unpack

函数unpack可以返回多个值,它传入一个array,然后返回array中的每一个值

参考:http://blog.csdn.net/wzzfeitian/article/details/8653101

 

 

Golang 这个的实现版本在: https://github.com/kdar/goqless

其中的调用逻辑被封装在下面代码:

github.com\kdar\goqless\client.go

func (c *Client) Do(name string, keysAndArgs ...interface{}) (interface{}, error) {

  return c.lua.Do(name, keysAndArgs...)
}

这里的 name 是 qless的命令, 类似下面的 get, 其他是这里的参数。

-- Return json for the job identified by the provided jid. If the job is not

-- present, then `nil` is returned
function QlessAPI.get(now, jid)
  local data = Qless.job(jid):data()
  if not data then
    return nil
  end
  return cjson.encode(data)
end