Глава 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.

RDB манипуляции

Как мы уже описывали в своём предыдущем рецепте, для некоторого хранилища данных в оперативной памяти подобного 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 основные шаги такие:

  1. Чтобы включить удержание 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
     	   
  2. Если же мы желаем разрешить RDB на постоянной основе, установите значение настройки save в соответствующем файле конфигурации Redis:

    
    $ cat conf/redis.conf |grep "^save"
    save 900 1
    save 300 10
    save 60 10000
     	   
  3. Для отключения свойства удержания RDB для некоторого запущенного экземпляра Redis добавьте пустую строку в соответствующую опцию save с помощью redis-cli:

    
    $ bin/redis-cli config set save ""
    OK
     	   
  4. Для отключения RDB на постоянной основе просто экранируйте комментарием или удалите имеющиеся опции save в своём файле настроек Redis:

    
    #save 900 1
    #save 300 10
    #save 60 10000
     	   
  5. Чтобы проверить включена ли функциональность RDB, запросите соответствующий файл настроек save из redis-cli. Если в соответствующей опции save имеется некая пустая строка, это указывает на то, что функция RDB отключена. В противном случае будет получена разрешённая политика RDB переключения взятия моментальных снимков:

    
    $ bin/redis-cli CONFIG GET save
    1) "save"
    2) "900 1 300 10 60 10000"
     	   
  6. Мы можем убедиться в том был ли сгенерирован соответствующий файл RDB в установленном каталоге данных Redis:

    
    $ ls -l dump.rdb
    -rw-rw-r-- 1 redis redis 286 Oct 23 22:11 dump.rdb
     	   
  7. Для создания некоего моментального снимка RDB вручную вызовите команду SAVE в redis-cli. Данный redis-cli выполнит блокировку на какое- то время и затем выполнит возврат в командную строку таким образом:

    
    127.0.0.1:6379> SAVE
    OK
    (23.25s)
    127.0.0.1:6379>
     	   
  8. В качестве альтернативы мы можем вызвать BGSAVE для осуществления дампа RDB без блокировки:

    
    127.0.0.1:6379> BGSAVE
    Background saving started
     	   
  9. Проверьте состояние 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
     	   
  10. Быстро выполните наполнение некими образцами данных при выполнении дампа RDB:

    
    $ node generator.js hash 100000
     	   
  11. Проверьте соответствующий журнал своего Сервера 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
     	   
  12. Для выборки необходимых замеров и состояния удержания вызовите из 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 с высокой доступностью Пауля Бертуччи и Раджу Шривастава}

Изучение RDB

Мы уже изучили что посредством перманентности 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 необходимые шаги таковы:

  1. Установите некую пару строковых ключ- значение:

    
    127.0.0.1:6379> SET key value
    OK
     	   
  2. Установите пару списочных ключ- значение:

    
    127.0.0.1:6379> LPUSH listkey v1 v2
    (integer) 2
     	   
  3. Настройте пару ключ- значение хэша:

    
    127.0.0.1:6379> HSET hashkey k1 v1 k2 v2
    (integer) 2
     	   
  4. Настройте пару ключ- значение множества:

    
    127.0.0.1:6379> SADD setkey v1 v2
    (integer) 2
     	   
  5. Установите пару ключ- значение сортированного множества:

    
    127.0.0.1:6379> ZADD zset 1 v1 2 v2
    (integer) 2
     	   
  6. Для включения выполнения дампа RDB вызовите в redis-cli команду SAVE:

    
    127.0.0.1:6379> SAVE
    OK
     	   
  7. В редакторе bvi откройте только что созданный нами файл dump.rdb:

    
    $ bvi dump.rdb
     	   

Полученное содержимое dump.rdb отображено на следующем снимке экрана:

 

Рисунок 6-1



Как это работает...

В нашем предыдущем примере в имеющемся экземпляре Redis были размещены некоторые образцы проверочных данных. После этого был создан некий дамп RDB посредством команды SAVE.

После этого мы ближе рассмотрим что имеется в RDB в не заземлённом виде при помощи двоичного редактора bvi в Linux. Всё содержимое нашего файла RDB было преобразовано bvi в шестнадцатеричный вид. Рассматривая самые первые пять чисел (52 45 44 49 53) одно за другим в таблице ASCII (RapidTables), мы можем заключить, что этими первыми символами являются REDIS:

 

Рисунок 6-2



Следующими четырьмя символами после нашей магической строки являются 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 таков:

 

Рисунок 6-3



Ввиду ограничений в пространстве данной книги мы не будем вдаваться в подробности указанного вышк формата данных. Если вас это интересует, вы можете рассмотреть исходные коды файлов 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

AOF манипуляции

В наших двух предыдущих рецептах мы изучили варианты RDB для удержания данных Redis. Однако, использование RDB для перманентности не предоставляет очень сильной устойчивости. Как уже упоминалось, некий дамп данных RDB содержит только моментальный снимок данных Redis на какой- то момент времени. Хотя Redis выполняет дампы данных в свой файл RDB периодически, имеющиеся между двумя дампами RDB данные будут утрачены навсегда в случае падения процесса Redis или же при наличии некоего аппаратного отказа. AOF является неким дописываемым только в конец (append-only) файлом журнала, который регистрирует поступающие команды записи своего Сервера Redis. Значение надёжности данных AOF выше чем у RDB, так как все команды записи добавляются в конец этого файла. В данном рецепте мы покажем как вы можете включить AOF в Redis и ознакомим вас с некоторыми важными параметрами AOF.

Подготовка...

Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis.

Как это сделать...

Основные шаги по манипуляции AOF таковы:

  1. Для включения удержания AOF в некотором запущенном экземпляре Redis вызовите команду CONFIG SET следующим образом:

    
    127.0.0.1:6379> CONFIG SET appendonly yes
    OK
     	   
  2. Если вы желаете разрешить AOF на постоянной основе, добавьте appendonly yes в свой файл настроек Redis и перезапустите этот сервер:

    
    $ cat conf/redis.conf |grep "^appendonly"
    appendonly yes
     	   
  3. Чтобы отключить функциональность применения удержания AOF для какого- то исполняемого экземпляра Redis, установите appendonly в значение no:

    
    $ bin/redis-cli config set appendonly no
    OK
     	   
  4. Для отключения удержания AOF на постоянной основе просто установите appendonly no в своём файле настроек и перезапустите этот сервер:

    
    appendonly no
     	   
  5. Для проверки того что функция AOF включена мы можем применить INFO PERSISTENCE и отыскать соответствующие элементы AOF:

    
    127.0.0.1:6379> INFO PERSISTENCE
    # Persistence
    loading:0
    ...
    aof_enabled:1
    aof_rewrite_in_progress:0
     	   
  6. Или же мы можем проверить был ли создан соответствующий файл 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

В своём предыдущем рецепте мы изучили как устанавливать перманентность AOF в Redis. В этом рецепте мы собираемся бросить взгляд на само содержимое файла AOF и пояснить весь процесс перезаписи AOF.

Подготовка...

Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis.

Для целей данной демонстрации нам следует отключить AOF и вначале сбросить все данные при помощи команды FLUSHALL.

Как это сделать...

Основные шаги исследования AOF таковы:

  1. Включите удержание AOF:

    
    127.0.0.1:6379> CONFIG SET appendonly yes
    OK
     	   
  2. Так как в Redis нет никаких данных, у нас должен иметься некий пустой файл AOF:

    
    $ ls -l
    -rw-rw---- 1 redis redis 0 Oct 23 20:47 appendonly.aof
     	   
  3. В 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
     	   
  4. При помощи текстового редактора откройте свой файл 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
    ...
     	   
  5. Из redis-cli исполните команду BGREWRITEAOF:

    
    127.0.0.1:6379> BGREWRITEAOF
    Background append only file rewriting started
     	   
  6. Проверьте свой файл 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, так и AOF. Когда дело касается перманентности данных, всегда существуют различные моменты, которые вам следует принимать во внимание: утрата данных в случае некоего выхода из строя, стоимость производительности при сохранении данных, размер необходимого файла удержания, а также скорость восстановления данных. Что касается RDB, записываемые в Redis между двумя моментальными снимками данные могут быть утрачены. Значение латентности и стоимость памяти некоторого системного вызова fork() в RDB могут стать некоторой проблемой при высоком уровне обмена на запись и большом наборе данных. Однако при сопоставлении с AOF, некий файл дампа RDB занимает меньше дискового пространства и восстановление из какого- то дампа RDB выполняется быстрее. На самом деле, вы можете включить обе функциональности одновременно.

В данном рецепет мы рассмотрим как взять самое лучшее от обоих подходов удержания.

Подготовка...

Вам требуется завершить установку своего Cервера Redis, которое мы описывали в своём рецепте Загрузка и установка Redis в Главе 1, Приступая к Redis. Потребуются также базовые знания как RDB, так и AOF.

Как это сделать...

  1. Чтобы включить обе функциональности, и 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
     	   
  2. Заполните свой Сервер 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
     	   
  3. Проверьте наличие дампа 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
     	   
  4. Проверьте размер соответствующих файлов дампа RDB и журнала AOF:

    
    $ du -sm dump.rdb appendonly.aof
    24      dump.rdb
    47      appendonly.aof
     	   
  5. Проверьте первые 20 строк своего файла AOF с помощью редактора Vim:

     

    Рисунок 6-4



    Затем мы проверим самые последние 10 строк нашего файла AOF при помощи редактора Vim следующим образом:

     

    Рисунок 6-5



  6. Замените настройку 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
     	   
  7. Проверьте соответствующие размеры файлов дампа RDB и журнала AOF:

    
    $ du -sm dump.rdb appendonly.aof
    24      dump.rdb
    24      appendonly.aof
     	   
  8. Проверьте самые первые 20 строк своего файла AOF в редакторе Vim:

     

    Рисунок 6-6



    После этого проверьте самые последние 10 строк своего файла AOF в редакторе Vim следующим образом:

     

    Рисунок 6-7



Как это работает...

В своём предыдущем примере в нашем экземпляре 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.