Redis保证高可用主要有以下几个方面:数据持久化主从复制故障自动恢复集群化在本文中,我们首先介绍Redis保证高可用的基础:数据持久化。因为Redis的主从复制和自动故障恢复都需要依赖Redis持久化相关的东西。同时还可以利用Redis的数据持久化进行数据备份,保证数据安全。Redis是一个内存数据库,它的数据是存储在内存中的。如果实例宕机,所有数据都将丢失。如何保证数据的完整性和安全性,也是提高服务高可用性的重要机制之一。Redis提供了完善的持久化机制,可以将内存中的数据持久化到磁盘中,方便我们备份数据和快速恢复数据。在本文中,我们将分析Redis的数据持久化是如何实现的?我们经常听到的RDB和AOF有什么区别?以及它们不同的使用场景。持久化方式Redis提供的数据持久化方式主要有两种:RDB:生成数据快照文件AOF:实时追加命令日志文件分别对应不同的使用场景,下面我们依次分析。RDB介绍RDB的全称是RedisDatabaseBackupfile(Redis数据备份文件),也称为Redis数据快照。我们可以通过执行save或者bgsave命令让Redis在本地生成一个RDB快照文件。这个RDB文件包含了整个实例几乎完整的数据内容。它的优点是:RDB文件数据是压缩写入的,所以RDB文件的大小小于整个实例内存。实例宕机恢复时,RDB文件的加载速度非常快,可以在短时间内快速恢复。文件中数据的缺点也很明显:由于是数据在某一时刻的快照,其数据并不完整。生成一个RDB文件的成本比较高,会消耗大量的CPU和内存资源,所以RDB比较适合以下场景:主从全同步数据数据库备份对丢失数据不敏感的业务场景,实例宕机后数据快速恢复Redis主从全同步数据使用RDB文件。由此可见,RDB非常适合做数据备份。我们可以定时让Redis生成RDB文件,然后备份快照文件。定时生成RDBRedis也提供了定时触发生成RDB文件的配置项:CopyOnWrite在Redis上执行save和bgsave命令生成RDB文件,但是前者是在前台执行的,也就是说生成RDB文件的时候,将阻止整个实例。在RDB生成之前,任何请求都不能被处理。对于一个大内存的实例,生成一个RDB文件是非常耗时的,这显然是我们无法接受的。所以通常我们会选择执行bgsave让Redis在后台生成RDB文件,这样Redis仍然可以处理客户端请求而不阻塞整个实例。但是并不代表后台生成RDB是免费的。Redis利用操作系统提供的CopyOnWrite技术,在后台将内存数据的快照写入文件,也就是大家熟知的fork系统调用。fork系统调用会产生一个子进程,子进程与父进程共享相同的内存地址空间,这样子进程此时就可以拥有与父进程相同的内存数据。虽然子进程和父进程共享同一个内存地址空间,但是在fork子进程时,操作系统需要将父进程的内存页表复制给子进程。如果整个Redis实例占用的内存很大,那么它的内存页表也会很大,复制的时候会很费时。同时,这个过程会消耗大量的CPU资源。父进程也被阻塞,直到复制完成,无法处理客户端请求。fork执行后,子进程可以扫描自己所有的内存数据,然后将所有数据写入到rdb文件中。之后,父进程仍然处理客户端的请求。在处理写命令时,父进程会重新分配一块新的内存地址空间,向操作系统申请新的内存使用,不再与子进程共享。这个过程就是CopyOnWrite(写实拷贝)名称的由来。这样,父子进程的内存就会逐渐分离,父进程会申请新的内存空间,改变内存数据,而子进程的内存数据不会受到影响。由此可见,在生成RDB文件时,不仅要消耗CPU资源,还需要占用高达一倍的内存空间。我们在Redis中执行info命令,可以看到fork子进程的耗时,可以用来评估fork时间是否达到预期。同时要保证Redis机器有足够的CPU和内存资源,合理设置生成RDB的时机。AOF简介AOF的全称是AppendOnlyFile(追加日志文件)。与RDB不同的是,AOF记录了每条命令的详细信息,包括完整的命令类型、参数等,只要产生写命令,就会实时写入到AOF文件中。我们可以通过配置文件开启AOF:通过磁盘刷盘开启AOF后,Redis会将每一次写操作命令记录到一个文件中,并持久化到磁盘中。为了保证数据文件的安全,Redis还提供了文件刷写功能。timing:appendfsyncalways:每次写入就刷盘,对性能影响最大,占用磁盘IO量比较高,数据安全性最高appendfsynceverysec:每秒刷盘一次,相对较少影响性能,节点宕机1秒数据丢失最多appendfsyncno:闪存盘根据操作系统的机制,对性能影响最小,数据安全性低,节点宕机和数据丢失取决于操作系统闪存盘的机制。从上面我们可以看出,AOF相对于RDB的优势在于,AOF对数据文件更新及时,比RDB保存了更完整的数据,这样在数据恢复的时候可以恢复到最完整的数据,减少了数据丢失的风险。如果RDB文件和AOF文件同时存在,Redis会优先使用AOF文件进行数据恢复。但是它的缺点也很明显:随着时间的推移,AOF文件会越来越大。AOF文件刷写会增加磁盘IO的负担,可能会影响Redis的性能(开启每秒刷写时)。其中一种情况,Redis提供了AOF瘦身功能,可以设置当AOF文件较大时自动触发AOF重写。Redis会扫描整个实例的数据,重新生成一个AOF文件,达到瘦身的效果。但是这个重写过程也消耗了大量的CPU资源。由于AOF可以将数据丢失的风险降到最低,因此普遍适用于对数据丢失敏感的业务场景,比如涉及金钱交易的业务。性能影响如果将AOF刷写的时机设置为每次写入都刷写,Redis的写性能会大大降低,因为每次写命令都需要写一个文件刷写到磁盘再返回。当写入量较大时,会增加磁盘IO的负担。性能和数据安全不能同时实现。Redis虽然提供了实时刷机的机制,但在实际场景中很少使用。通常我们选择每秒刷盘的方式,这样既能保证良好的写入性能,又能在实例宕机时丢失最多1秒的数据,从而达到性能和安全的平衡。总结我们对RDB和AOF的总结如下。我们需要针对不同的业务场景选择合适的持久化方式,也可以根据RDB和AOF的优势结合使用,既保证Redis数据的安全,又兼顾其性能。
