Redis进阶

Redis进阶

发布订阅

一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis进阶

 

命令 描述
SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息。(创建频道)
UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。
PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道。
PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。
PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态。
PUBLISH channel message 将信息发送到指定的频道。

事务

隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

原子操作:事务中的命令要么全部被执行,要么全部都不执行。

三个阶段:

  • 开始事务。MULTI

  • 命令入队(FIFO)。

  • 执行事务。EXEC

命令 描述
MULTI 标记一个事务块的开始。
EXEC 执行所有事务块内的命令。
WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
UNWATCH 取消 WATCH 命令对所有 key 的监视。
DISCARD 取消事务,放弃执行事务块内的所有命令。

WATCH命令是一个乐观锁

Redis持久化机制

RDB

  1. RDB(Redis Database)持久化是把当前进程数据生成快照保存在RDB文件的过程。

  2. RDB持久化生成的RDB文件是一个经过压缩的二进制文件。

  3. 触发RDB持久化过程分为手动触发和自动触发。

手动触发

命令 描述
SAVE 异步保存数据到硬盘(备份,将rdb文件移动到安装目录并重启服务集合恢复)
BGSAVE 在后台异步保存当前数据库的数据到磁盘

自动触发

Redis会判断是否满足持久化的条件,满足则自动执行bgsave命令进行持久化。是否满足则是通过Redis核心配置文件redis.conf来配置的。比如:

 1 # RDB 保存的条件
 2 save 900 1  # 表示 900 秒内如果至少有 1 个 key 值变化,则把数据持久化到硬盘
 3 save 300 10
 4 save 60 10000
 5 ​
 6 # bgsave 失败之后,是否停止持久化数据到磁盘,yes 表示停止持久化,no 表示忽略错误继续写文件。
 7 stop-writes-on-bgsave-error yes
 8 ​
 9 # RDB 文件压缩
10 rdbcompression yes
11 ​
12 # 写入文件和读取文件时是否开启 RDB 文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。
13 rdbchecksum yes
14 ​
15 # RDB 文件名
16 dbfilename dump.rdb
17 ​
18 # RDB 文件目录
19 dir ./

载入

  1. 如果Redis开启了AOF持久化功能,就会优先使用AOF文件来还原数据库状态,因为AOF文件的更新频率比RDB文件的更新频率高。

  2. 只有在AOF持久化关闭的状态时,服务器才会使用RDB文件来还原数据库状态。

  3. 服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。

优缺点

  1. 优点:RDB文件是一个紧凑的二进制文件,适用备份、全量复制的场景。加载RDB文件恢复数据远远快于AOF文件。

  2. 缺点:不能实时持久化,数据丢失的风险高。每次BGSAVE创建子进程属于重量级操作,频繁执行成本高。

AOF

  1. AOF(Append Only File)持久化以独立日志方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。

  2. AOF的主要作用就是解决了数据持久化的实时性

  3. 被写入AOF文件的所有命令都是以Redis的命令请求协议格式保存的,因为Redis命令请求协议格式是纯文本格式,所以我们可以直接打开一个AOF文件观察里面的内容。

  4. 默认情况下AOF功能是关闭的。我们需要修改配置文件:appendonly no改为appendonly yes。

工作流程

  1. 命令追加:服务器执行完一个写命令后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区末尾。

  2. 文件同步:AOF缓冲区根据对应的策略向硬盘做同步操作。

  3. 文件重写:随着AOF越来越大,需要定期对AOF文件进行重写,达到压缩的目的。

  4. 重启加载:当Redis重启时,可以加载AOF文件进行数据恢复。

文件同步策略

  1. appendfsync always:每次写入都要同步AOF文件,从效率上看,是最慢的,从安全性上看,是最安全的。

  2. appendfsync everysec:每1秒钟同步一次,该策略为AOF的缺省策略。

  3. appendfsync no:从不同步。高效但是数据不会被持久化

Redis明明是单线程,为什么性能还那么高?

  1. 纯内存访问,所有数据放在内存中,内存响应的速度非常快。

  2. 非阻塞I/O,Redis使用epoll作为I/O多路复用技术的实现的,再加上Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多事件。

  3. 单线程避免了线程切换竞态产生的消耗

单线程优缺点

  1. 单线程可以简化数据结构和算法的实现。

  2. 单线程可以避免竞态产生的消耗,锁和线程切换通常是性能杀手。

  3. 对于每个命令的执行时间有要求,如果某个命令执行过长,会造成其他命令阻塞,对于Redis这种高性能的服务来说是致命的。

Redis流水线(管道)

  1. 在一般情况下,用户每执行一个Redis命令,客户端和服务器都需要进行一次通信:客户端向服务器发送命令请求,而服务器则会将执行命令所得的结果返回给客户端。

  2. 减少客户端和服务器之间的通信次数,可以有效提高程序的执行效率。

  3. 流水线功能可以将多条命令打包一起发送,并且在一次命令回复中包含所有被执行命令的结果,使用这个功能可以有效提升程序在执行多条命令时的效率。

 1 import redis
 2  
 3 #创建连接池获取连接
 4 pool = redis.ConnectionPool(host='wykd', port=6379,password='123456', decode_responses=True)
 5 rp1 = redis.Redis(connection_pool=pool)
 6  
 7 #创建管道,可以选择开启或关闭事务,这里的事务与Redis事务一样是弱事务型
 8 pipe = rp1.pipeline(transaction=True)
 9 #在管道中添加命令
10 pipe.set('new','123')
11 pipe.set('name', 'wyk2')
12 pipe.set('company', 'csdn2')
13 pipe.hincrby('hage','wyk',1)
14  
15 #这个命令会报错,因为hage为hash类型不能使用get命令,此时无论开启关闭事务,管道中的其他命令也依然会正常执行
16 #pipe.get('hage') 
17  
18 #也可以用下面的语法将多个命令拼接到一起
19 # pipe.set('name', 'wyk').set('company', 'csdn').hset('hage', 'wyk',28).hincrby('hage','wyk',1)
20  
21 #执行pipeline里的脚本
22 pipe.execute()
上一篇:Redis持久化


下一篇:【Reids】(RDB&AOF&事务&删除策略)