0

我希望尽可能高效地获取 redis 键列表。我们可以根据自己的喜好在 redis 服务器上对此进行建模,因此这与解决问题的正确方法一样重要。让我描述一下情况。

假设有大量“客户”作为字符串存储在 Redis 中。

customer__100000
customer__100001
customer__100002

每个客户都有很多属性。其中将是他们居住的城市。每个城市也存储在 Redis 中。

city__New York
city__San Francisco
city__Washington DC

通过不同的过程,我最终会得到一组客户密钥(预过滤器的相交集)。一旦我有了这些密钥,我需要找出哪些不同的我在这些客户中拥有我在这里的最终目标是获得城市的名称,但是如果我能获得可以提取城市名称的钥匙,那也很好。

为了给出我在这里谈论的规模的想法,假设我们正在处理具有大约 70 个属性(城市是其中之一)的 200-300k 客户,每个属性从 50 到 100,000。我想尽可能保持高效。

4

1 回答 1

2

与其将客户存储为字符串,不如将它们存储为哈希值。Redis 的哈希 ziplist 编码非常节省空间。如果你存储超过 70 个元素,你应该考虑hash-max-ziplist-entries在你的 redis.conf 中提高限制

SORT当您使用 Redis 哈希时,您可以做一些有趣的事情。通过使用SORTwith GETSTORE您可以从客户那里获取所有城市并将它们存储为列表(不区分)。然后,您可以通过调用lpopsadd覆盖列表将列表转换为集合。

这是一个示例 Redis Lua 脚本:

-- a key which holds a set of customer keys
local set_of_customer_keys = KEYS[1]
-- a maybe-existing key which will hold the set of cities
local distinct_set = ARGV[1]
-- attribute to get (defaults to city)
local attribute = ARGV[2] or 'city'
-- remove current set of distinct_cities
redis.call("DEL", distinct_set)
-- use SORT to build a list out of customer hash values for `attribute` 
local cities = redis.call("SORT", set_of_customer_keys, "BY", "nosort", "GET", "*->"..attribute)
-- loop through all cities in the list and add them to the distinct cities set
for i, city in pairs(cities) do
  redis.call("SADD", distinct_set, city)
end
-- return the distinct cities
return redis.call("SMEMBERS", distinct_set)

您还可以保留一customer__100000__cities组与客户的属性一起永久存储并用于sinter *customer_cities_keys获取一组不同的城市,但这会降低内存效率。

于 2013-04-17T15:56:46.870 回答