redis之RDB快照 1.0

对于redis来说,因为它保存在内存中,是内存性数据库,如果redis重启或者宕机后,其内存中的数据会全部丢失,所以应该想办法将内存中的数据进行持久化保存,等到下次redis重启或者恢复后能够根据这些持久化进行恢复

这里就用到了rdb快照技术,redis会将内存中的数据以rdb文件的形式保存,每当redis重启或者恢复后都会读取rdb文件中的数据然后进行数据恢复,rdb文件的结构可以简单描述如下:
RDB{

标识符:redis 表示该文件使用市rdb文件

db_version:表示rdb文件保存形式的版本

databases:{

selectdb:表示接下来要读的将是一个数据库库号码

db_num:保存着一个数据库号码

key_value_pairs:保存的键值对

}包含着0个或者多个数据库的,以及各个数据库中的键值对。

EOF常量标识一个rdb文件正文的结束

check_sum:redis会在读取rdb文件时计算一个校验和,与check_sum所记录的校验和进行对比,以判断rdb文件是否出错或损

}

redis的rdb快照保存方式有两种:第一种save,save会在主线程中读取数据库数据,进行rdb保存,在这个期间redis无法接受对于数据库的写操作,所以对于单线程的redis来说是一个比较致命的影响

所以采用了bgsave reids会通过执行bgsave命令创建一个子进程,然后通过在子进程中读取数据库数据进行保存。此时如果客户端要修改数据,因为在这个期间会进行读取操作,所以采取会采用 写实复制策略(在redis(5)中有详细介绍)。即为所要修改的数据分配创建一个副本,然后将该副本写入到rdb文件中,我觉得这个时机是本次生成rdb结束后  ,   这样对于写的操作就不会有影响了

然后对于我们需要讨论的一点就是,以什么频率来进行rdb快照,如果频率过高的话,那么对于redis来说,每次创建子进程的过程会阻塞主线程,所以频率过高的话,也会影响redis性能。同时大量的写磁盘操作,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。

在redis 4.0之后采用了aof与rdb互相使用的方式,即在第一次时使用rdb进行全量恢复,之后到下一次进行全量快照的时间,在这段期间内,对于数据库的修改,采用aof日志的形式,记录对于数据库的操作,所以如果服务器宕机,因为aof日志记录了之前的操作,虽然没有来得及更新rdb文件,但是恢复数据库时,可以结合上一次的rdb快照和aof日志进行完整恢复。所以rdb与aof的结合使用可以不用频繁进行rdb操作,同时如果服务器在下一次rdb之前宕掉了,也会通过上一次rdb与aof日志的结合进行恢复

关于 AOF 和 RDB 的选择问题,:数据不能丢失时,内存快照和 AOF 的混合使用是一个很好的选择;

如果允许分钟级别的数据丢失,可以只使用 RDB(因为每次rdb之间有是时间设定);

如果只用 AOF,优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。

在这里还有一点需要介绍,用户可以主动设置save参数来决定bgsave,例如save 900 1 save 300 10 服务器在900秒内,对数据库至少进行1次修改,在300秒内,对数据库至少进行10次修改,两个条件任意满足一个,服务器都会执行bgsave命令。

rdb文件在磁盘上是经过压缩的

 

posted @ 2020-10-13 18:53  xzwcomeon  阅读(125)  评论(0编辑  收藏  举报