Redis持久化:RDB和AOF配置和对比

来源:互联网 发布:全国教师网络培训平台 编辑:程序博客网 时间:2024/06/05 03:02

1. 前言

  1. Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,
  2. 需要将数据从内存中同步到硬盘中,这一过程就是持久化。
  3. Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。

2. RDB持久化

  1. 持久化机制:指定的时间间隔内将内存中的数据集以快照写入磁
  1. RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。
  1. 进行快照的条件可以由用户在配置文件中自定义,由两个参数构成:时间和改动的键的个数
  2. 当在指定的时间内被更改的键的个数大于指定的数值时就会进行快照。
  3. RDBRedis默认采用的持久化方式,在配置文件中已经预置了3个条件:
    1. save 9001#900秒内有至少1个键被更改则进行快照
    2. save 30010#300秒内有至少10个键被更改则进行快照
    3. save 6010000#60秒内有至少10000个键被更改则进行快照
    1. 可以存在多个条件,条件之间是“或”的关系,只要满足其中一个条件,就会进行快照。 
    2. 如果想要禁用自动快照,只需要将所有的save参数删除即可。
    1. Redis默认会将快照文件存储在当前目录(可CONFIG GET dir来查看)的dump.rdb文件中,
    2. 可以通过配置dirdbfilename两个参数分别指定快照文件的存储路径和文件名。
  • RDB持久化配置(修改redis.conf文件)
  1. RDB持久化配置(修改redis.conf文件)注:标红为配置文件修改部分
  2. deamonize 已进程的形式启动程序改为:yes
  3. timeout 客户端没有操作就中断服务0不中断
  4. RDB快照的配置
  5. database 默认有多少个库16个库
  6. save 9001900秒有一次操作就快照一次
  7. rdbcompression对快照进行压缩 yes
  8. dbfilename 这里可以修改dump.rdb的名字
  9. dir ./默认生成当前目录(目录可以修改)
  1. 文件修复:redis-check-dump(突然断电什么的造成文件损坏)
  1. 通过shutdwon 不会丢失快照数据,直接kill -9直接杀掉异常关机不会实现备份。

  • RDB实现快照的过程
  1. i.Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
  2. ii.父进程继续接收并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件;
  3. iii.当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此一次快照操作完成。
  1. 在执行fork的时候操作系统(类Unix操作系统)会使用写时复制(copy-on-write)策略
  2. fork函数发生的一刻父子进程共享同一内存数据,当父进程要更改其中某片数据时(如执行一个写命令),
  3. 操作系统会将该片数据复制一份以保证子进程的数据不受影响,所以新的RDB文件存储的是执行fork一刻的内存数据。

  1. Redis在进行快照的过程中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候RDB文件都是完整的。
  2. 这使得我们可以通过定时备份RDB文件来实Redis数据库备份。
  3. RDB文件是经过压缩(可以配置rdbcompression参数以禁用压缩节省CPU占用)的二进制格式,所以占用的空间会小于内存中的数据大小,更加利于传输。
  1. 除了自动快照,还可以手动发送SAVEBGSAVE命令让Redis执行快照
    1. 两个命令的区别在于,SAVE是由主进程进行快照操作,会阻塞住其他请求BGSAVEredis执行fork函数复制出一个子进程来进行快照操作
  2. Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。
  3. 根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将一个记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费2030秒钟。 
  4. 通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。
  5. 这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
  6. 如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。

  • RDB持久化优劣
  1. 优势:整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的
  2. 劣势:rdb是以每隔一段时间进行一次快照进行的数据持久,如果一旦在这一时间段出现服务器故障,将会灾难性的。
    1. 解决:这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
    2. 如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。


3. AOF持久化

  1. 持久化机制:以日志形式记录服务器每一个操作,在Redis服务器启动之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。
  • AOF持久化配置(修改redis.conf文件)
  1. 默认情况下Redis没有开启AOF(append only file)方式的持久化,可以在redis.conf中通过appendonly参数开启:
    1. appendonly yes

  2. 在启动时Redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,载入的速度相较RDB会慢一些
  3. 开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。
  4. AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:
    1. appendfilename appendonly.aof

  5. 配置redis自动重写AOF文件的条件
    1. auto-aof-rewrite-percentage 100#当目前的AOF文件大小超过上一次重写时的AOF文件大小的百分之多少时会再次进行重写,如果之前没有重写过,则以启动时的AOF文件大小为依据
    2. auto-aof-rewrite-min-size 64mb#允许重写的最小AOF文件大小


  6. 手动重写AOF文件
    1. 手动执行bgrewriteaof进行重写
    1. 重写的过程只和内存中的数据有关,和之前的aof文件无关。
    2. 所谓的“重写”其实是一个有歧义的词语,实际上, AOF 重写并不需要对原有的 AOF 文件进行任何写入和读取,
    3. 它针对的是数据库中键的当前值。



  7. 配置写入AOF文件后,要求系统刷新硬盘缓存的机制

    1. # appendfsync always #每次执行写入都会执行同步,最安全也最慢
    2. appendfsync everysec #每秒执行一次同步操作
    3. # appendfsync no #不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),最快也最不安全

  8. 文件修复
    1. redis-check-aof


  9. Redis允许同时开启AOFRDB,既保证了数据安全又使得进行备份等操作十分容易。此时重新启动RedisRedis会使用AOF文件来恢复数据,因为AOF方式的持久化可能丢失的数据更少
  • AOF持久化优劣
  1. AOF持久化方式优劣势:
  2. 优势:Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步
  3. 1)修改同步:每修改一次同步一次,对于性能的消耗非常大。
  4. 2)每秒同步:每秒钟进行的操作进行一次同步
  5. 3)不同步
  6. 劣势:对于相同数量的数据集而言,AOF文件通常要大于RDB文件,并且根据同步策略的不同,AOF在运行效率上往往会慢于RDB


4.动态切换持久化方案
  1. 动态切换redis持久方式,从 RDB 切换到 AOF(支持Redis2.2及以上)
  2. CONFIG SET appendonly yes
  3. CONFIG SET save ""(可选)

  1. 注意:redis启动时,如果rdb持久化和aof持久化都打开了,那么程序会优先使用aof方式来恢复数据集,
  2. 因为aof方式所保存的数据通常是最完整的。如果aof文件丢失了,则启动之后数据库内容为空。
  1. 注意:如果想把正在运行的redis数据库,从RDB切换到AOF,建议先使用动态切换方式,再修改配置文件,重启数据库。
  2. (不能直接修改配置文件,重启数据库,否则数据库中数据就为空了。)



5.持久化后,服务器宕机的恢复数据(主从复制)
  1. 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据。
  2. 但是由于数据是存储在一台服务器上的,如果这台服务器的硬盘出现故障,也会导致数据丢失。
  3. 为了避免单点故障,我们希望将数据库复制多个副本以部署在不同的服务器上,即使有一台服务器出现故障其他服务器依然可以继续提供服务。
  4. 这就要求当一台服务器上的数据库更新后,可以自动将更新的数据同步到其他服务器上,Redis提供了复制(replication)功能可以自动实现同步的过程
  • 配置方法

  1. 通过配置文件从数据库的配置文件中加入slaveof master-ip master-port主数据库无需配置
  2. 通过命令行参数启动redis-server的时候,使用命令行参数--slaveof master-ip master port
    1. redis-server --port 6380--slaveof 127.0.0.16379

  3. 通过命令SLAVEOF master-ip master-port
    1. redis>SLAVEOF 127.0.0.16379

  4. SLAVEOF NO ONE可以是当前数据库停止接收其他数据库的同步,转成主数据库
  • 优点及应用场景
  1. 1.读写分离通过复制可以实现读写分离以提高服务器的负载能力。
  2. 在常见的场景中,读的频率大于写,当单机的Redis无法应付大量的读请求时(尤其是较耗资源的请求,比如SORT命令等)可以通过复制功能建立多个从数据库,
  3. 主数据库只进行写操作,而从数据库负责读操作
  4. 2.从数据库持久化持久化通常相对比较耗时,为了提高性能,可以通过复制功能建立一个(或若干个)从数据库,并在从数据库中启用持久化,
  5. 同时在主数据库禁用持久化。当从数据库崩溃时重启后主数据库会自动将数据同步过来,所以无需担心数据丢失。
  6. 而当主数据库崩溃时,需要在从数据库中使用SLAVEOF NO ONE命令将从数据库提升成主数据库继续服务,
  7. 并在原来的主数据库启动后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可将数据同步回来。


6.其他相关命令
  1. redisconfig命令
  2. 使用config set可以动态设置参数信息,服务器重启之后就失效了。
    1. config set appendonly yes
    2. config set save "90 1 30 10 60 100"

  3. 使用config get可以查看所有可以使用config set命令设置的参数
    1. config get *

  4. 使用config rewrite命令对启动Redis服务器时所指定的 redis.conf 文件进行改写(Redis2.8及以上版本才可以使用),
  5. 主要是把使用config set动态指定的命令保存到配置文件中。
    1. config rewrite

  6. 注意:config rewrite命令对 redis.conf 文件的重写是原子性的,并且是一致的: 
    1. 如果重写出错或重写期间服务器崩溃,那么重写失败, 原有 redis.conf 文件不会被修改。 
    2. 如果重写成功,那么 redis.conf 文件为重写后的新文件。

  1. ps -ef | grep redis 查看进程服务是否启动
  2. kill -93004杀掉进程
  3. bgrewriteaof 手动重写aof
  4. requirepass password 配置redis访问密码
  5. auth password 客户端登陆输入访问密码

原创粉丝点击