中关村村草 发表于 2012-02-16 19:52

Redis新分支,进行服务端lua脚本支持的开发

Redis新分支,进行服务端lua脚本支持的开发










早在一年前,在Redis 的google group上就曾有人提出redis能不能提供诸如keya=kayb这样类似脚本语言的方法来操作数据。而最近Redis作者antirez同学连续发表的两篇博文将Redis执行脚本一事正式提到日程上来。

1 服务端执行脚本的好处:

按antirez同学的说法,Redis执行脚本有如下一些好处:

•能够上Redis更快!很多Redis应用的使用方式是read-compute-write模式,这使得一次简单的数据计算都需要客户端与服务端进行两次通信,而如果把中间的compute过程转移到服务端执行,则可以成倍地减少round-trip时间。
•充分利用CPU!Redis的绝大多数应用场景都是IO密集型,即使是到达CPU100%极限(Redis无法使用多核)的,CPU的使用也大多是在网络协议栈的处理上,但如果使用服务端执行的脚本,则可以充分将Redis Server的CPU利用起来。
•但最根本的原因在于:这样我们可以只在Redis中实现最基本的能够满足99%用户需求的功能,把其它独特应用场景下的1%的功能留给自定义的服务端执行脚本来实现。对于害怕Redis引入服务端脚本后变得冗余庞大的同学,看到这里可以舒一口气了,因为这就是为了防止满足无休止的需求而提出的终极解决方案。
2 如何实现

在考虑各个方案后,Redis采用了内嵌lua解释器的方式,lua语言是一种小巧灵活的语言,被广泛地嵌入在很多服务程序中,我们熟悉的人nginx-lua模块,tokyotyrant也支持lua的嵌入。

3 使用方法及例子
Redis的方案是客户端将lua脚本作为命令传给服务端,服务端读到脚本,调用解释器进行解释后进行执行并返回。如下例:

EVAL   [... ]•EVAL:服务端执行脚本的命令
•body:lua脚本的内容
•num_keys_in_args:在后面的参数中,有几个是表示key的
•args…:参数,其中包括num_keys_in_args个key,剩下的是普通的参数
下面是几个作者提供的使用例子:

例1:直接返回keys和args

redis> eval "return {KEYS,KEYS,ARGV,ARGV}" 2 key1 key2 arg1 arg2
1) "key1"
2) "key2"
3) "arg1"
4) "arg2"例2:lua的数据结构在Redis的返回中的形式

redis> eval "return 10" 0
(integer) 10
redis> eval "return 'foobar'" 0
"foobar"
redis> eval "return {1,2,'a','b'}" 0
1) (integer) 1
2) (integer) 2
3) "a"
4) "b"
redis> eval "return {err='Some Error'}" 0
(error) Some Error
redis> eval "return {ok='This is a status reply'}" 0
This is a status reply例3:用lua访问Redis存储数据

OK
redis> eval "return redis('get',KEYS)" 1 x
"foo"例4:一个真实的例子

# Conditional decrement.
#
# Decrement the value of a key only if the current value is greater than
# a specified value.

require 'rubygems'
require 'redis'

r = Redis.new
cond_decr = < tonumber(ARGV)
    then
      value = value - 1
      redis('set',KEYS,value)
    end
    return value
LUA

r.set(:x,4)
5.times {
    puts(r.eval(cond_decr,1,:x,0))
}
上面脚本的执行结果如下:

ruby cond-decr.rb
3
2
1
0
0
目前服务端脚本支持的分支已经在github上可以看到,有兴趣的同学可以试用一下。

相关链接:
Redis and scripting Scripting branch released

如果有一天21 发表于 2012-02-17 22:22

谢谢分享
页: [1]
查看完整版本: Redis新分支,进行服务端lua脚本支持的开发