R 和 redis 的联合使用

redis作为强大的Key-Value服务,如何和R进行结合,这里做一些简单的记录

redis安装

redis安装非常简单,几乎不用管什么依赖关系:

1
2
3
4
5
6
wget http://download.redis.io/releases/redis-x.x.x.tar.gz
tar xzf redis-x.x.x.tar.gz
cd redis-x.x.x
make
make-test
sudo make install

官网上有足够的资料介绍。安装完毕后,生成redis-server、redis-cli、redis-benchmark、redis-stat。

  • redis-server:服务启动程序
  • redis-cli:Redis命令行操作工具
  • redis-benchmark:Redis性能测试工具
  • redis-stat:Redis状态检测工具

在Terminal中执行 redis-server 即可启动服务。

简单的试用一下redis,打开新的Terminal,执行redis-cli进入命令行:

1
2
3
4
5
6
7
8
9
10
11
sunbjt@ubuntu:~$ redis-cli 
127.0.0.1:6379> set y 10
OK
127.0.0.1:6379> get y
"10"
127.0.0.1:6379> EXPIRE y 10
(integer) 1
127.0.0.1:6379> get y
"10"
127.0.0.1:6379> get y
(nil)

上面的意思是设置了Key y的Value 为10,并获取;设置过期时间10秒,看y的值有,10秒后y为空。

使用rredis

在R中直接执行

install.packages('rredis')

即可安装完毕。这个包适配性很强,在所有的R环境中均可使用,包括经常出问题的Microsoft WIndows。

假定我们在client端已经启动了R

1
2
3
4
5
6
7
8
9
> library(rredis)
> redisConnect('192.168.226.128') # ip为redis服务地址
> x <- rnorm(5)
> x
[1] -0.8542932 0.2279106 -2.6222566 -0.1386406 -1.2380619
> redisSet('x', x)
[1] "OK"
> redisGet('x')
[1] -0.8542932 0.2279106 -2.6222566 -0.1386406 -1.2380619

多变量传输:

1
2
3
4
5
redisMSet(list(x=pi,y=runif(5),z=sqrt(2)))
redisMGet(c("x","y","z"))
redisExpire("z",1)
Sys.sleep(1)
redisGet("z")

可能在redis-cli上看R传输过去的都是乱码,解决办法就是 encode 一下

1
redisSet('z', charToRaw('10'))

以及更加底层的,可以使用任意有效 redis 函数的R函数:

1
redisCmd('get', 'x')

rredis pipelining

redis 的 wiki 上有以下描述:

A Request/Response server can be implemented so that it is able to process new requests even if the client didn't already read the old responses. This way it is possible to send multiple commands to the server without waiting for the replies at all, and nally read the replies in a single step.

因此,只需要在 rredis 环境下首先声明 redisSetPipeline(TRUE),而后所有指令传递过去之后,并不直接返回到 R,而是缓存在 redis 服务端,再通过一个显式的函数(redisGetResponse)获得执行。

1
2
3
4
5
6
7
redisSetPipeline(TRUE)
t1 <- proc.time()
for(j in 1:100) redisSet(paste('x', j, sep = ''), charToRaw(as.character(j)))
resp <- redisGetResponse()
proc.time() - t1
redisConnect('192.168.226.128') # 连接被关闭,需重新打开redis连接
redisGet('x1')

redis 这么牛掰的 KV 服务器能做的事情肯定不止这么多,以上仅仅是一个简单的介绍。如果有合适的小型项目,再看看能不能做出点有意思的东西来。