Обратите внимание: хотя этот вопрос немного специфичен для Redis, основная проблема носит общий характер: процесс занимает столько полосы пропускания ввода-вывода жесткого диска, что другие процессы не могут ничего записать.
У нас есть виртуальная машина Ubuntu внутри хоста Xen XCP на базе Ubuntu (установлена на двух жестких дисках в программном массиве RAID1). Эта виртуальная машина запускает сервер Redis с нагрузкой около 2K команд / с.
Проблема: когда сказал сервер Redis BGREWRITEAOF
, он блокирует своих клиентов примерно на 10 секунд.
Подробности:
Используется только постоянство AOF, без RDB. Redis настроен на использование файла fsync AOF один раз в секунду.
На BGREWRITEAOF
Redis разветвляет и выполняет всю работу с интенсивным использованием диска в дочернем процессе. Тем временем основной процесс продолжает добавлять данные в свой файл AOF.
BGREWRITEAOF
занимает около 10 секунд (1,5 ГБ данных, скорость записи на диск 150 МБ / с). Дочерний процесс, выполняющий перезапись, потребляет всю пропускную способность ввода-вывода жесткого диска.
Родительский процесс пытается fsync
, это занимает более двух секунд, срабатывает защита данных и блокировка write
вызывается, блокируя родительский процесс до тех пор, пока BGREWRITEAOF
закончил с диском.
Вот подробная информация и обсуждение которые привели меня к приведенной выше интерпретации событий.
Вопрос: Мне кажется подозрительным, что процессу разрешено выполнять столько операций ввода-вывода на диск, что все остальное блокируется. Могу ли я что-нибудь сделать на системном уровне, чтобы это исправить? Я в порядке, если BGREWRITEAOF
займет немного больше времени, если родительскому процессу разрешено сохранять свои данные во время перезаписи.
Обратите внимание, что я знаю обходные пути, такие как перемещение сохраняемости AOF на подчиненное устройство, используя no-appendfsync-on-rewrite
Опция конфигурации Redis и т.д .; этот вопрос касается именно решения проблемы, а не ее обхода.
AFAICS вы можете попробовать изменить планировщик ввода-вывода. Попробуйте использовать эту команду:
echo cfq > /sys/block/$DEVICE/queue/scheduler
Где $ DEVICE - ваш диск RAID1. Эта команда устанавливает планировщик «Completely Fair Queuing» для вашего устройства.
Я бы посоветовал изменить ваш планировщик ввода-вывода и применить некоторые техники легкой настройки. Хотя у меня нет подробного руководства по настройке, некоторые ответы и предложения, подробно описанные в этом вопросе может помочь и вам.
Рассмотрите возможность замены лифта ввода-вывода на крайний срок или нет алгоритм и повторное тестирование. Вы можете внести это изменение на лету, используя технику, подробно описанную в другом ответе. Добавьте запись в команду ядра GRUB, например, чтобы сделать это постоянным при перезагрузках (добавьте: elevator=deadline
)
Возможно, вам помогут некоторые подробности о базовом оборудовании или настройке хост-системы. Есть ли в подсистеме хранения какой-либо кэш записи с батарейным или флеш-резервом? Это может иметь значение.
Наконец, вы можете попробовать несколько легких инструментов тестирования / мониторинга, чтобы увидеть, что происходит. Если у вас есть доступ к iostat
, например, вы можете запустить его в другом окне терминала при тестировании приложения.
Например. iostat -x 1
будет работать с 1-секундными выборками и предоставит некоторую информацию о скорости чтения / записи, времени обслуживания ввода / вывода и времени ожидания. Мне также нравится собирать для этого.