2014-01-03 7 views
3

У нас есть список номеров, хранящихся в redis как ключи (300 миллионов ключей, которые представляют собой десятизначные цифровые клавиши).Redis: Найти ключи, которые существуют

Наши пользователи дают нам список около 1 миллиона номеров и ожидают, что мы выберем подмножество этих чисел, которые не существуют в redis как ключи. Ожидание - получить результат на второй секунде, и мы пытались использовать Redis для этого же.

Первоначально он выглядел как правильный путь (используя EXISTS), но теперь мы спрашиваем, есть ли лучшие способы добраться до результирующего, не зацикливая эти числа и не создавая подмножество.

Может кто-нибудь, пожалуйста, сообщите нам, как мы могли бы сделать это эффективно?

ответ

0

Да, вы должны избегать цикла в списке пользователей и использовать EXISTS для каждого ключа. Команды Redis относительно медленны (из-за архитектуры клиент/сервер) в отличие от переменных манипуляций на обычном языке.

Одно из решений, которое я бы предложил, потребует некоторой кодировки: я бы получил все существующие ключи с помощью KEYS (http://redis.io/commands/keys), а затем отсортировал результат и список пользователей. Затем вы можете выполнить быстрый поиск, чтобы проверить, находятся ли ключи пользователя в ключах redis.

На самом деле вы можете использовать множество в Python, с той разницей, уже закодированной http://docs.python.org/2/library/sets.html (Это несортированное, но реализация является ДИКТ, который является Хешем).

+5

KEYS никогда не следует использовать против экземпляра экземпляра production, поскольку это сложность O (n) и блокирует другие запросы во время их запуска. Это займет некоторое время, чтобы запустить экземпляр OP, так как он имеет 300 миллионов ключей. – Adam

+0

его следует использовать с осторожностью, я согласен. Скорость слишком медленная для записей 300M. Возможно, копия списка ключей должна поддерживаться за пределами Redis для более быстрого доступа. – Pixou

+0

@Pixou, только ключи с 300 миллионами записей занимают ~ 12 ГБ памяти. Сохранение этих данных в Redis, а также наличие ключевого списка за пределами Redis будет дорогостоящим делом.Также вы могли бы предложить, что вы подразумеваете под «поддерживаемым за пределами Редиса, чтобы быть доступным быстрее». Какую технологию/структуру данных мы можем использовать? Здесь может помочь ссылка. Еще раз спасибо за предложение. – user3156581

2

Старый вопрос, который я знаю, но я думал, что это заслуживает более полного ответа.

Проблема с получением всех ключей от redis и последующим выполнением теста сдерживания заключается в том, что вам нужно вытащить 300 м ключи из redis для каждой проверки или сохранить «локальную» копию этих ключей, которая побеждает точку в redis ,

Вместо того, чтобы передавать данные на обработку, гораздо лучше выполнить обработку данных.

Вы можете использовать redis sets, и пусть redis сделает набор.

Использование 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 должны быть переданы, а не всего 300м.

Примечание: из-за памяти мой набор ref_keys имеет только 30-метровые ключи и тест на герметичность занимает 3 с. SDIFF имеет «временную сложность: O (N), где N - общее количество элементов во всех заданных наборах». поэтому я подозреваю, что вам будет трудно получить время до секунды на товарном оборудовании.

Смежные вопросы