Говоря о производительности, нам нужно немного разобраться в деталях, прежде чем я смогу ответить на ваш вопрос.
Наивный подход предполагает: чем больше потоков (параллелизм), тем выше пропускная способность.
Мое утверждение не является неправильным, но это также не так. Параллелизм и результирующая производительность не являются (всегда) линейными, потому что за кулисами так много задействовано. Превращение чего-то из последовательной в параллельную обработку может привести к чему-то, что выполняет в два раза больше работы по сравнению с последовательным выполнением. В этом примере предполагается, что вы запускаете многоядерный компьютер, который не занят ничем другим, и у него достаточно полосы пропускания для требуемой обработки работы (I/O, Network, Memory). Если вы масштабируете этот пример от двух потоков до восьми, но ваш компьютер имеет только четыре физических ядра, могут возникнуть странные вещи.
Прежде всего, процессору необходимо запланировать два потока, так что каждый из потоков, вероятно, ведет себя так, как если бы они выполнялись последовательно, за исключением того, что процесс, ОС и процессор увеличивали накладные расходы, вызванные вдвое большим количеством потоков, сердечники. Оркестр этих парней стоит за счет стоимости, которую нужно заплатить, по крайней мере, в распределении памяти и времени процессора. Если рабочая нагрузка требует тяжелых операций ввода-вывода, то обработка работы может быть ограничена пропускной способностью ввода-вывода и одновременной работой с вещами может увеличить пропускную способность, поскольку процессор в основном ждет, пока входы/выходы не возвращаются с данными для обработки. В этом сценарии 4 потока могут быть заблокированы вводом/выводом, в то время как остальные 4 потока выполняют некоторую работу. Аналогично относится к памяти и другим ресурсам, используемым вашим приложением. Фактически, есть намного больше, что копает в переключение контекста, предсказание ветвей, кеширование L1/L2/L3, блокировка и многое другое, что достаточно, чтобы написать 500-страничную книгу. Давайте останемся на базовом уровне.
Совместное использование ресурсов и определенные ограничения приводят к различным профилям масштабируемости. Некоторые из них линейны до определенного уровня параллелизма, некоторые попадают в крышу и добавляют больше результатов параллелизма в одну и ту же пропускную способность, некоторые имеют колено, когда добавление параллелизма делает его еще более медленным из-за $reasons
.

Теперь мы можем проанализировать, как Redis, Redis Cluster, и параллелизм связаны.
Redis - это сетевой сервис, который требует сетевого ввода/вывода.Сеть может быть очевидной, но мы должны добавить этот факт к нашим соображениям, что означает, что сервер Redis делится своим сетевым соединением с другими вещами, запущенными на одном и том же хосте, и вещами, использующими коммутаторы, маршрутизаторы, концентраторы и т. Д. То же самое относится к клиенту, даже в том случае, если вы сказали всем другим ничего не запускать во время тестирования.
Следующее, Redis использует однопоточную модель обработки пользовательских задач (не хотят копать в фоновом I/O, освобождении свободной памяти и асинхронной репликации). Итак, вы могли предположить, что Redis использует одно ядро для своей работы, но на самом деле он может использовать больше. Если несколько клиентов отправляют команды за раз, Redis последовательно обрабатывает команды в порядке поступления (кроме операций блокировки, но оставьте это для этого сообщения). Если вы запускаете экземпляры N Redis на одном компьютере, где N также является числом ядер процессора, вы можете снова запустить снова в сценарий совместного доступа. Этого можно избежать.
У вас есть один или несколько клиентов, которые говорят на вашем сервере (-ях) Redis. В зависимости от количества клиентов, участвующих в вашем тесте, это имеет эффект. Запуск 64 потоков на 8-ядерном компьютере может быть не лучшей идеей, так как только 8 ядер могут выполнять работу за один раз (давайте оставим гиперпотоки и все это отсюда, не хотите слишком сильно вас путать). Запрос более чем восьми потоков приводит к эффектам разделения времени. Запуск бит больше потоков, чем процессорные ядра для Redis и других сетевых сервисов, не так уж плох, так как всегда есть некоторые накладные расходы/задержки, поступающие из ввода-вывода (сети). Вам необходимо отправить пакеты с Java (через JVM, ОС, сетевой адаптер, маршрутизаторы) в Redis (маршрутизаторы, сеть, yadda yadda yadda), Redis должен обработать команды и отправить ответ обратно. Обычно это занимает некоторое время.
Клиент сам (при одновременном использовании на одной JVM) блокирует определенные ресурсы для синхронизации. Особенно запрашивая новые подключения с использованием существующих/создания новых соединений, это сценарий блокировки. Вы уже нашли ссылку на конфигурацию пула. Хотя один поток блокирует ресурс, ни один другой поток не может получить доступ к ресурсу.
Зная основы, мы можем копаться в том, как измерить пропускную способность, используя Jedis и Redis Cluster:
заторы на Redis Cluster может быть проблемой. Если все клиентские потоки разговаривают с одним и тем же узлом кластера, то другие узлы кластера неактивны, и вы эффективно измеряете, как ведет себя один узел, но не кластер: Решение: Создайте четную рабочую нагрузку (Уровень: Жесткий!)
Заторы на клиенте: Запуск 64 потоков на 8-ядерном компьютере (это только мое предположение здесь, поэтому, пожалуйста, не бить меня, если я ошибаюсь) - это не лучшая идея. Повышение количества потоков на клиенте немного выше количества узлов кластера (при условии, что даже рабочая нагрузка для каждого узла кластера) и немного больше количества ядер ЦП может повысить производительность, это никогда не слишком плохая идея. Наличие 8x потоков (по сравнению с количеством ядер процессора) является избыточным, потому что оно добавляет накладные расходы на планирование на всех уровнях. В целом, технология разработки связана с поиском наилучшего соотношения между работой, накладными расходами, ограничениями пропускной способности и параллелизмом. Таким образом, поиск наилучшего количества потоков - это собственное поле в области информатики.
Если запуск теста с использованием нескольких систем, в которых выполняется целый ряд потоков, является чем-то, что может быть ближе к рабочей среде, чем выполнение теста из одной системы. Распределенное тестирование производительности - это мастер-класс (Уровень: очень тяжелый!). Трюк здесь - контролировать все ресурсы, которые используются вашим тестом, убедившись, что ничего не перегружено или не найдено переломный момент, когда вы определяете предел определенного ресурса. Мониторинг клиента и сервера - это просто легкие детали.
Поскольку я не знаю ваши настроек (число узлов кластера Redis, распределение узлов кластера между различными серверами, нагрузками на серверах Redis, клиент, и сеть во время испытания, вызванной другими вещами, чем тест), невозможно сказать, в чем причина.
У нас есть общий документ, https://commons.apache.org/proper/commons-pool/apidocs/org/apache/commons/pool2/impl/GenericObjectPoolConfig.html, но не уверен, как он относится к jedis – dmc