龙岗公司网站建设,平面设计和电商设计的区别,wordpress文章到微信,WordPress全局屏蔽谷歌Redis#xff1a;持久化 持久化RDBdump.rdb优缺点 AOF文件同步重写机制 混合持久化 持久化
虽然Redis是一个内存级别的数据库#xff0c;但是Redis也是有持久化的能力的。当系统崩溃时#xff0c;Redis就会被强制退出#xff0c;此时内存中的数据就会丢失。为了能够在下次… Redis持久化 持久化RDBdump.rdb优缺点 AOF文件同步重写机制 混合持久化 持久化
虽然Redis是一个内存级别的数据库但是Redis也是有持久化的能力的。当系统崩溃时Redis就会被强制退出此时内存中的数据就会丢失。为了能够在下次重启时恢复数据Redis会把数据在硬盘中备份一份也就是说Redis持久化的目的不是为了保存更多的数据而是为了恢复数据。
Redis有两种处理持久化的方式RDB和AOF两者的区别可以简单理解如下
RDB定期同步内存与硬盘的数据AOF只要内存的数据被修改立刻同步到硬盘
本博客就基于这两种方式讲解Redis的持久化。 RDB
RDB全称Redis DataBase用于持久化Redis中的数据其会定期把Redis的数据保存下来这份数据就称为一个快照随后存储到硬盘中。
除了等到指定时间让其自动生成快照RDB还支持程序员通过指令生成快照
save此时Redis会立刻生成快照但是由于Redis是单线程模型其它的所有操作都会被阻塞bgsaveRedis立刻生成快照但是是在后台运行不会影响其他操作
在实际开发中一般都使用bgsave而不是save。此时就有疑问了Redis不是单线程模型吗如何做到在后台生成快照而不影响其他操作的
其实Redis在这使用了多进程的模式流程如下 当用户执行bgsave此时父进程通过fork创建子进程随后子进程去完成快照生成父进程继续响应其他命令。当子进程持久化完毕就给父进程发送信号通知父进程。如果父进程在收到信号之前收到了来自其他用户的bgsave命令此时不做处理直接返回因为已经有子进程正在进行持久化了此时多个bgsave命令只执行一次持久化。
此处的fork是Linux的一个系统调用因为Redis本身就只支持在Linux上运行所以就直接用Linux的系统调用了。当执行fork时会把父进程拷贝一份一模一样的出来比如进程地址空间页表PCB等等都会拷贝一份。当然也包括内存中的数据此时子进程就可以拿到Redis原先的所有数据进而生成快照
但是要是把变量全部拷贝一份不会很浪费空间吗其实这里用了一个写时拷贝子进程和父进程刚拷贝完其实是使用相同的内存数据当父子进程任何一方进行了写入才会发生拷贝。所以其实最后子进程几乎没有发生多少拷贝又可以看到父进程的数据进而生成快照。 dump.rdb
那么RDB文件到底在哪里
打开Redis的配置文件/etc/redis/redis.conf可以找到以下内容
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the dbfilename configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /var/lib/redisdir后的路径就是存储RDB文件的存储位置。在该目录下会有一个dump.rdb文件这就是生成的快照。这个文件内部存储的是二进制如果直接查看会得到乱码。
并且这个数据不是简单的二进制存储还会进行压缩提高存储效率。
那么RDB的文件多久更新一次这也在配置文件中
# Save the DB to disk.
#
# save seconds changes [seconds changes ...]
#
# Redis will save the DB if the given number of seconds elapsed and it
# surpassed the given number of write operations against the DB.
#
# Snapshotting can be completely disabled with a single empty string argument
# as in following example:
#
# save
#
# Unless specified otherwise, by default Redis will save the DB:
# * After 3600 seconds (an hour) if at least 1 change was performed
# * After 300 seconds (5 minutes) if at least 100 changes were performed
# * After 60 seconds if at least 10000 changes were performed
#
# You can set these explicitly by uncommenting the following line.save 3600 1 300 100 60 10000找到Save the DB to disk.字段这就是RDB的自动保存机制配置文件的格式为
save seconds changes [seconds changes ...]只要在seconds秒内到达了changes次数的修改那么就会更新文件比如save 3600 1 300 100 60 10000的意思就是
如果在3600 s内修改了1次数据3600秒后更新dump.rdb如果在300 s内修改了100次数据300秒后更新dump.rdb如果在60 s内修改了10000次数据60秒后更新dump.rdb
另外的如果配置save “”也就是加一个空字符串相当于禁止通过该方式自动更新。
除此之外Redis还有一些其他方式也会自动生成快照 0
通过配置文件的save属性定期生成快照Redis正常关闭时进行主从复制时执行flushall指令时 优缺点
优点
因为RDB会把数据进行压缩所以RDB的存储效率很高占用的硬盘资源少通过RDB恢复效率比AOF快很多
缺点
每次生成RDB都要额外创建一个子进程这需要消耗额外的资源执行 AOF
AOF全称Append Of File其保存的是Redis的每一个具体操作类似于MySQL的保存方式。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只需要把appendonly后面的值改为yes就可以打开这个模式了一旦这个模式打开那么RDB模式就会失效。
修改配置文件后要重启redis服务端
service redis-server restart在该字段的后面紧跟着AOF的文件存储位置
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打开.aof文件可以看到以下格式的语句
*2^M
$6^M
SELECT^M
$1^M
0^M
*8^M
$4^M
XADD^M
$58^M
pcp:values:series:2756fc65948d7070a2a980759d7e4267d49ccef4^M
$6^M
MAXLEN^M可以看到很多认识指令比如SELECTXADDMAXLEN。
那么AOF模式下每次操作都要把指令保存到硬盘这种IO操作是非常低效的那不是会极大的降低Redis的执行效率
其实Redis这里采用了一个缓冲的策略每次操作都把指令保存到aof_buf缓冲区中这是一个内存区域对内存的读写非常高效当aof_buf内部的数据量达到一定值才会写入硬盘。这样就减少了IO次数保证了Redis的效率。 文件同步
将aof_buf的数据写入到硬盘的文件称为文件同步。文件同步有多种策略如果同步的频率高了那么Redis的效率就会低但是如果同步的频率太低了由于缓冲区在内存中一旦程序崩溃丢失的数据就更多。因此Redis给用户提供了多个级别让用户自己取舍。
在配置文件中可以设置同步频率
# 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 noappendfsync用于设置同步的频率其中频率是always everysec no默认策略是everysec每秒刷新一次。
always每次写入都进行同步everysec每秒钟同步一次no依据操作系统的同步策略但是这个策略是不可控的 重写机制
当写入的数据多此时.aof生成的文件就会很大而且会出现冗余的问题比如以下操作
set key1 111
set key1 222
set key1 333
set key1 444由于第四次写入覆盖了前三次的值那么前三次操作就都是无效的如果Redis真的每一条数据都保存下来那么这个案例就多浪费了 3/4的空间。
为此Redis会对.aof文件进行重写剔除文件中的冗余操作合并一些操作从而减小.aof文件的大小。
重写机制也分为手动触发和自动触发如果想要手动触发输入指令bgrewriteaof。
自动触发要参照两个参数
auto-aof-min-size触发重写的最小大小只有.aof超过该大小才触发重写默认为64MBauto-aof-rewrite-percentage表示.aof当前占用的大小相比于上次重写增加的比例
重写流程如下 和之前的bgsave类似重写也是通过创建子进程完成的子进程将当前内存中的所有数据重写写入一个新的.aof文件然后直接覆盖之前的.aof即可。
也就是说重写的过程并不是通过复杂的算法检测哪些内容重复哪些可以合并。而是直接看当前的最终状态是什么当前有什么就写入什么。
此处有一个步骤3.1在子进程写入的过程中父进程也会接收到数据此时父进程会把数据写入到旧的.aof文件中。这主要是为了防止在重写.aof的过程中崩溃一旦父子进程同时崩溃那么就只能通过旧的.aof进行恢复如果重写过程中不对旧的.aof更新那么重写这段时间的数据就会丢失。
另外的由于子进程创建时只保存创建那一瞬间的父进程的内存状态此时父进程接收到的后续的数据子进程是看不到的。所以父进程还要通过3.2将数据写入一个中间缓存aof_rewrite_buf将当前的新数据保存下来。
直到5.1子进程完成写入给父进程发送一个信号父进程就知道子进程写入完成了。随后通过5.2把子进程重写期间收到的数据写入到新的.aof文件最后再完成5.3文件的覆盖。 混合持久化
如果观察appendonlydir目录会找到多个文件 这内部同时包含.aof和.rdb文件这因为Redis采用了混合持久化的方式。
由于.aof文件是文本文件加载速度很慢为了提高AOF模式的加载速度于是把.rdb的二进制存储模式引入了进来。每次进行重写的时候会把当前的快照放到.rdb内部以二进制的格式存储。而再重写之后到来的数据存储.aof文件中用于保持实时更新。
也就是说混合持久化综合了两者的优点采用.rdb存储旧数据提高加载效率。而,aof存储新来的数据保证数据存储的及时性。每当重写时把当前整个Redis的快照放到.rdb而.aof存储重写期间到来的数据。