redis——持久化

拓展:

内存存储器属于DRAM(动态随机存取存储器),DRAM采用电荷存储信息,是易失性存储器,断电丢失信息。

磁盘属于ROM,采用存储介质存储信息,是非易失性存储器,断电不会丢失信息。

持久化就是将内存中易失性的数据刻写到磁盘中的存储介质中,保证断电后也能够长久保存。

Redis持久化的两种方式:RDB快照与AOF日志

一、RDB——快照

1、原理

①fork一个子进程生成快照。由于Redis是单线程的,同时处理请求和生成快照,会严重影响处理请求的效率,所以在进行RDB持久化时会调用glibc的fork函数产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端读写请求。子进程会生成一个临时快照文件,当RDB结束时,会替换原来的快照文件dump.rdb

②COW写时复制策略。fork的子进程刚刚产生时,和父进程共享内存;当子进程生成快照的同时,如果父进程接受写请求,需要对数据进行修改时,就会复制需要修改数据所在的页(内存管理方式——页式存储,1页4KB),然后父进程在复制页上修改,子进程根据原来的页生成快照。理论上不会超过原来内存的两倍,redis中冷数据比例较高,远达不到两倍。

2、RDB的时机

①调用指令SAVE与BGSAVE时,会生成快照。区别在于BGSAVE会fork子进程,子进程执行RDB工作;SAVE不会fork子进程,由主进程执行RDB工作(严重降低请求效率)。

②调用shutdown时如果没有开启AOF日志持久化,会触发RDB持久化。

③调用flushall清除所有缓存时,也会触发RDB持久化,此时RDB是空的。

3、RDB的相关配置

 启动时的配置文件redis.conf

①自动触发RDB:仅利用redis的缓存功能时,可写死save "" 生成空的rdb文件。

save 900 1        //每900秒内至少有一个key值变化,默认BGSAVE触发RDB
save 300 10      //每900秒内至少有一个key值变化,默认BGSAVE触发RDB
save 60 10000  //每900秒内至少有一个key值变化,默认BGSAVE触发RDB

②stop-writes-on-bgsave-error:当BGSAVE触发RDB报错时是否停止写操作,提醒开发人员redisRDB持久化出错了。

 ③rdbcompression:生成的dump.rdb文件是否压缩

 ④rdbchecksum :dump.rdb文件生成后是否校验准确性

 ⑤dbfilename:生成的持久化文件名称,默认dump.rdb

 ⑥dir:生成持久化文件路径,也是rdb启动时读取文件目录

二、AOF——日志

RDB快照是全量备份,AOF日志是连续的增量备份。

1、原理

①redis在接收到客户端写操作指令后,进行参数校验、逻辑处理,如果没问题,就立即将该指令文本存储到AOF日志中,即先执行指令后将日志存盘。

②fsync : 增量备份,所以需要不停的对AOF文件进行写操作,一般的写操作,内存将该存储的数据直接分配到一个内存缓存区,然后由操作系统异步将数据写入回磁盘,如果机器突然宕机了,可能导致缓存区数据没有写回磁盘,导致AOF日志内容丢失。Linux的glibc提供fsync函数强制将内存缓存区的数据写到磁盘,将写操作变成一个同步操作。同步IO操作会导致磁盘读写速度拖累内存读写处理速度,很慢,如果redis执行一条指令fsync一次,那么就跟MySQL等磁盘数据库差不多,丢失内存数据库的高性能优势。所以一般生产环境每个1s左右执行一次fsync操作。异步IO——>同步IO:写入缓存区--等待--写回磁盘——> 写入缓存区-->强制直接写回磁盘不需等待。

2、AOF日志文件重写

AOF是增量备份,所以日志文件会越来越大,AOF重启会非常耗时,需要对AOF日志重写。

redis提供了bgrewriteaof指令用于对AOF日志进行瘦身,原理开辟一个子进程对内存进行遍历,转换成一系列redis的操作指令,序列化到一个新的AOF日志文件中,代替旧的AOF日志文件。

rpush list  1  // 1
rpush list  2  // 1 2
rpush list  3  // 1 2
rpush list  4  // 1 2 3 4
lpop             // 2 3 4
//会根据内存实际数据2 3 4,将上面一系列指令重写
rpush list 2 3 4 

3、AOF的时机

每个写操作都会触发AOF

但由于内存缓存和fsync执行频率受到限制,一般生产机器中,通常是1s左右执行一次fsync,即可能会导致1s左右的日志丢失。

4、AOF的相关配置

①appendonly : 是否启用AOF持久化,默认不启用

 ②appendfilename : AOF日志名称

 ③appendfsync :fsync发生频率,默认每秒一次;另有总是和不执行

 ④no-appendfsync-on-rewrite:后台进程是否同步,rdb的save与aof的fsync同步,即save时会阻塞fsync,fsync时会阻塞save

 ⑤auto-aof-rewrite-percentage :自动触发AOF重写的条件 :与上一次重写文件大小的比值

     auto-aof-rewrite-min-size  : 自动触发AOF重写的条件:文件需要>64mb

     只有两个都满足,才会触发AOF重写

⑥aof-load-truncated : AOF启动redis时是否忽略最后一条可能存在问题的指令(宕机导致)。

 

⑦aof-use-rdb-preamble : 是否启用rdb+aof混合持久化。先rdb然后aof提高redis启动效率

5.AOF采用RESP协议存储日志文件。

RESP是Redis序列化协议(Redis Serialization Protocol)的简写,直观的文本协议,优势在于实现过程异常简单,解析性能好

RDB快照是二进制文件,AOF采用的RESP协议存储日志,RESP也是redis的客户端与服务端的通讯协议。

Redis协议将传输的结构数据分为5种最小单位类型,单元结束时统一加上回车换行符号 。

① 单行字符串以“+”符号开头。

+hello world

② 多行字符串以“$”符号开头,后跟字符串长度。

$11
hello world

$-1
      //特殊字符:NULL
$0

  //空字符串:""

③ 整数值以“:”符号开头,后跟整数的字符串形式

:1024

④ 错误消息以“-”符号开头

-WRONGTYPE Operation against a key holding the wrong kind of value

⑤ 数组以“*”号开头,后跟数组的长度

*3
:1
:2
:3

简单测试一下

三、总结

1.rdb是全量备份,aof是增量备份

2.rdb存储某一时刻的内存状态(二进制文件),aof存储是所有写操作的日志(RESP协议保存写指令),

3.rdb启动redis速度比aof快,但数据精确度没有aof准确,rbd适用于灾难恢复,aof适用于日常恢复

4.redis4.0后支持混合持久化,是两种持久化的折中。在aof重写时生成rdb文件和aof文件,然后aof文件继续增量更新。重新启动时先加载rdb后再加载aof日志,提高启动效率和数据精确度。

拓展:

设置中的bind参数:绑定的是当前服务器网卡接口,用哪一个网卡接受请求,不设置则默认全部,注意

①设置不存在的网卡接口会启动报错。

②设置监听两个网卡并不是两个网卡生效,仅后面一个网卡生效

 仅监听192.168.0.114

 

原文地址:https://www.cnblogs.com/wqff-biubiu/p/12289614.html