2013-06-30 4 views
1

Если я что-то вродеЕсть ли лучший способ подсчета большого количества ключей в Redis?

number_of_keys = redis_instance.keys('foo*').size 

Однако есть 10000 ключей для этого запроса, есть способ, чтобы ускорить этот процесс, так как я просто хочу, чтобы сосчитать их, а не возвращать целую партию из них первыми и затем запустите метод ruby ​​.size, чтобы подсчитать их?

Проблема в том, что возвращение 10 000 ключей является немного медленным и расточительным, учитывая, что я на самом деле не нуждаюсь в них - все, что мне нужно, - это посмотреть, сколько их есть.

EDIT: Я должен указать, что redis_instance является экземпляром redis class.

+0

не может понять, что вы хотите? Не могли бы Вы уточнить? –

+0

обновленный вопрос, надеюсь, теперь имеет смысл теперь –

+0

как ваш ожидаемый результат должен понравиться, дайте простой пример su и что внутри 'redis_instance', покажите нам? –

ответ

3

Итак, прежде чем сказать что-нибудь еще, согласно documentation:

Внимание: рассмотреть КЛЮЧИ как команда, которая должна использоваться только в производственных средах с крайней осторожностью. Он может испортить производительность , когда он выполняется против больших баз данных. Эта команда предназначена для для отладки и специальных операций, таких как изменение вашего пространства клавиш . Не используйте KEYS в вашем обычном коде приложения. Если вы используете , ищите способ поиска ключей в подмножестве вашего пространства ключей, рассмотрите с использованием наборов.

Итак, если вы можете выбросить все, что вам нужно, нужно пересчитать в хэш и сделать HLEN на этом, если вещи не станут слишком грязными, это было бы предпочтительнее.

Предупреждение в стороне, вы должны 100% сделать это как сценарий Lua. Ваше узкое место здесь, без сомнения, будет пропускной способностью сети, и Lua полностью решает это для вас. Lua будет запускать всю вашу серверную часть сервера сценариев, поэтому вы будете захватывать все ключи и подсчитывать их все в своем поле Redis без какой-либо передачи по сети, а затем вы будете отправлять только счет. Сценарий будет прост:

local all_keys = redis.call('KEYS', ARGV[1]) 
return #all_keys 

Который вы бы назвали с помощью «foo *» в качестве аргумента. В чистом Redis, это было бы (непроверенные):

EVAL "your_script.lua" 0 'foo*' 

Я не использовал Redis в Рубине раньше, так что вам нужно, чтобы перевести это в Ruby.

+0

Спасибо Eli, решение HLEN кажется предпочтительным, поскольку я не знаком с Lua. –

1

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

+0

Проблема: все эти ключи имеют определенную продолжительность жизни, прежде чем они перейдут в Poof, что делает INCR не жизнеспособным решением, или я неверен? –

+0

'INCR' не является жизнеспособным вариантом, если у вас есть TTL на ваших ключах. Купите более быстрый компьютер - вы будете сканировать всю оперативную память, возможно, также использовать процессоры bitchin. –

+2

Следующая версия Redis будет поддерживать события в ключевом пространстве, что должно позволить обновлять этот счетчик. – Catnapper

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