怎么做淘宝推广网站,个人网站怎么推广,上海搬家公司排名第一,外国人的做视频网站吗有道无术#xff0c;术尚可求#xff0c;有术无道#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 执行原理2.1 Redis 6.x2.1.1 直接写2.1.2 重写 2.2 Redis 7.x2.2.1 直接写2… 有道无术术尚可求有术无道止于术。 本系列Redis 版本 7.2.5 源码地址https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 执行原理2.1 Redis 6.x2.1.1 直接写2.1.2 重写 2.2 Redis 7.x2.2.1 直接写2.2.2 重写 3. 配置项3.1 appendonly3.2 appendfilename3.3 appenddirname3.4 appendfsync3.5 no-appendfsync-on-rewrite3.6 auto-aof-rewrite-percentage、auto-aof-rewrite-min-size3.7 aof-load-truncated3.8 aof-use-rdb-preamble3.9 aof-timestamp-enabled 1. 概述
默认情况下Redis 使用RDB持久化但如果进程出现问题或电源中断可能会导致几分钟的写入数据丢失具体取决于配置的保存点。
Append Only FileAOF是另一种持久化模式它提供了更好的持久性保证。AOF 以日志的形式来记录每个写操作Redis重启时通过读取和执行AOF文件中的命令来重建数据集。
优点
备份机制更稳健丢失数据概率更低。可读的日志文本通过操作AOF文件可以处理误操作。
缺点
比起RDB占用更多的磁盘空间。恢复备份速度要慢。每次读写都同步的话有一定的性能压力。存在个别Bug造成不能恢复。
2. 执行原理
2.1 Redis 6.x
Redis 6 及之前的版本中生成的 AOF 只有一个 appendonly.aof 整个执行流程如下 2.1.1 直接写
Redis 在执行写操作时并不是将指令直接写入到文件中而是先写入到缓冲区aof_buf然后根据相应的策略同步 fsync 到磁盘中支持以下三种不同的模式后面配置有详细介绍
no操作系统自行决定always每次写入都会立即被刷新到磁盘everysec每秒只进行一次 fsync 调用
写入的 AOF 文件如下所示 当 Redis 宕机重启时可以通过读取和执行 AOF 文件中的命令来重建数据集。但是每一次写指令都会存入到 AOF 文件可能会导致文件变得非常大文件太大时无论是写入还是加载都会变得特别慢。
2.1.2 重写
为了避免 AOF 文件多大问题控制文件大小并优化性能Redis 支持运行时触发 AOF 文件重写rewrite用以压缩 AOF 文件的大小。
重写机制可以通过 BGREWRITEAOF 命令手动触发也可以自动触发配置参数如下
# 当 AOF 文件大小超过上次重写后 AOF 文件大小的百分比时自动触发默认值为 100
auto-aof-rewrite-percentage 100
# 当 AOF 文件大小超过指定值时自动触发默认值为 64 MB
auto-aof-rewrite-min-size 64mb当触发重写机制后 Redis 主进程会阻塞等待微秒级并执行 fork 创建子进程创建完成后会继续接收新的请求命令并将 fork 后的写操作写入到缓冲区并刷盘。此外新操作还会写入到重写缓冲区aof_rewrite_buf中以便重写完成后合并到新文件中确保和内存数据的一致性。
重写子进程会根据当前时刻 Redis 的数据快照将每个键值对转换为相应的写入命令并写入到一个临时文件中 temp-rewriteaof-bg-pid.aof。当上述操作完成后主进程会将重写缓冲区中的数据发送给子进程由子进程将数据追加到临时AOF文件中。
子进程重写完成后会发送消息给主进程主进程负责将重写缓冲区可能存在未发送的数据中剩余数据继续追加到临时AOF文件并执行原子性的重命名操作覆盖原先的AOF文件至此整个重写流程结束。
上述 AOF 重写机制存在一些问题
内存开销主进程 fork 之后的新操作会同时写入到缓冲区和重写缓冲区重复内容会带来额外的内存冗余开销。一旦内存开销太大可能会触发 Redis 内存限制影响正常命令的写入甚至会触发操作系统限制被 OOM Killer杀死导致服务不可用。CPU 开销可能会造成 Redis在执行命令时出现 RT 上的抖动甚至造成客户端超时的问题。 重写期间主进程需要花费CPU时间向重写缓冲区写数据并使用eventloop事件循环向子进程发送重写缓冲区中的数据在子进程执行重写操作的后期会循环读取pipe中主进程发送来的增量数据然后追加写入到临时AOF文件在子进程完成重写操作后主进程会进行收尾工作。其中一个任务就是将在重写期间重写缓冲区中没有消费完成的数据写入临时AOF文件。如果遗留的数据很多这里也将消耗CPU时间。 磁盘IO开销重写期间主进程的双写操作缓冲区中的数据最终会被写入到当前使用的旧AOF文件中产生磁盘IO。重写缓冲区中的数据也会被写入重写生成的新AOF文件中产生磁盘IO。因此同一份数据会产生两次磁盘IO。代码复杂度Redis使用六个 pipe 进行主进程和子进程之间的数据传输和控制交互这使得整个重写逻辑变得更为复杂和难以理解。
2.2 Redis 7.x
Redis 7 对 AOF 机制进行了优化发布了新特性Multi Part AOF将单个 AOF 拆分为多个该特性由阿里云数据库Tair团队贡献。
AOF文件分为三种类型
BASE基础AOF文件它一般由子进程通过重写产生该文件最多只有一个。INCR增量AOF文件它一般会在重写开始执行时被创建该文件可能存在多个。HISTORY表示历史AOF它由BASE和INCR AOF变化而来每次重写成功完成时本次重写之前对应的BASE和INCR AOF都将变为HISTORYHISTORY类型的AOF会被Redis自动删除。
为了管理这些AOF文件引入了一个清单manifest文件来跟踪、管理这些AOF。同时为了便于AOF备份和拷贝所有的AOF文件和manifest文件放入一个单独的文件目录中默认为 appendonlydir 整个执行流程如下 2.2.1 直接写
Redis 刚启动时就会创建BASE、INCR文件 在没有触发重写机制时执行流程和 Redis 6 一样只是命令被写入的文件是 appendonly.aof.1.incr.aof 。当 Redis 重启时会加载BASE、INCR文件中的命令来重建数据集。 2.2.2 重写
当触发重写机制后 Redis 主进程会阻塞等待微秒级并执行 fork 创建子进程创建完成后会继续接收新的请求命令并将 fork 后的写操作写入到新打开的INCR增量AOF文件不再需要写入到重写缓冲区aof_rewrite_buf中降低了内存消耗。
子进程的重写操作完全是独立的重写期间不会与主进程进行任何的数据和控制交互最终重写操作会产生一个新打开的BASE AOF文件。
新生成的BASE AOF和新打开的INCR AOF就代表了当前时刻 Redis的全部数据。重写结束时主进程会负责更新 manifest 文件将新生成的BASE AOF和INCR AOF信息加入进去并将之前的BASE AOF和INCR AOF标记为HISTORY会被Redis异步删除。一旦manifest文件更新完毕就标志整个重写流程结束。
Multi Part AOF的引入成功的解决了之前重写存在的内存和CPU开销解决了对Redis实例甚至业务访问带来的不利影响。
3. 配置项
redis.conf 中 AOF 相关的配置如下
############################## APPEND ONLY MODE ################################ By default Redis asynchronously dumps the dataset on disk. This mode is
# good enough in many applications, but an issue with the Redis process or
# a power outage may result into a few minutes of writes lost (depending on
# the configured save points).
#
# The Append Only File is an alternative persistence mode that provides
# much better durability. For instance using the default data fsync policy
# (see later in the config file) Redis can lose just one second of writes in a
# dramatic event like a server power outage, or a single write if something
# wrong with the Redis process itself happens, but the operating system is
# still running correctly.
#
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check https://redis.io/topics/persistence for more information.appendonly no# The base name of the append only file.
#
# Redis 7 and newer use a set of append-only files to persist the dataset
# and changes applied to it. There are two basic types of files in use:
#
# - Base files, which are a snapshot representing the complete state of the
# dataset at the time the file was created. Base files can be either in
# the form of RDB (binary serialized) or AOF (textual commands).
# - Incremental files, which contain additional commands that were applied
# to the dataset following the previous file.
#
# In addition, manifest files are used to track the files and the order in
# which they were created and should be applied.
#
# Append-only file names are created by Redis following a specific pattern.
# The file names prefix is based on the appendfilename configuration
# parameter, followed by additional information about the sequence and type.
#
# For example, if appendfilename is set to appendonly.aof, the following file
# names could be derived:
#
# - appendonly.aof.1.base.rdb as a base file.
# - appendonly.aof.1.incr.aof, appendonly.aof.2.incr.aof as incremental files.
# - appendonly.aof.manifest as a manifest file.appendfilename appendonly.aof# For convenience, Redis stores all persistent append-only files in a dedicated
# directory. The name of the directory is determined by the appenddirname
# configuration parameter.appenddirname appendonlydir# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: dont fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#
# The default is everysec, as thats usually the right compromise between
# speed and data safety. Its up to you to understand if you can relax this to
# no that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode thats snapshotting),
# or on the contrary, use always thats very slow but a bit safer than
# everysec.
#
# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html
#
# If unsure, use everysec.# appendfsync always
appendfsync everysec
# appendfsync no# When the AOF fsync policy is set to always or everysec, and a background
# saving process (a background save or AOF log background rewriting) is
# performing a lot of I/O against the disk, in some Linux configurations
# Redis may block too long on the fsync() call. Note that there is no fix for
# this currently, as even performing fsync in a different thread will block
# our synchronous write(2) call.
#
# In order to mitigate this problem its possible to use the following option
# that will prevent fsync() from being called in the main process while a
# BGSAVE or BGREWRITEAOF is in progress.
#
# This means that while another child is saving, the durability of Redis is
# the same as appendfsync no. In practical terms, this means that it is
# possible to lose up to 30 seconds of log in the worst scenario (with the
# default Linux settings).
#
# If you have latency problems turn this to yes. Otherwise leave it as
# no that is the safest pick from the point of view of durability.no-appendfsync-on-rewrite no# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb# An AOF file may be found to be truncated at the end during the Redis
# startup process, when the AOF data gets loaded back into memory.
# This may happen when the system where Redis is running
# crashes, especially when an ext4 filesystem is mounted without the
# dataordered option (however this cant happen when Redis itself
# crashes or aborts but the operating system still works correctly).
#
# Redis can either exit with an error when this happens, or load as much
# data as possible (the default now) and start if the AOF file is found
# to be truncated at the end. The following option controls this behavior.
#
# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
# the Redis server starts emitting a log to inform the user of the event.
# Otherwise if the option is set to no, the server aborts with an error
# and refuses to start. When the option is set to no, the user requires
# to fix the AOF file using the redis-check-aof utility before to restart
# the server.
#
# Note that if the AOF file will be found to be corrupted in the middle
# the server will still exit with an error. This option only applies when
# Redis will try to read more data from the AOF file but not enough bytes
# will be found.
aof-load-truncated yes# Redis can create append-only base files in either RDB or AOF formats. Using
# the RDB format is always faster and more efficient, and disabling it is only
# supported for backward compatibility purposes.
aof-use-rdb-preamble yes# Redis supports recording timestamp annotations in the AOF to support restoring
# the data from a specific point-in-time. However, using this capability changes
# the AOF format in a way that may not be compatible with existing AOF parsers.
aof-timestamp-enabled no3.1 appendonly
appendonly 用于控制是否启用AOF持久化。
appendonly no被设置为 no默认 时Redis 不会使用 AOF 持久化机制。
3.2 appendfilename
appendfilename 用于配置 AOF 文件的基础名称。
appendfilename appendonly.aofRedis 7 及更高版本使用一组仅追加文件进行AOF文件主要有两种类型
基础文件是数据集在文件创建时完整状态的快照。基础文件可以是 RDB二进制序列化格式或 AOF文本命令格式。增量文件包含在上一个文件之后对数据集应用的其他命令。
此外还使用清单文件来跟踪文件的创建顺序以及它们应该被应用的顺序。
Redis 根据特定的模式创建AOF文件的名称。文件名的前缀基于appendfilename配置参数后面跟着关于序列和类型的额外信息。
例如如果 appendfilename被设置为appendonly.aof那么可能会产生以下文件名
appendonly.aof.1.base.rdb 作为基础文件。appendonly.aof.1.incr.aof, appendonly.aof.2.incr.aof 作为增量文件。appendonly.aof.manifest 作为清单文件。
3.3 appenddirname
appenddirname 配置AOF文件的存储目录。
appenddirname appendonlydir3.4 appendfsync
appendfsync 用于配置AOF缓冲区将操作同步sync到磁盘的AOF文件中的策略。
# appendfsync always
appendfsync everysec
# appendfsync nofsync() 是一个系统调用它告诉操作系统将数据实际写入磁盘而不是等待更多的数据进入输出缓冲区。不同的操作系统对 fsync() 的实现可能有所不同一些系统会立即将数据写入磁盘而另一些系统则会尽快尝试这样做。
Redis 支持三种不同的 fsync 模式
no不进行 fsync 调用让操作系统自行决定何时将数据刷新到磁盘。这种方式速度最快但可能存在数据丢失的风险。always每次写入 AOF 日志后都进行 fsync 调用。这是最慢但最安全的方式因为每次写入都会立即被刷新到磁盘。everysec每秒只进行一次 fsync 调用。这是速度和数据安全性之间的一个折中方案。
默认值是 everysec因为它通常是在速度和数据安全性之间最好的折中方案。你可以根据自己的需求调整这个设置。如果你能接受一些数据丢失的风险并且追求更好的性能可以考虑使用 no 模式但请注意如果你能接受数据丢失那么默认的基于快照的持久化模式可能更合适。相反如果你追求更高的数据安全性即使这意味着性能会降低可以使用 always 模式。
3.5 no-appendfsync-on-rewrite
no-appendfsync-on-rewrite 用于配置在BGSAVE或BGREWRITEAOF正在进行时是否阻止主进程调用fsync()。
no-appendfsync-on-rewrite no当AOF的fsync策略设置为always或everysec时如果有一个后台保存进程后台保存或AOF日志后台重写正在对磁盘进行大量I/O操作在某些Linux配置下Redis可能会在fsync()调用上阻塞过长时间。目前这个问题没有修复方法因为即使在不同的线程中执行fsync也会阻塞我们的同步write调用。
默认为no不阻止主进程fsync()还是会把数据往磁盘里刷但是遇到重写操作可能会发生阻塞数据安全但是性能降低。
当设置为yes时在BGSAVE或BGREWRITEAOF正在进行时主进程将不会执行fsync调用。这意味着在这段时间内Redis的持久性与appendfsync no设置时相同即数据不会立即同步到磁盘。在最坏的情况下你可能会丢失最多30秒使用默认Linux设置的AOF日志数据。因此如果你对延迟很敏感可以将其设置为yes。但是从持久性的角度来看将其保持为no默认值是最安全的选择。
3.6 auto-aof-rewrite-percentage、auto-aof-rewrite-min-size
AOF采用文件追加方式文件会越来越大为避免出现此种情况新增了重写机制当AOF文件的大小超过所设定的阈值时Redis会fork出一条新进程来将文件重写也是先写临时文件最后再重命名。
重写过程会创建一个新的 AOF 文件其中只包含能够恢复当前数据状态所必需的最少命令从而减小 AOF 文件的大小。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mbauto-aof-rewrite-percentage 用于设置一个百分比阈值当 AOF 文件的大小相对于上一次重写后的大小增长了超过这个百分比时Redis 就会自动触发 BGREWRITEAOF 命令来重写 AOF 文件。设置为 100即 100%那么当 AOF 文件的大小增长了一倍时触发重写。
auto-aof-rewrite-min-size 用于设置一个 AOF 文件重写所需的最小大小以字节为单位。只有当 AOF 文件的大小既超过了指定的百分比 auto-aof-rewrite-percentage 又超过了 auto-aof-rewrite-min-size 指定的最小大小时Redis 才会触发 AOF 文件的重写。
3.7 aof-load-truncated
aof-load-truncated 用于配置如果 AOF 文件末尾被截断时的相关处理策略。
aof-load-truncated yes在 Redis 启动过程中当 AOF 数据被加载回内存时可能会发现 AOF 文件末尾被截断。例如在运行 Redis 的操作系统崩溃时尤其是当 ext4 文件系统被挂载但没有使用 dataordered 选项。然而当 Redis 本身崩溃或中止但操作系统仍然正常工作时这种情况不会发生。
当发生这种情况时Redis 可以选择报错退出或者加载尽可能多的数据现在是默认行为并启动如果 AOF 文件末尾被截断。以下选项控制这种行为。
aof-load-truncated yes会加载一个被截断的 AOF 文件并且 Redis 服务器会开始记录日志以通知用户该事件。aof-load-truncated no服务器会报错并拒绝启动。当选项设置为 no 时用户需要使用 “redis-check-aof” 工具修复 AOF 文件后再重新启动服务器。
3.8 aof-use-rdb-preamble
aof-use-rdb-preamble 用于配置是否使用 RDB 格式创建AOF的基础文件。使用 RDB 格式总是更快、更高效。
aof-use-rdb-preamble yes3.9 aof-timestamp-enabled
aof-timestamp-enabled 用于配置 Redis 是否支持在 AOF 中记录时间戳以支持从特定时间点恢复数据。但是使用这种功能会以可能与现有 AOF 解析器不兼容的方式更改 AOF 格式。
aof-timestamp-enabled no