• Reids5 持久化


    持久化的意思就是把缓存中的数据保存到磁盘中,保证重启redis server之后数据不丢失,以及初始化redis server数据

     redis5有三种持久化方式一种 是保存缓存数据结果(RDB) ,另一种是保存缓存执行的命令(AOF) 还有就是混合持久化

    RDB

     

    默认是开启的,这是三个匹配规则,意思就是  

    #   save ""    (关闭rdb持久化,redis注释是#)
    save 900 1      (900秒内只要进行一次修改操作,那就进行持久化)
    save 300 10     (300秒内只要进行10次修改操作,那就进行持久化)
    save 60 10000   (60秒内只要进行1万次修改操作就会进行持久化)

    如果想关闭就设置  save " "

    其他的配置

    dbfilename dump.rdb    设置持久化保存的文件
    dir ./     设置保存的目录

     手动触发持久化

    比较我的缓存中存入了一条用户登录的session状态,那么我想让它立刻保存下来不丢失

    save

    save 是阻塞式持久化,如果说当前set了很多bigkey 那么就会越耗时

    bgsave

    bgsave是fork 一个子进程去进行持久化,相当于复制了自己的替身去工作,但是如果redis server 现在已经用了大概10G的内存,替身并不会复制原本的物理内存空间,大约会复制20MB 的内存空间

    linux 有写时复制机制(copy-on-write) 相当于是共享了数据的内存,window上就不知道怎么实现的了

    所以不会阻塞,正常情况下fork耗时应该是每G 20毫秒

    可以通过 info stats 查看最后一次fork 耗时  

    info stats

    latest_fork_usec:1199   单位是微妙, 一毫秒=1000微秒

    建议设置redis server 运行最大使用的内存,以免fork 太多无用数据

    AOF

    appendonly yes  (设置yes 为开启 no为关闭)
    
    appendfilename "appendonly.aof"   (保存的文件名)

     对执行修改的命令进行保存,如果开启了将会不断的追加命令进入文件

    这就是个aof文件的构造,里面是一些命令

    *2
    $6
    SELECT
    $1
    0
    *3
    $3
    set
    $5
    hello
    $4
    word
    *3
    $3
    set
    $3
    php
    $3
    jav
    View Code

     三种持久化保存的方式

    appendfsync always  

    命令写入 aof的缓冲区 然后调用系统 fsync 操作同步到aof文件种,完成了立刻返回
    每次写入命令都会进行同步,性能是可想而知的(非常不建议配置)

    appendfsync everysec

    命令写入aof缓冲区之后,redis server 会每一秒进行一次同步,这样即使你突然宕机了数据也只丢失了一秒钟的,其实我觉得redis 可以加个配置自定义秒数
    是建议的配置项目
    appendfsync no

    命令写入aof缓冲区之后,redis 不对其进行同步,而是交给操作系统来进行同步(多长时间同步一次不可控)


    AOF追加阻塞


    使用everysec进行同步的时候流程如下

    reids-server 主线程负责把数据写入到AOF缓冲区,然后由一个新的线程去同步,当然这不是fork,新线程每秒钟会进行一次同步操作
    主线程会对比上次同步的时间,如果同步时间在两秒钟之内,则会继续走,如果大于两秒则会阻塞,等子线程执行完成,
    所以说丢数据的话可能会丢失两秒钟,
    导致这种情况的原因就是同步过慢,磁盘是主要问题
    每当阻塞了
    aof_delayed_fsync:0 这个就会+1

    使用iotop命令定位磁盘问题所在




    重写机制

    当aof文件越来越大的时候,我们就需要给文件瘦瘦身了
    比如
    set hello 123
    set hello java
    这个两段命令,第一个其实就已经不在需要了,只保留第二段即可
    还有比如
    set php 123
    set java 231
    就会变成
    mset php 123 java 123
    aof文件瘦身了之后文件占的磁盘变小了,加载的时候也会变快


    手动瘦身
    
    
    bgrewriteaof
    
    
    
    这和bgsave 是一样的流程 fork 进程然后再进行持久化


    自动瘦身

      auto-aof-rewrite-percentage 100 体积达到上次瘦身之后的百分之多少就开始再次瘦身,默认100% 那就是上次的两倍
      auto-aof-rewrite-min-size 64mb  aof文件重新的最小体积,就是aof达到64mb才会进行瘦身

    自动瘦身的代码可以写为

    当前AOF文件小 > AOF瘦身最小值  && (    当前AOF文件大小  - 上次瘦身后AOF文件大小 ) / 上次AOF瘦身后大小 >= 瘦身百分比

               

    如果上次瘦身之后的文件大小为1MB 那么触发这个百分比瘦身的条件 当前AOF就得是2MB   (2-1)/1 =1  1对应百分比就是100%  

     

    AOF 一些参数(文件大小都是字节B) 1KB=1000B

    aof_current_size: 1232 当前AOF文件大小
    
    aof_base_size:22  最近一次重写后AOF的大小
    
    aof_pending_rewrite:0 是否有AOF操作在等待执行。
    
    aof_buffer_length:0 AOF buffer的大小
    
    aof_rewrite_buffer_length:0 AOF重写buffer的大小。
    
    aof_pending_bio_fsync:0 在等待执行的fsync操作的数量。
    
    aof_delayed_fsync:0   Fsync操作延迟执行的次数。

    aof_rewrite_in_progress:0 AOF重写子进程是否在运行

    rdb_bgsave_in_progress:0 bgsave 子进程是否在运行
    aof_rewrite_scheduled:1   是否预定了AOF重写服务  
    
    
    自动瘦身采取的也是fork 子进程来进行写入磁盘

    是否预定AOF瘦身服务

    就是当手动执行aof瘦身重写的时候,发现哎呀 原来RDB也在进行磁盘同步,所以我等等吧,等它执行完再执行

    redis中的代码

    void bgrewriteaofCommand(redisClient *c) {
    
        // 不能重复运行 BGREWRITEAOF
        if (server.aof_child_pid != -1) {
            addReplyError(c,"Background append only file rewriting already in progress");
    
        // 如果正在执行 BGSAVE ,那么预定 BGREWRITEAOF    
        // 等 BGSAVE 完成之后, BGREWRITEAOF 就会开始执行
        } else if (server.rdb_child_pid != -1) {
            server.aof_rewrite_scheduled = 1;
            addReplyStatus(c,"Background append only file rewriting scheduled");
    
        // 执行 BGREWRITEAOF
        } else if (rewriteAppendOnlyFileBackground() == REDIS_OK) {
            addReplyStatus(c,"Background append only file rewriting started");
    
        } else {
            addReply(c,shared.err);
        }
    }
    View Code

    重写的时候的流程操作



     

    重启加载数据

     流程图

     如果AOF文件损坏的话可能会启动失败,但是可以使用redis-check-aof 工具去修复它,但记得先备份

    redis-check-aof --fix

    如果是从其他服务器上拷贝过来的AOF文件和RDB文件

    首先停止确保新机器的AOF是开启的,然后停止redis server  把AOF文件考到指定的目录,然后启动,数据就来了,

    如果不同的版本的话,还是建议使用redis 数据同步工具 比如 https://github.com/alibaba/RedisShake

         混合持久化

     顾名思义就是将两种持久化方式合在一起

     开启方式

    aof- use- rdb- preamble yes

    混合就是将AOF重写数据重写成RDB格式,然后有新的数据写入的时候再append AOF文件中,

    就是一半RDB数据,一半AOF追加的命令,这波操作真的骚 

    实践一下

     先写入几条数据,然后手动重写数据,再写入几条数据,最后再看文件的数据

    127.0.0.1:6380> set hello word
    OK
    127.0.0.1:6380> set php jav
    OK
    127.0.0.1:6380> keys *
    1) "php"
    2) "hello"
    127.0.0.1:6380> keys *
    1) "php"
    2) "hello"
    127.0.0.1:6380> keys *
    (empty list or set)
    127.0.0.1:6380> keys *
    (empty list or set)
    127.0.0.1:6380> set java php
    OK
    127.0.0.1:6380> set qq 123
    OK
    127.0.0.1:6380> set ss hhh
    OK
    127.0.0.1:6380> bgrewriteaof
    Background append only file rewriting started
    127.0.0.1:6380> sadd wwad asdf asf
    (integer) 2
    127.0.0.1:6380> zadd adad 22 asd 33 asdads
    (integer) 2
    127.0.0.1:6380>
    [wl@YMH redis-5.0.5]$ od -c appendonly.aof
    0000000   R   E   D   I   S   0   0   0   9 372  	   r   e   d   i   s
    0000020   -   v   e   r 005   5   .   0   .   5 372  
       r   e   d   i
    0000040   s   -   b   i   t   s 300   @ 372 005   c   t   i   m   e 302
    0000060  
       W   E   ^ 372     u   s   e   d   -   m   e   m 302   0
    0000100 006  
      0 372  f   a   o   f   -   p   r   e   a   m   b   l
    0000120   e 300 001 376  0 373 003  0  0 002   q   q 300   {  0 004
    0000140   j   a   v   a 003   p   h   p  0 002   s   s 003   h   h   h
    0000160 377   l 002 300 005 253 265 260   `   *   2  
      
       $   6  
    0000200  
       S   E   L   E   C   T  
      
       $   1  
      
       0  
      
    
    0000220   *   4  
      
       $   4  
      
       s   a   d   d  
      
       $   4
    0000240  
      
       w   w   a   d  
      
       $   4  
      
       a   s   d   f
    0000260  
      
       $   3  
      
       a   s   f  
      
       *   6  
      
       $
    0000300   4  
      
       z   a   d   d  
      
       $   4  
      
       a   d   a
    0000320   d  
      
       $   2  
      
       2   2  
      
       $   3  
      
       a
    0000340   s   d  
      
       $   2  
      
       3   3  
      
       $   6  
      
    
    0000360   a   s   d   a   d   s  
      
    
    0000370
    View Code

     混合持久化的加载速度是远远高于AOF的,加载的时候先读取文件中第一面的RDB二进制数据,再读取命令数据

    现在混合持久化已经是默认打开的了,优秀

    !!

  • 相关阅读:
    第五次博客作业
    第三次博客作业
    个人简介
    实验三
    实验二
    实验一
    《构建之法》心得体会
    第三次博客园作业
    软件测试实验二
    个人简历
  • 原文地址:https://www.cnblogs.com/wlphp/p/12302929.html
Copyright © 2020-2023  润新知