架构师培训:Redis怎么做到数据不丢的?

69 篇文章 0 订阅

虽然它是一个内存数据库,但是也不影响他对数据完整性的支持,这就有赖于它的持久化技术:
  架构师培训

快照:是全量备份,在存储上是非常紧凑的二进制内存数据。我知道Redis是单线程的,所以它在持久化的化的时候会调用操作系统的rdbSave函数fork一个子进程将当前内存中非过期数据序列化(需要注意的是rdbSave函数有两个指令实现,SAVE和BGSAVE两个,前者为阻塞指令,后者为非阻塞,既我当前所说的),父进程将不受快照操作的阻塞,这也就是操作系统鼎鼎大名的:COW(CopyOnWrite)机制。这个机制我们作为一个题外话插入,拓展一下大家的知识储备,面试的时候能把这个讲清楚也是一个加分项:
  COW:子进程刚产生的时候它和主进程共享内存里面的数据段跟代码段,Linux为了节省内存资源,让他们共享起来,在进程分离的一瞬,内存基本没变化。进程分离的步骤大致是:fork函数会在子进程同时返回,在父进程里面返回子进程的pid,在子进程里返回0,如果系统内存资源不足则返回-1,fork失败。子进程做数据持久化不会修改现有内存数据,只对数据进行遍历然后序列化到磁盘。这时候有人就会问了:子进程读父进程的数据,主进程此时还对外提供服务,那么主进程肯定会不停的修改内存数据,子进程怎么保证自己读到的数据跟主进程的最新数据一致呢?这时候我们就得引入系统的COW机制了,COW将数据段分成N个数据页,当主进程修改任意一个页面数据的时候,将会把此页面从共享内存中复制一份分离出来,然后对复制出来的新页面进行修改,此时子进程的内存页是没有变化的。这就是快照的概念了,当fork成功的一瞬间一直到它持久化到磁盘的数据始终是一致的。当下次子线程进入的时候就会共享到那些被修改过的页面数据了(主进程未修改过的+页分离数据)。一般情况下页分离的数量取决于Redis的热数据的多少。
  RDB文件结构:一条RDB文件包含以下内容,|REDIS|RDB-VERSION|SELECT-DB|KEY-VALUE-PAIRS|EOF|CHECK-SUM|。REDIS,标识着这是一个Redis的RDB文件;RDB-VERSION,为一个四字节的整数表示,不同RDB-VERSION版本的文件是不兼容的;DB-DATA,它会在RDB文件中出现多次,每个DB-DATA部分保存着一个非空数据库的所有数据;SELECT-DB,表示键值对应的数据库号码,确保数据被还原到正确的数据库;OPTIONAL-EXPIRE-TIME域是可选的,如果键没有设置过期时间那么这个域就不会出现;TYPE-OF-VALUE域记录着VALUE域的值所使用的编码;VALUE域则是根据值的实际数据结构保存的格式。
  AOF日志:是增量备份,是内存数据修改的指令文本记录,它跟RDB有一个区别就是包含过期key,当key被惰性删除或者定期删除会在文件中追加一条del指令。AOF在长期运行中会比较庞大,定期会重写,而且备份回放AOF比快照回放慢得多。这里需要注意的一点是:Redis在收到客户端指令时会先将指令存储到AOF日志文件中,然后再执行指令。这样好处就是如果发生宕机已经持久化到AOF中的指令可以通过回放来恢复数据,防止数据意外丢失。当AOF随着时间越来越大的时候就会需要对其重写:Redis提供了bgrewriteaof指令对AOF进行重写,其原理就是开辟一个子线程对当前内存进行遍历转化成一个新的文本指令,生成一个新的AOF文件保存在操作系统cache中,操作系统再异步将操作系统cache中的数据写到磁盘,生成真正的AOF文件。生成新AOF文件结束后将在这期间发生的增量指令追加到AOF文件中,追加完成后立即使用最新AOF文件删除旧AOF文件。在上述过程中会存在一个问题,当Redis的AOF写入操作系统cache成功后未来得及刷盘就宕机的话,这部分数据是会丢失的。下面就引入了解决此问题的办法:操作系统函数fsync,它可以将操作系统cache中指定内容强制刷新到磁盘中。只要调用fsync执行成功就能保证AOF文件不丢失。只要是IO操作,那必然跟内存操作存在量级的性能差异,所以fsync的频率(fsync三种方式,AOF_FSYNC_NO:不保存;AOF_FSYNC_EVERYSEC:每一秒钟保存一次;AOF_FSYNC_ALWAYS:每执行一个命令保存一次)也是影响Redis性能的一个指标,我们要根据自己系统的特性在保证高性能的同时尽量少的丢失数据。我们一般为了提升主节点的性能可能会不开启fsync,这个工作交给从节点,但是这一前提是要做好容错和监控处理,我们可以通过冗余设计或者更高级的分布式设计减少错误概率,保证至少要保证一个从节点的数据同步正常。
  相关推荐:【鲁班学院】java高级培训-能懂系列之Map详解
  如果你想了解更多关于java架构师的专业知识,可以加入JAVA架构师交流群:1037935907,里面都是同行,有资源分享包括但不限于(分布式架构、高可扩展、高性能、高并 发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、、Mycat、Netty、Kafka、Mysql 、Zookeeper、Tomcat、Docker、Dubbo、Nginx)。欢迎一到五年的工程师加入,合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值