Настройка производительности Redis

Мы запускаем веб-приложение и переключаемся с memcached на redis (2.4) для кэширования. Теперь мы несколько разочарованы работой redis. Redis работает на одном сервере, и мы используем только очень простые операции GET и SET. По некоторым запросам, которые сильно используют кешированные значения, у нас есть до 300 запросов GET для redis, но эти запросы занимают до 150 мс. У нас около 200 000 активных ключей и около 1000 запросов redis в секунду. Нет проблем с диском io, ram или cpu. Из-за нашего существующего кода мы не можем просто группировать запросы redis вместе. Memcached был примерно в 4 раза быстрее. Что нам нравится в redis, так это то, что мы не нуждаемся в кеш-подогреве и можем использовать более продвинутые функции хранилища данных в будущем. Мы ожидали, что redis будет работать аналогично memcached. Поэтому, возможно, мы пропустили что-то в нашей конфигурации, которая в основном является конфигурацией по умолчанию.

Знаете ли вы о какой-либо лучшей практике для настройки производительности redis?

Ответы

Ответ 1

Сначала вы можете прочитать страницу сравнения Redis. Это дает хорошее резюме основных моментов для проверки настройки Redis.

Даже если вы не используете конвейерную обработку, 300 GET в 150 мс не так эффективны. Это означает, что средняя задержка составляет 500 us. Однако это зависит от размера ваших объектов. Большие объекты, больше латентности. На моем очень старом 2 ГГц ядре AMD я могу измерить 150-секундные задержки для небольших объектов (несколько байтов).

Чтобы быстро проверить среднюю задержку экземпляра Redis, вы можете использовать:

$ redis-cli --latency

Для получения этой опции обязательно используйте недавнюю версию Redis (не 2.4). Примечание: 2.4 сейчас довольно старый, используйте Redis 2.6 - при необходимости скопируйте свою собственную версию Redis, это действительно просто.

Чтобы быстро запустить тест для изучения латентности, вы можете запустить:

$ redis-benchmark -q -n 10000 -c 1 -d average_size_of_your_objects_in_bytes

Он работает с уникальным соединением и без конвейерной обработки, поэтому задержка может быть выведена из пропускной способности. Попробуйте сравнить результат этих тестов с цифрами, измеренными с вашим приложением.

Есть несколько моментов, которые вы можете проверить:

  • В какой клиентской библиотеке Redis вы используете? С каким языком разработки? Для некоторых языков сценариев вам необходимо установить модуль hiredis для получения эффективного клиента.
  • Является ли ваша машина виртуальной машиной? На какой ОС?
  • Являются ли соединения с Redis постоянными? (т.е. вы не должны подключаться/отключаться при каждом HTTP-запросе вашего сервера приложений).

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

При 1000 q/s (низкая пропускная способность по стандартам Redis или memcached), я бы сказал, что более вероятно, что ваша проблема связана с клиентской стороной (т.е. выбор клиентской библиотеки, соединение/отключение и т.д.)., чем с самим сервером Redis.

Наконец, я должен упомянуть, что если вы создаете несколько запросов Redis для HTTP-запроса, рассмотрите pipelining команды, которые вы отправляете в Redis as насколько это возможно. Это действительно ключевой момент для разработки эффективных приложений Redis.

Если ваши серверы приложений находятся в том же поле, что и Redis, вы также можете использовать сокеты домена unix вместо loopback для подключения к Redis. Это немного улучшает производительность (до 50% больше пропускной способности, когда конвейеризация НЕ используется).

Ответ 2

Проверьте, использует ли redis ОС-память подкачки. Если это так, это добавит латентность. Чтобы узнать, найдите "Латентность, вызванную заменой" здесь: http://redis.io/topics/latency

Если ваше серверное оборудование поддерживает NUMA, лучше запустить redis-server с numactl. Не забудьте отключить режим восстановления зоны (vm.zone_reclaim_mode = 0) в sysctl, если вы начинаете с redis-сервера с NUMA.

Ответ 3

Попробуйте script, чтобы запросить 300 GET внутри Lua script. Он должен работать быстрее, потому что вы экономили время прикосновением к стеку TCP/IP, даже если ваш клиентский код работает локально с Redis.