我打算使用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数据集存储在CouchDBMongoDB(使用GridFS)中取得了一些成功。

10-07 13:01