我经常遇到这样的情况:我要存储的信息比 Redis 的任何简单数据结构都更复杂。我仍然想使用 Redis,但我想知道人们在理想情况下想要使用嵌套结构时是否有任何标准替代方案?
2 回答
你基本上有两种策略:
您可以序列化您的复杂对象并将它们存储为字符串。我们建议将 json 或 msgpack 用于序列化格式。这很容易从大多数客户端语言进行操作。如果需要服务器端访问,那么服务器端 Lua 脚本可以轻松地对此类对象进行编码/解码,因为 Redis 是使用 msgpack 和对 Lua 的 json 支持进行编译的。
您可以将对象拆分为不同的键。您可以存储几个键,例如 user:id、user:id:address_list、user:id:document_lists 等...... EXEC 块可用于保证数据的一致性,并聚合往返。
请参阅此答案中的一个简单示例:
最后,Redis 不是面向文档的数据库。如果您确实有很多复杂的文档,也许 MongoDB、ArangoDB、CouchDB、Couchbase 等解决方案可以更好地为您服务......
当需要修改对象时,将复杂对象序列化为字符串,并将字符串保存到Redis,效率非常低。由于您必须将字符串取回客户端,将其反序列化为对象,对其进行修改,再次将其序列化为字符串,然后将其保存回 Redis。太多的工作...
现在是 2019 年,有一些新的 Redis 模块可以使 Redis 支持嵌套数据结构,例如RedisJSON、redis-protobuf。
免责声明:我是 redis-protobuf 的作者,所以我会在这个模块上给出一些例子。redis-protobuf也比RedisJSON更快,内存效率更高,因为它使用文本格式以外的二进制格式来序列化/反序列化数据。
首先,您需要以Protobuf 格式定义嵌套数据结构并将其保存到本地文件:
syntax = "proto3";
message SubMsg {
string s = 1;
int32 i = 2;
}
message Msg {
int32 i = 1;
SubMsg sub = 2;
repeated int32 arr = 3;
}
然后在redis.conf中使用以下配置加载模块:
loadmodule /path/to/libredis-protobuf.so --dir proto-directory
之后,您可以读写嵌套数据结构:
PB.SET key Msg '{"i" : 1, "sub" : {"s" : "string", "i" : 2}, "arr" : [1, 2, 3]}'
PB.SET key Msg.i 10
PB.GET key Msg.i
PB.SET key Msg.sub.s redis-protobuf
PB.GET key Msg.sub.s
PB.SET key Msg.arr[0] 2
PB.GET key Msg.arr[0]