redis02-redis data persistence

1 Introduction

As you can see from the previous article " redis01-The Essence of High-Performance Redis ", we often add a layer of cache (such as Redis) to the database layer to ensure data access efficiency.
In this way, the performance has indeed been greatly improved, but Redis itself is also a first-tier service, and there is also the possibility of downtime and failure.
Once the service is suspended, possible consequences include the following:

  1. Redis data is stored in memory, so once it is suspended, all data in memory will be lost.
  2. I/O migrates from the memory level to the disk level, and performance drops rapidly.
  3. Requests that originally access the cache will be directed to the database through the cache layer, putting great pressure on the database and even causing an avalanche.

Therefore, the consequences of a cache layer crash are disastrous. In order to avoid downtime and data loss after downtime, and to ensure rapid data recovery, Redis provides two capabilities for persisting data, AOF (Append Only FIle) logs and RDB snapshots.

2.RDB memory snapshot

In large-scale high-concurrency distributed scenarios, a common problem is that Redis hangs, resulting in access failure, and all requests are directed to the database through the cache layer, putting great pressure on the database.
Redis data is stored in the cache. Even if we restart and resume use, the cache pool is still empty because the memory is released.
The process of re-establishing the cache is also a critical blow to the database, which is likely to cause an avalanche of the entire system call chain.
We know that Redis data is stored in memory. Can the data in memory be further written to the disk? When Redis restarts, the data on the disk can be quickly restored to the memory. In this way, even if Redis is down and restarted, it can still provide services normally.
But one issue cannot be ignored. One of the biggest differences between Redis and MySQL is that one is stored in memory and the other is persisted on disk. However, if every data change (new addition, modification, deletion of cache) must be written to the memory and written to the disk at the same time, the cost will be too high. Memory + disk will greatly reduce the performance of Redis. In addition, atomic operations must be ensured to avoid data inconsistency between memory and disk.

2.1. Using memory snapshots

In order to avoid the negative effects of real-time writing and high-frequency disk operations. Redis provides a memory snapshot strategy.
We know that when Redis executes write (add, delete, modify) instructions, the data in the memory will continue to change. Memory snapshot refers to the state of the data in Redis memory at a certain moment. Just like taking a photo, you freeze the data at that moment and persist it to the disk. Students who play games can imagine saving.
Snapshot files are called RDB files, which is the abbreviation of Redis DataBase.
Redis executes RDB memory snapshots regularly, so that it does not have to save to disk every time a write command is executed. It only needs to write to disk when executing a memory snapshot. This not only ensures efficient reading and writing of Redis, but also achieves scheduled persistence, so that data can be quickly restored after a downtime.
Insert image description here
When doing data recovery, the RDB file is directly read into the memory to complete the recovery.

2.2 Generate RDB policy

Redis provides two modes for generating RDB files:

  • Save: Executed by the main thread, blocking synchronously, new operations can only be performed after the save is completed;
  • bgsave: After execution, it will return OK immediately. At the same time, the function fork of glibc is called to generate a sub-process for writing RDB files. The snapshot persistence is completely handled by the sub-process. The main process continues to perform its own work, non-blocking.

2.2.1.save mode

The save mode is executed by the main process. It is highly not recommended to use the main process execution method. In " redis01-The Essence of High-Performance Redis ",
we know that its main operations are completed on a single-threaded model. Therefore, try to avoid RDB file generation that affects the main thread's network I/O and key-value pair reading and writing.

2.2.2.bgsave mode

Redis uses the operating system's multi-process copy-on-write technology COW (Copy On Write) to achieve snapshot persistence. This is very important. For details, you can read this article "Copy On Write Mechanism ".
Redis will call the glibc function fork to generate a child process during persistence. This child process will handle the snapshot persistence action. The child process can share all the memory data of the main process, so it reads the data of the main process and then writes into the RDB file. The parent process continues to process the client's write operations and is not affected.
When creating an RDB file, the program checks the keys in the database and only saves unexpired keys to the newly created RDB file.
When the main process executes the write command to modify the data, a copy of the data will be made. The bgsave sub-process reads the copy data and writes it to the RDB file, so the main process can directly modify the original data.
Insert image description here
This not only ensures the integrity of the snapshot, but also allows the main process to modify the data at the same time, avoiding any impact on normal business.

2.2.3 Avoid over-frequent full photos

Although Redis uses the bgsave function to fork the child process to complete the snapshot of the data in the memory in the background, it does not affect the parent process to continue processing various operations of the client.
However, one thing to note is that executing full data snapshots too frequently will inevitably lead to serious performance overhead:

  • Frequently generating RDB files and writing them to disk will cause excessive disk pressure and reduce efficiency.
  • The bgsave child process that comes out of the fork will block the running of the main thread to a certain extent because it shares the data of the main thread. The larger the memory of the main thread, the longer the blocking time.

2.3 Summary RDB

  • The recovery speed of snapshots is fast, but the frequency of generating RDB files needs to be controlled at a certain level. If the frequency is too low and the snapshot interval is large, more data will be lost; if the frequency is too fast, additional overhead will be consumed and Redis performance will be reduced.
  • RDB recommends using binary + data compression to write to disk. The file size is small and the data recovery speed is fast.

3.AOF log

The AOF log stores the sequential instruction sequence of the Redis server. The AOF log only records instructions that modify the memory.
Assuming that the AOF log records all modified instruction sequences since the creation of the Redis instance, then all instructions can be executed sequentially on an empty Redis instance.
In other words, the memory data structure of the current instance of Redis can be established through replay. Are you familiar with this model? Have you ever thought about the relay log during MySQL master-slave synchronization?

3.1 Comparison before and after log changes

There are two modes for AOF recording logs. One is write-ahead log, also called write-ahead log (WAL): before actually writing the data, the modified data is written to the log file.
The other is post-write logging: perform the write operation first, and then record the log after the data is stored in the memory.
The write-ahead log is similar to the redo log in the MySQL Innodb engine. The log is recorded before modifying the data and then modified.

It is recommended to use the post-write log mode to avoid additional checking overhead and no need to perform syntax checking on executed commands. If you use write-ahead logging, you need to check whether the syntax is correct first. Otherwise, the log records wrong commands, and an error will occur when using log recovery. In addition, recording the log after writing will not block the execution of the current write command.

3.2. Possible problems

  • There may be loss: for example, Redis just finished executing the command and crashed before recording the log, so the command data was lost.
  • AOF avoids blocking of the current command, but the AOF log is executed by the main thread. During the process of writing the log to the disk, if the disk pressure is high, the execution will slow down and subsequent operations will be reduced.

3.3. Write-back strategy

The above problem is inevitable when Redis reads and writes at high frequencies. To solve it, just create a layer of buffering during writing to avoid through blocking. At this time, Redis provides an execution strategy called writeback strategy.

3.3.1 Write-back strategy description

In order to improve the writing efficiency of log files, the writeback strategy will be changed as follows:

  • When you call the write function to write data to a file, it is not actually written to the disk, but the written data is temporarily stored in the memory buffer of the operating system.
  • The data in the buffer is not actually written to the disk until the buffer space is filled or exceeds the specified threshold.
    This approach obviously improves efficiency, but it also brings security issues to the written data. If the server goes offline, the written data stored in the memory buffer will be lost.
    To this end, the system provides two synchronization functions, fsync and fdatasync, which can force the operating system to immediately write the data in the buffer to the hard disk, thereby ensuring the security of the written data.
    The AOF configuration item appendfsync writeback strategy provided by Redis directly determines the efficiency and security of the AOF persistence function. The following are the three enumerations of appendfsync:
  1. always: synchronous writeback, the buffer content will be written back to the AOF file after the write command is executed.
  2. everysec: Write back every second. After the write command is executed, the log is written to the AOF file buffer, and the buffer synchronizes the content to the disk every second.
  3. no: Controlled by the operating system, after the write execution is completed, the log is written to the AOF file memory buffer, and the operating system decides when to write back to the disk.

Writing to disk will cause performance losses, so the write-back strategy must make a trade-off based on the actual situation, such as whether you prefer performance or reliability.

  • Always synchronous writeback can ensure that data is not lost, but every time a write command is executed, it needs to be written to the disk, which has the worst performance.
  • Everysec writes back every second, avoiding the performance overhead of synchronous writeback, but if the service goes down, there will be data loss for about 1 second. This mode is a compromise between performance and reliability.
  • no operating system control, after executing the write command, write to the AOF file buffer, and then execute the subsequent write disk command, the performance is the best, but more data may be lost.

We can choose a strategy based on the actual situation of the service, whether to favor high performance or high reliability.

  • For high performance requirements, choose the No strategy
  • For high reliability guarantee, choose the Always strategy
  • If you can accept a small amount of data loss and want better performance, choose the Everysec policy.

4. Mixed RDB/AOF mode

In reality, using RDB or AOF is almost meaningless. Using rdb to restore the memory state will inevitably result in the loss of some data. Use AOF log replay. Replay has a certain impact on performance, and it takes a long time when the Redis instance is large.
Redis 4.0 solves this problem and uses a new persistence mode - hybrid persistence, which 混合模式is turned off by default.
Store the contents of the RDB file together with the incremental AOF log file after the RDB snapshot time point. At this time, the AOF log no longer needs to be the full log, but the incremental AOF log that occurred from the latest snapshot time point to the present. Usually, this part of the AOF log is very small.
So the execution sequence is as follows:

  1. Find the rdb content, if present load the rdb content first and then replay the remaining aof.
  2. There is no rdb content, and the entire file is directly replayed in aof format.

In this way, snapshots do not need to be executed frequently. At the same time, because AOF only needs to record the data after the latest snapshot, it does not need to record all operations, avoiding the problem of a single replay file being too large.

5. Summary

  • RDB provides a snapshot mode to record the Redis memory status at a certain time. RDB is designed with bgsave and copy-on-write to avoid the impact on read and write instructions during snapshot execution as much as possible. However, frequent snapshots will put pressure on the disk and fork will block the main thread. Need to know the frequency.
  • The AOF log stores the sequential instruction sequence of the Redis service, writes the log file through the replay instruction, and uses the write-back strategy to avoid the pressure of high-frequency reading and writing on Redis.
  • The photo time interval of RDB snapshots will inevitably lead to data loss. If minute-level data loss is allowed, you can only use RDB.
  • If only AOF is used, the writeback strategy prefers the everysec configuration option because it strikes a balance between reliability and performance.
  • When data cannot be lost, the mixed use of memory snapshots and AOF is a good choice.

Guess you like

Origin blog.csdn.net/d495435207/article/details/131544393