Redis в docker-контейнере не сохраняет данные
Feb 5, 2018 08:57 · 422 words · 2 minute read
Случайно заметил, что при остановке docker-контейнера redis не сохраняет данные из памяти в файл dump.rdb, и, следовательно, при следующем запуске данных в redis’е не окажется.
Давайте разберемся!
Версия docker:
docker version 
Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:24:23 2017
 OS/Arch:      linux/amd64
Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:00 2017
 OS/Arch:      linux/amd64
 Experimental: true
Используемый в примере образ — redis:4.0-alpine (ed8544cc83de).
Скачиваем docker-образ командой:
docker pull redis:4.0-alpine
4.0-alpine: Pulling from library/redis
Digest: sha256:0153c5db97e5852b25c5c4715cf88cff9d9dfd8fef5c4c81df8b4dd1a984abc7
Status: Image is up to date for redis:4.0-alpine
В моем случае контейнер с redis запускается в связке с другими контейнерами, описанными в файле docker-compose.yml. Описание интересующего нас сервиса выглядит так:
...
  redis:
    container_name: redis
    image: redis:4.0-alpine
    command:
      - 'redis-server'
      - '--loglevel ${REDIS_LOGLEVEL:-warning}'
      - '--databases 2'
      - '--maxmemory ${REDIS_MAXMEM:-50mb}'
      - '--maxmemory-policy ${REDIS_POLICY:-noeviction}'
      - '--requirepass ${REDIS_PASS}'
    volumes:
      - redis:/data
    ports:
      - "6379:6379"
...
Как описано здесь, для персистентности данных можно использовать RDB (наш случай) или AOF стратегии. Для работы RDB в конфиге redis должны быть определены значения параметра save, например в настройках по умолчанию это выглядит так:
...
save 900 1
save 300 10
save 60 10000
...
Проверим значения данного параметра в нашем случае (контейнер должен быть запущен):
docker exec -it redis redis-cli -a password config get save
1) "save"
2) ""
Приводим описание сервиса redis в файле docker-compose.yml к следующему виду:
...
  redis:
    container_name: redis
    image: redis:4.0-alpine
    command:
      - 'redis-server'
      - '--loglevel ${REDIS_LOGLEVEL:-warning}'
      - '--databases 2'
      - '--save 900 1'
      - '--save 300 10'
      - '--save 60 10000'
      - '--maxmemory ${REDIS_MAXMEM:-50mb}'
      - '--maxmemory-policy ${REDIS_POLICY:-noeviction}'
      - '--requirepass ${REDIS_PASS}'
    volumes:
      - redis:/data
    ports:
      - "6379:6379"
...
Перезапускаем контейнеры командой (контейнер redis будет пересоздан с новыми настройками):
docker-compose up -d
Проверяем значение параметра save:
docker exec -it redis redis-cli -a password config get save
1) "save"
2) "900 1 300 10 60 10000"
Теперь согласно установленным значениям данные из памяти сбрасываются в файл dump.rdb:
- каждые 15 минут, если изменилось одно значение;
 - каждые 5 минут, если изменилось 10 значений;
 - каждую минуту, если изменилось 10000 значений.
 
Кроме того, при остановке docker-контейнера данные также сохраняются — в этом можно убедиться просматривая логи:
...
1:signal-handler (1513773035) Received SIGTERM scheduling shutdown...
1:M 20 Dec 12:30:35.439 # User requested shutdown...
1:M 20 Dec 12:30:35.439 * Saving the final RDB snapshot before exiting.
1:M 20 Dec 12:30:35.445 * DB saved on disk
1:M 20 Dec 12:30:35.445 # Redis is now ready to exit, bye bye...
Подобный баг был оформлен почти год назад, оставил в нем свой комментарий.