redis是基于内存的数据库,持久化就是把内存的数据写在硬盘上。
redis实现持久化有两种方式:rdb(redis databas默认方式),aof。
1、rdb持久化:(数据库目录下 dump.rdb文件,快照)
# redis的所有数据都存在dump.rdb这个文件下。
# 新的dump.rdb会覆盖旧的dump.rdb文件,只存在一个dump.rdb。
# 拷贝这个文件就能进行数据的备份
# redis会根据特定的策略把内存的数据写入到这个文件中
vim /etc/redis/6379.conf #存储策略在219~221行
save 900 1 #900秒 && 对1条数据进行修改,则把数据写入dump.rdb文件
save 300 10 #300秒 && 对10条数据进行修改,则把数据写入dump.rdb文件
save 60 10000 #60秒 && 对10000条数据进行修改,则把数据写入dump.rdb文件
xxx> save #把内存的数据写入硬盘,阻塞写入,写入时不能访问数据
xxx> bgsave #把内存的数据写入硬盘,不会进行阻塞
rdb优点:
适用于大规模数据恢复,对数据完整性要求不高的场合
会创建一个子进程进行持久化操作
rdb缺点:
意外宕机时,内存中的数据会全部丢失
由于创建子进程进行持久化,因此当用户量多的时候,持久化速度会变慢
2、aof持久化:(append only file,日志)
# 将用户的写操作追加在aof文件中
# 记录redis服务所有的写操作,不断的将新的写操作记录到aof文件在
# 这个服务默认没有开启,拷贝aof文件也可以进行备份
# 读取aof的优先级大于读取rdb的优先级
# 每隔1秒写入到磁盘中,最多丢失1秒的数据。
①、启用aof服务:
# 由于aof的优先级高于rdb,因此通过配置文件的方式启动服务,会清空之前的数据
vim /etc/redis/6379.conf #修改配置文件启动服务
appendonly yes
appendfsync everysec # 703行, -- 每秒刷新一次到硬盘上。always -- 每写入一条就刷新到磁盘上(性能比较差)
# 一般都采用命令行的方式去配置,这样不需要停止服务,数据也不会被清空
xxx> config set appendonly yes #开启aof服务
xxx> config rewrite #修改配置文件
②、恢复数据:
# 只需要把appendonly.aof拷贝到数据库目录下就可以了
# 一定要先停止redis服务,再恢复数据(拷贝文件)
③、aof配置优化:(/etc/redis/6379.conf)
1°:记录写操作的方式
appendfsync always #时时记录,并且同步数据
appendfsync everysec #每1秒记录一次,并且同步数据(默认)
appendfsync no #写入aof中,不进行同步
2°:缩减aof文件
# redis在内存中存储的数据是有限的,有一些会自动过期,有一些会被用户删除,有一些会redis的缓存算法自动清除。
# redis中的旧数据会被不断淘汰,常用的数据会被保存在内存中
# 已经被清理掉的数据还是会保存在aof文件中,因此需要对aof进行缩减,只将那些保留在内存中的数据写入到aof文件中。
# 执行的过程是:开辟一个新的进程,根据当前内存中的数据开始构建一个新的aof文件,当接受到client的数据时,同时写入新的和旧的aof文件,最后用新的aof文件替换旧的aof文件。
auto-aof-rewrite-min-size 64mb # 保证aof文件大于64mb才进行缩减,第一次缩减是64m
auto-aof-rewrite-percentage 100 # 之后再往aof文件中写入当前容量的100%时进行压缩
例如:假设上次缩减之后的容量大小是128mb,那么这次当aof文件到达256mb的时候开始进行缩减。此时还需要跟min-size去比较, 256>64因此会缩减。
3°:修复aof文件:(aof文件不要手动去修改)
redis-check-aof --fix appendonly.aof
aof优点:appendfsync everysec可以保证宕机时只丢失最后一秒的数据
aof缺点:aof文件体积太大,速度慢
实际开发中同时启动aof和rdb
如果有aof和rdb文件,优先使用aof进行恢复,rdb文件中的数据不会恢复到内存中。
写总结的第五十一天!!!
补充:
redis企业级数据备份方案:
1. RDB做冷备
写crontab定时调度脚本做数据备份。
1). 每小时备份一次rdb文件,只保留最近48小时的。
crontab -e
0 * * * * bash /usr/local/redis/copy/rdb_copy_hourly.sh
vim /usr/local/redis/copy/rdb_copy_hourly.sh
#!/bin/bash
curr_date=`date +%Y%m%d%k` # 当前时间精确到小时
rm -fr /usr/local/redis/rdb_bak/$curr_date
mkdir /usr/local/redis/rdb_bak/$curr_date
cp /var/lib/redis/6379/dump.rdb /usr/local/redis/rdb_bak/$curr_date
del_date=`date -d -48hour +%Y%m%d%k` # 当前时间48小时之前精确到小时
rm -fr /usr/local/redis/rdb_bak/$del_date
2). 每天备份一下当天的rdb文件,保留最近1个月的。
crontab -e
0 0 * * * bash /usr/local/redis/copy/rdb_copy_daily.sh
vim /usr/local/redis/copy/rdb_copy_daily.sh
#!/bin/bash
curr_day=`date +%Y%m%d`
rm -fr /usr/local/redis/rdb_bak/$curr_day
mkdir /usr/local/redis/rdb_bak/$curr_day
cp /var/lib/redis/6379/dump.rdb /usr/local/redis/rdb_bak/$curr_day
del_day = `date -d -1month +%Y%m%d`
rm -fr /usr/local/redis/rdb_bak/$del_day
3). 每次备份的时候都把之前旧的备份给删除。
4). 每天晚上将当天备份的所有数据发送一份到远程的云服务器上。
2. 数据恢复方案
1). 如果redis进程挂掉,直接重启redis服务,直接基于aof文件恢复
2). 如果时redis所在的机器挂掉,尝试重启机器,重启redis服务,然后基于aof文件恢复。
3). 如果当前机器上的rdb,aof文件出现了损坏/丢失,那么可以尝试使用当前机器上最新的rdb数据副本进行恢复数据。
# 使用rdb文件恢复数据的时候,要关闭aof恢复的方式以及删除aof文件。如果开打了aof就会优先使用aof文件进行恢复,而不使用rdb文件,如果aof文件不存在,会生成一个新的,空的aof文件用于恢复,这就会导致redis中没有数据。
# 关闭redis,配置文件中关闭aof,删除(备份)aof文件,拷贝rdb文件,启动redis,用命令行的方式开启aof
4). 如果当前机器上的所有rdb文件出现了损坏,那么从远程的服务器上拉去一份最新的rdb文件来进行恢复。使用rdb文件恢复数据的时候,要关闭aof恢复的方式以及删除aof文件。
5). 如果某个时间点之后的数据出现了错误,数据全混乱了,那么可以选择这个时间点之前的某个时间点的数据进行恢复。