大家都知道,Redis之所以性能好,读写快,是因为Redis是一个内存数据库,它的操作都几乎基于内存。但是内存型数据库有一个很大的弊端,就是当数据库进程崩溃或系统重启的时候,如果内存数据不保存的话,里面的数据就会丢失不见了。这样的数据库并不是一个可靠的数据库。
所以数据的持久化是内存型数据库的重中之重。它不仅提供数据保存硬盘的功能,还可以借此用硬盘容量扩展数据存储空间,使得Redis的可以存储超过机器本身内存大小的数据。
Redis对于数据持久化提供了两种持久化的方案,RDB与AOF。它们的原理和使用场景都大不相同,下面我们来详细地了解下。
RDB,提供一个某个时间点的数据的Snapshot,保存在RDB文件中。它可以通过SAVE/BGSAVE
命令手动执行,把数据Snapshot写到RDB文件,也可以通过配置,定时执行。
Redis也可以通过加载RDB文件,把数据从磁盘加载读取到Redis中。
连上Redis,设值一些值,然后执行SAVE
命令。
然后可以查看下redis.conf的持久化工作目录。进入目录可以看到保存了一个dump.rdb文件。该文件是一个二进制文件,无法直接正常打开。
至于SAVE/BGSAVE
的区别,就是前置是阻塞执行,此时服务不会接受请求,后者是Fork一个子进程出来,由该进程去执行保存RDB文件的操作,不影响用户请求。
P.S. Redis是单进程的,所以BGSAVE
只能Fork一个子进程,而不是创建一个线程处理。
以上是手动执行的过程。但在生产我们很少会手动登上服务去执行操作,所以更多的时候是依赖Redis的配置,定时保存RDB文件。
打开redis.conf
配置文件,找到SNAPSHOTTING的配置,Save Point的设置。
图中的配置意思是,当至少有一个key变更时,900秒后会执行一次SAVE。其他配置同理,有10次变更,300秒后保存一次.....
在Redis中,这个自动保存RDB的功能是默认开启的。
先kill掉Redis进程,再重新启动Redis Server,会发现日志会有这样的一行,
并且Redis中,依然有之前设置的三个值。说明Redis在启动的时候,会加载数据初始化。
不过,这里加载的初始化数据不一定是RDB的。如果Redis开启了AOF,会优先从AOF初始化数据,否则才会加载RDB的数据。
优点:
缺点:
Redis的另外一种持久化方案就是AOF,Append Only File。AOF相当于一个操作的日志记录,每次对于数据的变更都会记录追加到AOF日志。当服务启动的时候就会读这些操作日志,重新执行一次操作,从而恢复原始数据。
AOF默认是关闭的。打开redis.conf配置文件,找到appendonly no
改成appendonly yes
。
AOF和RDB是可以共存的,只要保存的文件名不冲突。
配置文件往下拉,看到fsync
的配置。
fsync()是一个系统调用函数,告诉操作系统把数据写到硬盘上,而不是缓存更多数据才写到硬盘。这样的调用可以及时保存数据到硬盘上。
Redis提供了三种fsync的调用方式
开启AOF后,会再工作目录看到appendonly.aof
文件。
在客户端上执行一些命令后,打开AOF文件,可以观察到有对应的操作的记录日志。
文件解析说明:
set a 1
是三个参数,所以是*3set
这个参数是三字节,所以是$3,key值a是一个字节,所以是$1set
,a
,1
就是具体的数据AOF虽然比RDB更可靠,但缺点也是比较明显的,就是每次写操作都要把操作日志写到文件上,这样会导致文件非常冗余。
假若你要自增一个计数器100次,如果不重写,AOF文件就就会有这100次的自增记录,如INCR a
。如果执行了日志重写,那么文件只会保留set a 100
而不是100条INCR a
。这样拥有相同的结果,但可以大大减少AOF的文件大小,并且可以让AOF载入的时候提升载入的效率。
看回redis.conf
配置,有两项控制rewrite的选项。
来实验一下重写的结果,我们先设定一个a值,然后自增多次,查看AOF文件内容。里面有很多INCR的语句记录
然后我们手动执行下BGREWRITEOF
,执行日志重写。
可以看到,多个incr语句,变成了一个set a 6
语句,减少了5个incr a
语句的操作日志。
优点:
缺点
以上已经基本了解过RDB和AOF的使用、基本原理以及对应的优缺点。那么在实际当中,我们到底怎么去选择用哪种持久化方式呢?
一般来说,不考虑硬盘大小,最安全的做法是RDB与AOF同时使用,即使AOF损坏无法修复,还可以用RDB来恢复数据。
如果Redis的数据在你的服务中并不是必要的数据,例如只是当简单的缓存,没有缓存也不会造成缓存雪崩。说明数据的安全可靠性并不是首要考虑范围内,那么单独只使用RDB就可以了。
不推荐单独使用AOF,因为AOF对于数据的恢复载入来说,比RDB慢。并且Redis官方也说明了,AOF有一个罕见的bug。出了问题无法很好的解决。所以使用AOF的时候,最好还是有RDB作为数据备份。
根据官方的意愿描述,在未来可能会有一种RDB与AOF相结合的持久化模型。到时Redis持久化就不再如此麻烦费劲了,我们拭目以待吧。
更多技术文章、精彩干货,请关注
博客:zackku.com
微信公众号:Zack说码
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。