Redis持久化
Redis作为目前最常用的键值对缓存数据库,因其具有访问速度快而备受欢迎,而其极快的访问速度是基于数据都在内存中来达到的。但是我们并不能保证redis服务一直正常,如果数据仅仅存储于内存中,那么意外的宕机就会导致数据丢失,所以Redis提供了数据持久化功能,目的就是将内存中的数据保存到磁盘上,同时也要最大可能的不影响读写操作的性能。
Redis提供了RDB(redis Database)和AOF(Append Only File)两种持久化方式,默认开启了RDB方式,该模式会在Redis启动后,自动生成dump.rdb文件,默认在redis-server命令的目录下。
下面我们详细的介绍一下这两种持久化方式。
RDB(redis Database)
在仅开启RDB模式的情况下,Redis启动时,会先加载dump.rdb文件,将磁盘快照加载到Redis内存中,默认会在redis-server所在目录下查找dump.rbd文件,而当我们再启动时指定了redis.conf文件,那么则使用redis.conf文件中配置的dir
选项指定的dump.rdb文件路径。
RDB模式是将Redis内存中存储的数据全部以二进制的方式存储到磁盘上,就像是word文档的定时自动保存功能,防止数据丢失。
触发RDB持久化的方式很简单,大致有三种:
1:客户端发送save命令
当客户端向服务器发送save命令时,服务器会阻塞save命令只会的其他请求,直到数据同步完成。如果Redis内存中数据量太大,同步数据操作执行时间过长,而这期间Redis服务器会阻塞其他所有请求,所以,此命令和keys *
命令一样,不能在生产环境使用
2:客户端发送bgsave命令
bgsave命令和save命令功能一样,都是触发执行RDB持久化,不同的是当客户端发出bgsave命令时,Redis服务端会fork一个子进程来执行数据持久化,当内存中的数据全部持久化完成之后,子进程会自动退出。所以基于这种方式,主进程仍然可用继续接收其他请求,但是fork子进程的过程是同步的,也就是说在fork子进程的过程中,Redis服务器同样不能接收其他请求,所以如果fork子进程的过程耗费太长时间,仍然有阻塞其他客户端请求的情况发生
3:服务端自动触发
Redis在redis.conf配置文件中通过save参数指定触发RDB持久化的条件,该方式和bgsave一样,会fork一个子进程执行RDB持久化,但是如果设置的触发时间太短,则容易频繁的写入rdb文件,频率过高的话会严重影响服务器性能,但是时间设置太长则会有造成数据丢失的可能。
################################ SNAPSHOTTING ################################ # # Save the DB on disk: # # save <seconds> <changes> # # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # # In the example below the behaviour will be to save: # after 900 sec (15 min) if at least 1 key changed # after 300 sec (5 min) if at least 10 keys changed # after 60 sec if at least 10000 keys changed # # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000
save 900 1
:900s内如果有至少1条写命令,则触发RDB持久化
save 300 10
:300s内如果有至少10条写命令,则触发RDB持久化
save 60 10000
:60s内如果有至少10000条写命令,则触发RDB持久化
save ""
:关闭RDB持久化
AOF(Append Only File)
AOF方式在Redis中是默认未开启的,在开启AOF后,会将内容写入到appendonly.aof文件中,文件的内容是服务器接收到的所有对数据进行修改的命令集合,按照时间顺序追加到文件尾部,并且在故障恢复的时候,会优先读取appendonly.aof文件中的内容,因为aof的默认策略是每秒钟写入一次,所以当采用aof进行持久化的时候,最多也仅仅丢失一秒的数据。
配置信息:redis.conf文件中
随着服务运行时间越来越久,内存中的数据变更次数越来越多,会造成aof文件越来越大,当然我们可以在配置文件redis.conf中设置aof文件重写策略,默认当aof文件大小达到64mb且增长比例超过了之前是100%的时候进行重写,重写的规则是将内存中的数据的当前值全部以对应的set命令写入到新的aof文件中,比如当前aof文件100mb,重写之后80mb,那么只有当文件再次达到160mb(160>=80*2&&160>64)的时候才会再次进行重写。如果在AOF文件写入的过程中突然宕机,可能会导致aof文件损坏,我们可以使用redis-check-aof --fix命令来修复。
###### APPEND ONLY MODE ###### # 开启aof持久化 appendonly yes # aof文件名称,存储位置在dir参数指定的文件夹内 appendfilename "appendonly.aof" # appendfsync always # 每一次操作都做持久化 appendfsync everysec # 每一秒持久化一次 # appendfsync no # 不自动做持久化,手动触发 aof-load-truncated yes aof-use-rdb-preamble yes
AOF重写
AOF是采用文件追加的方式做持久化,这就无法避免文件会越来越大,所以Redis针对于这种情况,提供了aof文件rewrite机制,当aof文件超过redis.conf中配置的情况时,就会自动触发rewrite操作,只保留同一个key的最近的一条指令记录,且默认在rewrite的时候暂停aof持久化,我们也可以使用指令bgrewriteaof
手动的触发aof的rewrite。
# 在aof文件rewrite的时候不做持久化 no-appendfsync-on-rewrite no # 自动rewrite的比例 auto-aof-rewrite-percentage 100 # 自动rewrite的文件最小大小 auto-aof-rewrite-min-size 64mb
但是rewrite之后,aof文件的内容和rdb文件的格式一样了
打开redis.conf配置文件
# When rewriting the AOF file, Redis is able to use an RDB preamble in the # AOF file for faster rewrites and recoveries. When this option is turned # on the rewritten AOF file is composed of two different stanzas: # # [RDB file][AOF tail] # # When loading Redis recognizes that the AOF file starts with the "REDIS" # string and loads the prefixed RDB file, and continues loading the AOF # tail. aof-use-rdb-preamble yes
AOF在重写的时候,会使用优先RDB文件进行快速rewrite。那么如果我们想要AOF仍然保持指令级的重写,只需要将参数aof-use-rdb-preamble
修改为no
即可
两种方式的对比的优缺点
优点
RDB: 1:恢复备份速度快 2:最新全量数据备份,文件体积小,占用磁盘小 3:备份过程由子进程进行,对Redis主进程影响较小
AOF: 1:备份频繁,数据丢失的概率低 2: 文件内容可读性较高
缺点
RDB: 1:备份频率低,数据丢失概率高 2:使用不当会引起redis主进程阻塞 3: 数据量过大时,fork子进程也会发生阻塞 4: 子进程在执行过程中会耗费过多内存
AOF: 1:文件体积较大,占用磁盘空间较多 2:恢复数据速度慢 3:文件易损坏
转自:https://blog.csdn.net/luxiaoruo/article/details/107033291