SPL:访问 Redis

RedisK-V数据库,value可以是StringHashmapListSetSortedset。针对每种value提供了一系列不同的操作命令,加上一些管理命令,总计三百多个。这些命令返回的结果格式不尽相同,而且也只能简单地存取数据,分组、聚合、排序、子查询、多步骤等计算能力较弱。计算引擎SPLRedisJava APIjava-redis-client》封装成redis_command()函数,能方便地执行Redis命令,取出数据,弥补Redis的计算能力。

创建/关闭Redis连接

使用方式类似关系数据库的JDBC连接,SPL也用成对的创建/关闭方式连接Redis

redis_open(redisUrl),参数redisUrlRedis服务器地址。

redis_close(redisConn)redisConn是要关闭的Redis连接。

示例:A1创建连接,中间做一些读写、计算操作后,A3关闭A1创建的连接


A

1

=redis_open("127.0.0.1:6379")

2

……

3

=redis_close(A1)

执行Redis命令

redis_command(redisConn,commandParts),两个参数,redisConnRedis连接,commandParts是组成一个完整Redis命令的序列,序列长度不定,不同Redis命令长度不同,同一个Redis命令,带有不同控制选项时,长度也不同。

 

示例:


A

1

=redis_open("127.0.0.1:6379")

2


3

=redis_command(A1,["COMMAND"])

4

=create(Name,Arity,Flags,FirstKey,LastKey,Step)

5

>A3.run(curr=~,A4.insert(0,curr(1),curr(2),curr(3),curr(4),curr(5),curr(6)))

6


7

=redis_command(A1,"SCAN 0 COUNT 5".split(" "))

8

=redis_command(A1,["SCAN",A7(1),"COUNT","5"])

9

=redis_command(A1,["SCAN",A8(1),"COUNT","5"])

10

=A7(2)&A8(2)&A9(2)

11


12

'return redis.call("SET",KEYS[1],ARGV[1])

13

=redis_command(A1,["EVAL",A12,"1","foo","bar"])

14


15

=redis_command(A1,["SET","time1",string(long(now()))])

16

=redis_command(A1,["GET","time1"])

17

=datetime(long(A16))

18


19

=redis_close(A1)

 

第一段(A3~A5)代码中,A3执行COMMAND命令获得Redis全部命令的定义

..

每个命令定义是一个没有结构的序列,不方便查看。A4定义一个新的方便查看的序表结构,A5A3中的结果整理到A4序表中,A4结果:

..

 

第二段(A7~A10)代码执行SCAN命令,获取key name列表,SCAN 0 COUNT 50cursor id,新的SCAN初始为0。取到的结果有两个值,第一个是cursor id,第二个是key name列表:

..

A7返回的 cursor id拼成了A8的命令,同样的用A8返回的cursor id再拼入A9的命令中,A10把得到的三个结果列表合并起来:

..

 

第三段(A12~A13)执行EVAL命令,调用一段Lua脚本,EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 foo bar

A12定义一段任意复杂的Lua脚本,A13SPLredis_command()调用EVAL命令执行A12的脚本。简单命令的各个部分都是用空格分开的,如SCAN 0 COUNT 5,因此可以用SPLsplit(" ")拆分得到命令序列,但现在执行脚本,脚本中可能存在换行、引号,就不适宜和EAVL命令拼成一个大字符串再split了,而是像A13这样直接定义命令序列的各个元素。

..

 

Redis里只有字符串类型,没有日期时间类型,保存日期数据时需要做下转换,如第四段(A15~A17)中,要存储日期的时间戳(毫秒数)字符串,读回SPL时,再转换回来。A15把当前时间调用SET time1 1644980173398命令把当前时间存储到Redis,生成当前时间的时间戳字符串用到了SPLstring()long()now()函数,A16GET time1命令读取回来,A17SPLlong()datetime()函数转换回日期类型:

..

..

..