当前位置:首页 > 问答 > 正文

Redis快照功能真有点神奇,缓存数据瞬间保存又恢复挺方便的感觉

“Redis快照功能真有点神奇,缓存数据瞬间保存又恢复挺方便的感觉”这个说法,其实非常生动地概括了很多人初次接触Redis持久化机制时的直观感受,它不像那些听起来就头大的专业术语,而是用一种很接地气的方式,点出了Redis一个核心的、实用的价值,下面我们就围绕这种感觉,展开聊聊。

这个“神奇”的感觉从哪里来?主要来自于一种反差,我们平常印象里的“保存数据”,尤其是大量数据,往往意味着一段不短的等待时间,你把一个好几十个G的游戏存档备份一下,或者把电脑里的文件拷贝到移动硬盘,那个进度条总是慢悠悠地走,但Redis的快照,在很多情况下,确实给人一种“瞬间”完成的错觉,你这边刚发个命令,那边好像就已经搞定了,这种速度上的优势,是“神奇感”的第一来源。

Redis快照功能真有点神奇,缓存数据瞬间保存又恢复挺方便的感觉

Redis是怎么做到这么“快”的呢?这就要提到它快照(在Redis里叫RDB)的基本原理了,Redis快照并不是一边处理新的用户请求,一边慢吞吞地把数据一点一点写到磁盘文件里,如果那样做,速度肯定会受磁盘I/O的拖累,感觉就不“瞬间”了,Redis用了一个很聪明的办法,它创建了一个子进程,这个子进程就像是主进程的一个“分身”,这个分身拥有当时主进程内存中数据的一个完整的“视图”或“副本”,这个分身就专心致志地、安静地把这个数据副本写入到一个临时的RDB文件中,而与此同时,主进程一点没闲着,继续正常接收和处理来自客户端的各种读写命令,完全不受影响,等到子进程把这个临时的RDB文件完整地、好好地写完了,它会用这个新文件去替换掉旧的快照文件(如果有的话),这个替换操作通常非常快,几乎是原子性的,从用户的角度看,除了在创建子进程的那一刹那可能会有极其短暂的停顿(在数据量巨大时能感觉到),整个保存数据的过程,服务基本上是持续可用的,这就营造了“瞬间保存”的体验,这种感觉,就像是在高速行驶的汽车上,给车窗外的风景拍了一张无比清晰的照片,而车子本身完全没有减速。

再说说“恢复挺方便”,方便体现在两个方面,第一是操作简单,当Redis服务器因为某种原因重启时,如果你配置了快照功能,它会在启动的时候自动去寻找指定的RDB文件,然后把这个文件里的数据全部加载回内存,这个过程对管理员来说几乎是透明的,不需要执行复杂的导入命令或者处理繁琐的步骤,Redis自己就搞定了,第二是效率高,因为RDB文件是经过压缩的二进制文件,它存储的是某个时间点上数据的最终状态,而不是一条条的操作记录,所以加载速度通常比另一种AOF(追加日志文件)方式要快很多,能让你重启后的Redis服务迅速达到就绪状态,继续提供服务,这种“开箱即用”的便捷性,自然让人感到“方便”。

Redis快照功能真有点神奇,缓存数据瞬间保存又恢复挺方便的感觉

任何神奇的技术背后都有其 trade-off(权衡),这种“瞬间”快照的代价是什么呢?最主要的就是它保存的是“某个时间点”的数据,而不是“每分每秒”的数据,从最后一次成功创建快照,到Redis发生故障的那一刻,这中间的所有数据更新,如果没有被下一次快照覆盖,那就会丢失,这就好比你是每隔一小时拍一张照片,如果相机在拍照后第59分钟坏了,那你这59分钟内的变化就没了,快照的“瞬间”是以可能丢失一部分数据为代价的,它适合那些对数据完整性要求不是极其苛刻的场景,比如用作缓存、存储一些可以重新计算的数据等。

为了平衡这种数据丢失的风险,Redis允许你灵活地配置快照策略,你可以设置在900秒内如果至少有1个key发生变化,就自动触发一次快照;或者在300秒内至少有10个key变化,也触发一次;还可以在60秒内至少有10000个key变化,再触发一次,这种多条件的配置,让你可以根据业务的重要性和数据更新的频繁程度,在“性能”和“数据安全性”之间找到一个适合自己的平衡点,调得好,既能享受到快照的“瞬间”和“方便”,又能把数据丢失的风险控制在可接受的范围内。

“Redis快照功能真有点神奇,缓存数据瞬间保存又恢复挺方便的感觉”这句话,确实抓住了RDB持久化模式的精髓,它的神奇在于通过fork子进程等巧妙设计,实现了服务几乎不中断的数据备份;它的方便在于恢复过程自动化、速度快,虽然它并非完美无缺,存在数据丢失的风险,但通过合理的配置,它依然是许多应用场景下一种非常高效、实用的数据持久化方案,带给开发者实实在在的便利。