Redis单线程的高效性
Redis是单线程,效率依然很高。因为其在内存上进行读取速度很快,而多线程场景下进行CPU上下文切换会非常耗时。
1. 五种基本数据类型
String
使用场景:除了字符串,也可以设置为数字
- 计数器
- 统计多单位的数量
- 对象缓存存储
List
Hash
Set
Zset
2. 三种特殊数据类型
geospatial
hyperloglog
bitmaps
3. 事务
Redis单条命令保证原子性,但是事务不保证原子性,和Mysql不一样。
Redis事务不支持回滚,而是执行余下代码,因此内部可保证简单与快速。
Redis事务本质:
- 一次性:一组命令的集合,执行前会被放入队列缓存,事务命令集都会被序列化
- 顺序性:收到执行请求后,事务命令顺序执行,任意命令失败,不影响其余命令执行;
- 排他性:事务执行时,其他命令请求无法插入当前事务。
Redis事务执行:先入队再执行
- 开启事务(multi)
- 命令入队(…)
- 执行事务(exec)
- 放弃事务(discard)
放弃事务:事务队列中所有命令均不执行 编译型异常:命令有错时,编译出错,事务所有命令均不执行 运行时异常:编译可通过但有语义错误,正确命令正常执行,错误命令抛出异常。
4. Redis乐观锁
执行时不加锁,更新数据时再判断是否被改动过。可判断版本号version
- 获取version
- 执行命令
- 数据写入时比较version
Redis监视
- watch监视一个或多个key,若事务执行期间key改动,则必执行失败(所有命令均不执行)
- 事务exec或discard后会自动unwatch。
- 事务执行失败后,可再次监视获取最新version,重新执行事务。
Redis持久化
RDB方式
概述: Redis database,默认持久化方式。在指定时间间隔内将内存中的数据集快照写入磁盘。redis会将数据存在内存中,满足一定条件时会对数据进行快照操作并生成临时RDB文件,之后持久化到硬盘中(替换旧的RDB文件)。
存储文件名: dump.rdb
快照触发时机:
-
自定义配置save
save m秒 n改键,若注释掉则不进行持久化
满足要求自动触发bgsave
-
执行save
该命令期间redis服务器被阻塞,无法处理其他命令,直到RDB完成。完成后若有旧RDB则替换。
-
执行bgsave
该命令首先使redis进程fork子进程(阻塞),之后主进程保持响应客户端请求,子进程后台异步进行RDB持久化。
RDB特征:
- 快照时不修改原RDB文件,因此任何时候RDB文件均完整。可定时备份RDB实现redis数据库备份。
- 子进程会处理保存工作,父进程无需执行磁盘I/O。
- 全量备份,RDB恢复大数据集速度优于AOF
- 快照持久化期间无法感知redis内存数据被修改,因此可能丢失数据。因此持久化重要数据可以考虑AOF
AOF方式
概述: append only file,默认不开启。每执行一条更改redis数据的命令,Redis就会将其写入磁盘中的AOF文件,以此同步数据库状态。这对redis性能会有一点影响,使用较快磁盘可改善AOF性能。
存储文件名:appendonly.aof
redis客户端执行命令时,先通过网络将resp协议文本发送给redis服务器,AOF文件使用网络通讯协议格式来保存命令。
命令同步至AOF文件
-
命令传播
redis客户端以resp协议发送命令,服务器将字符串文本转换为redis字符串对象。命令执行完后,将命令信息传播至AOF程序
-
缓存追加
AOF将redis字符串对象还原回resp协议格式,追加至服务器AOF缓存redis.h/struct redisServer{sds aof_buf}
redis.h struct redisServer { sds aof_buf; //追加至aof缓存 }; -
文件写入和保存
WRITE:aof_buf缓存内容写入AOF临时文件末尾。
SAVE:若满足设定的AOF保存条件,则调用fsync函数,将AOF文件持久化到磁盘。
AOF保护模式
-
不保存
只在redis被关闭、AOF功能关闭、写缓存刷新时,会由主进程执行SAVE持久化操作,主进程期间被阻塞。
-
每秒保存
SAVE操作由后台子进程调用,不引起服务器主进程阻塞,但SAVE速度影响WRITE操作的阻塞时长(进程切换或硬件有关)。
-
每条命令保存
每执行一次,WRITE与SAVE被执行,SAVE由主进程执行,期间主进程被阻塞。
Redis发布订阅
Redis主从复制
主从复制方式
① 全量复制
首次同步
-
建立连接、协商同步
从server执行replicaof命令,请求主server同步,主server返回FULLRESYNC,表征全量复制。
-
主server同步数据至从server
主server执行bgsave,fork子进程生成RDB文件,并发送给从server,从server清空当前数据后载入该RDB文件。期间主server收到新的写命令会存入replication buffer。
-
主server发送新写命令至从server
主server将replication buffer记录的写命令发送至从server,从server执行写命令。
首次同步即完成。
② 命令传播(基于长连接)
首次同步会传输数据。之后不用再传输数据,双方只需维持一个TCP连接,主server不断传输新的写命令至从server,由从server执行即可。
基于长连接的命令传播来保证首次同步后的主从server数据一致性。
③ 增量复制
若slave与master断开连接后又恢复,此时slave会发送psync{runId}{offset}命令给master,master根据slave_repl_offset与master_repl_offset作差判定期间丢失命令是否全部在缓冲区中:
- 若在,则在repl_backlog_buffer中查找增量写入replication buffer,并通过增量复制传播给slave
- 否则重新进行全量复制。为降低全量概率,可以适当调整repl_backlog_size大小。
主从复制key过期
Redis处理key过期有惰性删除和定期删除两种方式。配置主从复制后slave无权处理过期key,master累积过期key到一定量后,发送del至slave,删除slave的key。slave变为master后重获处理过期key的权限。
分摊Master server压力
Master server生成并传输RDB文件很耗时,slave server数量过多时master压力会很大,可以将master生成并传输RDB的压力分摊到充当经理的slave server。
实现方法为:slave server执行replicaof指向经理server。
Redis缓存穿透 击穿 雪崩
Redis底层数据结构
Redis配置文件
基本配置
bind 127.0.0.1
port 6379
protected-mod yes #保护模式
unit配置 # unit对大小写不敏感
daemonize yes #守护进程方式运行,默认no关闭
pidfile /var/run/redis_6379.pid #若后台执行,需要指定pid文件
loglevel notice #日志级别 debug/verbose/notice/warning
logfile "" #日志的文件位置
database 16 #默认16个数据库
持久化配置