[一]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)条件可以配置多个,条件和条件之间是或的关系



redis 保存配置文件 redis数据保存_redis 保存配置文件

 

==>用户执行SAVE或者BGSAVE命令

&手动执行SAVE命令

(1)当服务重启,手动迁移以及备份时,我们也需要手动执行快照操作

(2)当手动执行save命令时,redis同步进行快照操作,在快照执行的过程中会阻塞所有来自客户端的请求。

(3)当数据库中数据比较多的时候,这一过程会导致Redis较长时间不响应。所以要尽量避免在生产环境中使用这一个命令


redis 保存配置文件 redis数据保存_操作系统_02

 

&手动执行BGSAVE命令

(1)需要手动执行快照推荐使用BGSAVE命令

(2)BGSAVE命令可以在后台异步地执行快照操作,快照的同时服务器还可以继续响应来自客户端的请求。

(3)如果想知道快照是否完成,请执行LASTSAVE命令获取最近一次成功执行快照的时间。返回Unix时间戳


redis 保存配置文件 redis数据保存_数据_03



===>执行FLUSHALL命令

(1)当执行FLUSHALL命令时,redis会清除数据库中所有的数据。需要注意的是,不论清空数据库过程是否出发了自动快照条件,只要自动快照条件不为空,Redis就会执行一次快照。

(2)如果配置文件中没有设置自动快照的条件,执行FLUSHALL命令,不会执行快照,而是直接清空redis内存中的数据。

(2)执行FLUSHALL命令,底层是先触发了自动快照,自动快照完成,再清空数据库。

redis 保存配置文件 redis数据保存_redis_04

===>执行复制时


(1)设置主从模式时,Redis会在复制初始化时进行自动快照。


(2)当执行复制操作的时候,即使没有定义自动快照条件,并且没有手动执行快照操作。也会生成RDB快照文件


 

===>快照的过程


(1)Redis使用forx函数复制一份当前进程(父进程)的副本(子进程)


(2)父进程继续接受并处理客户端发来的命令,而子进程开始将内存中的数据写出硬盘的临时文件


(3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成


===>快照的原理。


redis 保存配置文件 redis数据保存_数据_05


(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秒往硬盘写一次数据。


  1. # appendfsync always   #每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用  
  2. appendfsync everysec     #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐  
  3. # appendfsync no    #完全依赖os,性能最好,持久化没保证  ,交由操作系统每30秒往硬盘刷写一次。


redis 保存配置文件 redis数据保存_数据_06


redis 保存配置文件 redis数据保存_操作系统_07