因为我们知道,如果不进行数据的持久化,一旦服务器退出,数据就会丢失掉.
持久化方式之RDB
RDB(快照)持久化: 保存某个时间点的全部数据快照到dump.rdb
文件中.
其中,快照, 可以理解为拍照一样,把整个内存数据映射到硬盘中,保存一份到硬盘,因此恢复数据起来比较快,把数据映射回去即可.
RDB的创建命令(手动)
- SAVE(很少用):
阻塞Redis的服务器进程,直到RDB文件被创建完毕,创建结束后会发送OK信号
,这个很少被使用是因为SAVE指令是在主线程中保存快照的,而Redis是通过一个主线程来处理所有的请求的,这种方式会阻塞所有请求 - BGSAVE: Fork(派生)出一个子进程来创建RDB文件,不阻塞服务器进程,父进程继续处理接收到的命令,子进程完成文件的创建后会发送OK信号给父进程(即Redis主进程).
我们可以通过last save指令
查看操作是否成功(里面记录了上一次成功执行SAVE/BGSAVE的时间).
自动化触发RDB持久化的方式
- 根据redis.conf配置里的SAVE m n定时触发(通过BGSAVE方式),即m秒内数据集存在n次修改时,自动触发BGSAVE.
- 主从复制时候,主节点自动触发(主节点发送RDB文件给从节点进行复制操作).
- 执行Debug Reload.
- 执行Shutdown且没有开启AOF持久化.
BGSAVE原理
注意:
- 当执行BGSAVE指令后,它会首先检查有没有正在执行的AOF/RDB子进程,有就直接返回错误.
- 其实调用BGSAVE指令生成RDB文件就是通过调用操作系统的fork()方法: 其作用就是创建进程(传统方式下,fork函数创建子进程时会直接把全部资源复制给子进程,这种实现方式简单但是效率很低,而在linux下它做了改进,实现了Copy-on-Write写时复制)
Copy-on-Write写时复制
如果有多个调用者同时要求相同的资源(比如说内存或者磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给调用者(资源修改后会更新指针)
,而其他调用者所见到的最初的资源仍保持不变.
Redis持久化
当Redis需要做持久化时,Redis会fork一个子进程,子进程将数据写到磁盘上一个临时的RDB文件中,当子进程完成临时文件的写入之后,就将原来的RDB文件给替换掉,这样也就相当于实现了写时复制
缺点:
- 每次快照持久化都是将内存数据完整的写入到磁盘,由于是内存数据的全量同步,数据量大会由于大量的I/O操作而影响性能.
- 由于快照方式是在一定间隔时间做一次,可能会因为Redis宕机而丢失从当前至最近一次快照期间的数据,如果要求不能丢失任何修改的话可以采用AOF持久化.