关于一些redis杂谈(1)

目录

1.关于RDB和AOF复制对过期时间的处理

1.1生成RDB文件

1.2载入rdb文件

1.3AOF文件的写入

1.4 AOF重写

1.5复制

2.RDB的自动保存

2.1自动间隔性保存

2.2设置保存条件

2.3dirty计数器和lastsave属性

2.3检查保存条件是否满足(时间事件)

 3.关于文件的写入和同步


1.关于RDB和AOF复制对过期时间的处理

我们将探讨过期键对Redis服务器中其他模块的影响, 看看RDB持久化功能、AOF持久化功能以及复制功能是如何处理数据库 中的过期键的

1.1生成RDB文件

在执行SAVE命令或者BGSAVE命令创建一个新的RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB 文件中。

举个例子

如果数据库中包含三个键k1、k2、k3,并且k2已经过 期,那么当执行SAVE命令或者BGSAVE命令时,程序只会将k1和k3的 数据保存到RDB文件中,而k2则会被忽略

因此,数据库中包含过期键不会对生成新的RDB文件造成影响

1.2载入rdb文件

在启动Redis服务器时,如果服务器开启了RDB功能,那么服务器 将对RDB文件进行载入:

1.如果服务器以主服务器模式运行,那么在载入RDB文件时,程序 会对文件中保存的键进行检查,未过期的键会被载入到数据库中,而过 期键则会被忽略,所以过期键对载入RDB文件的主服务器不会造成影响。

2.如果服务器以从服务器模式运行,那么在载入RDB文件时,文件 中保存的所有键,不论是否过期,都会被载入到数据库中。不过,因为主从服务器在进行数据同步的时候,从服务器的数据库就会被清空,所 以一般来讲,过期键对载入RDB文件的从服务器也不会造成影响

1.3AOF文件的写入

当服务器以AOF持久化模式运行时,如果数据库中的某个键已经过期,但它还没有被惰性删除或者定期删除,那么AOF文件不会因为这个过期键而产生任何影响

当过期键被惰性删除或者定期删除之后,程序会向AOF文件追加 (append)一条DEL命令,来显式地记录该键已被删除

举个例子

如果客户端使用GET message命令,试图访问过期的 message键,那么服务器将执行以下三个动作:

1)从数据库中删除message键。

2)追加一条DEL message命令到AOF文件。

3)向执行GET命令的客户端返回空回复

1.4 AOF重写

和生成RDB文件时类似,在执行AOF重写的过程中,程序会对数据 库中的键进行检查,已过期的键不会被保存到重写后的AOF文件中

1.5复制

当服务器运行在复制模式下时,从服务器的过期键删除动作由主服务器控制

·主服务器在删除一个过期键之后,会显式地向所有从服务器发送 一个DEL命令,告知从服务器删除这个过期键

从服务器在执行客户端发送的读命令时,即使碰到过期键也不会将过期键删除,而是继续像处理未过期的键一样来处理过期键

·从服务器只有在接到主服务器发来的DEL命令之后,才会删除过期键。

通过由主服务器来控制从服务器统一地删除过期键,可以保证主从 服务器数据的一致性,也正是因为这个原因,当一个过期键仍然存在于 主服务器的数据库时,这个过期键在从服务器里的复制品也会继续存在

举个例子:

有一对主从服务器,它们的数据库中都保存着同样的三个键message、xxx和yyy,其中message为过期键

 1.如果这时有客户端向从服务器发送命令GET message,那么从服务 器将发现message键已经过期,但从服务器并不会删除message键,而是 继续将message键的值返回给客户端,就好像message键并没有过期一 样

 2.假设在此之后,有客户端向主服务器发送命令GET message,那么 主服务器将发现键message已经过期:主服务器会删除message键,向客 户端返回空回复,并向从服务器发送DEL message命令

 

2.RDB的自动保存

2.1自动间隔性保存

因为BGSAVE命令可以在不阻塞服务器进程的情况下执行,所以 Redis允许用户通过设置服务器配置的save选项,让服务器每隔一段时间 自动执行一次BGSAVE命令。 用户可以通过save选项设置多个保存条件,但只要其中任意一个条 件被满足,服务器就会执行BGSAVE命令

举个例子

save 900 1
save 300 10
save 60 10000

那么只要满足以下三个条件中的任意一个,BGSAVE命令就会被执 行:

·服务器在900秒之内,对数据库进行了至少1次修改。

·服务器在300秒之内,对数据库进行了至少10次修改。 

服务器在60秒之内,对数据库进行了至少10000次修改

2.2设置保存条件

当Redis服务器启动时,用户可以通过指定配置文件或者传入启动参数的方式设置save选项,如果用户没有主动设置save选项,那么服务 器会为save选项设置默认条件

save 900 1
save 300 10
save 60 10000

接着,服务器程序会根据save选项所设置的保存条件,设置服务器 状态redisServer结构的saveparams属性

struct redisServer {
// ...
//
记录了保存条件的数组
struct saveparam *saveparams;
// ...
};

saveparams属性是一个数组,数组中的每个元素都是一个saveparam 结构,每个saveparam结构都保存了一个save选项设置的保存条件

struct saveparam {
//
秒数
time_t seconds;
//
修改数
int changes;
};

2.3dirty计数器和lastsave属性

一个lastsave属性: ·dirty计数器记录距离上一次成功执行SAVE命令或者BGSAVE命令 之后,服务器对数据库状态(服务器中的所有数据库)进行了多少次修 改(包括写入、删除、更新等操作)。

·lastsave属性是一个UNIX时间戳,记录了服务器上一次成功执行 SAVE命令或者BGSAVE命令的时间

struct redisServer {
// ...
//
修改计数器
long long dirty;
//
上一次执行保存的时间
time_t lastsave;
// ...
};

举个例子:

(1)redis> SET message "hello"
OK

(2)redis> SADD database Redis MongoDB MariaDB
(integer) 3

(1)那么程序会将dirty计数器的值增加1。

(2)那么程序会将dirty计数器的值增加3

2.3检查保存条件是否满足(时间事件)

Redis的服务器周期性操作函数serverCron默认每隔100毫秒就会执 行一次,该函数用于对正在运行的服务器进行维护,它的其中一项工作 就是检查save选项所设置的保存条件是否已经满足,如果满足的话,就 执行BGSAVE命令

程序会遍历并检查saveparams数组中的所有保存条件,只要有任意 一个条件被满足,那么服务器就会执行BGSAVE命令

举个例子:如果Redis服务器的当前状态如图

 1.那么当时间来到1378271101,也即是1378270800的301秒之后,服 务器将自动执行一次BGSAVE命令,因为saveparams数组的第二个保存 条件——300秒之内有至少10次修改——已经被满足

2.假设BGSAVE在执行5秒之后完成,上图被update了下图(计数清零)

 3.关于文件的写入和同步

为了提高文件的写入效率,在现代操作系统中,当用户调用 write函数,将一些数据写入到文件的时候,操作系统通常会将写入 数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、 或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁 盘里面。

这种做法虽然提高了效率,但也为写入数据带来了安全问题, 因为如果计算机发生停机,那么保存在内存缓冲区里面的写入数据 将会丢失。

为此,系统提供了fsync和fdatasync两个同步函数,它们可以强 制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写 入数据的安全性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值