6

我在 R 中有许多大型数据框,我打算使用 redis 存储它们。我对 redis 完全陌生,但今天一直在阅读它并且一直在使用 R 包rredis

我一直在玩小数据,并使用redisSet()andredisGet()函数保存和检索小数据帧。但是,当使用代码保存较大的数据帧(其中最大的是 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

谢谢

4

1 回答 1

7

简而言之:你不能。Redis 最多可以在 String 值中存储 512 Mb 的数据,并且您的序列化演示数据帧大于:

> length(serialize(bigDF, connection = NULL)) / 1024 / 1024
[1] 610.352

技术背景:

serialize.cerealize在包的函数中通过redisSetand调用rredis:::.redisCmd

> rredis:::.cerealize
function (value) 
{
    if (!is.raw(value)) 
        serialize(value, ascii = FALSE, connection = NULL)
    else value
}
<environment: namespace:rredis>

题外话:你为什么要在redis中存储这么大的数据集?Redis 用于小型键值对。另一方面,通过在CouchDBMongoDB(使用 GridFS)中添加压缩文件RData作为附件,我在存储大型 R 数据集方面取得了一些成功。

于 2013-04-25T19:57:45.257 回答