【问题标题】:Redis design help (From Relational to NoSQL)Redis 设计帮助(从关系到 NoSQL)
【发布时间】:2015-07-06 18:00:17
【问题描述】:

我是一名 SQL 开发人员,对 redis 很陌生,但它的性能非常有趣。我有一个问题,我认为 redis 可以帮我很大的忙。我有一个熟悉的 SQL 表:

| CONTAINER <String><NoUnq> | PROCESS <String><NoUnq> | PROCESS_DATA <String><NoUnq> | TimeCreated <TimeStamp><NoUnq>|

此表在填充到最大值时大约有 ~450,000,000 行。我在 AWS 上运行它。有了这些行,我选择了一个容器中的所有进程(~1,000,000 个容器),所以我会在 sql 中有这样的东西(当然容器是索引的):

SELECT * FROM table WHERE container = '[CONTAINER_NAME]';

然后我有一个 cronjob 脚本,它每小时运行一次,并使用以下内容从容器中删除旧进程:

DELETE FROM table WHERE TimeCreated <= [SOME_TIME];

所以基本上我喜欢不超过 4-5 小时的进程。看着 Redis,我觉得我可以设计类似的东西来提高我的性能,但是在将这种类似 SQL 的设计转换为 Redis 时遇到了麻烦。

我的第一个想法是使用 HSET,但我发现 HSET 不允许在字段上使用 EXPIRE 命令,因此我无法自动删除旧进程。我最关心的是性能和效率。

【问题讨论】:

  • 您是否正在查看 Redis 中两个语句(SELECT 和 DELETE)的等效项?
  • 并不完全等同于我认为 get 和 del 命令,但我正在寻找的是一种选择具有相同容器的所有键的有效方法。同样,我想删除所有旧的键。

标签: mysql amazon-web-services redis nosql


【解决方案1】:

看起来您可以(并且可能应该)使用HSET。看起来你不需要使字段过期。您需要使密钥过期。基于此密钥上的container nameEXPIREAT 的密钥名称。如果你像上面写的那样讲述表关系结构,最类似的模拟是一个表行是一个键:

MULTI
HMSET <container name:rowId> PROCESS <value> PROCESS_DATA <value>
EXPIREAT <container name:rowId> <TimeCreated>
EXEC

您还可以使用 ZSET 来存储与时间相关的行列表:

ZADD <container name> <TimeCreated> <rowId> 

因此,您可以将 zRange 用作 SELECT 等效项。您也可以使用 LUA 脚本通过一个请求来获取容器的内容。类似的东西(我可能会在 LUA 语法的某个地方出错):

 local result = {}
 local tmp = redis.call( 'zrange', KEYS[1], ARG[1], ARG[2], 'withscores' )
 for k, v in pairs(tmp) do
    result[v] = redis.call('hgetall', KEYS[1] + ':' + k)
 end
 return result

其中 KEYS1 - 容器名称,ARG1 - 从 , ARG2- 到。

附言此外,您应该了解 how redis expire keys 以了解您实例中的内存会发生这种情况。

【讨论】:

  • 感谢您的回复。这会删除整个容器吗?如果是这样,我不能拥有这个,因为容器中会有其他进程不会太旧,所以我需要它们仍然在那里。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 2023-03-22
相关资源
最近更新 更多