Отвечу на вопрос, касающийся протокола Redis. То, как это работает на конкретном языке, в этом случае более или менее одинаково.
Прежде всего, давайте проверим, как работает конвейер Redis: это просто способ отправить несколько команд на сервер, выполнить их и получить несколько ответов. В этом нет ничего особенного, вы просто получаете массив с ответами на каждую команду в конвейере.
Конвейеры работают намного быстрее, потому что сохраняется время приема-передачи для каждой команды, т.е. для 100 команд существует только одно время приема-передачи вместо 100. Кроме того, Redis выполняет все команды синхронно. Выполнение 100 команд требует потенциально 100 боевых действий, чтобы Redis выбрал эту единственную команду, конвейер обрабатывается как одна длинная команда, поэтому для синхронного выбора требуется только один раз.
Подробнее о конвейерной обработке можно узнать здесь: https://redis.io/topics/pipelining. Еще одно замечание, поскольку каждый конвейерный пакет работает бесперебойно (с точки зрения Redis), имеет смысл отправлять эти команды просматриваемыми фрагментами, то есть не отправлять 100 тыс. Команд в одном конвейере, что может заблокировать Redis на длительный период времени, разделите их на блоки по 1 или 10 тыс. команд.
В вашем случае вы запускаете в цикле следующий фрагмент:
// Increment the number of times the user record has been accessed
$pipe->incr('accessed:' . $user_id);
// Pulls the user record
$pipe->get('user:' . $user_id);
Вопрос в том, что вводится в конвейер? Допустим, вы хотите обновить данные для u1
, u2
, u3
, u4
как идентификаторы пользователей. Таким образом, конвейер с командами Redis будет выглядеть так:
INCR accessed:u1
GET user:u1
INCR accessed:u2
GET user:u2
INCR accessed:u3
GET user:u3
INCR accessed:u4
GET user:u4
Скажем:
- К u1 раньше обращались 100 раз,
- К u2 раньше обращались 5 раз,
- u3 ранее не использовался и
- u4 и сопутствующих данных не существует.
В этом случае результатом будет массив ответов Redis, содержащий:
101
u1 string data stored at user:u1
6
u2 string data stored at user:u2
1
u3 string data stored at user:u3
1
NIL
Как видите, Redis будет рассматривать отсутствующие значения INCR как 0
и выполнять incr(0)
. Наконец, Redis ничего не сортирует, и результаты появятся в запросе в соответствии с запросом.
Привязка к языку, например Драйвер Redis просто проанализирует этот протокол и предоставит представление проанализированным данным. Без сохранения набора команд драйвер Redis не сможет правильно работать, а вам, как программисту, будет невозможно что-то сделать. Просто имейте в виду, что этот запрос не дублируется в ответе, т.е. вы не получите ключ для u1
или u2
при выполнении GET
, а только данные для этого ключа. Таким образом, ваша реализация должна помнить, что в позиции 1
(индекс, отсчитываемый от нуля) появляется результат GET
для u1
.
person
ovanes
schedule
31.05.2017