Redis 持久化

版权声明:欢迎转载,转载请说明出处https://csdn.yanxml.com。大数据Github项目地址https://github.com/SeanYanxml/bigdata。 https://blog.csdn.net/u010416101/article/details/79690065

前言

Redis主要作为一个内存管理器,是否具有持久话策略?答案是肯定的。
Redis的持久化策略主要包括2种:

  • 全量策略 bgsave
  • 增量策略 aof

全量策略

关于持久化策略的文件主要保存在redis.conf文件内,其主要配置信息如下所示:

################################ 快照  #################################    
#    
# Save the DB on disk:保存数据库到磁盘    
#    
#   save <秒> <更新>    
#    
#   如果指定的秒数和数据库写操作次数都满足了就将数据库保存。    
#    
#   下面是保存操作的实例:    
#   900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)    
#   300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)    
#   60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)    
#    
#   注释:注释掉“save”这一行配置项就可以让保存数据库功能失效。    
#    
#   你也可以通过增加一个只有一个空字符串的配置项(如下面的实例)来去掉前面的“save”配置。    
#    
#   save ""    

save 900 1    
save 300 10    
save 60 10000    

#在默认情况下,如果RDB快照持久化操作被激活(至少一个条件被激活)并且持久化操作失败,Redis则会停止接受更新操作。    
#这样会让用户了解到数据没有被正确的存储到磁盘上。否则没人会注意到这个问题,可能会造成灾难。    
#    
#如果后台存储(持久化)操作进程再次工作,Redis会自动允许更新操作。    
#    
#然而,如果你已经恰当的配置了对Redis服务器的监视和备份,你也许想关掉这项功能。    
#如此一来即使后台保存操作出错,redis也仍然可以继续像平常一样工作。    
stop-writes-on-bgsave-error yes    

#是否在导出.rdb数据库文件的时候采用LZF压缩字符串和对象?    
#默认情况下总是设置成‘yes’, 他看起来是一把双刃剑。    
#如果你想在存储的子进程中节省一些CPU就设置成'no',    
#但是这样如果你的kye/value是可压缩的,你的到处数据接就会很大。    
rdbcompression yes    

#从版本RDB版本5开始,一个CRC64的校验就被放在了文件末尾。    
#这会让格式更加耐攻击,但是当存储或者加载rbd文件的时候会有一个10%左右的性能下降,    
#所以,为了达到性能的最大化,你可以关掉这个配置项。    
#    
#没有校验的RDB文件会有一个0校验位,来告诉加载代码跳过校验检查。    
rdbchecksum yes    

# 导出数据库的文件名称    
dbfilename dump.rdb    

# 工作目录    
#    
# 导出的数据库会被写入这个目录,文件名就是上面'dbfilename'配置项指定的文件名。    
#     
# 只增的文件也会在这个目录创建(这句话没看明白)    
#     
# 注意你一定要在这个配置一个工作目录,而不是文件名称。    
dir ./   

每次会定时备份数据库dump.rdb内的内容。


增量策略

aof,增量备份策略。配置文件如下所示:

    ############################## APPEND ONLY MODE ###############################  
    # 是否开启AOF,默认关闭(no)  
    appendonly yes  

    # 指定 AOF 文件名  
    appendfilename appendonly.aof  

    # Redis支持三种不同的刷写模式:  
    # appendfsync always #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。  
    appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。  
    # appendfsync no     #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。  

    #在日志重写时,不进行命令追加操作,而只是将其放在缓冲区里,避免与命令的追加造成DISK IO上的冲突。  
    #设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no  
    no-appendfsync-on-rewrite no   

    #当前AOF文件大小是上次日志重写得到AOF文件大小的二倍时,自动启动新的日志重写过程。  
    auto-aof-rewrite-percentage 100  

    #当前AOF文件启动新的日志重写过程的最小值,避免刚刚启动Reids时由于文件尺寸较小导致频繁的重写。  
    auto-aof-rewrite-min-size 64mb  

Question

Redis的备份策略主要分为全量备份与增量备份2种。

就全量备份而言,主要设置的参数是存储在什么地方,什么样的情况下进行备份操作。(例如save 900 1 save 300 10 save 60 10000,900秒1次更改,300表10次,60秒10000次更改等)

就增量备份而言,普遍设置是1秒更新一次,有着更为全面的1次更改更新一次。(appendfsync always & appendfsync everysec)

需要特别注意的是,备份策略的设置对于redis的性能与Redis的高可用性有着极大的影响。所以,常常对于这个方面需要根据需要做出一定的权衡。

  • Q1: Redis的持久话策略,重启时过程?
    全量(bgsave)与增量(aof),重启先使用bgsve全量更新,后使用aof更新最近的更改。

  • Q2: Redis突然断电,会如何?
    全量会根据更新策略丢失一部分数据,增量也有可能会丢失,看更新的策略。(如果是everysync,每秒备份一次,会丢失上一秒未备份的数据。)

  • Q3: Redis的aof与bgsave是如何做到的?
    不知道。汗~

    你给出两个词汇就可以了,fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。

  • Q4: aof与rdb物理文件结构?

# aof (增量)每次的更改动作信息
*8
$5
HMSET
$31
out_local_OCTOPUS_worktime-2018
$8
holidays
$203
["20180429 - 20180501##五一劳动节##法定节假日","20180616 - 20180618##端午节##法定节假日","20180922-20180924##中秋节##法定节假日","20181001-20181007##国庆节##法定节假日"]
$9
workHours
$16
["09:00- 17:00"]
$14
adjustWorkDays
$102
["20180428##周六因劳动节调整为工作日","20180929-20180930##因国庆节调整为工作日"]
*2
$3
DEL
$31
out_local_OCTOPUS_worktime-2018
*8
$5
HMSET
$31
out_local_OCTOPUS_worktime-2018
$9
workHours
$16
["09:00- 17:00"]
$8
holidays
$203
["20180429 - 20180501##五一劳动节##法定节假日","20180616 - 20180618##端午节##法定节假日","20180922-20180924##中秋节##法定节假日","20181001-20181007##国庆节##法定节假日"]
$14
adjustWorkDays
$102
["20180428##周六因劳动节调整为工作日","20180929-20180930##因国庆节调整为工作日"]

# rdb (全量)二进制文件 直接查看为乱码
��+D� m����/M�ulC=w�effe+�v�q   �
Ǟ@JH�b` ��*]�5cu�� ��3E"a"sh/�‹���]C.�g���6!��O`Ѐ
                                               �����0�I����s� �
 p@S��!��<�!l�� ���     �i-��0�� WA"�h(�`� "�T�Rea0Q@'%�.� ��,�MwInWork_(($*v<� ) {C�D@G$sj�ye8&j+<�be��e<"* meansj��X�.@C�^�?To��Bc*"X,=B��˂0�-�!��,��A"b <�\�5��N+�al�a�
            ��
*u
定时回吐
�s�U ��:"�"O��S����Sz�P$�"�/�so~96mC0tes/X*!+`�i�g�za�Qz��:O�Id $�0(eg7:��   Result.�U��P-�� ��                        p@/$^�meter�������b�Column��:Т�[���9: ����(�p�]*�reSqlCW��_Y� '"4E��                                                                                        �==F��!@$obj)�Clas�8ڀ_c@
@#"'��@
   k��  �`7=�Y��a� +�[�
�,,db�Condw-#�� �9���

out_local_OCTOPUS_workTimeFrom� OCTOPUS_out_local_workTimeTo�
  • 注意: 知乎上看了一个问题。当Redis内的数据大于内存的时候,有可能会导致数据异常,以至于丢数据~所以Redis内数据的大小一定要 小于内存的容量。

redis做持久化数据的数据库时,当保存的数据量大于可用内存的时候,还可用吗?redis做缓存有LRU机制
redis可用,但lru机制 会丢数据

Reference

[1]. redis的持久化:RDB的配置和原理
[2]. redis的持久化:AOF的配置和原理
[3]. 天下无难试之Redis面试题刁难大全
[4]. redis做持久化数据的数据库时,当保存的数据量大于可用内存的时候,还可用吗?

没有更多推荐了,返回首页