我知道的老问题,但我认为它应该得到更全面的答案。
从 redis 获取所有密钥然后进行包含测试的问题是,每次检查都必须从 redis 中提取 300m 个密钥,或者保留这些密钥的“本地”副本,这会破坏 redis 中的要点。
与其把数据交给处理,不如把处理交给数据。
你可以使用redis sets,让redis做set diffing。
这里使用python-redis,但显然redis的执行可以用任何语言完成。
import os, base64, time, redis
r = redis.Redis()
def create_keys(n, size=10):
data = base64.b64encode(os.urandom(n * size))
return [data[i:i+size] for i in range(0, n * size, size)]
if not r.exists('ref_keys'):
for _ in range(3):
r.sadd('ref_keys', *create_keys(1*10**6))
print('{} keys in reference key set'.format(r.scard('ref_keys')))
existing_keys = r.srandmember('ref_keys', number=50*10**3)
keys_to_check = existing_keys + create_keys(50*10**3)
start = time.time()
try:
r.sadd('check_ref', *keys_to_check)
missing = r.sdiff('check_ref', 'ref_keys')
finally:
r.delete('check_ref')
print('number of missing keys: {}, time taken {:0.3f}s'.format(len(missing), time.time() - start))
(这里的大部分代码(和时间)都用于创建测试用例。)
只需要传输选中的 1m 密钥,而不是全部 300m。
注意:由于记忆,我的ref_keys 集只有 30m 个密钥,收容测试用了 3 秒。 SDIFF 具有“时间复杂度:O(N),其中 N 是所有给定集合中的元素总数。”所以我怀疑你很难在商品硬件上将时间控制在 1 秒以下。