如何在使用 rredis 从 R 编写的 Redis 中实现数据压缩以减少内存使用?

How to implement data compression in Redis written from R with rredis to reduce memory usage?

我需要压缩存储在 Redis 中的数据。我将数据从 R(使用包 rredis)写入 Redis,如下所示:

redisSet("x","{\"email\":\"master@disaster.com\",\"Ranking\":[{\"Number\":37665,\"rank\":1},{\"Number\":41551,\"rank\":2},{\"Number\":21684,\"rank\":3},{\"Number\":35946,\"rank\":4}]}")

实际场景中将有 4000 个,而不是该值列表中的 4 个元素,总共有 70000 个这样的键。目前,这些密钥中的每一个都占用 ~0.15 MB。

我了解到可以显着压缩 Redis 中这些条目的内存使用,例如使用 LZO 或 Snappy 等算法。但是我找不到有关具体实现的信息。 一些解决问题的建议?谢谢!

没有内置的方法。

但是,Redis 可以存储二进制数据,因此您可以使用任何喜欢的压缩算法压缩您的数据,并将压缩后的二进制数据存储到 Redis。读取数据时,需要得到二进制数据,用同样的压缩算法解压。

感谢提示!我能够实现它,这里有一些细节:

我按照建议使用了在 R(基本包)中实现的压缩功能。

memCompress()

我尝试了不同的压缩方式 gzip 和 bzip2。

memCompress(type="gzip",...)
memCompress(type="bzip2",...)

这是带有玩具示例的代码:

#In R:
x<-"{\"email\":\"master@disaster.com\",\"Ranking\":[{\"Number\":37665,\"rank\":1},{\"Number\":41551,\"rank\":2},{\"Number\":21684,\"rank\":3},{\"Number\":35946,\"rank\":4}]}"
y<-memCompress(charToRaw(x),type="gzip")
# [1] 78 9c 4d c9 3d 0a 80 20 00 06 d0 bb 7c b3 04 e6 4f e5 d4 09 1a 5a a3 c1 4a 42 ca 02 ad 29 bc 7b 11 48 6d 0f de 05 e3 b4 5d a1 e0 74 38 8c
# [47] af 27 1b 5e 64 e3 ee 40 d0 ea 6d b1 db 0c d5 5d 68 4e 37 18 0f c5 0a 29 05 81 7f 0a 8a 46 f2 0d a7 42 d0 34 f9 7f 72 2a 4b 9e 86 fd 87 89
# [93] 8a cb 34 3c f6 f1 06 b3 67 2d c4
rawToChar(memDecompress(y,type="gzip"))
# [1] "{\"email\":\"master@disaster.com\",\"Ranking\":[{\"Number\":37665,\"rank\":1},{\"Number\":41551,\"rank\":2},{\"Number\":21684,\"rank\":3},{\"Number\":35946,\"rank\":4}]}"  



# R to redis:
redisConnect(host="XXX.XX.XX.XXX", port=XXXX, timeout =10) # Insert your redis information (IP and port)
x<-"{\"email\":\"master@disaster.com\",\"Ranking\":[{\"Number\":37665,\"rank\":1},{\"Number\":41551,\"rank\":2},{\"Number\":21684,\"rank\":3},{\"Number\":35946,\"rank\":4}]}"
redisSet("x",x) #Wrong transfer of character string to redis
# redis-cli # On redis server
# get x # On redis server
# "X\n\x00\x00\x00\x02\x00\x03\x03\x02\x00\x02\x03\x00\x00\x00\x00\x10\x00\x00\x00\x01\x00\x04\x00\t\x00\x00\x00\x93{\"email\":\"master@disaster.com\",\"Ranking\":[{\"Number\":37665,\"rank\":1},{\"Number\":41551,\"rank\":2},{\"Number\":21684,\"rank\":3},{\"Number\":35946,\"rank\":4}]}"
redisSet("x",charToRaw(x)) #Right transfer of character string to redis
# redis-cli # On redis server
# get x # On redis server
# "{\"email\":\"master@disaster.com\",\"Ranking\":[{\"Number\":37665,\"rank\":1},{\"Number\":41551,\"rank\":2},{\"Number\":21684,\"rank\":3},{\"Number\":35946,\"rank\":4}]}"
redisSet("x",memCompress(charToRaw(x),type="gzip")) #Right transfer of compressed string to redis
# redis-cli # On redis server
# get x # On redis server
# "x\x9cM\xc9=\n\x80 \x00\x06\xd0\xbb|\xb3\x04\xe6O\xe5\xd4\t\x1aZ\xa3\xc1JB\xca\x02\xad)\xbc{\x11Hm\x0f\xde\x05\xe3\xb4]\xa1\xe0t8\x8c\xaf'\x1b^d\xe3\xee@\xd0\xeam\xb1\xdb\x0c\xd5]hN7\x18\x0f\xc5\n)\x05\x81\x7f\n\x8aF\xf2\r\xa7B\xd04\xf9\x7fr*K\x9e\x86\xfd\x87\x89\x8a\xcb4<\xf6\xf1\x06\xb3g-\xc4"

# I have not implemented the reimport to R yet. So feel free to add it :)

这个短字符串没有改进。但是对于长版本(4000 而不是 json 文件中的 4 个元素)有一个巨大的改进:

在这种情况下,压缩使内存使用和写入时间提高了约 85%!

压缩: 将 500 个用户(每个用户有 4.000 个元素)写入 Redis 的时间:12.62 秒 内存由 500 个用户保存,每个用户在 Redis 上有 4.000 个元素:11.782 MB

未压缩: 将 500 个用户(每个用户有 4.000 个元素)写入 Redis 的时间:88.76 秒 内存由 500 个用户保存,每个用户在 Redis 上有 4.000 个元素:78.192 MB