Redis - это неблокируемый неблокирующий асинхронный сервер, поэтому при использовании конвейеризации не добавляется конкуренция . Redis радостно обрабатывает каждую операцию, как только получает их, поэтому на практике может обрабатывать несколько конвейерных операций. По сути, Redis-серверу действительно все равно, конвейерная операция или нет, он просто обрабатывает каждую операцию по мере их получения.
Преимущество конвейеризации заключается в уменьшении задержки клиента, когда вместо ожидания ответа от redis-сервера для каждой операции перед отправкой следующей, клиент может просто закачать все операции за одну запись, а затем прочитать все ответы в одном чтении.
Примером этого в действии является мой Redis mini StackOverflow клон , каждый щелчок которого вызывает ToQuestionResults()
, который, поскольку операции передаются по конвейеру, отправляет все операции при 1 вызове записи Socket и считывает результаты в 1 чтение блокировки сокета, которое более эффективно, чем чтение блокировки на вызов:
https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/RedisStackOverflow/RedisStackOverflow.ServiceInterface/IRepository.cs#L180
Мое беспокойство по поводу использования ТРУБОПРОВОДА
что я верю, что это заблокирует все остальные
клиенты во время обслуживания команды.
Это недопустимая проблема, и я бы не стал задумываться о том, как Redis работает здесь, предположим, что он делает это наиболее эффективно, когда Pipelining не блокирует обработку команд других клиентов. Концептуально вы можете думать, что redis-сервер обрабатывает каждую команду (конвейерную или нет) в порядке FIFO (то есть не тратится время на ожидание / чтение всего конвейера).
Вы описываете что-то похожее на MULTI / EXEC (т.е. транзакции Redis), где все операции выполняются сразу, как только сервер Redis читает EXEC (т.е. транзакция EOF). Это также не проблема, и Redis-сервер по-прежнему не тратит впустую время, ожидая получения всей вашей транзакции, он просто помещает частичный набор команд во временную очередь, пока не получит окончательный EXEC, который затем обрабатывается одновременно.
Вот как redis достигает атомарности, обрабатывая каждую команду по одной, как только она их получает. Поскольку нет других потоков, нет переключения контекста потока, нет блокировок и нет проблем с многопоточностью. Он в основном достигает параллелизма, обрабатывая каждую команду очень быстро.
Так что в этом случае я бы использовал конвейерную обработку, так как это всегда выигрыш, тем более, чем больше команд вы конвейеризуете (так как вы уменьшаете количество блокирующих чтений).