我正在测试 Redis 是否可以成为键值存储的良好解决方案。就我而言,租户的用户可以在我们的系统中保存键值对。数据如下所示:
{
"user" : "x1",
"tenant" : "y1",
"key": "key1",
"value": "value1",
"last_updated": "xxx-xx-xxx"
"another-metadata-field": "ddd"
}
Run Code Online (Sandbox Code Playgroud)
我的主要目标是:
select value from table where user=x and tenant=y and key=z
)。select * from table where user=x and tenant=y
或select * from table where tenant=z
)我可以使用 RDBMS 来做到这一点,但我想它会比使用内存数据库(持久性)慢。
对于 Redis,我考虑通过以下方式保存数据(使用本机 Redis 类型):
127.0.0.1:6379> sadd tenant1 user1
(integer) 1
127.0.0.1:6379> sadd tenant1 user2
(integer) 1
127.0.0.1:6379> sadd tenant1_user1 key1
(integer) 1
127.0.0.1:6379> sadd tenant1_user1 key2
(integer) 1
127.0.0.1:6379> hset "tenant1:user1:key1" value 50
(integer) 1
127.0.0.1:6379> hset "tenant1:user1:key1" last_updated "xx-xx-xxxx"
(integer) 1
127.0.0.1:6379> hget "tenant1:user1:key1" value
"50"
Run Code Online (Sandbox Code Playgroud)
通过这种方法,我可以快速检索特定的密钥,但为了检索特定用户/租户的所有键值,我需要执行如下操作:
// Get all key-values of specific user and tenant
smembers tenant1_user1
1) "key1"
2) "key2"
hgetall "tenant1:user1:key1"
1) "value"
2) "50"
3) "last_updated"
4) "xx-xx-xxxx"
// Get all key-value pairs of tenant
127.0.0.1:6379> smembers tenant1
1) "user2"
2) "user1"
127.0.0.1:6379> smembers tenant1_user1
1) "key1"
2) "key2"
127.0.0.1:6379> hgetall "tenant1:user1:key1"
1) "value"
2) "50"
3) "last_updated"
4) "xx-xx-xxxx"
Run Code Online (Sandbox Code Playgroud)
我想知道 :
这是在这个用例中实现的 redis 方式吗?
如果值为 json,则将 json 保存为字符串在内存利用率方面似乎是一个错误的决定。redis-json 适合这里吗?
在我看来你走在正确的道路上。通过使用哈希和集合的方法,您可以相对轻松地进行一些性能改进......
HSET
是可变参数,因此您可以一次设置多个属性,从而节省网络往返时间:
HSET "tenant1:user1:key1" value 50 last_updated "xx-xx-xxxx"
Run Code Online (Sandbox Code Playgroud)
您可以使用 Lua 脚本 ( https://redis.io/docs/interact/programmability/eval-intro/ ) 使使用集合和哈希值的查找作为原子操作在 Redis 服务器上执行。如果您使用的是 Redis 7 ( https://redis.io/docs/interact/programmability/functions-intro/ ),请考虑使用函数。这允许您在服务器上执行循环和分支/条件逻辑。
如果您有权访问 Redis Stack ( https://redis.io/docs/getting-started/install-stack/ ) - 请注意,它的许可方式不同,但对于大多数用例来说仍然是免费的 ( https://redis. io/docs/about/license/),那么您可以使用搜索功能。您将继续将数据存储在哈希中(或在 Redis Stack 中使用 JSON 文档,因为它将 JSON 添加为本机数据类型)。然后使用该FT.CREATE
命令在数据集上创建索引,描述要索引的字段。然后,Redis 将为您跟踪数据的更改并自动更新索引,而您的应用程序无需维护额外的数据结构(例如集合)。
然后,您可以使用该FT.SEARCH
命令执行类似 SQL 的查询。这是一个相当大的话题,如果您决定走 Redis Stack 路线,Redis 大学有涵盖这些概念的课程:
你还问过:
如果值为 json,则将 json 保存为字符串在内存利用率方面似乎是一个错误的决定。redis-json 适合这里吗?
将 JSON 序列化为 Redis 字符串(例如将其存储为哈希中的字段)的成本很高,因为您需要将所有 JSON 发送到 Redis 或从 Redis 发送所有 JSON 才能读取其中的任何内容,并且无法自动更新它。如果您有权访问 Redis Stack,则使用 JSON 数据类型可以显着减少客户端和服务器之间不必要的数据移动,并以原子方式对 Redis 中的 JSON 文档执行各种操作。
归档时间: |
|
查看次数: |
412 次 |
最近记录: |