在Redis中存储相似项的巨大随机列表
Redis 2.0.3 我需要在Redis中存储一个庞大的项目列表。每个项目都是一个短字符串(少于256个字符) 我需要在列表上执行两个操作:在Redis中存储相似项的巨大随机列表,redis,data-storage,high-load,Redis,Data Storage,High Load,Redis 2.0.3 我需要在Redis中存储一个庞大的项目列表。每个项目都是一个短字符串(少于256个字符) 我需要在列表上执行两个操作: 添加许多(数千到一百万)相同的项目。(一天几次) 从列表中删除一个随机项。没有必要有“公平”的随机性。任何“足够好”的方法都可以。(每秒最多数百次) 我没有足够的内存来逐个存储列表中的所有项目 我认为我需要分批存储项目、名称和计数器。(将有多达数千个不同的项目,更像数百个。) 但我不知道如何有效地组织这件事 有什么提示吗?好吧,既然没有人来帮我,这里
- 添加许多(数千到一百万)相同的项目。(一天几次)
- 从列表中删除一个随机项。没有必要有“公平”的随机性。任何“足够好”的方法都可以。(每秒最多数百次)
有什么提示吗?好吧,既然没有人来帮我,这里有一个伪代码的“愚蠢”解决方案
function maybe_get_next_item()
item_name = SRANDMEMBER "items-set"
item_key = "items:" + item_name
new_item_count = DECR (item_key)
if new_item_count < 0 then
LOCK -- As explained in SETNX docs
new_item_count = GET (item_key) -- More added while we were locking?
if new_item_count and new_item_count < 0 then
SREM (item_name) -- No, expire it
end
UNLOCK
end
if new_item_count and new_item_count >= 0 then
return item_name
end
return false -- this item not found
end
function get_next_item()
item_name = maybe_get_next_item()
while not item_name and (SCARD "items-set" > 0) do
item_name = maybe_get_next_item()
end
return item_name -- false if all items are expended
end
我怀疑
insert_items()
中的LOCK
/UNLOCK
可能是多余的,可以用MULTI
/EXEC
替换,但我认为中的LOCK
/UNLOCK
可能需要它才能正常工作(我不知道如何替换为MULTI
/EXEC
)…注意,这里的概率是倾斜的,因为相同项目的数量在获得项目的机会中不起任何作用。这对于我的特定用例来说是可以的。在2.2上,更好的方法是使用WATCH:
function insert_items(item_name, amount)
LOCK -- As explained in SETNX docs
SADD "items-set" (item_name)
INCRBY ("items:" + item_name) amount
UNLOCK
end