redis发布订阅/持久化
Redis 通过 PUBLISH 、 SUBSCRIBE 等命令实现了订阅与发布模式。
redis订阅发布:
`https://www.cnblogs.com/pyyu/p/10013703.html`
## redis持久化
`https://www.cnblogs.com/pyyu/p/10009493.html`
Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。
### RDB持久化
redis提供了RDB持久化的功能,这个功能可以将redis在内存中的的状态保存到硬盘中,它可以手动执行。
也可以再redis.conf中配置,定期执行。
RDB持久化产生的RDB文件是一个经过压缩的二进制文件,这个文件被保存在硬盘中,redis可以通过这个文件还原数据库当时的状态。
```
RDB(持久化)
内存数据保存到磁盘
在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
优点:速度快,适合做备份,主从复制就是基于RDB持久化功能实现
rdb通过再redis中使用save命令触发 rdb
rdb配置参数:
dir /data/6379/
dbfilename dbmp.rdb
每过900秒 有1个操作就进行持久化
save 900秒 1个修改类的操作
save 300秒 10个操作
save 60秒 10000个操作
save 900 1
save 300 10
save 60 10000
```
启动redis服务端,准备配置文件
```
daemonize yes
port 6379
logfile /data/6379/redis.log
dir /data/6379 #定义持久化文件存储位置
dbfilename dbmp.rdb #rdb持久化文件
bind 10.0.0.10 127.0.0.1 #redis绑定地址
requirepass redhat #redis登录密码
save 900 1 #rdb机制 每900秒 有1个修改记录
save 300 10 #每300秒 10个修改记录
save 60 10000 #每60秒内 10000修改记录
```
2.启动redis服务端
3.登录redis设置一个key
`redis-cli -a redhat`
4.此时检查目录,/data/6379底下没有dbmp.rdb文件
5.通过save触发持久化,将数据写入RDB文件
```
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> save
OK
```
## redis持久化之AOF
AOF(append-only log file)
记录服务器执行的所有变更操作命令(例如set del等),并在服务器启动时,通过重新执行这些命令来还原数据集
AOF 文件中的命令全部以redis协议的格式保存,新命令追加到文件末尾。
优点:最大程序保证数据不丢
缺点:日志记录非常大
`redis-client 写入数据 > redis-server 同步命令 > AOF文件`
配置参数
```
AOF持久化配置,两条参数
appendonly yes
appendfsync always 总是修改类的操作
everysec 每秒做一次持久化
no 依赖于系统自带的缓存大小机制
```
1.准备aof配置文件 redis.conf
```
daemonize yes
port 6379
logfile /data/6379/redis.log
dir /data/6379
dbfilename dbmp.rdb
requirepass redhat
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
```
2.启动redis服务
`redis-server /etc/redis.conf`
3.检查redis数据目录/data/6379/是否产生了aof文件
```
[root@web02 6379]# ls
appendonly.aof dbmp.rdb redis.log
```
4.登录redis-cli,写入数据,实时检查aof文件信息
`[root@web02 6379]# tail -f appendonly.aof`
5.设置新key,检查aof信息,然后关闭redis,检查数据是否持久化
```
redis-cli -a redhat shutdown
redis-server /etc/redis.conf
redis-cli -a redhat
```
redis 持久化方式有哪些?有什么区别?
rdb:基于快照的持久化,速度更快,一般用作备份,主从复制也是依赖于rdb持久化功能
aof:以追加的方式记录redis操作日志的文件。可以最大程度的保证redis数据安全,类似于mysql的binlog
### RDB和AOF到底该如何选择
(1)不要仅仅使用RDB,因为那样会导致你丢失很多数据。
(2)也不要仅仅使用AOF,因为那样有两个问题,第一,你通过AOF做冷备,没有RDB做冷备,来的恢复速度更快; 第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug。
(3)综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。
### redis持久化文件加载流程
首先是会去判断是否开启了AOF,如果存在存在AOF文件,则直接加载AOF文件
如果找不到AOF文件,则直接启动程序,不会加载RDB文件
如果没有开启AOF,会去加载RDB文件,通过RDB恢复数据
### 企业级的数据备份方案
RDB非常适合做冷备份,每次生成之后,就不会再有修改了。使用定时脚本执行备份方案,crontab -e,该命令详情及使用方法请看百度百科。
### 数据备份方案
1.写crontab定时调度脚本去做数据备份。2.每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份。3.每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份。4.每次copy备份的时候,都把太旧的备份给删了。5.每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去
### 数据恢复方案
如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据,最多就丢一秒的数据量。如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复AOF没有破损,也是可以直接基于AOF恢复的。AOF append-only,顺序写入,如果AOF文件破损,那么用redis-check-aof fix修复,但是要注意的是,修复会导致错误的那条语句被删除,进而导致数据丢失。
我们删除aof文件一行数据并进行修复
```
[root@elasticsearch-04 ~]# redis-cli
127.0.0.1:6379> settest 268900
OK
127.0.0.1:6379> gettest
"268900"
# 要等几秒才能写入aof文件里面
[root@elasticsearch-04 redis]# cd /var/redis/
[root@elasticsearch-04 redis]# ls
appendonly.aof dump.rdb
#删除一行
[root@elasticsearch-04 redis]# vim appendonly.aof
#修复(删除的这一条会丢失)
[root@elasticsearch-04 redis]# redis-check-aof --fix appendonly.aof
0x 71: Expected to read 5bytes, got 0bytes
AOF analyzed: size=113, ok_up_to=86, diff=27
This will shrink the AOF from 113bytes, with 27bytes, to 86bytes
Continue? [y/N]: y
Successfully truncated AOF
```
如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复。当前最新的AOF和RDB文件都出现了丢失/损坏到无法恢复,一般不是机器的故障,找到RDB最新的一份备份,小时级的备份可以了,小时级的肯定是最新的,copy到redis里面去,就可以恢复到某一个小时的数据。
```
[root@elasticsearch-04 redis]# scp -r dump.rdb root@172.17.120.20:/var/redis/
root@172.17.120.20's password:
dump.rdb 100% 186 1.1KB/s 00:00
```
在172.17.120.20上执行:
```
[root@redis-120-20 redis]# systemctl restart redis.service
[root@redis-120-20 redis]# redis-cli
127.0.0.1:6379> gethaha
"248"
127.0.0.1:6379> gettest
"268900"
```