Redis持久化
redis将所有的数据都存储在内存中,所以访问速度很快,但是一旦 redis
重启,所有存储在 redis
中的数据都会丢失。所以要持久化到硬盘中,重启以后可以恢复数据。
redis 持久化的方式有两种,一种是 RDB
方式,一种是 AOF
方式,
- RDB 是按照规则,“定时”将内存中的数据持久化到硬盘中
- AOF 者还是每次执行命令的时候,将命令本身保存下来
但是更多的时候,还是将两者结合起来使用
下面是使用宝塔安装的 redis 的配置界面
RDB方式(快照方式)
RDB方式就是通过快照
实现的,当符合一定条件的时候,就将所有的数据生成副本,保存到硬盘中,这个过程叫做快照。
自动快照
redis的快照条件,可以在配置文件里更改。
save 900 1
save 300 10
save 60 10000
每一行有两个参数:时间窗口、更改键的个数,可以同时保存多个条件,只要满足一个条件,电脑就会自动进行快照
手动快照
当服务器需要重启,手动迁移的时候,需要手动执行快照,redis提供两个命令来完成这一任务
#save命令
save #同步快照,当快照执行的时候,会阻塞所有客户端请求
#bgsave命令
bgsave #Background saving started,后台异步进行快照
lastsave #查看异步是否成功,查看最后一次执行的时间戳
其他触发快照的情况
- 当执行
flushall
命令的时候,redis 会清楚数据库中所有的数据,不管有没有达到触发条件,redis 都会执行一次快照。 - 当执行主从复制的时候,会生成 RDB 快照
RDB原理(快照原理)
Redis默认将文件存储在dump.rdb
文件中,名称和路径可以自己更改
快照过程
- Redis会启动子进程使用
fork
函数复制当前进程的副本 - 父进程继续接受处理客户端请求,子进程开始将内存中的数据写入临时文件
- 当写完临时文件,子进程会用临时文件替换旧的 RDB 文件
快照方式持久化存在的问题
使用 RDB
实现持久化,一旦 redis 异常退出,这样会丢掉最后一次快照后更改的所有数据,但是一般影响并不大,但是如果数据相对来说比较重要,希望将损失降到最低,还需要使用 AOF
实现持久化
AOF方式(append only file)
AOF可以将Redis执行的每一条写命令追加到磁盘文件中,这一过程显然会降低redis的性能,但是大部分情况下是可以接受的,而且还可以使用较快的硬盘来提高AOF的性能。
开启
如果是使用的宝塔安装的,可以直接把下面的选项打开,如果是原始安装的,可以通过参数来启动
AOF的优化
例如下面的例子,执行了三条 redis 命令
set f1 1
set f2 2
set f3 3
但是我们可以看出来,其实前两条是冗余的,因为前两条会别第三条覆盖掉,我们当然希望Redis自动优化 aof
文件,删除无用的记录,显然redis也是这样做的。当达到一定的条件,就会重写 AOF
文件。
auto-aof-rewrite-percentage 100 #当内容超过上次内容的100%的时候,就会发生重写
auto-aof-rewrite-min-size 64mb #限制了自动重写的大小,即内容比较少的似乎,即使翻很多倍,也不会重写
当然也可以手动重写
bgrewriteaof #手动重写命令
同步硬盘数据
上图中的第二个选项appendfsync
是用来设置同步的时机的,这个是因为AOF会将命令记录在AOF文件中,但是事实上,由于操作系统的缓存机制,数据并不会真正的写入到磁盘上,而是写入了磁盘缓存,所以上面的选项就是选择多久写一次。一般是 1秒
,写的太频繁会影响性能。
Redis的主从复制
主从复制和 mysql 的主从复制道理差不多
- 主数据库可以进行读写操作,当操作导致数据变化,可以自动同步给从数据库
- 从数据库一般只读,并接受从主数据库中同步过来的数据
- 一个主数据库可以有多个从数据库,而一个从数据库,只能有一个主数据库。
配置主从复制
#开启一个redis,端口号6380,作为6379端口的从库
redis-server --port 6380 --slaveof 127.0.0.1 6379
redis-cli #打开默认的6379的客户端
redis-cli -p 6380 #新开一个窗口,打开6380的客户端
结果如下
经过测试,发现从库只能读,不能写。
查看主从数据库配置
分别在主从库里执行如下命令,查看主从复制情况
info replication
主库info信息
# Replication
role:master #角色
connected_slaves:2 #几个从库
slave0:ip=127.0.0.1,port=6380,state=online,offset=950,lag=1 #从库 1
slave1:ip=127.0.0.1,port=6388,state=online,offset=950,lag=1 #从库 2
master_replid:c8c89aadcb4f0759db4d091c307cbbe60e5bbb98
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:950
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:950
从库info信息
role:slave #角色
master_host:127.0.0.1 #端口号
master_port:6379 #主表端口号
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:1188
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:c8c89aadcb4f0759db4d091c307cbbe60e5bbb98
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1188
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1188
主从复制原理
复制过程
- 当一个从数据库启动的时候,会向主数据库发送
SYNC
命令。 - 主数据库收到命令后,会立刻在后台保存快照,并将此期间收到的数据缓存起来
- 主数据库将快照和所有的缓存命令发给从数据库
- 复制初始化完成以后,主数据库每当收到写命令,就会将数据同步给从数据库,以保证主从数据库的一致性
断网重连
Redis2.8以后,当数据库断网以后,主数据库只需要将断线期间执行的命令传给从数据库,而2.8之前的版本,是进行重新的初始化。这里用到的技术就是有条件的增量数据传输。
从数据库持久化
为了保证主数据库性能,可以使用一个或多个从数据库来实现持久化,而不是在主数据库中。
哨兵
在典型的一主多重的 redis
系统中,当一个主数据库遇到异常中断服务,开发者可以手动的选择一个从数据库来升格为主数据库,但是整个过程如果都需要人工介入有点太麻烦,难以实现自动化。所以redis2.8以后,实现自动化的系统监控和古故障恢复功能
所以哨兵的主要作用有两个:
- 监控主数据库和从数据库是否正常运行
- 主数据库出现故障,自动把从数据库转成主数据库
哨兵的部署
首先开启两个 redis 服务
redis-server --port 6380 --slaveof 127.0.0.1 6379 #从库 1
redis-server --port 6381 --slaveof 127.0.0.1 6379 #从库 2
在任意一个文件夹下建立如下文件
建立文件夹sentinel.conf
,文件名随便
# 最后的 1 ,表示的是最低投票数
# 其次注意,我们写哨兵,只需要监控主数据库就可以了,其他的都自会关联
sentinel monitor myredis_sentinel 127.0.0.1 6379 1
这样的话,哨兵模式就启动了,如果主机挂掉,其他的就会自动更新成主数据库