Redis 入门到分布式 (五) Redis持久化的取舍和选择

Redis持久化的取舍和选择

        持久化的作用
        RDB
        AOF    
        RDB和AOF的选择

一、持久化的作用

           什么是持久化

           持久化的实现方式

1、什么是持久化?

Redis 所有数据保存在内存中,对数据的更新将异步的保存到磁盘上。

如图:

2、持久化方式:

  快照:

  1. MySQL Dump
  2. Redis RDB

   写日志:

  1. MySQL Binlog
  2. Hbase HLog
  3. Redis AOF

二、 RDB1

        什么是RDB
        触发机制-主要三种方式
        触发机制-不容忽略方式
        实验

1、什么是RDB?

Redis是在内存中保存数据的,redis通过一条命令将redis的数据完整的生成一个快照,然后保存到硬盘当中,也就是RDB文件。该文件是二进制的编码保存的。

当我们需要对redis做一个恢复,比如对redis做一个重启,那我们就可以去加载RDB某时某刻的一个二进制备份文件恢复到redis当中。

2、触发机制-主要三种方式:

  •  save(同步)   
  •    bgsave(异步)   
  •    自动

3、save命令:

客户端对redis发送一条save命令,redis就会创建一个RDB文件

代码如下:

redis > save 
OK

文件策略: 如存在老的RDB文件,新替换老

复杂度:   O(N)

4、 API—— bgsave命令

       客户端去执行bgsave,它不会同步的去执行命令,而是使用linux的一个函数 fork(),生成主进程的子进程,也就是redis的子进程,让子进程去执行createRDB生成RDB文件。

       某些情况下,在fork()阶段可能因为bgsave操作太多而造成阻塞。(概率极低)

       bgsave命令的文件策略和复杂度与save是相同的。

5、save和bgsave的对比:

三、RDB2

1、 自动生成RDB策略:

1)该策略通过配置来实现,参数如下:

2)解析:

      第一条: 900秒内改变了一条数据,执行一次save操作

      第二条: 300秒内改变了10条数据,执行一次save操作

      第三条: 60秒内改变了10000条数据,执行一次save操作

   注意: 具体时间和数据量可以通过redis.conf修改

3)配置文件:

上图就是配置文件中的RDB配置参数。

dbfilename dump.rdb

dir ./

日志文件名与存放目录

stop-writes-on-bgsave-error yes            Bgsave发生错误就停止写入

rdbcompression yes                                  对rdb文件采取压缩

rdbchecksum yes                                       对rdb文件进行校验

4)最佳配置:

dbfilename dump-${port}.rdb

dir /bigdiskpath

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

一般不采取默认的save 持久化时间、文件数规则,根据具体的项目要求定义;

Rdb的持久化文件采取 dump-${port}.rdb ,即配置端口号的方式进行创建。从而对rdb文件进行区分、避免相互覆盖;

对bgsave错误采取停止写入操作;

并进行默认压缩和校验操作。

2、触发机制-不容忽略方式:

  1. 全量复制
  2. debug reload
  3. shutdown

以上三个操作都会触发rdb文件的生成。

3、RDB总结

 1)RDB是Redis内存到硬盘的快照,用于持久化

 2)save通常会阻塞Redis

 3) bgsave 不会阻塞Redis,但是会fork新进程

 4)save自动配置满足任一就会被执行

 5)有些触发机制不容忽视

四、AOF1

AOF

        RDB现存问题
        什么是AOF
        AOF三种策略
        AOF重写

1、RDB的问题:

RDB存在耗时、耗性能的问题。

分析:

1.O(n)数据:耗时

RDB生成redis的数据就是将redis在内存中的数据dump到硬盘当中,然后形成一个rdb文件,首先,它是比较耗时的,我们需要把所有数据全部进行dump,并且它是一个IO的过程,本身的写操作会消耗不少CPU;

2.fork() : 消耗内存,copy-on-write策略

其次,涉及到了性能上的消耗。Redis的RDB存在一个fork()的过程,即对主进程拆分出子进程的操作,虽然是使用的copy-on-write策略,并未对全部数据做操作,但依旧会产生内存的消耗。

3.Disk I/O : IO性能

由内存往硬盘中写文件是一个IO的过程,文件越大,对IO性能影响越大。

4.不可控、丢失数据

使用RDB的缺陷在于,当T1执行多个命令后,在T2时间点满足了RDB自动创建条件后,进行了dump操作;当再次执行多个写命令后,由于系统或其他原因导致redis服务器宕机。

此时,默认是会在服务器重新恢复后通过rdb文件将最后一次dump的数据恢复到redis中,那么这里就可能会存在最后一次dump后执行的写命令无法得到恢复的问题。即,数据存在丢失的问题。

因此,这一RDB机制所能保障的数据安全是不可靠的。

解决RDB数据不完整的方法:使用AOF持久化机制

什么是AOF?

2、AOF运行原理——创建

当客户端向redis执行一条写命令时,redis会向AOF文件同步写入那条写操作的命令。该写入操作是实时的。

3、AOF运行原理——恢复:

4、AOF的三种策略:

    always
    everysec
    No

5、 Redis的AOF写入方案

redis在执行AOF的写命令时,不是直接写入到硬盘当中,而是先将写命令的日志写入到硬盘的缓冲区当中,缓冲区会根据一些策略将数据刷新到硬盘对应的aof文件中,从而提高AOF文件写入的效率。

1)策略1: always

而always的意思代表用户在redis客户端每一条写入的命令都会进行同步写入到硬盘当中,这样数据就不会有丢失的危险。

2)策略2:everysec

Redis的命令写入到缓冲区中,缓冲区会在每一秒执行一次命令日志刷新到硬盘当中的操作。

注意:

        ①这可能会在redis宕机后丢失一秒的数据

        ②这是redis的默认配置

3)策略3:no

操作日志刷新到硬盘的频率和时间有操作系统来决定,操作系统决定什么时候刷新,就什么时候刷新。

6、对三种策略的比较:

五、AOF2

1、AOF的问题:

由于时间的推移或写入命令的变多、并发量的增加,AOF文件会变得很大,从而导致很多问题发生。比如:使用AOF来进行恢复会非常慢,并且文件的无限制增大,对于硬盘的管理还是写入命令的速度都会有一定的影响。

解决方案: AOF重写

2、重写图示:

AOF重写原理:将一些过期的、重写的、一些可以优化的命令进行化简成一个很少的文件。

3、AOF重写作用:

  • 减少硬盘占用量
  • 加速恢复速度

4、例子:

Incr key

Incr key

.......

Incr key(一亿次)

比如incr命令或incrby命令,做自增操作。此时有一个key,它自增到了一个亿,相对于AOF文件来说,它需要做一亿次incr操作,那么,可以想象到,它的文件会是非常大的,它会占用很多的空间。

优化:

Incr key 10000000000(一亿)

使用AOF重写进行优化后就只需要执行一次incr命令就可以了。

同样的,在进行恢复的时候,执行一次incr命令远比执行一亿次incr要高效的多。

5、AOF重写实现两种方式:

  • bgrewriteaof
  • AOF重写配置

6、bgrewriteaof :

客户端对redis服务端的主进程发送一条 bgrewriteaof命令,redis会去异步执行aof操作,并返回类似OK的结果给客户端。

当redis得到 bgrewriteaof命令后,会fork()出一个子进程,由子进程去执行 aof重写操作。

注意:AOF重写操作是对redis中的命令进行回溯,从而实现对命令的优化精简重写。

7、AOF重写配置:

配置:

例:

     ①AOF文件达到100MB执行重写

     ②AOF文件的增长幅度达到原来80%进行重写

统计:

8、执行重写操作的基本条件,必须同时满足:

自动触发机制:

 aof_current_size > auto-aof-rewrite-min-size

当前文件必须达到最小尺寸

aof_current_size-aof_base_size/aof_base_size >auto-aof-rewrite-percentage

增长幅度满足增长率:当次文件的尺寸减去上次重写文件的尺寸的差除以上次重写文件的尺寸的比率。

9、AOF重写流程:

解析:

3-1进程是指子进程依旧会将写命令写入到aof_buf当中,然后去写到AOF文件当中。

 除此之外,我们为了能让新的aof_buf文件能够将新的增量数据写到AOF文件当中,可以使用图中的3-2进程来完成。3-2进程会将增量数据写入到一个新的AOF文件当中,最终,会用新的AOF文件来替代老的AOF文件来完成这一重写的完整过程。

10、AOF功能的相关配置:

 appendonly  yes

要使用AOF的所有功能,必须将该配置打开,置为 yes

appendfilename "appendonly-${port}.aof"

在默认文件名appendonly的基础上添加端口port已区分不同的AOF文件,避免覆盖

appendfsync everysec

使用每秒一次的刷新策略

dir /bigdiskpath

用于保存RDB、AOF的文件目录,一般选择比较大的目录存放,必要情况,可以进行分盘操作

no-appendfsync-on-rewrite yes

在做AOF重写时要不要做append操作,这里的配置意思是我们不做append操作。因为AOF的重写是很消耗性能的,要将子进程的数据从缓存刷新到磁盘当中是有很大的消耗的。

六、AOF实验

1、AOF功能演示:

 修改配置:

   客户端查看配置:

动态设置appendonly:

127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> config set appendonly yes
OK

配置启动重写:

127.0.0.1:6379> config rewrite
OK

测试:

127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> set hello java
OK
127.0.0.1:6379> set hello redis
OK

[root@rich redis]# more appendonly.aof

127.0.0.1:6379> incr counter
(integer) 1
127.0.0.1:6379> incr counter
(integer) 2
127.0.0.1:6379> rpush list a
(integer) 1
127.0.0.1:6379> rpush list b
(integer) 2
127.0.0.1:6379> rpush list c
(integer) 3

查看是否生成.aof文件:

查看所有的写操作:

[root@rich redis]# head appendonly.aof

写操作的命令会被进行append

重写aof文件

重写后文件:

查看重写:

重写结果:

七、RDB和AOF抉择 

   RDB 和 AOF 比较

   RDB最佳策略

   AOF最佳策略

   最佳策略

1、RDB与AOF:

问题:在工具目录下,既有RDB文件,也有AOF文件,那么当redis挂掉,重启之后,它时是加载RDB还是AOF呢?(数据安全性)

Redis会优先加载AOF,因为AOF的数据级别是比较高的,大部分情况下,它能够保存比RDB更新的数据。

2、RDB最佳策略:

  ①“关”,建议把RDB关掉,rdb不具备有实时数据安全性;

  ②集中管理,部分场景下比较适合使用,按天、小时进行备份的情况下,数据量级相对较轻,文件比较小、容易传输及管理

  ③主从,从开? 在从节点进行RDB的策略,注意操作不要太重

3、AOF 最佳策略:

 ①“开”:缓存和存储;大部分情况下建议开AOF,有利于持久化;并且大部分情况下只会丢失 1 秒的数据。

 ②AOF重写集中管理,

 ③everysec,每秒去刷盘

4、最佳策略:

①小分片就是使用maxmemory进行规划;

 比如:我們每個分片的最大内存maxmemory 只设置4G,那么无论是fork()等复制传输都会产生较小的开销;

②缓存或者存储

③监控(硬盘、内存、负载、网络)

④足够的内存 (避免内存的不满,导致over)

猜你喜欢

转载自www.cnblogs.com/wushaopei/p/11979111.html