Глава 6. Перманентность
Содержание
В этой главе мы рассмотрим такие рецепты:
-
Манипулирование RDB
-
Исследование RDB
-
Манипулирование AOF
-
Исследование AOF
-
Сочетание RDB и AOF
В своей предыдущей главе мы изучили как настраивать Redis подчинённым для репликации данных с хозяина. С точки зрения избыточности данных для резервного копирования имеющихся данных могут применяться репликации данных Redis/
Для того чтобы сберегать свои данные в безопасности Redis также предоставляет механизм удержания (persist - перманентности) данных на диске. Существует два варианта удержания данных: RDB и AOF. RDB является снимком на некий момент времени данных Redis, что исключительно для резервного копирования и восстановления данных. AOF является неким журналом операций записи, которые будут повторно выполняться при запуске сервера.
В данной главе мы сделаем введение в то как разрешать и настраивать в Redis RDB и AOF. Мы также бросим взгляд на соответствующие форматы файлов RDB и AOF, а также на важные параметры настроек для их регулирования при установке перманентности Redis. К окончанию данной главы мы поговорим о сочетании в Redis RDB и AOF.
Как мы уже описывали в своём предыдущем рецепте, для некоторого хранилища данных в оперативной памяти подобного Redis, включение свойств удержания является наилучшей защитой от утраты данных. Одним из очевидных способов реализации перманентности является создание время- от- времени моментальных снимков оперативной памяти, в которой хранятся наши данные. Именно таким способом в основном и работает в Redis RDB.
В данном рецепте мы взглянем на то как осуществлять такую функциональность удержания и настраивать её, а также изучим дополнительные подробности относительно производства моментальных снимков.
Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis.
Для целей данной демонстрации вам следует сбросить все данные при помощи команды FLUSHALL
, а затем
мы наполним какими- то образцами данных свой экземпляр Redis применив инструментарий случайной генерации данных для Redis, введённый нами в рецепте
Поиск неисправности репликации из Главы 5,
Репликации:
for i in `seq 10`
do
nohup node generator.js hash 1000000 session &
done
Для манипуляций RDB основные шаги такие:
-
Чтобы включить удержание RDB для запущенного экземпляра Redis вызвите соответствующую команду
CONFIG SET
следующим образом:127.0.0.1:6379> CONFIG SET save "900 1" OK 127.0.0.1:6379> CONFIG SET save "900 1 300 10 60 10000" OK
-
Если же мы желаем разрешить RDB на постоянной основе, установите значение настройки
save
в соответствующем файле конфигурации Redis:$ cat conf/redis.conf |grep "^save" save 900 1 save 300 10 save 60 10000
-
Для отключения свойства удержания RDB для некоторого запущенного экземпляра Redis добавьте пустую строку в соответствующую опцию
save
с помощьюredis-cli
:$ bin/redis-cli config set save "" OK
-
Для отключения RDB на постоянной основе просто экранируйте комментарием или удалите имеющиеся опции
save
в своём файле настроек Redis:#save 900 1 #save 300 10 #save 60 10000
-
Чтобы проверить включена ли функциональность RDB, запросите соответствующий файл настроек
save
изredis-cli
. Если в соответствующей опцииsave
имеется некая пустая строка, это указывает на то, что функция RDB отключена. В противном случае будет получена разрешённая политика RDB переключения взятия моментальных снимков:$ bin/redis-cli CONFIG GET save 1) "save" 2) "900 1 300 10 60 10000"
-
Мы можем убедиться в том был ли сгенерирован соответствующий файл RDB в установленном каталоге данных Redis:
$ ls -l dump.rdb -rw-rw-r-- 1 redis redis 286 Oct 23 22:11 dump.rdb
-
Для создания некоего моментального снимка RDB вручную вызовите команду
SAVE
вredis-cli
. Данныйredis-cli
выполнит блокировку на какое- то время и затем выполнит возврат в командную строку таким образом:127.0.0.1:6379> SAVE OK (23.25s) 127.0.0.1:6379>
-
В качестве альтернативы мы можем вызвать
BGSAVE
для осуществления дампа RDB без блокировки:127.0.0.1:6379> BGSAVE Background saving started
-
Проверьте состояние
pid
своего процесса выполнения дампа, воспользовавшись соответствующей командойps -ef |grep redis
:$ps -ef |grep redis redis 10708 21158 91 21:21 ? 00:00:06 redis-rdb-bgsave 0.0.0.0:6379 redis 21158 1 5 17:35 ? 00:12:46 bin/redis-server 0.0.0.0:6379
-
Быстро выполните наполнение некими образцами данных при выполнении дампа RDB:
$ node generator.js hash 100000
-
Проверьте соответствующий журнал своего Сервера Redis:
$ cat log/redis.log 21158:M 21 Oct 21:21:41.408 * Background saving started by pid 777 777:C 21 Oct 21:22:04.316 * DB saved on disk 777:C 21 Oct 21:22:04.346 * RDB: 322 MB of memory used by copy-on-write 21158:M 21 Oct 21:22:04.449 * Background saving terminated with success
-
Для выборки необходимых замеров и состояния удержания вызовите из
redis-cli
INFO Persistence
:127.0.0.1:6379> INFO Persistence # Persistence loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:1 rdb_last_save_time:1508590312 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:21 rdb_current_bgsave_time_sec:20 rdb_last_cow_size:2637824
RDB работает подобно фотоаппарату для имеющейся оперативной памяти Redis. Когда достигается необходимая политика включения, выполняется некая
фотография имеющихся в Redis данных путём вывода дампа в некий файл на текущем локальном диске. Прежде чем
перейти к подробному рассмотрению данного процесса, мы для начала поясним те значения опции save
, которые
определяют установленную политику включения RDB, которые упомянуты в нашем предыдущем разделе. Соответствующий шаблон устанавливаемых значений выглядит
как x1, y1, x2, y2,..... Что означает, что выполнение дампа
имеющихся данных в Redis осуществляется после x секунд если были изменены по крайней мере по крайней мере
y ключей и нет никакого иного процессы выполнения дампа.
Для нашего предыдущего примера, 900 1
означает, что если по крайней мере 1 ключ был изменён в пределах 900
секунд, будет выполнен некий моментальный снимок. Мжет иметься более одной политики в соответствующей опции save
для управления тем насколько часто выполняется моментальный снимок RDB.
Redis не выполняет соответствующий дамп пока не завершится в фоновом режиме самый последний сброс. Вам никогда не следует применять
SAVE
в своей промышленной реализации, так как он блокирует ваш Сервер Redis. Вместо этого, применив
BGSAVE
, имеющийся основной поток Redis продолжит обработку входящих команд пока создаётся посредством
fork()
некий дочерний процесс, который затем сохранит необходимый файл данных дампа в каом- то временном файле
с названием temp-<bgsave-pid>.rdb
. После того как этот процесс выполнения дампа завершится, данный
временный файл будет переименован в то имя, которое определено настройкой dbfilename
в том локальном
каталоге, который задан настройкой dir
для замены имеющегося старого дампа. Между прочим, эти две настройки можно
изменять динамически из redis-cli
.
Отслеживая свои процессы при помощи команды ps
вы можете перехватить соответствующий процесс с
установленным названием redis-rdb-bgsave
, который ответвляется вашим Сервером Redis для выполнения
BGSAVE
. Этот дочерний процесс сохраняет все данные в то время, когда осуществляется соответствующая
команда BGSAVE
. Благодаря механизму COW
(Copy-On-Write,
Копирования-
записью) нет необходимости для запущенного дочернего процесса применять такой же объём памяти, который имеет сам Сервер Redis.
На протяжении выполнения дампа мы можем воспользоваться INFO Persistence
для получения соответствующих
измерений выполняемого удержания. В данном примере значением rdb_bgsave_in_progress
является
1
, что указывает на тот факт, что выполняется процесс получения дампа. Значением
rdb_current_bgsave_time_sec
является то время, которое прошло при выполнении
BGSAVE
.
По завершению данным потомком замены имеющегося старого файла дампа, он выполняет в журнале регистрацию сообщения на основе того какой объём частных данных использовал этот потомок следующим образом:
777:C 21 Oct 21:22:04.346 * RDB: 322 MB of memory used by copy-on-write
В основном оно исчисляет какой объём изменений выполнил родительский процесс по сравнению с дочерним (в том числе буферы чтения, буферы записи,
изменения данных и тому подобного). В нашем примере мы выполняли наполнение Redis некими образцами данных на протяжении осуществления дампа,
поэтому та память, которая использовалась COW (в соответствующей команде INFO
) не является очень маленьким
(для 2 ГБ данных в Redis, если ничего не записывается на протяжении дампа, как правило, COW использует 10- 20 МБ). Данное измерение также сохраняется
в соответствующей метрике rdb_last_cow_size
, получаемой в команде
INFO
.
По окончанию BGSAVE
, соответствующее состояние самого последнего
BGSAVE
сохраняется в измерении rdb_last_bgsave_status
, а временной
штамп UNIX этого последнего успешного сохранения запоминается в rdb_last_save_time
:
127.0.0.1:6379> INFO Persistence
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1508639640
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:20
rdb_current_bgsave_time_sec:-1
rdb_last_cow_size:15036416
Вот некоторые относящиеся к удержанию RDBварианты настройки. Вам рекомендуется оставлять установленные по умолчанию значения, которыми является
значение yes
для всех перечисленных ниже опций:
-
stop-writes-on-bgsave-error yes
: При отказеBGSAVE
, в качестве некоего механизма защиты, ваш Сервер Redis остановит приём на запись когда данный параметр установлен в значениеyes
. -
rdbcompression yes
: Сжатие может впечатляющим образом уменьшить получаемый размер файла дампа за счёт большего использования ЦПУ для осуществления сжатия LZF. -
rdbchecksum yes
: Создаёт некую контрольную сумму CRC64 в самом конце получаемого файла моментального снимка. Значение стоимости производительности в оплату в процессе сохранения и загрузки такого файла моментального снимка около 10%. Для получения максимальной производительности установитеno
, но это уменьшит устойчивость к разрушению данных.
Тот дамп, который вырабатывается SAVE/BGSAVE
можно применять в качестве некоего файла резервной копии
данных. Вы можете применять crontab
в своей операционной системе для периодического копирования получаемого
файла RDB в какой- то локальный каталог или в удалённую распределённую файловую систему, например, Amazon S3/ HDFS для целей применения в дальнейшем:
cp /redis/data/dump.rdb /somewhere/safe/dump.$(date +%Y%m%d%H%M).rdb
Для восстановления некоего моментального снимка RDB вам придётся скопировать соответствующий файл в то местоположение, которое определено установкой
параметра dir
и установить необходимые полномочия чтения/ записи для данного файла тому пользователю, который
запускает соответствующий экземпляр Redis. После этого от вас требуется остановить исполняемый экземпляр вызвав команду
SHUTDOWN NOSAVE
и переименовать свой новый файл дампа в то название, которое задаётся
dbfilename
. При перезапуске этот набор данных загружается в Redis из данного файла резервной копии.
Дополнительное обсуждение деталей относительно перманентности RDB вы можете отыскать на https://redis.io/topics/persistence
Если вам интересно то как работает COW в некоторой операционной системе, вы можете изучить подробности в en.wikipedia.org {Прим. пер.: или ознакомиться с нашими переводами Мастерство FreeBSD: ZFS Майкла В. Лукаса и Аллана Джуда или отдельных глав Мастерство SQL Server 2016 с высокой доступностью Пауля Бертуччи и Раджу Шривастава}
Мы уже изучили что посредством перманентности Redis выполняет дамп своих хранимых в памяти данных в некий файл с названием
dump.rdb
по умолчанию. Для начинающих этого может быть достаточно для понимания тех моментов, которые
упоминаются в нашем предыдущем рецепте. Для тех чокнутых, которые страстно желают узнать подробнее о том как соответствующий файл RDB работает в
качестве двоичного представления данных Redis в оперативной памяти имеется великолепное преимущество изучить сам формат RDB. В данном рецепте мы
окунёмся в тонкости формата имеющегося файла RDB чтобы понять что мы можем делать со знаниями об имеющемся формате RDB.
Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis.
Для исследования двоичного формата некоего файла необходим какой- то редактор бинарных файлов. В Linux Ubuntu наиболее распространённым
бинарным редактором является bvi
. Установите его следующим образом:
$ sudo apt-get install bvi
Для MacOS вы можете выгрузить HexFiend.
Для своих целей демонстрации необходимо выполнить сброс всех данных при помощи команды FLUSHALL
.
Так как мы будем изучать свой файл RDB в шестнадцатеричном виде, следует просматривать символ ASCII в какой- то таблице ASCII. Великую помощь в этом оказывает вебсайт RapidTables.
Для изучения RDB необходимые шаги таковы:
-
Установите некую пару строковых ключ- значение:
127.0.0.1:6379> SET key value OK
-
Установите пару списочных ключ- значение:
127.0.0.1:6379> LPUSH listkey v1 v2 (integer) 2
-
Настройте пару ключ- значение хэша:
127.0.0.1:6379> HSET hashkey k1 v1 k2 v2 (integer) 2
-
Настройте пару ключ- значение множества:
127.0.0.1:6379> SADD setkey v1 v2 (integer) 2
-
Установите пару ключ- значение сортированного множества:
127.0.0.1:6379> ZADD zset 1 v1 2 v2 (integer) 2
-
Для включения выполнения дампа RDB вызовите в
redis-cli
командуSAVE
:127.0.0.1:6379> SAVE OK
-
В редакторе
bvi
откройте только что созданный нами файлdump.rdb
:$ bvi dump.rdb
Полученное содержимое dump.rdb
отображено на следующем снимке экрана:
В нашем предыдущем примере в имеющемся экземпляре Redis были размещены некоторые образцы проверочных данных. После этого был создан некий дамп RDB
посредством команды SAVE
.
После этого мы ближе рассмотрим что имеется в RDB в не заземлённом виде при помощи двоичного редактора bvi
в
Linux. Всё содержимое нашего файла RDB было преобразовано bvi
в шестнадцатеричный вид. Рассматривая самые
первые пять чисел (52 45 44 49 53) одно за другим в таблице ASCII (RapidTables), мы можем заключить, что этими первыми символами являются REDIS
:
Следующими четырьмя символами после нашей магической строки являются 30 30 30 38
, которые указывают на
значение версии формата RDB 0008. REDIS0008
является магической строкой какого- то файла RDB.
После этой магической строки имеется восемь видов метаданных, сохранённых в нашем файле RDB:
-
redis-ver
: Значение версии данного экземпляра Redis. -
redis-bits
: Значение архитектуры того хоста, на котором запущен данный экземпляр Redis. Для этих метаданных допустимыми являются значения 64 или 32. -
ctime
: Значение временного штампа Unix момента создания данного RDB. -
used-mem
: Значение размера используемой памяти на момент вывода дампа. -
repl_stream_db
: Значение индекса имеющейся базы данных в некоторой цепочке репликации, существует только когда установлена некая репликация. -
aof-preamble
: Следует ли помещать данный моментальный снимок RDB как некую преамбулу существующего файла AOF. -
repl-id
: Значение идентификатора репликации основного хозяина. -
repl-offset
: Значение смещения репликации основного хозяина.
Между прочим, FA
в этом файле RDB является неким вспомогательным кодом операции. После такого вспомогательного
кода всегда имеется некая пара ключ- значение.
После сохранения необходимых метаданных для каждой базы данных из определённого Сервера Redis текущий процесс вывода дампа сохраняет получаемый индекс
базы данных (в данном примере FE 00
, указывающий значение индекса базы данных равным
00
), код изменения размера хэша, а также код операции изменения размера базы данных, помимо срока истечения кода
операции изменения размера. Затем стартует некая итерация для записи каждого элемента из Redis для записи в этот файл дампа. Соответствующий формат пары
ключ- значение в Redis таков:
Ввиду ограничений в пространстве данной книги мы не будем вдаваться в подробности указанного вышк формата данных. Если вас это интересует, вы
можете рассмотреть исходные коды файлов rdb.c
и rdb.h
.
Данный файл RDB завершается неким EOF и контрольной суммой CRC64.
Понимая формат RDB вы можете создавать свои собственные инструменты Redis для анализа памяти, экспорта/ импорта данных, а также слияния множества экземпляров
Redis. Если вы выполните поиск в GitHub по ключевым словам Redis RDB
вы изучите намного больше о
существующем формате RDB.
Относительно дополнительных деталей формата RDB вы можете обратиться к https://github.com/sripathikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format и https://github.com/leonchen83/redis-replicator/wiki/RDB-dump-data-format
Сам автор Redis, Antirez, также описывает архитектуру RDB: https://redis.io/topics/rdd-2
В наших двух предыдущих рецептах мы изучили варианты RDB для удержания данных Redis. Однако, использование RDB для перманентности не предоставляет очень сильной устойчивости. Как уже упоминалось, некий дамп данных RDB содержит только моментальный снимок данных Redis на какой- то момент времени. Хотя Redis выполняет дампы данных в свой файл RDB периодически, имеющиеся между двумя дампами RDB данные будут утрачены навсегда в случае падения процесса Redis или же при наличии некоего аппаратного отказа. AOF является неким дописываемым только в конец (append-only) файлом журнала, который регистрирует поступающие команды записи своего Сервера Redis. Значение надёжности данных AOF выше чем у RDB, так как все команды записи добавляются в конец этого файла. В данном рецепте мы покажем как вы можете включить AOF в Redis и ознакомим вас с некоторыми важными параметрами AOF.
Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis.
Основные шаги по манипуляции AOF таковы:
-
Для включения удержания AOF в некотором запущенном экземпляре Redis вызовите команду
CONFIG SET
следующим образом:127.0.0.1:6379> CONFIG SET appendonly yes OK
-
Если вы желаете разрешить AOF на постоянной основе, добавьте
appendonly yes
в свой файл настроек Redis и перезапустите этот сервер:$ cat conf/redis.conf |grep "^appendonly" appendonly yes
-
Чтобы отключить функциональность применения удержания AOF для какого- то исполняемого экземпляра Redis, установите
appendonly
в значениеno
:$ bin/redis-cli config set appendonly no OK
-
Для отключения удержания AOF на постоянной основе просто установите
appendonly no
в своём файле настроек и перезапустите этот сервер:appendonly no
-
Для проверки того что функция AOF включена мы можем применить
INFO PERSISTENCE
и отыскать соответствующие элементы AOF:127.0.0.1:6379> INFO PERSISTENCE # Persistence loading:0 ... aof_enabled:1 aof_rewrite_in_progress:0
-
Или же мы можем проверить был ли создан соответствующий файл AOF в имеющемся каталоге данных Redis:
$ ls -l -rw-r--r-- 1 root root 233 Oct 22 22:16 appendonly.aof
Когда включена опция AOF, Redis создаст соответствующий файл AOF в своём каталоге данных Redis. Значением имени файла AOF по умолчанию является
appendonly.aof
, которое можно изменить установкой параметра appendfilename
в имеющихся настройках Redis. Redis будет также наполнять этот файл AOF текущими данными в оперативной памяти.
Всякий раз когда Сервер Redis получает некую команду на запись, которая в результате приведёт к изменению реальных данных в памяти, он также
добавляет в конец своего файла AOF эту команду. Однако, если мы получше взглянем на процесс записи файла, на самом деле основная операционная
система сопровождает некий буфер, в который вначале записываются соответствующие команды Redis. Данные из этого буфера подлежат сбросу на
соответствующий диск для сохранения на постоянной основе. Данный процесс выполняется в имеющейся операционной системе Linoc системным вызовом API
fsync()
, который является неким блокирующим вызовом до тех пор, пока соответствующее дисковое устройство
не подтвердит что эти данные в текущем буфере сброшены успешно.
У нас имеется возможность регулировать значение частоты вызова fsync()
при добавлении в конец соответствующего
файла AOF команд. Это осуществляется посредством параметра настройки Redis appendfsync
и имеется три варианта:
-
always
:fsync()
будет вызываться для каждой команды записи. Такой вариант обеспечивает утрату только одной команды в случае неожиданного крушения сервера или отказа оборудования. Однако, посколькуfsync()
является вызовом с блокированием, значение производительности Redis будет ограничено производительностью записи на его физический диск. Не рекомендуется устанавливатьappendfsync
в значениеalways
по причине существенной деградации производительности Сервера Redis. -
everysec
: Будет вызыватьfsync()
один раз в секунду. При таком варианте в случае неожиданного отказа будут утрачены данные только одной секунды. Часто рекомендуется применять именно эту опцию для оптимальности баланса между надёжностью данных и производительностью. -
no
:fsync()
никогда не будет вызываться со стороны Redis. Данный вариант оставляет на усмотрение самой операционной системы решение когда выполнять сброс имеющихся данных из её буфера на диск. В большинстве систем Linux такая частота установлена на раз в 30 секунд.
При останове Сервера Redis fsync()
будет вызван в явном виде чтобы убедиться что все данные из буфера записи сброшены
на диск.
Данный файл AOF будет применяться для восстановления имеющихся данных при запуске его Сервера Redis. Redis просто воспроизводит данный файл считывая имеющиеся команды и помещая их в память по одной. Соответствующие данные восстанавливаются после обработки всех команд.
При сохранении в конец своего файла AOF команд записи Redis, размер этого файла может значительно возрастать. Это замедляет соответствующий процесс
воспроизведения при запуске Redis. Redis предоставляет некий механизм сжатия своего файла AOF с помощью некоторой AOF
rewrite. Как вы можете предвосхитить, некоторые из имеющихся ключей Redis были удалены или истёк их срок, поэтому они могут быть
вычищены из своего файла AOF. Соответствующие значения для определённых ключей Redis обновлялись множество раз, причём только самое последнее
значение требуется сохранять в имеющемся файле AOF. Эта основная идея упаковки данных при некоторой перезаписи AOF. Мы можем воспользоваться командой
BGREWRITEAOF
для инициации такого процесса перезаписи или позволить Redis выполнять перезапись AOF автоматически.
Мы обсудим перезаписи AOF в своём следующем рецепте.
В случае крушения основной операционной системы соответствующий файл AOF может быть разрушен или усечён. Redis предоставляет некий инструмент,
redis-check-aof
, который можно применять для исправления такого некорректного файла AOF. Для исправления
файла AOF просто запустите:
$ bin/redis-check-aof --fix appendonly.aof
По следующей ссылке вы можете найти дополнительные обсуждения удержания AOF
Для пояснения удержания данных Redis самим автором написан блог-пост
Что касается fsync()
:
https://linux.die.net/man/2/fsync
В своём предыдущем рецепте мы изучили как устанавливать перманентность AOF в Redis. В этом рецепте мы собираемся бросить взгляд на само содержимое файла AOF и пояснить весь процесс перезаписи AOF.
Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis.
Для целей данной демонстрации нам следует отключить AOF и вначале сбросить все данные при помощи команды
FLUSHALL
.
Основные шаги исследования AOF таковы:
-
Включите удержание AOF:
127.0.0.1:6379> CONFIG SET appendonly yes OK
-
Так как в Redis нет никаких данных, у нас должен иметься некий пустой файл AOF:
$ ls -l -rw-rw---- 1 redis redis 0 Oct 23 20:47 appendonly.aof
-
В
redis-cli
исполните следующие команды:127.0.0.1:6379> SET k1 v1 OK 127.0.0.1:6379> INCR counter (integer) 1 127.0.0.1:16379> INCR counter (integer) 2 127.0.0.1:6379> SET k2 v2 OK 127.0.0.1:6379> DEL k1 (integer) 1 127.0.0.1:6379> DEL k3 (integer) 0 127.0.0.1:6379> HSET mykey f1 v1 f2 v2 (integer) 2
-
При помощи текстового редактора откройте свой файл AOF:
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n *3\r\n$3\r\nset\r\n$2\r\nk1\r\n$2\r\nv1\r\n *2\r\n$4\r\nincr\r\n$7\r\ncounter\r\n *2\r\n$4\r\nincr\r\n$7\r\ncounter\r\n ...
-
Из
redis-cli
исполните командуBGREWRITEAOF
:127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started
-
Проверьте свой файл AOF снова в текстовом редакторе:
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n *3\r\n$3\r\nSET\r\n$7\r\ncounter\r\n$1\r\n2\r\n *3\r\n$3\r\nSET\r\n$2\r\nk2\r\n$2\r\nv2\r\n *6\r\n$5\r\nHMSET\r\n$5\r\nmykey\r\n$2\r\nf1\r\n$2\r\nv1\r\n$2\r\nf2\r\n$2\r\nv2\r\n
В своём разделе Подготовка... мы отключили перманентность и вычистили все данные в Redis. Повторное включение удержания AOF после этого создаёт некий пустой файл AOF. Обратите внимание, пожалуйста, что нам приходится вначале перед сьросом данных отключать удержание AOF, в противном случае имеющийся файл AOF не будет пустым пока мы не запустим перезапись AOF.
На шаге 3 мы вызываем семь команд для манипуляции командами REDIS:
-
SET k1 v1
-
INCR counter
-
INCR counter
-
SET k2 v2
-
DEL k1
-
DEL k3
-
HSET mykey f1 v1 f2 v2
Когда мы открыли для инспекции свой файл AOF, мы обнаружили что содержимое этого файла выглядит теми командами, которые мы только что исполнили, причём в формате RESP, который мы ввели в рецепте Общее представление о протоколе Redis из Главы 1, Приступая к Redis.
Имеются два исключения:
-
В самом начале имеется команда,
SELECT 0
, которая означает выбор базы данных0
. Redis поддерживает на самом деле множество баз данных, которые могут определяться номерами от0
до15
, базой данных по умолчанию является0
. -
Команда
DEL k3
не включена в наш файл AOF, так как эта команда не вызывает никаких изменений в имеющейся базе данных (ключk3
не существует).
На шаге 5 мы исполняем некую перезапись AOF.После её завершения мы можем увидеть, что файл AOF был уплотнён со следующими изменениями:
-
Две команды
INCR
заменены одной командойSET
. -
Команды для
k1
были исключены, так как он был удалён. Redis имеет некий алгоритм уплотнения и перезаписи своего файла AOF, другими примерами являются: командыSET
заменяются какой- то командойMSET
, удаляются команды для ключей с истекшим сроком и тому подобное.
Для выполнения перезаписи AOF от основного процесса Redis будет ответвлён некий дочерний процесс. Этот дочерний процесс создаст камкой- то новый файл AOF
для сохранения своих результатов перезаписи, поэтому сам старый файл AOF не испытает воздействия в случае неудачной операции перезаписи. Имеющийся
родительский процесс продолжит обслуживать обмен и будет выводить в дамп своего старого файла AOF команды записи. При ответвлении своего дочернего процесса
применяется поддерживаемый механизм COW, поэтому он не потребует того же объёма памяти что и его предок. Тем не менее, благодаря такому механизму COW
сам дочерний процесс не способен получить доступ к вновь получаемым данным после ветвления. Redis решает эту проблему позволяя своему родительскому процессу
помещать команды записи которые он получает ветвления в некий буфер с названием aof_rewrite_buf_blocks
. После того
как его дочерний процесс завершает перезапись своего нового файла AOF, он отправляет некий сигнал своему процессу предку. Этот родительский процесс
сбрасывает команды из aof_rewrite_buf_blocks
в новый файл AOF, а затем заменяет свой старый файл AOF этим новым.
Помимо включения вручную перезаписи AOF с помощью команды BGREWRITEAOF
, мы также можем настроить Redis
на исполнение перезаписи AOF в автоматическом режиме. Этой цели служат два следующих параметра:
-
auto-aof-rewrite-min-size
: Некая перезапись AOF не будет включаться если размер данного файла AOF меньше указанного здесь размера. Значением по умолчанию является 64 МБ. -
auto-aof-rewrite-percentage
: Redis запоминает значение размера файла AOF после самой последней операции перезаписи AOF. Если текущий размер файла AOF увеличивается на это процентное соотношение, будет включена другая перезапись AOF. Установка этого значения в0
запретит Automatic AOF Rewrite. Значением по умолчанию является100
.
Команда INFO PERSISTENCE
предоставляет много информации о перезаписи AOF. Например,
aof_last_bgrewrite_status
указывает значение состояния самой последней операции перезаписи AOF,
aof_base_size
является значением размера самого последнего файла AOF,
aof_rewrite_buffer_length
является размером aof_rewrite_buf_blocks
, который
мы упоминали выше:
127.0.0.1:6379> INFO PERSISTENCE
...
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:0
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:6393856
aof_current_size:143
aof_base_size:143
aof_pending_rewrite:0
aof_buffer_length:0
aof_rewrite_buffer_length:0
aof_pending_bio_fsync:0
aof_delayed_fsync:0
Для получения сведений относительно прочих элементов информации перманентности AOF вы можете обратиться к https://redis.io/commands/info.
В предыдущих рецептах этой главы мы описали варианты удержания как RDB, так и AOF. Когда дело касается перманентности данных, всегда существуют
различные моменты, которые вам следует принимать во внимание: утрата данных в случае некоего выхода из строя, стоимость производительности при
сохранении данных, размер необходимого файла удержания, а также скорость восстановления данных. Что касается RDB, записываемые в Redis между двумя
моментальными снимками данные могут быть утрачены. Значение латентности и стоимость памяти некоторого системного вызова
fork()
в RDB могут стать некоторой проблемой при высоком уровне обмена на запись и большом наборе данных.
Однако при сопоставлении с AOF, некий файл дампа RDB занимает меньше дискового пространства и восстановление из какого- то дампа RDB выполняется
быстрее. На самом деле, вы можете включить обе функциональности одновременно.
В данном рецепет мы рассмотрим как взять самое лучшее от обоих подходов удержания.
Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis. Потребуются также базовые знания как RDB, так и AOF.
-
Чтобы включить обе функциональности, и RDB, и AOF, в имеющемся файле конфигурации Redis установите следующие параметры настройки:
$ cat conf/redis.conf |egrep "^save|^append" save 900 1 save 300 10 save 60 10000 appendonly yes appendfilename "appendonly.aof" appendfsync everysec
-
Заполните свой Сервер Redis некими образцами данных при помощи команды
DEBUG POPULATE
и выполните операции удержания и для RDB, и для AOF. После этих действий установите некий образец пары строкового ключ- значение:127.0.0.1:6379> DEBUG POPULATE 1000000 OK (1.61s) 127.0.0.1:6379> SAVE OK 127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started 127.0.0.1:6379> SET FOO BAR OK
-
Проверьте наличие дампа RDB и записей в конце журнала AOF:
$ ls -l dump.rdb appendonly.aof -rw-rw-r-- 1 redis redis 48676857 Oct 25 10:25 appendonly.aof -rw-rw-r-- 1 redis redis 24777946 Oct 25 10:24 dump.rdb
-
Проверьте размер соответствующих файлов дампа RDB и журнала AOF:
$ du -sm dump.rdb appendonly.aof 24 dump.rdb 47 appendonly.aof
-
Проверьте первые 20 строк своего файла AOF с помощью редактора Vim:
Затем мы проверим самые последние 10 строк нашего файла AOF при помощи редактора Vim следующим образом:
-
Замените настройку
aof-use-rdb-preamble
наyes
и снова вызовитеBGREWRITEAOF
чтобы включить перезапись AOF:127.0.0.1:6379> CONFIG SET aof-use-rdb-preamble yes OK 127.0.0.1:6379> BGREWRITEAOF Background append only file rewriting started
-
Проверьте соответствующие размеры файлов дампа RDB и журнала AOF:
$ du -sm dump.rdb appendonly.aof 24 dump.rdb 24 appendonly.aof
-
Проверьте самые первые 20 строк своего файла AOF в редакторе Vim:
После этого проверьте самые последние 10 строк своего файла AOF в редакторе Vim следующим образом:
В своём предыдущем примере в нашем экземпляре Redis были размещены некие образцы данных. После этого при помощи команды
SAVE
был создан некий дамп RDB, а имеющийся файл AOF был перезаписан посредством команды
BGREWRITEAOF
.
Просмотрев файлы мы обнаружили, что все данные были удержаны в обоих видах RDB и AOF в каталоге данных Redis. На основании описаний наших предыдущих рецептов для нас не явилось сюрпризом обнаружить что размер файла AOF больше размера дампа RDB.
После этого мы проверили начальный и завершающий сегменты AOF при помощи редактора Vim. Соответствующие команды записи были сохранены в том виде AOF, который был описан в предыдущем рецепте Изучение AOF.
После включения обоиз методов RDB и AOF мы устанавливаем значение параметра настройки
aof-use-rdb-preamble
в yes
чтобы разрешить новую функцию
удержания смешанного формата, которая предоставляется начиная с Redis 4.x. После того как этот параметр установлен в значение
yes
, при перезаписи соответствующего файла AOF Redis вначале сбрасывает дамп своего набора данных в
оперативной памяти в виде RDB в качестве некоей преамбулы AOF. После перезаписи Redis продолжит регистрацию в журнале всех команд записи в
соответствующем файле AOF применяя обычный формат AOF. В таком виде смешанного формата ясно можно убедиться исследовав заголовок и хвост
соответствующего файла AOF после перезаписи. Вначале применяется собственно формат RDB, в самом начале этого файла AOF в том случае, когда
разрешено смешение форматов. Redis получает преимущества от такого смешения форматов удержания, так как он способен выполнять перезапись и
загрузку необходимых данных более быстро благодаря более компактному формату RDB и в то же самое время придерживаясь преимуществ AOF для
лучшей согласованности данных.
Для версий Redis, предшествующих 4.x, вы могли включать RDB и AOF одновременно для достижения большей сохранности. После появления Redis 4.x
предлагается включать AOF с удержанием в смешанном формате. Обратите внимание, что нет смысла включать смешанный формат при отключении опции AOF,
поскольку в такой файл AOF ничего не будет добавляться даже если вы вручную создадите этот файл AOF вызвав BGREWRITEAOF
.
Если вы можете жить с некоторыми возможными потерями данных, применение только RDB достигает наилучшей производительности. Более того, согласно автору
Redis, Antirez, не рекомендуется применять только AOF для предотвращения утраты данных по причине ошибок в
самом механизме AOF.
И, наконец, Redis гарантирует что выполнение дампа RDB и перезаписи AOF никогда не запускаются одновременно. При запуске Redis будет вначале
всегда загружать свой файл AOF, если такой имеется, даже в случае когда включены оба варианта удержания и имеется также и соответствующий файл
RDB. Это обусловлено тем, что имеющийся файл AOF рассматривается как предоставляющий более надёжную согласованность. При загрузке имеющегося файла
AOF, в том случае, когда включено удержание в смешанном формате, Redis вначале проверяет самые первые пять символов AOF. Если ими являются
REDIS
, что представляет собой магическую строку некоего файла RDB, как это было описано в нашем рецепте
Изучение RDB, такой файл AOF представляет собой смешанный формат. Наш Сервер Redis вначале
загружает соответствующую часть RDB, а потом оставшуюся часть AOF.