Redis和大量的密钥

时间:2016-12-08 11:37:24

标签: php lua redis

我面临着加速我的应用程序的需求(用PHP编写,简单的GET服务),我决定将它从RDBMS方法转移到Redis。花了一周研究如何做到这一点,并考虑到我的关系数据库中有很多字段,我在redis中创建了这样的结构: {nameOfTable:clientID:itemID},例如

SET clientSubjects:1:1 bigJSONStringHere1
SET clientSubjects:1:2 bigJSONStringHere2
SET clientSubjects:1:3 bigJSONStringHere3

SET clientSubjects:2:1 bigJSONStringHere4
SET clientSubjects:2:2 bigJSONStringHere5
SET clientSubjects:2:3 bigJSONStringHere6

我有大约2000万客户,每个客户有大约4-10个主题,所以它大约有1.5亿个密钥。 要查找所有客户的主题,每次我收到某个客户的请求时,我都必须使用SCAN。我遇到了一个问题,当我把所有客户端加载到Redis时,命令

scan 0 match clientSubjects:{someID}:* count 100返回:

1) "7241728"
2) (empty list or set)

而且......我的决定是在redis存储中查找密钥总数并将其用作COUNT参数。

这看起来像:

local keyspace = redis.call("info", "keyspace")
local keysCount = keyspace:match("keys=(%d+),")
local result = redis.call("SCAN", 0, "match", "clientSubjects:" .. ARGV[1] .. ":*", "count", keysCount) --ARGV means I pass clientID to lua script

所以一切正常,但需要大约3秒才能执行!但我需要它几毫秒......我该怎么办?

1 个答案:

答案 0 :(得分:1)

拥有2000万条记录,您需要大量内存来存储所有数据结构以及查询它的不同方式。

例如,要查找所有客户的主题,我会有一个名为clientSubjects:{clientID}的集合或列表,其中包含主题ID的值。

您应该有不同的数据结构以适应不同的查询,并避免使用SCAN之类的东西,因为这不是最佳的。

在我看来,带有一些放置好的索引的关系数据库会更适合这种情况,它会为你节省大量的时间和金钱,因为索引通常会保存在内存中并且可以回退到磁盘上。

请记住,Redis要求您将所有数据存储在内存中,因此当您添加更多数据结构来解决不同的查询类型时,这将变得更加昂贵。