Redis持久化

在一个高并发,但是数据量不大的系统中,使用Redis做数据库再好不过,结合Swoole,只需要很少的机器就能抗住很大的量。

Redis大多数的应用可能都是当做缓存,当作为一个数据库用的时候,就必须要考虑持久化的问题了。持久化的意思就是将内存中的数据写到磁盘中,当再次重启之后,数据可以从磁盘中进行恢复,不会丢失。Redis持久化有两个策略,一个是RDB快照,一个AOF日志,不管是什么策略,最终的目的都是将数据保存在磁盘上,并不高深。只需要耐心的看看这两种策略,就能明白了。

RDB快照

从名字上我们就能知道这是RedisDB的缩写了,Redis快照是这样生成的,到了需要生成快照的时候,通过fork当前进程,子进程中会继承父进程中所有的数据,子进程再循环这些数据,写入到磁盘中。

Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的,当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件,这样在任何时候出现故障,Redis的RDB文件都总是可用的。

RDB的缺点也很大,RDB里面的数据并不是最新的,并且每隔一段时间保存全量数据,对磁盘消耗也比较大。

AOF日志

AOF是append only file,这是一个追加的日志文件,内容就是一个一个的redis命令。可以想象,整个系统运行好几年之后,aof文件肯定会大到一个无法想象的地步,如果没有一个策略去整理的话。Redis提供了一个AOF重写的功能,Redis会根据内存中的数据来重写一份aof文件,这个aof文件对一个记录只会有一次操作,因此就能够大大减少了aof文件的大小,记录过程和RDB类似,也是fork一个进程,遍历所有的key,写入到临时文件,再用rename这个原子操作替换原来的aof文件。

AOF可靠性设置

AOF是一个写文件操作,其目的是将操作日志写到磁盘上,所以它也同样会遇到我们上面说的写操作的5个流程。那么写AOF的操作安全性又有多高呢。实际上这是可以设置的,在Redis中对AOF调用write(2)写入后,何时再调用fsync将其写到磁盘上,通过appendfsync选项来控制,下面appendfsync的三个设置项,安全强度逐渐变强。

appendfsync no

当设置appendfsync为no的时候,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作系统的调试了。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。

appendfsync everysec

当设置appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。但是当这一次的fsync调用时长超过1秒时。Redis会采取延迟fsync的策略,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就不管会执行多长时间都会进行。这时候由于在fsync时文件描述符会被阻塞,所以当前的写操作就会阻塞。

所以,结论就是,在绝大多数情况下,Redis会每隔一秒进行一次fsync。在最坏的情况下,两秒钟会进行一次fsync操作。

这一操作在大多数数据库系统中被称为group commit,就是组合多次写操作的数据,一次性将日志写到磁盘。

appednfsync always

当设置appendfsync为always时,每一次写操作都会调用一次fsync,这时数据是最安全的,当然,由于每次都会执行fsync,所以其性能也会受到影响。

业务场景

那么到底是使用RDB还是使用AOF呢?它们各有优缺点,因此需要根据业务的需要来配置不同的持久化策略。

计数器

比如使用redis做计数器的时候,就应该使用RDB,计数器几乎时时刻刻都在写入数据,使用AOF策略将会使得性能急剧下降,并且aof文件会十分庞大!

写少读多的业务

如果是一个写十分少但是读取特别多的的业务,那么使用AOF策略无疑是十分合适的,aof只会在写入的时候写入aof文件,因此整个系统如果写入很少,读取很多,那么aof简直完美,如果使用RDB的话,少量数据写入却需要每隔一定时间都保存一次全量数据,那么大部分保存的都是没有变化的数据,得不偿失。

赞赏

微信赞赏支付宝赞赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注