предисловие
Redis — это in-memory база данных, а данные хранятся в памяти, во избежание безвозвратной потери данных, вызванной выходом из процесса, необходимо периодически сохранять данные в Redis из памяти на локальный диск в виде данных или команд. При следующем перезапуске Redis используйте постоянные файлы для восстановления данных. Redis предоставляет два механизма сохранения, RDB и AOF.Первый сохраняет текущие данные на диск, а второй сохраняет каждую команду записи, выполненную на диск (аналогично Binlog MySQL). В этой статье будут подробно представлены две схемы сохраняемости RDB и AOF, включая метод работы и принцип реализации сохраняемости.
текст
Redis — это сервер базы данных, основанный на хранилище пар ключ-значение (KV).Давайте сначала представим внутреннюю структуру базы данных Redis и форму хранения KV, что поможет нам легче понять механизм сохранения Redis.
1. Структура базы данных Redis
Сервер Redis с одним компьютером по умолчанию имеет 16 баз данных (номера от 0 до 15), и количество баз данных можно настроить. Redis по умолчанию использует базу данных 0, и вы можете использовать команду SELECT для переключения баз данных.
Каждая база данных в Redis представлена структурой redis.h/redisDb, которая записывает пространство ключей отдельной базы данных Redis, время истечения срока действия для всех ключей, ключи в заблокированном и готовом состояниях, номер базы данных и многое другое.
typedef struct redisDb {
// 数据库键空间,保存着数据库中的所有键值对
dict *dict;
// 键的过期时间,字典的键为键,字典的值为过期事件 UNIX 时间戳
dict *expires;
// 正处于阻塞状态的键
dict *blocking_keys;
// 可以解除阻塞的键
dict *ready_keys;
// 正在被 WATCH 命令监视的键
dict *watched_keys;
struct evictionPoolEntry *eviction_pool;
// 数据库编号
int id;
// 数据库的键的平均 TTL,统计信息
long long avg_ttl;
} redisDb;
Поскольку Redis представляет собой базу данных пар ключ-значение, сама его база данных также является словарем, а соответствующая структура — redisDb. Среди них dict указывает на словарь, который записывает данные пары ключ-значение, его ключ является строковым объектом, а его значение может быть любым из объектов типа строк, списков, хэш-таблиц, наборов и упорядоченных наборов Redis. expires указывает на словарь, используемый для записи времени истечения срока действия ключа.Его ключ — это ключ базы данных в словаре, а его значение — это отметка времени истечения срока действия ключа базы данных, которая представлена типом long long.
2. Постоянство RDB
Постоянство RDB (также известное как постоянство моментальных снимков) относится к созданию моментальных снимков данных в памяти и сохранению их на диск.Суффикс сохраненного файла — .rdb. Файл rdb представляет собой сжатый двоичный файл, который можно прочитать из файла моментального снимка rdb для восстановления данных при перезапуске Redis. Основными функциями RDB являются две функции, rdbSave и rdbLoad.Первая используется для создания файла RDB и сохранения его на диск, а вторая используется для перезагрузки данных в файле RDB в память:
Файл RDB представляет собой один файл с полными данными, который очень подходит для аварийного резервного копирования и восстановления данных. Восстановление базы данных с помощью файла RDB занимает меньше времени. Обычно для загрузки файла моментального снимка 1G требуется всего около 20 секунд. в память. Redis предоставляет два способа создания файлов RDB: ручное сохранение триггера и автоматический интервал сохранения.Давайте сначала представим процесс создания и загрузки RDB.
2.1 Создание и загрузка RDB
Сервер Redis по умолчанию сохраняется через RDB.Элементы конфигурации, соответствующие файлу redis.conf, следующие:
# RDB文件的名称
dbfilename dump.rdb
# 备份RDB和AOF文件存放路径
dir /usr/local/var/db/redis/
2.1.1. Ручное сохранение триггера
Redis предоставляет две команды для создания файлов RDB: SAVE и BGSAVE. Существует два способа запустить Redis для выполнения резервного копирования RDB: один — вручную запустить создание моментального снимка с помощью команды SAVE и команды BGSAVE, а другой — настроить время сохранения и количество операций записи, а Redis автоматически запускает операцию сохранения в соответствии с условия.
1. Команда СОХРАНИТЬ
SAVE — это синхронная команда, которая блокирует серверный процесс Redis до тех пор, пока не будет создан файл RDB. Пока серверный процесс заблокирован, сервер не может обрабатывать никакие другие запросы команд.
- клиентская команда
127.0.0.1:6379> SAVE
OK
- Журнал сервера
6266:M 15 Sep 2019 08:31:01.258 * DB saved on disk
После выполнения команды SAVE Redis выполняет операцию SAVE над серверным процессом (PID — 6266), что блокирует обработку запросов клиента Redis во время этой операции.
2. Команда БГСОХРАНИТЬ
BGSAVE — асинхронная команда, в отличие от команды SAVE, которая напрямую блокирует серверный процесс, команда BGSAVE порождает дочерний процесс, который отвечает за создание RDB-файла, а серверный процесс (родительский процесс) продолжает обрабатывать клиентские команды.
- клиентская команда
127.0.0.1:6379> BGSAVE
Background saving started
- Журнал сервера
6266:M 15 Sep 2019 08:31:22.914 * Background saving started by pid 6283
6283:C 15 Sep 2019 08:31:22.915 * DB saved on disk
6266:M 15 Sep 2019 08:31:22.934 * Background saving terminated with success
Из журнала, выводимого сервером, можно обнаружить, что Redis в серверном процессе (PID — 6266) создаст (разветвит) дочерний процесс (PID — 6283) для команды BGSAVE отдельно, и дочерний процесс завершит RDB. сохранение процесса в фоновом режиме. Уведомление родительского процесса о завершении и выход. В течение всего процесса серверный процесс тратит лишь небольшое количество времени на создание подпроцессов и обработку семафоров подпроцессов, а остальное время находится в состоянии ожидания.
BGSAVE — это основной способ активировать сохраняемость RDB.Следующее представляет собой процесс создания моментальных снимков с помощью команды BGSAVE:
- Клиент инициирует команду BGSAVE, а основной процесс Redis определяет, есть ли дочерний процесс, который в данный момент выполняет резервное копирование, и возвращается напрямую, если он существует.
- Родительский процесс разветвляет дочерний процесс (процесс разветвления вызовет блокировку), этот процесс может использовать команду info stats для просмотра параметра last_fork_usec для просмотра времени, затраченного последней операцией разветвления, в микросекундах.
- После того, как вилка родительского процесса завершена, он вернется к подсказке о начале фонового сохранения информации, и в это время блокировка вилки будет снята.
- Дочерний процесс, созданный fork, начинает генерировать временный файл моментального снимка на основе данных памяти родительского процесса, а затем заменяет исходный файл
- После резервного копирования дочернего процесса он отправляет информацию о завершении родительскому процессу, а родительский процесс обновляет статистику.
3. Сравнение SAVE и BGSAVE
Заказ | SAVE | BGSAVE |
---|---|---|
Тип ввода-вывода | Синхронизировать | асинхронный |
блокировать ли | полный блок | Заблокировано на форке |
сложность | O(n) | O(n) |
преимущество | Не потребляет дополнительную память | Не блокируйте клиентов |
недостаток | блокирующий клиент | fork дочерний процесс потребляет память |
2.1.2 Автоматическое сохранение триггера
Поскольку команду BGSAVE можно выполнить, не блокируя серверный процесс, файл конфигурации Redis redis.conf предоставляет возможность сохранения, позволяющую серверу автоматически выполнять команду BGSAVE через равные промежутки времени. Пользователь может установить несколько условий сохранения с помощью параметра сохранения.Пока выполняется любое из условий, сервер будет выполнять команду BGSAVE. Файл конфигурации Redis redis.conf по умолчанию настроен со следующими тремя условиями сохранения:
save 900 1
save 300 10
save 60 10000
Затем, пока выполняется любое из следующих 3 условий, команда BGSAVE будет выполняться автоматически:
- Сервер внес как минимум 1 изменение в базу данных в течение 900 секунд.
- Сервер внес не менее 10 изменений в базу данных в течение 300 секунд.
- Сервер внес не менее 10 000 изменений в базу данных в течение 60 секунд.
Например, вставьте пару ключ-значение с помощью команды SET msg «hello», подождите 900 секунд, серверный процесс Reids автоматически активирует сохранение, и результат будет следующим:
6266:M 15 Sep 2019 08:46:22.981 * 1 changes in 900 seconds. Saving...
6266:M 15 Sep 2019 08:46:22.986 * Background saving started by pid 6266
6476:C 15 Sep 2019 08:46:23.015 * DB saved on disk
6266:M 15 Sep 2019 08:46:23.096 * Background saving terminated with success
Сервер Redis будет периодически запускать функцию serverCron, которая выполняется каждые 100 миллисекунд.Одна из его задач — проверить, выполняются ли условия сохранения, заданные параметром сохранения, и если да, то автоматически выполнить команду BGSAVE.
2.1.3 Включить автозагрузку
В отличие от использования команд SAVE и BGSAVE для создания файлов RDB, Redis не предоставляет команду для загрузки файлов RDB.Процесс загрузки файлов RDB автоматически завершается при запуске сервера Redis. Пока при запуске обнаруживается наличие файла RDB в указанном каталоге, Redis автоматически загружает файл RDB с помощью функции rdbLoad.
Ниже приведен журнал, распечатываемый при запуске сервера Redis, а второй журнал снизу распечатывается после успешной загрузки файла RDB.
$ redis-server /usr/local/etc/redis.conf
6266:M 15 Sep 2019 08:30:41.832 # Server initialized
6266:M 15 Sep 2019 08:30:41.833 * DB loaded from disk: 0.001 seconds
6266:M 15 Sep 2019 08:30:41.833 * Ready to accept connections
Поскольку файлы AOF относятся к добавочным резервным копиям команды записи, а файлы RDB относятся к полным резервным копиям данных, частота обновления выше, чем у файлов RDB. Поэтому, если на сервере Redis включена функция сохранения AOF, сервер будет предпочтительно использовать файл AOF для восстановления состояния базы данных; только когда функция сохранения AOF отключена, сервер будет использовать файл RDB для восстановления состояния базы данных. .
2.2 Файловая структура RDB
Файлы RDB представляют собой сжатые двоичные файлы, и некоторые сведения о внутренней структуре файлов RDB описаны ниже.
2.2.1 Путь хранения
И команда SAVE, и команда BGSAVE будут создавать резервную копию только текущей базы данных.Имя файла резервной копии по умолчанию — dump.rdb, а имя файла резервной копии можно изменить с помощью файла конфигурации dbfilename xxx.rdb. Каталог файла резервной копии и имя файла RDB можно просмотреть с помощью следующей команды:
$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/var/db/redis"
127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"
Путь хранения файла RDB можно настроить перед запуском или задать динамически с помощью команд.
- Элемент конфигурации: укажите каталог через конфигурацию dir, а dbfilename укажите имя файла.
- Динамическая спецификация: после запуска Redis путь к хранилищу RDB также может быть динамически изменен, что очень полезно, когда диск поврежден или недостаточно места.Команда выполнения:
CONFIG SET dir $newdir
CONFIG SET dbfilename $newFileName
2.2.2 Формат файла
Файлы RDB имеют фиксированные требования к формату.Они хранят двоичные данные, которые можно условно разделить на следующие 5 частей:
- REDIS: заголовок файла содержит символ REDIS длиной 5 байт, который используется для идентификации текущего файла как типа RDB.
- db_version: 4-байтовая длинная целочисленная строка, в которой записан номер версии файла RDB.
- aux: записывает информацию метаданных в файл RDB, включая 8 дополнительных
- redis-ver: номер версии экземпляра Redis.
- redis-bits: архитектура хоста, на которой работает экземпляр Redis, 64-битная или 32-битная.
- ctime: временная метка Unix, когда была создана RDB.
- used_mem: объем памяти, используемый при хранении снимков.
- repl-stream-db: индекс базы данных сервера Redis.
- repl-id: идентификатор основного экземпляра Redis (идентификатор репликации)
- repl-offset: смещение репликации основного экземпляра Redis.
- aof-preamble: размещать ли моментальные снимки RDB в заголовке файла AOF (то есть включать гибридное сохранение)
- базы данных: часть содержит ноль или любое количество баз данных, а также данные пары ключ-значение для каждой базы данных
- EOF: это 1-байтовая константа, используемая для обозначения конца основного содержимого файла RDB.
- check_sum: целое число длиной 8 байт, содержащее контрольную сумму, рассчитанную предыдущими четырьмя частями, используемую для проверки целостности файла RDB.
1. database
Раздел databases файла RDB содержит ноль или любое количество баз данных, и каждая непустая база данных состоит из трех частей: SELECTDB, db_number и key_value_pairs:
- SELECTDB: однобайтовая константа, которая сообщает пользовательской программе, что следующим чтением будет db_number.
- db_number: содержит номер базы данных. Когда программа прочитает db_number, сервер немедленно вызовет команду SELECT для переключения на базу данных с соответствующим номером
- key_value_pairs: сохраняет все данные пары ключ-значение в базе данных, включая два типа пар ключ-значение со сроком действия и без срока действия
2. key_value_pairs
Часть key_value_pairs RDB хранит одну или несколько пар ключ-значение.Если у пары ключ-значение есть время истечения срока действия, время истечения будет храниться перед парой ключ-значение. Ниже приведена внутренняя структура этих двух пар ключ-значение:
- EXPIREMENT_MS: однобайтовая константа, которая сообщает пользовательской программе, что следующее, что нужно прочитать, — это время истечения срока действия в миллисекундах.
- мс: 8-байтовое целое число, которое записывает время истечения срока действия пары ключ-значение, отметка времени в миллисекундах.
- TYPE: записывает тип значения длиной 1 байт. Каждая константа TYPE представляет тип объекта или базовую кодировку.Когда сервер считывает данные пары ключ-значение в файле RDB, программа решает, как читать и интерпретировать данные значения в соответствии со значением TYPE. Его значение обычно определяется как одна из следующих констант:
- REDIS_RDB_TYPE_STRING: Строка
- REDIS_RDB_TYPE_LIST: Тип списка
- REDIS_RDB_TYPE_SET: тип коллекции
- REDIS_RDB_TYPE_ZSET: отсортированный набор
- REDIS_RDB_TYPE_HASH: тип хеша
- REDIS_RDB_TYPE_LIST_ZIPLIST: Тип списка
- REDIS_RDB_TYPE_SET_INT_SET: Тип коллекции
- REDIS_RDB_TYPE_ZSET_ZIPLIST: отсортированный набор
- REDIS_RDB_TYPE_HASH_ZIPLIST: Тип хеша
- ключ: строковый объект, формат кодировки тот же, что и у значения типа REDIS_RDB_TYPE_STRING
- значение: в зависимости от типа TYPE, тип объекта может быть string, list, set, zset и hash
Чтобы просмотреть внутреннюю структуру файла RDB, выполните следующую команду, чтобы вставить данные 3 пар ключ-значение на сервер Redis:
127.0.0.1:6379> SADD fruits "apple" "banana" "orange"
(integer) 3
127.0.0.1:6379> LPUSH numbers 128 256 512
(integer) 3
127.0.0.1:6379> SET msg "hello"
OK
Выполните операцию SAVE, чтобы принудительно сохранить данные в процессе Redis в файле dump.rdb.
127.0.0.1:6379> SAVE
OK
Преобразуйте данные в двоичном файле dump.rdb в выходной формат ASCII с помощью команды Linux od, которая примерно совпадает с форматом хранения, упомянутым ранее:
$ od -c dump.rdb
0000000 R E D I S 0 0 0 9 372 \t r e d i s
0000020 - v e r 005 5 . 0 . 5 372 \n r e d i
0000040 s - b i t s 300 @ 372 005 c t i m e 200
0000060 200 200 231 ] 372 \b u s e d - m e m 302 200
0000100 \v 020 \0 372 \f a o f - p r e a m b l
0000120 e 300 \0 376 \0 373 003 \0 \0 003 m s g 005 h e
0000140 l l o 016 \a n u m b e r s 001 027 027 \0
0000160 \0 \0 022 \0 \0 \0 003 \0 \0 300 \0 002 004 300 \0 001
0000200 004 300 200 \0 377 002 006 f r u i t s 003 006 o
0000220 r a n g e 005 a p p l e 006 b a n a
0000240 n a 377 214 ک ** 3 366 < r X
0000253
2.3 Общие элементы конфигурации RDB
Ниже приведены общие элементы конфигурации (и значения по умолчанию), связанные с файлами RDB в файле redis.conf:
- save m n: Условие, при котором bgsave срабатывает автоматически; если нет сохранения конфигурации m n, это эквивалентно автоматическому отключению сохраняемости RDB, но его все же можно вызвать другими способами.
- stop-writes-on-bgsave-error yes: прекращает ли Redis выполнение команд записи при возникновении ошибки в bgsave. Если установлено значение «да», при возникновении проблемы с жестким диском ее можно будет вовремя обнаружить, чтобы избежать потери большого количества данных; если установлено значение «нет», Redis проигнорирует ошибку bgsave и продолжит выполнение Команда записи При использовании серверной системы Redis (особенно жесткого диска) В целях мониторинга рассмотрите возможность установки для этого параметра значения no.
- rdbcompression yes: включить ли сжатие файлов RDB.
- rdbchecksum yes: включить ли проверку файлов RDB, работает как при записи файлов, так и при чтении файлов. Отключение контрольной суммы дает повышение производительности примерно на 10% при записи и запуске файлов, но не при повреждении данных.
- dbfilename dump.rdb: Установите имя файла RDB.
- dir ./: укажите каталог, в котором находятся файлы RDB и файлы AOF.
3. Стойкость АОФ
Постоянство RDB заключается в периодической записи всего объема данных в памяти в файлы.Кроме того, RDB также обеспечивает постоянство на основе AOF (Append Only File). AOF будет записывать каждую команду записи, выполняемую сервером Redis, в файл журнала, а при перезапуске сервера снова выполнять команды в файле AOF, чтобы восстановить данные.
Основная функция AOF — решить проблему сохраняемости данных в реальном времени, и она стала основным способом сохранения данных в Redis.
3.1 Создание и загрузка AOF
По умолчанию функция AOF отключена, и Redis будет выполнять сохранение данных только через RDB. Чтобы включить функцию AOF, необходимо изменить элемент конфигурации appendonly в файле redis.conf на yes, чтобы при включении функции сохраняемости AOF сохраняемость моментальных снимков на основе RDB имела низкий приоритет. Измените redis.conf следующим образом:
# 此选项为AOF功能的开关,默认为no,通过yes来开启aof功能
appendonly yes
# 指定AOF文件名称
appendfilename appendonly.aof
# 备份RDB和AOF文件存放路径
dir /usr/local/var/db/redis/
3.1.1. Создание АОФ
После перезапуска серверного процесса Redis в каталоге dir будет создан файл appendonly.aof.Поскольку сервер в это время не выполняет никаких инструкций по записи, файл AOF пуст. Выполните следующие команды, чтобы записать несколько частей тестовых данных:
127.0.0.1:6379> SADD fruits "apple" "banana" "orange"
(integer) 3
127.0.0.1:6379> LPUSH numbers 128 256 512
(integer) 3
127.0.0.1:6379> SET msg "hello"
OK
Файл AOF имеет обычный текстовый формат, и приведенные выше команды записи записываются в файл appendonly.aof по порядку (опустите символ новой строки '\r\n'):
/usr/local/var/db/redis$ cat appendonly.aof
*2 $6 SELECT $1 0
*5 $4 SADD $6 fruits $5 apple $6 banana $6 orange
*5 $5 LPUSH $7 numbers $3 128 $3 256 $3 512
*3 $3 SET $3 msg $5 hello
Способ сохранения RDB заключается в сохранении данных пары «ключ-значение» яблока, банана и апельсина в виде двоичных файлов RDB, в то время как AOF заключается в сохранении SADD, LPUSH, SET и других команд, выполняемых сервером Redis, в текстовый файл AOF. На следующем рисунке показана структурная схема внутри файла AOF:
3.1.2 Загрузка АОФ
Снова перезапустите процесс сервера Redis и просмотрите журнал запуска, чтобы обнаружить, что Redis будет загружать данные через файл AOF:
52580:M 15 Sep 2019 16:09:47.015 # Server initialized
52580:M 15 Sep 2019 16:09:47.015 * DB loaded from append only file: 0.001 seconds
52580:M 15 Sep 2019 16:09:47.015 * Ready to accept connections
Считайте данные пары ключ-значение, восстановленные из файла AOF, с помощью команды:
127.0.0.1:6379> SMEMBERS fruits
1) "apple"
2) "orange"
3) "banana"
127.0.0.1:6379> LRANGE numbers 0 -1
1) "512"
2) "256"
3) "128"
127.0.0.1:6379> GET msg
"hello"
3.2 Процесс выполнения AOF
Для AOF не требуется устанавливать какие-либо условия запуска, и все команды записи на сервер Redis будут автоматически записываться в файл AOF.Ниже описан процесс выполнения сохраняемости AOF.
Процесс записи файла AOF можно разделить на следующие 3 этапа:
- Команда append (добавить): добавить команду записи, выполняемую Redis, в буфер AOF aof_buf.
- Запись файлов (запись) и синхронизация файлов (fsync): AOF синхронизирует данные aof_buf с жестким диском в соответствии с соответствующей политикой.
- Перезапись файла (перезапись): Периодически перезаписывайте AOF для сжатия команд записи.
3.2.1. Добавление команды
Redis использует один поток для обработки клиентских команд. Чтобы избежать прямой записи на диск каждый раз, когда есть команда записи, в результате чего дисковый ввод-вывод становится узким местом производительности Redis, Redis сначала добавит выполненную команду записи в буфер aof_buf, и Вместо записи непосредственно в файл.
Формат прилагаемой команды — это формат протокола командного запроса Redis.Это обычный текстовый формат, преимущества которого заключаются в хорошей совместимости, хорошей читабельности, простоте обработки, простоте операций и отсутствии вторичных накладных расходов. В файле AOF, за исключением команды select, используемой для указания базы данных (например, выберите 0 для выбора базы данных 0), которая добавляется Redis, все остальные команды записи отправляются клиентом.
3.2.2 Запись файлов и синхронизация файлов
Redis предоставляет различные стратегии синхронизации файлов для буферов AOF. Соответствующие стратегии включают функции write() и fsync() операционной системы, а именно:
1. write()
Чтобы повысить эффективность записи файла, когда пользователь вызывает функцию записи для записи данных в файл, операционная система сначала записывает данные в буфер памяти.Когда буфер заполнен или превышает указанный лимит времени , реальный Буфер записи данных на диск.
2. fsync()
Хотя нижний уровень операционной системы оптимизирует функцию write(), он также создает проблемы с безопасностью. Если данные в буфере памяти простоя будут потеряны, система также предоставляет функцию синхронизации fsync(), чтобы заставить операционную систему немедленно записать данные из буфера на диск, тем самым обеспечив сохранение данных.
Redis предоставляет элемент конфигурации appendfsync для управления стратегией синхронизации файлов буфера AOF.appendfsync можно настроить со следующими тремя стратегиями:
- appendfsync always: Сохранять каждый раз, когда выполняется команда
Сразу после записи команды в буфер aof_buf вызывается системная функция fsync для синхронизации с файлом AOF.После завершения операции fsync поток возвращается и весь процесс блокируется. В этом случае каждый раз, когда есть команда записи, она должна быть синхронизирована с файлом AOF, а ввод-вывод на жесткий диск становится узким местом производительности.Redis может поддерживать только около нескольких сотен операций записи в секунду, что серьезно снижает производительность Redis.
- appendfsync no:Не сохраняй
После записи команды в буфер aof_buf вызывается системная операция записи, и fsync-синхронизация над AOF-файлом не выполняется, за синхронизацию отвечает операционная система, а период синхронизации обычно составляет 30 секунд. В этом случае время на синхронизацию файлов неконтролируемо, а в буфере будет накапливаться много данных, поэтому безопасность данных не может быть гарантирована.
- appendfsync everysec: сохранять каждую секунду
После записи команды в буфер aof_buf вызывается системная операция записи, и поток возвращается сразу после завершения записи.Синхронная файловая операция fsync вызывается один раз в секунду отдельным процессом. Everysec — это компромисс между двумя упомянутыми выше стратегиями, баланс между производительностью и безопасностью данных, поэтому он также является конфигурацией Redis по умолчанию и более уважаемым вариантом конфигурации.
стратегия синхронизации файлов | блоки записи | блоки fsync | Потеря данных во время простоя |
---|---|---|---|
always | блокировать | блокировать | Данные максимум одной команды потеряны |
no | блокировать | не блокирует | Данные после последней fsync файла AOF операционной системой |
everysec | блокировать | не блокирует | Обычно не более 1 секунды данных |
3.2.3 Перезапись файлов
По мере того как команда продолжает запись в AOF, файл становится все больше и больше, что приводит к увеличению размера файла и увеличению времени восстановления данных. Чтобы решить эту проблему, Redis представляет механизм перезаписи для объединения команд записи в файле AOF для дальнейшего сжатия размера файла.
Перезапись файла AOF относится к преобразованию данных в процессе Redis в команды записи, синхронизации с новым файлом AOF и последующему использованию нового файла AOF для перезаписи старого файла AOF.Этот процесс не выполняет чтения и записи старого файла AOF. файл. работать.
1. Спусковой механизм
Процесс перезаписи AOF предусматривает два механизма: ручной запуск и автоматический запуск:
- Ручной триггер: прямой вызов команды bgrewriteaof. Выполнение этой команды чем-то похоже на выполнение bgsave. Все они являются подпроцессами разветвления для выполнения определенной работы и блокируются только при разветвлении.
- Автоматический запуск: определите время запуска в соответствии с элементами конфигурации auto-aof-rewrite-min-size и auto-aof-rewrite-percentage, а также состоянием aof_current_size и aof_base_size.
- auto-aof-rewrite-min-size: минимальный размер файла при выполнении перезаписи AOF, значение по умолчанию — 64 МБ.
- auto-aof-rewrite-percentage: при выполнении перезаписи AOF отношение текущего размера AOF (aof_current_size) к размеру AOF при предыдущей перезаписи (aof_base_size).
2. Перепишите процесс
Ниже приведен пример ручного запуска перезаписи AOF.При выполнении команды bgrewriteaof процесс перезаписи файла AOF выглядит следующим образом:
- Клиент инициирует запрос на перезапись AOF в основной процесс Redis с помощью команды bgrewriteaof.
- Когда в настоящее время нет дочернего процесса, выполняющего bgsave/bgrewriteaof, основной процесс Redis создает дочерний процесс посредством операции fork, и основной процесс блокируется в этом процессе. Если обнаружено, что подпроцесс bgrewriteaof возвращается напрямую; если найден подпроцесс bgsave, дождитесь завершения bgsave перед выполнением операции fork.
- После завершения операции fork основного процесса продолжайте обрабатывать другие команды и одновременно добавляйте новые команды записи в буферы aof_buf и aof_rewrite_buf.
- Прежде чем перезапись файла будет завершена, основной процесс продолжит добавлять команду записи в буфер aof_buf и синхронизироваться со старым файлом AOF в соответствии со стратегией appendfsync, что позволяет избежать потери данных, вызванной сбоем перезаписи AOF, и обеспечить правильность записи. оригинальный файл AOF
- Поскольку в операции форка используется технология копирования при записи, дочерний процесс может совместно использовать данные памяти только во время операции форка, а основной процесс добавит новую команду в буфер aof_rewrite_buf, чтобы избежать потери этой части данных при завершении операции. АОФ переписан
- Дочерний процесс считывает моментальный снимок данных в процессе Redis, генерирует команды записи и записывает их пакетами в новые файлы AOF в соответствии с правилами слияния команд.
- После того, как дочерний процесс заканчивает запись нового AOF-файла, он отправляет сигнал основному процессу, и основной процесс обновляет статистическую информацию, которую можно просмотреть через сохранение информации.
- После того, как основной процесс получает сигнал от дочернего процесса, он добавляет команду записи в буфер aof_rewrite_buf к новому файлу AOF.
- Основной процесс заменяет старый файл AOF новым файлом AOF, и процесс перезаписи AOF завершается.
3. Механизм сжатия
Причина, по которой перезапись файлов может сжимать размер файлов AOF, связана со следующими причинами:
- Просроченные данные больше не записываются в файл AOF.
- Недопустимые команды больше не записываются в файл AOF. Например: многократно устанавливать значения для данных (set mykey v1, set mykey v2), удалять данные пары ключ-значение (sadd myset v1, del myset) и т. д.
- Несколько команд можно объединить в одну. Например: sadd myset v1, sadd myset v2, sadd myset v3 можно объединить в sadd myset v1 v2 v3. Однако, чтобы предотвратить переполнение клиентского буфера из-за слишком большого размера одной команды, для ключей типа list, set, hash и zset необходимо использовать не одну команду, а константу, определенную Redis в качестве границы для разделения команды, разделенной на несколько
3.3 Общие элементы конфигурации AOF
Ниже приведены общие элементы конфигурации (и значения по умолчанию), относящиеся к файлам AOF в файле redis.conf:
- appendonly no: включить ли сохранение AOF
- appendfilename "appendonly.aof": имя файла AOF
- dir ./: каталог, в котором расположены файлы RDB и файлы AOF.
- appendfsync everysec: стратегия сохраняемости fsync
- no-appendfsync-on-rewrite no: следует ли подавлять операции fsync во время перезаписи файлов AOF. Если эта опция включена, загрузка ЦП и диска (особенно диска) может быть снижена при перезаписи файлов, но данные при перезаписи AOF могут быть потеряны, что необходимо сбалансировать между нагрузкой и безопасностью.
- auto-aof-rewrite-percentage 100: одно из условий срабатывания для перезаписи файла AOF.
- auto-aof-rewrite-min-size 64mb: одно из условий срабатывания для перезаписи файла AOF.
- aof-load-truncated yes: загружает ли сервер Redis файл AOF при запуске, если конец файла AOF поврежден.
4. Механизм восстановления данных
Как упоминалось ранее, когда функция сохранения AOF включена, сервер Redis будет предпочтительно выполнять команду файла AOF для восстановления данных при запуске сервера Redis.Только когда функция AOF отключена, данные файла моментального снимка RDB загружаться предпочтительно.
- Когда функция AOF отключена, а сохранение RDB включено, сервер Redis запускает журнал:
6266:M 15 Sep 2019 08:30:41.832 # Server initialized
6266:M 15 Sep 2019 08:30:41.833 * DB loaded from disk: 0.001 seconds
6266:M 15 Sep 2019 08:30:41.833 * Ready to accept connections
- Когда функция AOF включена и файл AOF существует, журнал запуска сервера Redis:
9447:M 15 Sep 2019 23:01:46.601 # Server initialized
9447:M 15 Sep 2019 23:01:46.602 * DB loaded from append only file: 0.001 seconds
9447:M 15 Sep 2019 23:01:46.602 * Ready to accept connections
- Когда функция AOF включена и файл AOF не существует, даже если файл RDB существует, он не будет загружен.Журнал запуска сервера Redis:
9326:M 15 Sep 2019 22:49:24.203 # Server initialized
9326:M 15 Sep 2019 22:49:24.203 * Ready to accept connections
5. Сравнение RDB и AOF
механизм сохранения | RDB | AOF |
---|---|---|
приоритет загрузки | Низкий | высокий |
размер файла на диске | маленький | Большой |
Скорость восстановления данных | быстрый | медленный |
безопасность данных | легко потерять данные | Определяется стратегией |
Уровень серьезности операции | Тяжелый | светлый |
5.1 Преимущества и недостатки RDB
5.1.1 Преимущества
- RDB — это сжатый и очень компактный файл, сохраняющий набор данных в определенный момент времени, подходящий для резервного копирования данных и аварийного восстановления.
- Это может максимизировать производительность Redis.При сохранении файла RDB серверному процессу нужно только разветвить дочерний процесс, чтобы завершить создание файла RDB, а родительскому процессу не нужно выполнять операции ввода-вывода.
- По сравнению с методом сохраняемости AOF восстановление больших наборов данных будет происходить быстрее.
5.1.2 Недостатки
- Безопасность данных RDB не так хороша, как у AOF. Сохранение всего набора данных является тяжелым процессом. В соответствии с конфигурацией однократное сохранение может занять несколько минут. Если сервер выходит из строя, то несколько минут данных может быть потерян.
- Когда набор данных Redis большой, он будет потреблять ЦП и время для дочернего процесса fork для завершения моментального снимка.
5.2 Преимущества и недостатки АОФ
5.2.1 Преимущества
- Более полные данные, более высокий уровень безопасности, потеря данных второго уровня (в зависимости от политики fsync, если она установлена каждую секунду, будет потеряно до 1 секунды данных)
- Файл AOF представляет собой командный файл только для добавления, а операция записи сохраняется в формате протокола Redis.Содержимое доступно для чтения и подходит для аварийного восстановления после случайного удаления.
5.2.2 Недостатки
- Для одного и того же набора данных объем файлов AOF намного больше, чем объем файлов RDB, и восстановление данных будет происходить медленнее.
- В зависимости от используемой стратегии fsync AOF может работать медленнее, чем RDB. Однако в целом производительность fsync в секунду по-прежнему очень высока.
6. Гибридная устойчивость RDB-AOF
Файлы моментальных снимков RDB редко используются для восстановления состояния в памяти при перезапуске сервера Redis, так как много данных теряется. Больше — использовать файлы AOF для воспроизведения команд, но производительность выполнения команд AOF намного ниже, чем у RDB. Таким образом, когда данные Redis велики, запуск занимает много времени.
Ввиду того, что моментальные снимки RDB могут привести к потере данных, а инструкции AOF медленно восстанавливают данные, Redis 4.0 предоставляет набор гибридных механизмов сохранения на основе AOF-RDB, сохраняя преимущества двух механизмов сохранения. Переписанный таким образом файл AOF состоит из двух частей: одна часть представляет собой данные заголовка в формате RDB, а другая часть представляет собой хвостовую команду в формате AOF.
Функция гибридного сохранения в Redis 4.0 по умолчанию отключена.Эту функцию можно включить, настроив aof-use-rdb-preamble на yes:
# 开启AOF-RDB混合持久化机制
aof-use-rdb-preamble yes
Проверьте, включена ли на сервере Redis функция гибридного сохранения:
127.0.0.1:6379> CONFIG GET aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "yes"
Как показано, содержимое файла данных RDB и файла инкрементной команды AOF существуют вместе. Команда AOF здесь больше не полная команда, а добавочная команда AOF, выполняемая серверным процессом от начала сохраняемости до конца сохраняемости.Обычно эта часть команды AOF невелика.
При перезапуске сервера Redis можно предварительно загрузить полный объем данных RDB в заголовке файла AOF, а затем воспроизвести добавочные команды AOF в конце файла AOF, что значительно сокращает время восстановления данных во время перезапустить процесс.
7. Выбор стратегии сохранения
7.1 Накладные расходы на производительность RDB и AOF
Прежде чем вводить стратегию сохраняемости, мы должны сначала понять, что независимо от того, является ли это RDB или AOF, включение сохраняемости вызовет снижение производительности.
- Постоянство РБД:
- Когда команда BGSAVE выполняет операцию форка, основной процесс сервера Redis будет заблокирован.
- Запись данных на диск подпроцессом Redis также создаст нагрузку на ввод-вывод.
- Стойкость АОФ:
- Частота записи данных на диск значительно увеличивается, давление ввода-вывода выше, и это может даже вызвать проблему блокировки добавления AOF.
- Перезапись файла AOF аналогична процессу RDB BGSAVE, но есть проблемы с блокировкой, когда родительский процесс разветвляется и давление ввода-вывода дочернего процесса
Условно говоря, поскольку AOF чаще записывает данные на диск, это окажет большее влияние на производительность основного процесса сервера Redis.
7.2 Стратегия настойчивости
В реальной производственной среде будут использоваться различные стратегии сохранения в зависимости от объема данных, требований безопасности приложений для данных, бюджетных ограничений и т. д.
- Не используйте никакие функции постоянства вообще
- Используйте либо RDB, либо AOF
- Включить сохранение RDB и AOF одновременно
Для распределенной среды выбор постоянства необходимо рассматривать вместе со стратегией master-slave Redis, поскольку репликация и постоянство master-slave также имеют функцию резервного копирования данных, а главный узел (Master Node) и подчиненный узел ( Slave Node) может быть выбрана независимо Схема Persistence.
Выбор стратегии сохранения обсуждается в следующих сценариях. Следующее обсуждение носит справочный характер. Фактическое решение может быть более сложным и разнообразным.
7.2.1 Кэширование базы данных
Не имеет значения, если данные в Redis полностью отбрасываются (например, Redis полностью используется в качестве кеша для данных уровня БД), тогда не требуется постоянства, будь то отдельная машина или архитектура master-slave.
7.2.2 Автономная среда
В автономной среде, если допустима потеря данных на десять минут или более, схема RDB более выгодна для производительности Redis; если допустима потеря данных только за секунды, более подходящей является схема AOF.
7.2.3 Развертывание Master-Slave
В большинстве случаев Redis настроит механизм развертывания master-slave. Подчиненный узел (slave) может не только осуществлять горячее резервное копирование данных, но также выполнять совместное чтение и запись запросов чтения Redis, а также роль замены после выхода из строя главного узла (master).
В этом случае один из возможных вариантов действий следующий:
- мастер: полностью отключить персистентность (включая функции RDB и AOF), чтобы можно было максимизировать производительность главного узла.
- подчиненный: отключите функцию RDB и включите функцию AOF (если требования к безопасности данных не высоки, вы также можете включить RDB и отключить AOF). Регулярно выполняйте резервное копирование постоянных файлов (например, резервное копирование в другие папки и отметку времени резервного копирования). Затем отключите функцию автоматической перезаписи AOF, затем добавьте запланированную задачу и вызывайте bgrewriteaof каждый день, когда сервер Redis простаивает (например, в 12 часов ночи), чтобы перезаписать вручную.
Почему включена репликация master-slave, может быть обеспечено горячее резервное копирование данных и необходимо настроить постоянство? Потому что в некоторых особых случаях репликации master-slave недостаточно для обеспечения безопасности данных, например:
- Одновременная остановка главного и подчиненного узлов: если главный узел и подчиненный узел расположены в одном и том же компьютерном зале, отключение питания может привести к одновременному отключению главного и подчиненного компьютеров и остановке процесса сервера Redis. Без настойчивости вы столкнетесь с полной потерей данных.
- Главный перезапуск: если главный узел выходит из строя из-за сбоя, и в системе есть автоматический механизм подтягивания (то есть перезапуск службы после обнаружения того, что служба остановлена), главный узел будет автоматически перезапущен.
- Поскольку постоянного файла нет, данные пусты после перезапуска ведущего, и данные синхронизации ведомого также становятся пустыми.
- Если ни на ведущем, ни на ведомом узле не включено сохранение, это также приведет к полной потере данных.
7.2.4 Удаленная готовность к стихийным бедствиям
Предыдущие стратегии устойчивости нацелены на общие системные сбои, такие как аварийный выход из процесса, простои, сбой питания и т. д. Эти сбои не повредят жесткий диск. Однако в некоторых аварийных ситуациях, которые могут привести к повреждению жесткого диска, таких как пожар или землетрясение, требуется аварийное восстановление за пределами площадки.
- Автономная среда: вы можете регулярно копировать файлы RDB или переписывать файлы AOF на удаленные машины с помощью команд scp, таких как Alibaba Cloud, AWS и т. д.
- Для развертывания master-slave вы можете регулярно выполнять операцию BGSAVE на главном узле, а затем копировать файл RDB на удаленный компьютер или выполнять команду bgrewriteaof на подчиненном узле, чтобы перезаписать файл AOF, а затем скопировать файл AOF. на удаленную машину.
Из-за небольшого размера файлов RDB и высокой скорости восстановления при аварийном восстановлении обычно используется метод RDB; частота резервного копирования за пределами площадки определяется в соответствии с потребностями безопасности данных и другими условиями, но лучше не меньше чем раз в день.
резюме
В этой статье в основном представлена структура базы данных сервера Redis, а также несколько механизмов сохраняемости, предоставляемых Redis, в том числе полная сохраняемость RDB на основе моментальных снимков данных, добавочная сохраняемость AOF на основе добавления команд и гибридная сохраняемость, поддерживаемая Redis 4.0. Для режима персистентности RDB приведены процесс создания и восстановления моментального снимка RDB, файловая структура RDB и соответствующие элементы конфигурации. Для метода сохраняемости AOF приведены процесс создания и восстановления журнала AOF, процесс выполнения AOF, внутренний формат файла AOF и соответствующие элементы конфигурации. В конце статьи анализируются преимущества и недостатки методов RDB и AOF, потери производительности и стратегии сохранения в автономной среде, развертывании master-slave и сценариях удаленной готовности к авариям.
Об официальном аккаунте
Эта учетная запись продолжает делиться сухими товарами серверных технологий, включая основы виртуальных машин, многопоточное программирование, высокопроизводительные фреймворки, асинхронное ПО, промежуточное ПО для кэширования и обмена сообщениями, распределенные и микросервисы, материалы для обучения архитектуре и расширенные учебные материалы и статьи.