Redis(五)--- Redis的持久化RDB与AOF

1、Redis数据库

咱们都知道Redis是基于内存的数据库,数据是以key-value键值对的方式存储的,那么key-value键值对是随意放在内存中的么,其实Redis的服务会建立不少的数据库空间,这些key-value键值对都是在各个数据库空间中存储的。redis

当咱们使用客户端工具连接Redis服务时,会在客户端中看到一系列的db*命名的项(如图),这些就是一个个数据库,Redis初始化建立16个数据库,数据库建立个数能够在配置文件中修改。数据库

而在命令行模式中是看不到这些数据库的具体数量的,但在命令行提示符的右侧会提示咱们当前处于哪一个数据库(如图),而且能够用上一章说到的SELECT命令进行数据库的切换;客户端默认链接第一个数据库,即0号数据库。安全

(1)数据库键空间服务器

key-value键值对存储在各个数据库中,而每一个数据库内部都是由一个redisDb结构,结构中有若干个属性,最主要的有两个属性dict、expires。网络

1 typedef struct redisDb {
2     // ...
3     // 数据库键空间,保存着数据库中的全部键值对
4     dict *dict;
5 
6     // 过时字典,保存着键的过时时间
7     dict *expires;
8     // ...
9 } redisDb;
    • dict 是字典结构,存储咱们的key-value键值对,这个字典称为数据库键空间,字典的键就是数据库的键,每一个键都是一个字符串,存储key值;字典的值就是数据库的值,每一个值均可以是五大对象中任意一种,存储value值;因此咱们存储的key-value最终是在数据库中以字典的结构存储的。
    • expires 一样是字典结构,但其存储的是key-value过时时间;当咱们设置了key-value的过时时间,那么key-value存储在dict字典中,而过时时间则存储在expires中;字典的键存储key,字典的值存储过时时间;这里须要注意的是,不管设置的过时时间是秒仍是毫秒,最终存储时都会转换为unix毫秒时间戳。

图中是带有过时字典的数据库例子数据结构

(2)持久化并发

上面说道的不管是数据库仍是期内的数据都是存储在服务器内内存中的,若是服务器一旦发生掉电,进程退出等状况,那么其内存中的数据就都消失不见了,在咱们大规模并发的项目下,显然这是灾难性的,因此应对这种状况的办法之一,就是持久化,把内存中的数放到磁盘中,意外发生后,可以从磁盘上进行数据恢复到内存中,这样就避免了数据丢失。异步

Redis提供了两种持久化方式RDB持久化和AOF持久化。工具

二、RDB持久化

RDB持久化是最直接的持久化方式,直接将内存中的数据保存到RDB文件中,当恢复时也是直接从RDB文件中恢复;spa

                      

 

    • RDB文件是通过压缩的二进制文件,这里对文件结构不作详解。
    • RDB持久化能够手动执行,也能够设置按期执行。
    • RDB持久化命令有两个SAVE(同步)和BGSAVE(异步),同步持久化过程当中,会拒绝客户端的全部请求;异步则是建立子进程执行,不会对客户端产生影响,具体能够看上一章的命令介绍。

自动间隔性保存

由于BGSAVE命令是异步执行,不会阻塞服务器,因此Redis容许用户自行配置SAVE选项,当选项触发时自动执行BGSAVE命令。 

当用户开启了触发自动BGSAVE后,若是不配置save选项,服务器会使用默认设置,以下:

  (1)在900秒内,对数据库进行了至少1次修改。

(2)在300秒内,对数据库进行了至少10次修改。

(3)在60秒内,对数据库进行了至少10000次修改。

以上三个条件,知足任意一条,就会进行BGSAVE操做

三、AOF持久化

AOF持久化与RDB不一样,AOF持久化是经过记录服务器所执行的命令来保存数据的。

    • 被写入AOF文件的全部命令都是以Redis请求协议格式保存的。
    • 数据的还原,就是经过读取AOF文件的这些命令进行的。
    • 执行的命名并非直接写入AOF文件的,而是先写入缓冲区,没执行一条命令就会追加到缓冲区的末尾,当一条命令执行完成后,返回数据前,会将缓冲区的数据写入到AOF文件中。

AOF文件的载入与还原

AOF持久化的数据还原过程就是读取AOF中命令从新执行命令的过程。

(1)Redis会建立一个伪客户端,伪客户端与真实的客户端执行命令的效果是同样的,只是不带网络链接。

(2)从AOF文件分析并读取一条命令。

(3)伪客户端执行这条命令。

(4)重复2和3过程,知道AOF文件中的全部命令处理完成。

AOF文件重写

AOF文件的持久化是记录被执行对的命令,这样随着时间愈来愈长,AOF文件中的内容会愈来愈多,体积也会愈来愈大,文件越大恢复数据的时间也越多。

在命令执行的过程当中有些键值对被删除了,有些被修改了,而这些过程命令是彻底没有必要再执行一遍的,因此Redis提供了AOF文件的重写功能对AOF进行重建,使用重建后的文件要比元AOF文件体积小不少。

    • AOF文件重写,并不须要对原AOF文件进行任何访问改动,他是经过对数据库内的数据读取来操做的,即查看数据库内有什么数据,而后根据数据类型进行建立这些数据的写入命令。
    • AOF文件重写过程当中,建立写入命令时会先检查元素数量,若是数量超过了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD=64常量的值,就会分红多条命令,
    • AOF文件重写是有子进程进行的,并不影响主进程处理命令;子进程而不是线程,由于进程带有数据副本,不锁数据的状况下,能保证安全。
    • AOF文件子进程重写过程当中,主进程仍然在处理数据,这样形成了子进程和主进程的数据不一致,子进程数据少了一部分,这种状况下Redis会建立一个AOF重写缓冲区;这样少的那部分命令会写到AOF重写缓冲区中,重写完成后,再把缓冲区这些命令写进新的AOF文件中,而后用新的AOF文件替换就得AOF文件。

四、总结

    • Redis初始化会建立一批数据库,每一个数据库的内部数据结构都是字典,key-value的最终存储也会落到字典上。
    • AOF持久化比RDB持久化频率更高、速度更快;当有AOF持久化时,RDB持久化命令不会再执行;但当RDB持久化命令执行时,AOF命令会等待其执行完成后再执行,而其余RDB命令不会执行。
    • AOF文件重写过程不会影响旧的AOF文件,即使AOF重写过程失败,也不会干扰原来的AOF恢复数据,只有在成功以后才会替换原来的文件。

 

参考:

《Redis设计与实现》黄健宏著,网上对Redis的详解等

此博客为笔者使用redis好久以后,参考网络上各种文章总结性书写,原创手打,若有错误欢迎指正。

相关文章
相关标签/搜索