2012-04-14 2 views
22

В настоящее время я играю с Redis, и у меня есть несколько вопросов. Можно ли получать значения из массива ключей?Получение нескольких ключевых значений от Redis

Пример:

users:1:name "daniel" 
users:1:age "24" 

users:2:name "user2" 
users:2:age "24" 

events:1:attendees "users:1", "users:2" 

Когда я redis.get events:1:attendees он возвращает "users:1", "users:2". Я могу пройти через этот список и получить пользователей: 1, получить пользователей: 2. Но это кажется неправильным, есть ли способ получить всю информацию о посетителях на сайте?

В рельсах я бы сделать что-то вроде этого:

@event.attendees.each do |att| 
    att.name 
end 

Но в Redis я не могу, потому что она возвращает ключи и не фактический объект, хранящийся в этом ключе.

спасибо :)

ответ

38

Выполнение цикла по элементам и синхронный доступ к каждому элементу не очень эффективно. С Redis 2.4, существуют различные способы, чтобы сделать то, что вы хотите:

  • с помощью команды сортировки
  • , используя конвейерную
  • с помощью VARIADIC параметра команды

С Redis 2.6, вы также можно использовать сценарии Lua, но здесь этого не требуется.

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

с помощью команды SORT

Вы можете использовать Redis сортировки команду для извлечения данных в одном туда и обратно.

redis> set users:1:name "daniel" 
OK 
redis> set users:1:age 24 
OK 
redis> set users:2:name "user2" 
OK 
redis> set users:2:age 24 
OK 
redis> sadd events:1:attendees users:1 users:2 
(integer) 2 
redis> sort events:1:attendees by nosort get *:name get *:age 
1) "user2" 
2) "24" 
3) "daniel" 
4) "24" 

Использование PIPELINING

Рубин поддержки клиентов (то есть конвейерной возможность отправлять несколько запросов к Redis и подождать несколько ответов).

keys = $redis.smembers("events:1:attendees") 
res = $redis.pipelined do 
    keys.each do |x| 
     $redis.mget(x+":name",x+":age") 
    end 
end 

Приведенный выше код будет извлекать данные только в двух направлениях.

Использование VARIADIC Команда Параметр

Команда MGET может быть использована для получения нескольких данных в одном кадре:

redis> smembers events:1:attendees 
1) "users:2" 
2) "users:1" 
redis> mget users:1:name users:1:age users:2:name users:2:age 
1) "daniel" 
2) "24" 
3) "user2" 
4) "24" 

Стоимость здесь также два туда и обратно. Это работает, если вы можете гарантировать, что количество ключей для извлечения ограничено. Если нет, конвейерная обработка - гораздо лучшее решение.

+0

Спасибо за ответ! Я собираюсь попробовать ваш предложенный код! Спасибо :) –

+0

Спасибо @Didier, всегда хорошо учиться новым вещам! –

5

Вы можете использовать команду EVAL Redis', чтобы отправить ему Lua script, который запускает петлю „на стороне сервера“ и возвращать результаты в блоке.