redis之(十二)redis数据的持久化
[一]redis的数据为什么要持久化
--->redis的存取数据性能高,是由于将所有数据都存储在内存中。当redis重启的时候,存储在内存中的数据就容易丢失。
--->把redis作为数据库使用。
--->把redis作为缓存服务器,但缓存被穿透后会对性能造成很大的影响,所有缓存同时失效会导致缓存雪崩,从而使服务无法响应。
--->因此我们希望redis能将数据从内存中以某种形式同步到硬盘,使得重启后可以根据硬盘中的纪录恢复数据,这一过程就叫做持久化
[二]redis的持久化,支持两种方式。
--->第一种:RDB方式:前者根据指定的规则,“定时”将内存中的数据存储在硬盘上。
--->第二种:AOF方式:每次执行命令后,将命令本身纪录下来。
--->两种持久化的方式可以单独使用其中一种,单更多情况下是二者结合使用
[三]RDB方式
--->前者根据指定的规则,“定时”将内存中的数据存储在硬盘上。
--->RDB方式的持久化是通过快照完成的,当符合一定条件时,redis会自动将内存中的所有数据生成一份副本并存储在硬盘上。这个过程就叫做:快照。
--->如果redis突然宕机,RDB快照只能恢复到最后一次快照的数据,而不能恢复到宕机前最后一刻的数据。因此要配合使用AOF方式进行数据持久化。
--->redis会在以下集中情况对数据进行快照。
(1)根据配置规则进行快照。
(2)用户执行SAVE或BGSAVE。
(3)执行FLUSHALL命令。
(4)执行复制时。
==>用户配置规则快照
(1)快照条件可以由用户在配置文件中自定义。由两个参数构成:时间窗口M和改动键的个数。
(2)意思就是每当时间M内被更改的键的个数大于N的时候,即符合自动生成快照。
(3)格式 save [seconds] [changes]
(4)条件可以配置多个,条件和条件之间是或的关系
==>用户执行SAVE或者BGSAVE命令
&手动执行SAVE命令
(1)当服务重启,手动迁移以及备份时,我们也需要手动执行快照操作
(2)当手动执行save命令时,redis同步进行快照操作,在快照执行的过程中会阻塞所有来自客户端的请求。
(3)当数据库中数据比较多的时候,这一过程会导致Redis较长时间不响应。所以要尽量避免在生产环境中使用这一个命令
&手动执行BGSAVE命令
(1)需要手动执行快照推荐使用BGSAVE命令
(2)BGSAVE命令可以在后台异步地执行快照操作,快照的同时服务器还可以继续响应来自客户端的请求。
(3)如果想知道快照是否完成,请执行LASTSAVE命令获取最近一次成功执行快照的时间。返回Unix时间戳
===>执行FLUSHALL命令
(1)当执行FLUSHALL命令时,redis会清除数据库中所有的数据。需要注意的是,不论清空数据库过程是否出发了自动快照条件,只要自动快照条件不为空,Redis就会执行一次快照。
(2)如果配置文件中没有设置自动快照的条件,执行FLUSHALL命令,不会执行快照,而是直接清空redis内存中的数据。
(2)执行FLUSHALL命令,底层是先触发了自动快照,自动快照完成,再清空数据库。
===>执行复制时
(1)设置主从模式时,Redis会在复制初始化时进行自动快照。
(2)当执行复制操作的时候,即使没有定义自动快照条件,并且没有手动执行快照操作。也会生成RDB快照文件
===>快照的过程
(1)Redis使用forx函数复制一份当前进程(父进程)的副本(子进程)
(2)父进程继续接受并处理客户端发来的命令,而子进程开始将内存中的数据写出硬盘的临时文件
(3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成
===>快照的原理。
(1)快照执行fork函数进行快照中,操作系统(类unix)会采用写时复制策略(copy-on-write).开启的子进程和父进程共享redis存储的数据。子进程(快照进程)往硬盘的临时文件里写数据。
(2)在fork函数执行中,有客户端想修改数据,操作系统则会对要修改的数据复制一份用于客户端修改。
(3)因此在快照时,redis的占用内存不会翻倍,但修改的数据块较多的时候,就会使得占用内存暴增,甚至翻倍,超过物理机的内存。
(4)向物理机申请额外内存。可通过修改操作系统配置文件。修改/etc/sysctl.conf文件,在文件中加入vm.overcommit_memory=1,然后重启系统或者执行sysct1 vm。overcommit_memory=1.当物理内存满的时候,liunx系统允许应用程序申请超过可用内存(物理内存+交换分区)的空间。
[四]AOF方式
--->每次执行命令后,将命令本身纪录下来。
--->当使用Redis存储非临时数据时,一般需要打开AOF持久化来降低进程中止导致的数据丢失。
--->AOF可以将Redis执行的每一条命令追加到硬盘文件中。这一过程,显然会降低redis的性能,单大部分情况下这个影响是可以接受的。例外使用较快的硬盘可以提高AOF的性能
--->默认情况下Redis并没有开启AOF(append only file)方式的持久化,可以修改配置文件参数为:appendonly yes. 生成的持久化文件名字为 appendfilename "appendonly.aof"
---> AOF持久化文件的存储路径和RDB的文件路径一样,通过配置文件中的dir参数配置
--->为了防止AOF文件的过大和记录的命令冗余。每当达到一定条件的时候,redis就会自动重写AOF文件,这个条件在配置文件中可以配置
#auto-aof-rewrite-percentage 100 #当目前的aof文件大小超过上一次重写时aof文件大小的百分之多少时会再次重写。
#auto-aof-rewrite-min-size 64mb #允许重写的最小aof文件的大小
--->操作系统存在缓存机制,其实每次要写往硬盘的数据,其实都是先写入操作系统缓存。然后操作系统的缓存每30秒往硬盘写一次数据。
- # appendfsync always #每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
- appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
- # appendfsync no #完全依赖os,性能最好,持久化没保证 ,交由操作系统每30秒往硬盘刷写一次。