面试官:Redis持久化有了解吗?可以聊一聊吗?
面试官心理分析:redis 如果仅仅只是将数据缓存在内存里面,如果 redis 宕机了再重启,内存里的数据就全部都弄丢了啊。你必须得用 redis 的持久化机制,将数据写入内存的同时,异步的慢慢的将数据写入磁盘文件里,进行持久化。如果 redis 宕机重启,自动从磁盘上加载之前持久化的一些数据就可以了,也许会丢失少许数据,但是至少不会将所有数据都弄丢。这个其实一样,针对的都是 redis 的生产环境可能遇到的一些问题,就是 redis 要是挂了再重启,内存里的数据不就全丢了?能不能重启的时候把数据给恢复了?
派大星:可以的,Redis持久化分为两种:
周期性
的持久化,具有时效性
。append-only
的模式写入一个日志文件中,在Redis重启的时候,可以通过回放AOF日志的写入命令来重新构建整个数据库。面试官:那你知道RDB和AOF这两种方式有什么区别吗?或者它们有什么优缺点?
派大星:首先来说对于RDB来讲:
dump.rdb文件
,同时也会造成时点与时点之前窗口数据容易丢失(8点得到一个rdb文件 9点刚要得到rdb文件 挂机了)。RDB 每次在 fork 子进程来执行 RDB 快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒。派大星:其次来说AOF,
fsync
操作,最多丢失1s的数据,AOF日志文件的命令是通过可读性非常好的方式进行记录,所以这个特性非常适合做灾难性的误删除的紧急恢复(比如某人不小心用 flushall 命令清空了所有数据,只要这个时候后台 rewrite 还没有发生)。fsync
一次日志文件的特性,会导致写的时候的QPS相比较于RDB的QPS要低一些。Redis性能也会有所降低。派大星:当然在Redis4.0之后也有所更新,具体如图所示:
当然AOF也会产生一写小的问题就是,进行数据恢复的时候,有可能不会恢复出一摸一样的数据。因为基于AOF这种较为复杂的基于命令日志/merage/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方式更加脆弱,容易有bug。不过AOF就是为了避免rewrite过程导致bug,因此每次rewirte的时候并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性就会好一些。
面试官:不错,那么在实际生产中,如何选择呢?
派大星:首先来说不要仅仅使用RDB,因为时点性的原因会导致丢失很多数据,同时也不要仅仅使用AOF,因为那样会有两个问题,第一通过AOF做冷备,没有RDB的体积小恢复的速度快,第二,RDB每次简单粗暴的生成快照文件更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug。Redis目前是支持同时开启这两种方式的持久化的,我们可以综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择;用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的是有可以采用RDB来进行快速的数据恢复。(同时Redis4.0之前Redis中RDB和AOF可以同时开启但是只会用AOF恢复,但是在4.0之后AOF中包含RDB全量增加记录的写操作)。
面试官:非常不错,我对你这边的情况还是比较满意的。
派大星:谢谢。