我打算使用Redis存储R中的许多大型数据帧。我对redis完全陌生,但是今天已经阅读了有关它,并一直在使用R包rredis
。
我一直在处理小数据,并使用redisSet()
和redisGet()
函数保存和检索小数据帧。但是,当要保存更大的数据帧时(当另存为.RData文件时,最大的数据帧为430万行和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
谢谢
最佳答案
简而言之:,您不能。 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>
题外话:为什么您仍要在redis中存储这么大的数据集? Redis适用于小型键/值对。另一方面,通过在其中添加压缩的
RData
作为附件,我在将大的R数据集存储在CouchDB和MongoDB(使用GridFS)中取得了一些成功。