• 技术文章 >数据库 >Redis

    redis怎么实现持久化

    silencementsilencement2019-06-04 17:05:06原创1560

    redis作为当下web编程必不可少的服务,它的特点的是显而易见,相对memcached而言,做缓存,重启数据不丢失,非常好用。那么问题来了,它是怎么做到的呢?

    RDB

    RDB就是持久化的一种手段,把内存中数据在某些条件下写到磁盘中去。那么在哪些条件下写入呢?不可能无脑写入,来一个写一个,影响性能,也不能等老半天才写一个,万一中间宕机了,数据全丢失,还不如用memcached。在redis的配置里有着这样的一段配置:

    save 900 1

    save 300 10

    save 60 10000

    很关键的一段配置,这时RDB持久化的核心。意思是:

    1.如果900秒时,有1个key变化(插入或者更新),我就同步到磁盘一下

    2.如果300秒时,有10个key变化(插入或者更新),我就同步到磁盘一下

    3.如果60秒时,有10000个key变化(插入或者更新),我就同步到磁盘一下

    这些时间点和变化的数量是怎么知道的,这时有另外两个极为关键的东西,一个叫dirty计数器,一个叫lastsave(上次save的时间),dirty计数器专门记录从上次save后变化key的数量,lastsave记录执行save的时间,举个例子刚开始时间是time1,dirty是0,这时有20个key发生了变化,dirty是20,然后现在的时间是time2,time2-time1 >= 300,满足第二个条件,这时内存中的数据会save一下,同时dirty清为0,然后再等待条件触发。

    如果我60秒内有10万个key,那么问题来了,一下大量磁盘io来临,这时redis主进程就会阻塞,期间的所有的命令都不执行,这哪能行,于是就来了一个叫bgsave的,它是redis主进程fork出来的一个子进程,专门执行rdb的持久化工作的。

    保存的文件格式是二进制格式的,万一数据库宕机,恢复不需要人为干预,redis会自动读取磁盘文件。

    AOF

    与RDB不同,AOF存储的是你执行的命令,当aof功能打开的时候,执行的更新命令不会直接写到aof文件中去,而是先写到一个aof buf中,我们知道不能一直往buf中写,buf也是内存啊,那么何时才能同步到磁盘中去呢?redis中也有这样一段配置

    appendfsync always

    appendfsync everysec

    appendfsync no

    意思是:

    1.只要有更新的命令我就同步

    2.如果上次同步时间距离现在超过一秒就同步

    3.不同步,等待操作系统自己判断(什么时候我有空我才同步)

    分析下,第一种io频繁,io压力大,但丢失数据的概率最小,第二种io压力不是很大,最多也就丢失1秒左右的数据,第三中io压力很小,丢失数据概率太大。综合考虑,一般第二种。但还有个问题,我执行了100次INCR num,按道理num就是100,aof中也有100个同样的命令,没毛病,那么请问执行100次INCR num和SET num 100有什么区别,同样的结果前者多了99倍的空间,很浪费啊,于是就出现了AOF重写,它是怎么做到的。很简单:首先从数据库读取现在的值,然后用一条记录代替,这就是AOF重写的原理。重写很花时间,所以也是子进程来处理。重写的过程中,如果有新的命令来临怎么办,老办法,写buf缓冲,重写完成后,把buf中的命令追加到新的aof中,然后用新的aof替代老的aof,就实现了重写。

    本文来自redis教程,欢迎学习。

    以上就是redis怎么实现持久化的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:redis持久化
    上一篇:redis判断值是否存在 下一篇:redis有多少个默认db

    相关文章推荐

    • redis是用什么语言写的• redis是否支持原子操作• 更换redis 是否需要 重启

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网