Redis的性能优势,很大程度上来说,是因为数据都在内存当中,大大提升了数据处理时的速度和效率。而存在内存当中,就要面临各种临时或意外故障可能带来了数据丢失问题,而这就涉及到Redis的内存快照策略。今天的大数据开发学习分享,我们就主要来讲讲Redis内存快照常见问题。
Redis内存快照,简单来理解,就是内存中的数据在某一个时刻的状态记录。
对Redis来说,它实现类似照片记录效果的方式,就是把某一时刻的状态以文件的形式写到磁盘上,也就是快照。这样一来,即使宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。这个快照文件就称为RDB文件。
Redis给哪些内存数据做快照?
Redis的数据都在内存中,为了提供所有数据的可靠性保证,它执行的是全量快照。
RDB文件的生成是否会阻塞主线程,这就关系到是否会降低Redis的性能。Redis提供了两个命令来生成RDB文件,分别是save和bgsave。
save:在主线程中执行,会导致阻塞;
bgsave:创建一个子进程,专门用于写入RDB文件,避免了主线程的阻塞,这也是Redis RDB文件生成的默认配置。
Redis快照时数据能修改吗?
在给别人拍照时,一旦对方动了,那么这张照片就拍糊了,我们就需要重拍,所以我们当然希望对方保持不动。对于内存快照而言,我们也不希望数据“动”。
如果快照执行期间数据不能被修改,是会有潜在问题的。
避免阻塞和正常处理写操作并不是一回事。此时,主线程的确没有阻塞,可以正常接收请求,但是,为了保证快照完整性,它只能处理读操作,因为不能修改正在执行快照的数据。
为了快照而暂停写操作,肯定是不能接受的。所以这个时候,Redis就会借助操作系统提供的写时复制技术(Copy-On-Write,COW),在执行快照的同时,正常处理写操作。简单来说,bgsave子进程是由主线程fork生成的,可以共享主线程的所有内存数据。bgsave子进程运行后,开始读取主线程的内存数据,并把它们写入RDB文件。
Redis会使用bgsave对当前内存中的所有数据做快照,这个操作是子进程在后台完成的,这就允许主线程同时可以修改数据。
Redis可以每秒做一次快照吗?
连续快照有利于在宕机时尽可能少的丢失数据,通常可想到的是使用使用bgsave对当前内存中的所有数据做快照,因为bgsave执行时不阻塞主线程,但是,如果频繁地执行全量快照,也会带来两方面的开销:
一方面,频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。
另一方面,bgsave子进程需要通过fork操作从主线程创建出来。虽然,子进程在创建后不会再阻塞主线程,但是,fork这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出bgsave子进程,这就会频繁阻塞主线程了。
Redis增量快照
增量快照,所谓增量快照,就是指,做了一次全量快照后,后续的快照只对修改的数据进行快照记录,这样可以避免每次全量快照的开销。
跟AOF相比,快照的恢复速度快,但是,快照的频率不好把握,如果频率太低,两次快照间一旦宕机,就可能有比较多的数据丢失。如果频率太高,又会产生额外开销,那么,还有什么方法既能利用RDB的快速恢复,又能以较小的开销做到尽量少丢数据呢?
Redis 4.0中提出了一个混合使用AOF日志和内存快照的方法。简单来说,内存快照以一定的频率执行,在两次快照之间,使用AOF日志记录这期间的所有命令操作。快照不用很频繁地执行,这就避免了频繁fork对主线程的影响。而且,AOF日志也只用记录两次快照间的操作,也就是说,不需要记录所有操作了,因此,就不会出现文件过大的情况了,也可以避免重写开销。
关于大数据开发学习,Redis内存快照常见问题,以上就为大家做了简单的解答了。具体到实际的开发和运行环境当中,Redis的快照机制是起到非常重要的作用的,内存快照是重要的手段之一。