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[1],KEYS[2],ARGV[1],ARGV[2]}" 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])" 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[1])
    then
        value = value - 1
        redis('set',KEYS[1],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

anyShare分享此文章的同学,将有机会送我iphone5!
          

无觅相关文章插件,快速提升流量

分类 Redis · tag , , ,

    • 非常遗憾的,diskstore将会无限期延后或者不再进行开发。详情可以看这里:http://blog.nosqlfan.com/html/1678.html