Redis从入门到高可用--Redis持久化的取舍与高可用

Redis从入门到高可用–Redis持久化的取舍与高可用

一、持久化的作用

1.1、什么是持久化
redis所的数据是保存在内存中,对数据的更新将异步地保存到磁盘上。
1.2、持久化的实现方式
1、快照---mysql的Dump、Redis的RDB
2、写日志---Mysql的Binlog、Hbase的Hlog、Redis的AOF

二、RDB

2.1、什么是RDB

image

2.2、触发机制–主要三种方式
(1)、save(同步):会造成阻塞,O(n),会替换掉旧的.rdb文件;
(2)、bgsave(异步):会fork一个子进程进行持久化操作,在fork的过程中依然可能造成阻塞,O(n),会替换旧的.rdb文件;
(3)、自动:
900秒内1次改变,
300秒内10次改变,
60秒内10000次改变,会自动生成(bgsave)RDB文件

redis.conf的几个参数说明:

dbfilename:rdb文件名
dir ./:生成的rdb文件存放的位置;
stop-writes-on-gbsave-error yes:bgsave发生错误是否停止写入;
rdbcompression yes:rdb文件是否采用压缩的格式;
rdbchecksum yes:是否对rdb文件进行一个校验和的检验;
2.3、触发机制–不容忽略方式
1、全量复制
2、debug reload
3、shutdown
2,4、实验

修改redis.conf如下几个配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
################################ GENERAL  #####################################

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes

# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
# default. You can specify a custom pid file location here.
pidfile /var/run/redis-6379.pid

# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379
...
# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile "6379.log"


...


# save ""

#save 900 1
#save 300 10
#save 60 10000


...

# The filename where to dump the DB
dbfilename dump-6379.rdb

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /root/redis/redis/data

...

其他配置保持默认

执行如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> dbsize
(integer) 0
127.0.0.1:6379> set k1 1
OK
127.0.0.1:6379> set k2 2
OK
127.0.0.1:6379> set k3 2
OK
127.0.0.1:6379> set k4 2
OK
127.0.0.1:6379> set k5 2
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379>

查看后台:

1
2
3
4
5
6
-rw-r--r--. 1 root root 2298 Jun  7 09:32 6379.log
-rw-r--r--. 1 root root 4753 Jun 7 09:24 6382.log
-rw-r--r--. 1 root root 50 Jun 7 09:32 dump-6379.rdb
[root@promote data]# pwd
/root/redis/data
[root@promote data]#

说明:
(1)、若在redis中的数据较大,比如400多M,当执行save命令进行持久化时,同时有另外的客户端在执行get操作,此时的get操作会被阻塞,知道save命令执行完成。
(2)、但是如果是在执行bgsave后,立即执行get操作,则不会阻塞get操作,因为此时主进程会fork一个子进程进行save,主进程执行get操作。
(3)、执行save或者bgsave都会生成一个临时的rdb文件,然后替换旧的rdb文件;

总结

1、rdb时redis内存到硬盘的快照,用于持久化;
2、save通常会阻塞redis;
3、bgsave不会阻塞redis,但是会fork新进程;
4、save自动配置满足任一就会被执行;
5、有些触发机制不容忽视;

三、AOF

3.1、RDB现存的一些问题
 RDB的缺点:
(1)、耗时,耗性能
耗时:O(n),fork:消耗内存,
DiskI/O:IO性能

(2)、不可控,丢失数据
会丢失最后一次的写数据
3.2、什么是AOF
AOF类似于日志,会将对数据的写操作写入AOF文件;
3.3、AOF三种策略
always:
每条命令fsync到硬盘;

everysec:
每秒把缓冲区fsync到硬盘
会丢失一秒的数据
no:
OS决定fsync

三者的比较:
            always      everysec        no
优点      不丢失数据   每秒一次sync     不用管
                        丢一秒数据

缺点       IO开销大,一般   丢一秒数据   不可控
        的sata盘只有几百
            TPS
3.4、AOF重写

image

重写的作用:减少磁盘占用量;加速恢复速度

AOF重写实现的两种方式:
1、命令:bgrewriteaof
AOF重写配置:
2、配置:      配置名                      含义
      auto_aof_rewrite_min_size     AOF文件重写需要的尺寸
     auto_aof_rewrite_percentage    AOF文件增长率

统计        统计名                      含义

        aof_current_size            AOF当前尺寸

        aof_base_size               AOF上次启动和重写的
                                    尺寸(单位:字节)


AOF自动触发时机需同时满足一下两个条件:
aof_current_size > auto_aof_rewrite_min_size
aof_current_size - aof_base_size/aof_base_szie > auto_aof_rewrite_percentage



配置说明:
appendonly  yes  :开启AOF持久化策略
appendfilename  "appendonly-${port}.aof"
appendfsync  everysec
dir /bigdiskpath
no-appendfsync-on-rewrite  yes:关闭aof的append
auto-aof-rewrite-percentage  100
auto-aof-rewrite-min-size  64mb

image

aof重写流程说明:
1、首先,在执行bgrewriteaof命令后,主进程(父进程)会fork一个子进程进行重写aof操作,如图中父进程--->fork--->子进程
2、子进程从内存中回溯重写aof文件如图步骤4,但是若此时主机依然在进行读写怎么办?
3、主进程会进行3-1和3-2操作,即将主进程的写操作写入aof_buf和aof_rewrite_buf中,aof_buf中的操作会继续写入旧的AOF文件中,
而aof_rewrite_buf中的数据会在重写完成以后再将缓存中的数据追加到新的AOF文件中,如5-2
3、子进程重写AOF文件完成后,会将新生成的AOF文件替换旧的AOF文件,如5-3;



AOF后台Rewrite存在的问题:
aof_rewrite_buf是个不限大小的buffer,但用户写入的数据量较多时会出现以下两个问题:
1、占用过多内存,浪费资源;
2、主进程将aof_rewrite_buf数据写入到新AOF文件中时会阻塞工作线程,即步骤5-2,用户正常请求的延时会变高,严重情况下会超时,
主备同步也会出问题,断开重连,重新同步等

AOF后台Rewrite解决方案:
(1)、官方解决方案:主要思路是AOF重写期间,主进程跟子进程通过管道通信,主进程实时将新写入的数据发送给子进程,子进程
从管道读出数据缓存在buffer中,子进程等待存量数据全部写入AOF文件后,将缓存数据追加到AOF文件中,此方案只是解决阻塞工作线程问题,但占用内存过多问题并没有解决。

(2)、新解决方案:主要思路是AOF重写期间,主进程创建一个新的aof_buf,新的AOF文件用于接收新写入的命令,sync策略保持不
变,在AOF重写期间,系统需要向两个aof_buf,两个AOF文件同时追加新写入的命令。当主进程收到子进程重写AOF文件完成后,停
止向老的aof_buf,AOF文件追加命令,然后删除旧的AOF文件(流程跟原来保持一致);将将子进程新生成的AOF文件重命名为appendon
ly.aof.last,具体流程如下:
    停止向旧的aof_buf,AOF文件追加命令;
    删除旧的的appendonly.aof.last文件;
    交换两个aof_buf,AOF文件指针;
    回收旧的aof_buf,AOF文件;
    重命令子进程生成的AOF文件为appendonly.aof.last;
3.5、AOF相关功能的演示
(1)、aof相关配置文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
appendonly no

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"


...


# appendfsync always
appendfsync everysec
# appendfsync no

...

# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

...

# Note that if the AOF file will be found to be corrupted in the middle
# the server will still exit with an error. This option only applies when
# Redis will try to read more data from the AOF file but not enough bytes
# will be found.
//如果aof文件不完整,有错误,当重启aof时是否忽略错误
aof-load-truncated yes
(2)、动态设置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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> exit

...

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
127.0.0.1:6379> incr counter
(integer) 1
127.0.0.1:6379> incr counter
(integer) 2
127.0.0.1:6379> incr counter
(integer) 3
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
127.0.0.1:6379> exit
(3)、可以查看,已经生成了appendonly.aof文件
1
2
3
4
5
6
7
[root@promote config]# cd ../data/
[root@promote data]# ll
total 24
-rw-r--r--. 1 root root 5412 Jun 8 02:57 6379.log
-rw-r--r--. 1 root root 4753 Jun 7 09:24 6382.log
-rw-r--r--. 1 root root 467 Jun 8 03:02 appendonly.aof
-rw-r--r--. 1 root root 50 Jun 7 09:32 dump-6379.rdb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
[root@promote data]# more appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
SET
$2
k4
$1
2
*3
$3
SET
$2
k5
$1
2
*3
$3
SET
$2
k1
$1
1
*3
$3
SET
$2
k3
$1
2
*3
$3
SET
$2
k2
$1
2
*2
$6
SELECT
$1
0
*3
$3
set
$5
hello
$5
world
*3
$3
set
$5
hello
$4
java
*3
$3
set
$5
hello
$5
redis
*2
$4
incr
$7
counter
*2
$4
incr
$7
counter
*2
$4
incr
$7
counter
*3
$5
rpush
$4
list
$1
a
*3
$5
rpush
$4
list
$1
b
*3
$5
rpush
$4
list
$1
c
(4)、开启 BGREWRITEAOF
1
2
3
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379> exit
(5)、查看aof文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[root@promote data]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
SET
$2
k4
$1
2
*5
$5
RPUSH
$4
list
$1
a
$1
b
$1
c
*3
$3
SET
$7
counter
$1
3
*3
$3
SET
$5
hello
$5
redis
*3
$3
SET
$2
k5
$1
2
*3
$3
SET
$2
k1
$1
1
*3
$3
SET
$2
k3
$1
2
*3
$3
SET
$2
k2
$1
2

四、RDB和AOF的抉择

4.1、RDB和AOF比较

image

文章目录
  1. 1. 一、持久化的作用
    1. 1.0.0.0.1. 1.1、什么是持久化
    2. 1.0.0.0.2. 1.2、持久化的实现方式
  • 2. 二、RDB
    1. 2.0.0.0.1. 2.1、什么是RDB
    2. 2.0.0.0.2. 2.2、触发机制–主要三种方式
    3. 2.0.0.0.3. 2.3、触发机制–不容忽略方式
    4. 2.0.0.0.4. 2,4、实验
  • 2.0.0.1. 总结
  • 3. 三、AOF
    1. 3.0.0.0.1. 3.1、RDB现存的一些问题
    2. 3.0.0.0.2. 3.2、什么是AOF
    3. 3.0.0.0.3. 3.3、AOF三种策略
    4. 3.0.0.0.4. 3.4、AOF重写
    5. 3.0.0.0.5. 3.5、AOF相关功能的演示
  • 4. 四、RDB和AOF的抉择
    1. 4.0.0.0.1. 4.1、RDB和AOF比较