当前位置 博文首页 > 帝莘:浅谈:Redis持久化机制(一)RDB篇
? 众所周知,redis是一款性能极高,基于内存的键值对NoSql数据库,官方显示,它的读效率可达到11万次每秒,写效率能达到8万次每秒,因为它基于内存以及存读效率高的特性,在市场上的应用中一般都把它作为缓存来使用,同时这也意味着它不能大量的无限制的填充数据,否则容易内存填满,导致redis会向硬盘申请虚拟内存,造成内存和外存的不断I/O,致使效率低下,甚至引起宕机,那么问题来了,既然只是当做缓存而不是为了永久存储数据,redis为什么要做持久化呢?这样做有什么意义呢?
? 说完redis持久化的原因,我们再详聊一下redis做持久化的第一种方式RDB,这种方式也是redis默认的一种持久化方式,默认是开启的。
? 从字面上来看,RDB也就是redis database,翻译成中文就是redis 数据库,也就是说这种持久化方式就是像数据库一样存储了数据,当然事实上也是这样的,RDB方式是通过存储快照数据来完成的,既然是快照数据,那就是说明这种方式只关注了某一刻缓存的数据状态,关注的是那一刻数据是什么,它并没有去记录这个数据变更的一系列过程。也就是说,RDB持久化方式关注的是数据存储的结果,而非是数据存储的过程。
? 另外,既然是快照数据,redis又要保证性能,因此要明白RDB持久化时肯定不会是实时的,肯定是隔一段时间触发一次,否则的话redis作为一个单线程处理的服务,光顾着去持久化数据了,怎么还有时间处理来自客户端的请求访问,这也就说明了由于有时间间隔,redis的RDB方式的持久化会丢失最后一次持久化后的数据,这也就表明了redis的持久化没有办法保证数据的完整性。
save "" # 不使用RDB存储 不能主从
save 900 1 # 表示15分钟(900秒钟)内至少1个键被更改则进行快照。
save 300 10 # 表示5分钟(300秒)内至少10个键被更改则进行快照。
save 60 10000 # 表示1分钟内至少10000个键被更改则进行快照。
命令显式触发(save或者bgsave命令)
127.0.0.1:6379> bgsave
Background saving started
1.redis父进程首先判断,当前是否正在执行save,如果正在执行,则先返回。
2.父进程fork()复制出子进程,在这个过程中父进程是阻塞的,不再处理redis接收到的其他命令。当父进程fork结束,又可以重新处理工作。
3.子进程创建RDB文件,根据父进程的内存快照生成临时快照文件,完成后对原有的文件进行替换。始终保持RDB文件的完整性。
4.子进程生成RDB文件完成后,就响应信息给父进程,父进程更新统计信息。
1、头部5字节固定为“REDIS”字符串
2、4字节“RDB”版本号(不是Redis版本号),当前为9,填充后为0009
3、辅助字段,以key-value的形式
字段名 | 字段值 | 字段名 | 字段值 |
---|---|---|---|
redis-ver | 5.0.5 | aof-preamble | 是否开启aof |
redis-bits | 64/32 | repl-stream-db | 主从复制 |
ctime | 当前时间戳 | repl-id | 主从复制 |
used-mem | 使用内存 | repl-offset | 主从复制 |
4、存储数据库号码
5、字典大小6、过期key
7、主要数据,以key-value的形式存储
8、结束标志
9、校验和,就是看文件是否损坏,或者是否被修改。
优点:
缺点: