我在R中有许多大型数据帧,我计划用redis存储它们。我对redis完全不熟悉,但今天一直在阅读它并且一直在使用R包rredis
。
我一直在玩小数据,并使用redisSet()
和redisGet()
函数保存和检索小数据帧。但是,在保存我的大型数据帧时(其中最大的数据是430万行,当保存为.RData文件时为365MB)
使用代码redisSet('bigDF', bigDF)
我收到以下错误消息:
Error in doTryCatch(return(expr), name, parentenv, handler) :
ERR Protocol error: invalid bulk length
In addition: Warning messages:
1: In writeBin(v, con) : problem writing to connection
2: In writeBin(.raw("\r\n"), con) : problem writing to connection
大概是因为数据帧太大而无法保存。我知道redisSet将数据帧写为字符串,这可能不是使用大型数据帧的最佳方法。有谁知道最好的方法吗?
编辑:我创建了一个非常大的虚拟数据帧,我重新创建了错误:
bigDF <- data.frame(
'lots' = rep('lots',40000000),
'of' = rep('of',40000000),
'data' = rep('data',40000000),
'here'=rep('here',40000000)
)
正在运行redisSet('bigDF',bigDF)
会给我一个错误:
Error in .redisError("Invalid agrument") : Invalid agrument
第一次,然后立即再次运行它我得到错误
Error in doTryCatch(return(expr), name, parentenv, handler) :
ERR Protocol error: invalid bulk length
In addition: Warning messages:
1: In writeBin(v, con) : problem writing to connection
2: In writeBin(.raw("\r\n"), con) : problem writing to connection
由于
答案 0 :(得分:7)
简而言之:你做不到。 Redis can store a maximum of 512 Mb of data in a String value您的序列化演示数据框大于:
> length(serialize(bigDF, connection = NULL)) / 1024 / 1024
[1] 610.352
技术背景:
serialize
通过.cerealize
和redisSet
在包的rredis:::.redisCmd
函数中调用:
> rredis:::.cerealize
function (value)
{
if (!is.raw(value))
serialize(value, ascii = FALSE, connection = NULL)
else value
}
<environment: namespace:rredis>
Offtopic:为什么要将这么大的数据集存储在redis中呢? Redis适用于小键值对。另一方面,我通过在那里添加压缩的RData
作为附件,在CouchDB和MongoDB(使用GridFS)存储大R数据集方面取得了一些成功。