一、持久化
持久化的意义
Redis是基于内存的NoSQL数据库,读写速度自然快,但内存是瞬时的,在redis服务关闭或重启之后,redis存放在内存的数据就会丢失,为了解决这个问题,redis提供了两种持久化方式,以便在发生故障后恢复数据。
持久化的选择
redis提供了两种不同的持久化方式来将数据存储到硬盘中。一种是快照方式(也叫RDB方式),它可以将莫一时刻存在于redis中的所有数据存储到硬盘;另一种叫只追加文件(AOF方式),它会定时的复制redis执行的所有写命令到硬盘。这两种持久化方式各有千秋,既可以同时使用,也可以独立使用,在某些情况下甚至可以两种都不使用。
RDB方式
RDB方式也称快照方式,通过创建快照来保存某个时间点上的数据副本(.rdb)到硬盘。在重启服务器后,redis会加载这个rdb文件来还原数据。先来看一下rdb持久化配置。 vi redis.conf 打开redis的配置文件,找到SNAPSHOTTING部分,发现如下内容:
save 900 1
save 300 10
save 60 10000
……
dbfilename dump.rdb
dir ./
说明:
- save seconds changes:表示在seconds秒后,如果有不少与changes个key发生改变,则保存一次快照。可以看到,rdb持久化默认是开启的,并且配置了三个save选项,如果想要关闭rdb持久化,将所有的save注释掉就好了
- dbfilename:rdb文件名
- dir:rdb文件存放路径
创建快照
BGSAVE:
BGSAVE命令可以用于创建一个快照,在redis接收到BGSAVE命令后会fork出一个子进程,子进程负责将快照写入硬盘,而父进程则继续处理命令请求。需要注意的是redis在创建子进程时会阻塞父进程,时间长短与redis占用的内存大小成正比。 除了手动的调用BGSAVE命令外,BGSAVE命令的触发条件有如下两种:
- 用户配置了save选项,从redis最近一次创建快照开始算起,当任意一个save选项的条件被满足时,会触发一次BGSAVE命令。
- 在进行主从复制连接时,刚连上来的从服务器会向主服务器发送SYNC命令请求数据同步,在主服务器收到SYNC命令后,会执行一次BGSAVE命令,后将生成的rdb文件发送给从服务器进行数据同步。
SAVE:
SAVE命令同样可以创建一个快照,但与BGSAVE命令不同的是SAVE命令不会创建子进程,所以接收到SAVE命令的redis服务器在快照创建完毕之前不会响应其他任何命令。由于在创建快照的过程中没有其他进程抢夺资源,所以SAVE命令创建快照的速度会比BGSAVE命令创建快照更快一些。即使这样,SAVE命令也并不常用,通常只会在没有足够内存或等待快照生成完毕也无所谓的情况下才会使用。 例如,当redis收到SHUTDOWN命令关闭服务时,就会执行一次SAVE命令,阻塞所有客户端,并在SAVE命令执行完毕后关闭。
RDB方式的优劣
优势:
- 仅用一个文件备份数据,灾后易于恢复
- 相比于aof,rdb文件更小,并且加载rdb文件恢复数据也更快
劣势:
- 如果redis服务因故障关闭或重启,会丢失最近一次快照创建后写入的数据
- 当数据量很大的时候,创建子进程会导致redis较长时间的停顿
AOF方式
简单来说,AOF持久化会将被执行的写命令写到aof文件的末尾,以此来记录数据发生的变化。因此,redis只要从头到尾重新执行一遍aof文件中包含的所有写命令,就可以恢复数据。
打开redis配置文件可以看到:
# 是否开启aof持久化,默认为关闭(no)
appendonly yes
# 设置对aof文件的同步频率
# 每接收到一条写命令就进行一次同步,数据保障最有力,但对性能影响十分严重
appendfsync always
# 每秒进行一次同步,推荐
appendfsync everysec
# 由操作系统来决定何时进行同步
appendfsync no
# 重写aof相关
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
重写/压缩aof文件
由于aof持久化会不断地记录redis的写命令,随着redis的运行,aof文件会越来越大,占用过多的硬盘空间,并增加redis进行数据还原操作的时间。因此,必须要有避免aof文件体积过大的控制方案。
redis提供了BGREWRITEAOF命令对aof文件进行重写,BGREWRITEAOF会通过移除原aof文件中冗余的命令来尽可能的减小aof文件的体积。BGREWRITEAOF的工作原理与BGSAVE很像,会由redis创建一个子进程,再由子进程对aof文件进行重写。
当然,BGREWRITEAOF命令同样也有自动触发的机制,可通过配置auto-aof-rewrite-percentage 和auto-aof-rewrite-min-size 来自动执行。例如,配置了auto-aof-rewrite-percentage 100 和 auto-aof-rewrite-min-size 64mb,并且开启了aof持久化,那么在aof文件体积大于64mb且当前文件比上一次重写后的文件体积大了一倍(100%)以上时,redis会自动执行BGREWRITEAOF 命令。
AOF持久化的优劣
优势:
- 可以将丢失数据的时间窗口降低至1秒,并且不会对性能在成太大影响
- aof对于日志文件采用的是追加模式,因此在写入过程中即使出现宕机,也不会破坏日志文件中已经存在的内容;若只写入一半数据就宕机,在redis下次启动时,可通过redis-check-aod工具来解决数据一致性的问题
劣势:
- aof文件的体积一直是AOF持久化最大的缺陷,即使有重写aof文件的机制存在
- 载入aof文件恢复数据的过程会比载入rdb文件耗时更长
二、主从复制
尽管redis性能十分优秀,但还是会遇到无法快速处理请求的问题,为了抗高并发带来的数据库性能问题,redis可以像关系型数据库一样进行主从复制、读写分离。即向主服务器写入数据,从服务器实时收到更新,并使用从服务器处理所有的读请求,而不是像以前一样将所有读请求都发送给主服务器,造成主服务器压力过大,通常读请求会随机地选择使用哪一个从服务器,从而使负载均衡地分配到每一个从服务器上。下图是一个简单的redis主从架构。
主从复制配置
首先在你的redis目录下执行vi redis6380.conf 在当前目录下创建一个redis配置文件,写入如下内容:
include /usr/local/redis-4.0.13/redis.conf
port 6380
pidfile /var/run/redis_6380.pid
logfile 6380.log
dbfilename dump6380.rdb
说明:
- include:向当前配置文件中引入所指向的配置文件的配置信息,这里引入的是redis默认配置文件,其中已经设置过远程访问、密码等,没必要在新的配置文件中重新设置。对于有必要重新配置的配置信息来说(如端口号),include行下进行的配置可以覆盖引用的配置。
- port:端口号,我们的主从服务器是跑在同一台虚拟机上的,因此需要配置不同的端口号。
- pidfile:自定义的pid文件,后台程序的pid存在这个文件里。
- logfile:日志文件。
- dbfilename:rdb文件的名字。
经过上述操作,一个新的主服务器就配置好了,接下来配置从服务器,同样在当前目录下创建一个redis配置文件起名redis6382vi redis6382.conf
include /usr/local/redis-4.0.13/redis.conf
port 6382
pidfile /var/run/redis_6382.pid
logfile 6382.log
dbfilename dump6382.rdb
slaveof 127.0.0.1 6380
masterauth 主服务器的密码
其中有一些从服务器额外的配置:
- slaveof:表示我是谁的从服务器,需要制定主服务器的ip地址和端口号
- masterauth:假如你的主服务器配置了密码,那么需要在此进行配置,否则从服务器将无法连接到主服务器
其他的从服务器配置也都类似,注意分配端口号,我这里又配置了一个6384。 配置成功后,在src目录下使用./redis-server ../redis6380.conf 就可以开启主服务器了,接下来开启从服务器会自动连到主服务器上,注意指定对应的配置文件。 执行ps -ef | grep redis 看到如下内容则表示主从服务器启动成功:
|