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" ```