Redis в systemd: почему не запускается
Главная ловушка Redis в systemd — параметр daemonize в его конфигурации. Если он включён вместе с Type=notify или simple, systemd теряет процесс и считает службу упавшей. Вторая по частоте причина — невозможность сохранить снимок данных на диск.
О службе
В дистрибутивных пакетах Redis уже настроен правильно: daemonize no в конфигурации и Type=notify в unit-файле. Проблема появляется при переносе конфигурации со старой машины или из руководства, где демонизация включена. Внешне это выглядит как мгновенный отказ запуска с кодом 0 или как «служба активна, но не отвечает».
Вторая особенность — сохранение данных. Redis периодически записывает снимок на диск и при неудаче переходит в режим отказа от записи: клиенты получают ошибки, хотя служба активна. Причины обычные — нет места, нет прав на каталог, или ядро отказало в выделении памяти для копии процесса.
Третья — предупреждение про overcommit. При сохранении Redis создаёт копию процесса, и ядро с настройкой vm.overcommit_memory=0 может отказать в выделении памяти. Redis пишет об этом предупреждение при старте, и на серверах с большим объёмом данных его стоит учитывать.
Как устроена
| Имя unit | redis-server.service в Debian и Ubuntu, redis.service в RHEL |
|---|---|
| Демонизация | в конфигурации должно быть daemonize no — уходом в фон управляет systemd |
| Каталог данных | /var/lib/redis, владелец redis; там же файл снимка dump.rdb |
| Проверка настроек | redis-server /etc/redis/redis.conf --test-memory 0 либо запуск вручную от пользователя redis |
| Порт по умолчанию | 6379, в дистрибутивах часто ограничен адресом 127.0.0.1 |
Частые ошибки
17 записей базы отмечены за этой службой.
Коды выхода
- status=0/SUCCESS, но служба считается упавшейПрограмма завершилась успешно, а systemctl показывает inactive или failed. Разбор: Type=simple против forking, RemainAfterExit, демонизация.
- status=1/FAILURE в systemdКод 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
- status=217/USER в systemdКод 217/USER означает, что systemd не смог определить или сменить пользователя из User=. Разбор причин: пользователя нет, имя недопустимо, конфликт с DynamicUser.
Сообщения журнала
- Permission denied в журнале службыОтказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
- Address already in use при запуске службыПорт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Connection refused в журнале службыСоединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- Данные теряются при перезапуске службыСлужба не успевает сохранить состояние при остановке: короткий таймаут, неверный сигнал, отсутствие обработки завершения.
Состояния результата
- Failed with result 'oom-kill'Состояние oom-kill: процесс службы убит из-за нехватки памяти. Как понять, упёрлись в предел службы или в память машины.
- start-limit-hit: служба заблокирована после серии перезапусковСостояние start-limit-hit и сообщение start request repeated too quickly: systemd перестал перезапускать службу. Как разблокировать и найти исходную причину.
Ресурсы и ограничения
- No space left on device в журнале службыНет места на устройстве: разбор по свободным блокам, по inode, по журналу systemd и по удалённым, но открытым файлам.
- Too many open files в журнале службыСлужба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
Сигналы
- signal=ABRT (status=6/ABRT) в systemdПроцесс службы завершён сигналом ABRT: программа сама прервала работу после внутренней проверки. Где искать причину.
- signal=BUS (status=7/BUS) в systemdПроцесс службы завершён сигналом BUS: ошибка доступа к памяти, часто из-за усечённого файла в отображении или заполненного диска.
Ошибки служб
- Redis: MISCONF Errors writing to the RDB snapshotRedis отказывается принимать запись: не удалось сохранить снимок на диск. Место, права, настройка overcommit.
- Redis: OOM command not allowed when used memory exceeds maxmemoryRedis отклоняет запись: достигнут maxmemory, а политика вытеснения не позволяет освобождать память.
- Redis: служба сразу останавливается из-за daemonize yesRedis уходит в фон сам, systemd теряет процесс и считает службу отработавшей. Как настроить правильно.
- Запись в Redis отказывает: узел работает как копияСлужба работает, чтение идёт, запись отклоняется: узел находится в роли копии и не принимает изменения.
Коды выхода этой службы
Числа в status=N ниже 200 назначает сама программа, 200 и выше — systemd, когда не смог подготовить запуск.
| status | Что означает у этой службы | Куда смотреть |
|---|---|---|
0/SUCCESS при inactive |
включена демонизация в конфигурации: процесс ушёл в фон, systemd счёл службу отработавшей. | разбор |
1/FAILURE |
ошибка в конфигурации, занятый порт или невозможность открыть файл данных. | разбор |
убит сигналом KILL |
нехватка памяти; у Redis это частый исход при отсутствии ограничения maxmemory. | разбор |
Диагностика
Состояние и код: при конфликте демонизации видно «inactive (dead)» с нулевым кодом.
systemctl status redis-server --no-pager -lКлючевые параметры, от которых зависит совместимость с systemd и поведение при сохранении.
grep -E "^(daemonize|dir|maxmemory|save|bind|port)" /etc/redis/redis.confRedis пишет подробный старт и предупреждения прямо в журнал.
journalctl -u redis-server -n 40 --no-pagerПрава на каталог данных и свободное место для снимка.
sudo ls -ld /var/lib/redis && df -h /var/lib/redisОтвечает ли служба и в каком состоянии сохранение данных.
redis-cli ping && redis-cli info persistence | head -12Параметры unit, которые тут важны
- Type=notify при daemonize no; forking только если демонизация включена
- MemoryMax=полезен как страховка, но основное ограничение задаётся параметром maxmemory самого Redis
- LimitNOFILE=число клиентов ограничено числом дескрипторов
- User=служба работает от redis; каталог данных должен принадлежать ему
Частые вопросы
Redis запускается и сразу «останавливается» без ошибок. Почему?
Почти наверняка в конфигурации включена демонизация. Поставьте daemonize no: процессом должен управлять systemd, а не сам Redis.
Источники
- Документация Redis: запуск и настройка
- systemd.service(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)