缓存中间件
2021-07-03 13:43:49 16 举报
AI智能生成
缓存中间件
作者其他创作
大纲/内容
Redis
简介介绍Redis
Redis是一个用C语言写的数据库,数据存储在内存中,所以读写操作效率高;支持多种数据类型,比如String、List、Set、Hash、Sorted Set、HyperLogLog、Geo;支持数据持久化、主从结构、(数据分片)集群部署;一般用作缓存、分布式锁等场景;
特点
支持多种数据类型
String
最基本数据类型,二进制存储
List
有序列表,按照插入顺序排序
Hash
String 元素组成的字典,一般用来存储对象(JSON)
Set
无序集合,使用Hash表实现,不允许重复
可以求交集、并集,适用共同好友、共同收藏场景
Sorted Set
通过分数来将集合元素从小到大排序
HyperLogLog
用于计数
Geo
用于地图坐标、地理位置信息
底层数据类型基础
简单动态字符串
链表
字典
跳跃表
整数集合
压缩列表
对象
支持磁盘持久化
RDB
快照持久化
手动触发RDB快照
SAVE 指令,会阻塞主线程
BGSAVE 后台执行快照,fork一个子线程执行
LASTSAVE 查看上一次快照时间
会生成 dump.rdb 文件
自动触发RDB快照
redis.conf 配置触发备份
save 900 1
900 秒内 如果有一次写入就执行备份
save 300 10
300 秒内有10次写入就执行备份
采用BGSAVE方式
主从复制时,主节点自动触发
Redis Shutdown时没有开启AOF
执行Debug Reload
缺点
内存数据的全量写入,如果内存数据过大,写磁盘IO大,会影响服务性能
如果Redis挂掉会丢失当前到最近一次快照期间的数据
AOF
指令持久化,保存写状态
除了查询指令,其他的都已增量的方式追加到AOF文件
存在问题
假设增量一个场景记录访问数,那么AOP文件会有很多重复指令,文件内容太大
日志重写解决增量指令
调用Fork,创建一个子线程
自线程将新的AOF写到临时文件,不依赖原来文件
主线程将新的变动同时写到内存和原来的AOF文件
主进程获取子进程的重写完成信号,往新的AOF文件同步增量
再用新的AOF文件替换掉旧的AOF文件
Redis在RDB 和 AOF 共存情况下如何恢复数据
如果有AOF文件,加载AOF
如果没有AOF,再看是否有RDB,加载RDB
RDB 和 AOF 优缺点
RDB 优点
内存全量备份
文件小、恢复快
RDB 缺点
会丢失最近一次备份之后的数据
AOF 优点
文件可读性好,适合保存增量数据,数据不会丢失
AOF 缺点
AOF文件大,加载数据慢
RDB(全量) + AOF(增量) 混合持久化方式
BGSAVE 做全量备份
AOF 做增量备份
支持主从
一主二从
哨兵机制
子主题
集群
支持分片
为什么Redis能这么快?
完全基于内存,绝大部分请求操作是基于内存的,执行效率高
数据结构简单
采用单线程、I/O多路复用模型,非阻塞I/O
从海量Key中查出某一固定前缀的Key?
KEYS
数据量少的情况使用
KEYS pattern
查询符合正则的KEYS
KEY 的数量过大导致服务端阻塞
SCAN
数据量大的情况使用
增量式查询
SCAN cursor [MATCH pattern] [COUNT count]
cursor 游标,下一次查询带上上一次的游标
pattern 匹配KEY,支持模糊查询
count 返回元素数量(result <= count)
如何通过Redis实现分布式锁?
分布式锁需要解决的问题
互斥型
安全性
防止死锁
容错性
原子操作
SETNX key value
如何解决SETNX长期有效问题?
设置过期时间
EXPIRE key seconds
大量Key同时过期的注意事项
在设置key过期时间式,加上一个随机值,使key过期时间分散
如何使用Redis做异步队列?
使用List数据类型
rpush 生产消息
lpop 从头消费元素
使用BLPOP设置等待时间
blpop list timeout seconds
没有等待队列
有值直接消费
一对一的
FIFO
Redis 发布/订阅
pub/sub
subscribe topic
publish topic xxx
无状态消息
无法保证消息不丢失
无法保证消息被消费(没有ACK 确认)
生产者在消息投递时,没有消费者接收,那么该消息会丢失
Redis 主从同步(主写从读)
全同步
增量同步
AOF 文件:增量写指令
Redis Sentinel 哨兵机制
解决主从中Master宕机主从切换问题
检查主从服务器是否运行正常
通过API向开发者发送故障通知
Redis集群
分片
去中心化
一致性hash算法
无法保证原子性
SETNX + EXPIRE 组合操作不是原子操作
SET key value [EX seconds] [PX millinseconds] NX|XX
EX 设置key多少秒过期
PX 设置key多少毫秒过期
NX 如果key不存在才可以设置成功
XX 如果key存在才可以设置成功
SET 设置成功返回OK,失败返回nil
为什么要使用Redis?
高性能角度
提升用户访问速度
用户在第一次DB查出数据后将数据缓存到Redis,用户之后访问数据就直接从Redis中获取
要保证数据的一致性
高并发角度
以MySQL为例,在高并发场景下,Redis的QPS是远远大于MySQL
使用缓存可以提高系统的并发
Redis单线程模型详解
Redis是基于Reactor模型实现的网络事件处理器(也就是文件处理器)
文件处理器采用IO多路复用程序,来监听多个Socket连接,根据Socket当前不同的任务来执行不同的事件处理
因为文件处理器是单线程执行的,所以就是常说的单线程模型
缓存穿透解决方案
将数据都缓存到Redis,并设置分散的过期时间
使用布隆过滤器
缓存中间件
Memcache
代码层次类似Hash
支持简单数据类型
不支持持久化
不支持主从
不支持分片
Redis和Memcahe区别和共同点?
共同点
都支持简单数据类型String,可以当缓存使用
数据都是基于内存操作,性能都很高
都有过期策略
区别
Redis支持更丰富的数据类型
Redis支持数据持久化、主从、集群
Redis是单线程多路复用模型,Memcache是多线程,非阻塞IO复用的网络模型
Redis支持发布订阅、Lua,Memcache不支持,Redis支持更多其他语言
Memcache过期策略使用惰性删除,Redis同时使用惰性删除和定期删除
Spring Cache
@Cacheable
表示当前方法或当前类所有方法支持缓存当一个被标记的方法在对象内部调用时,是不会走缓存的(AOP 增强和事物不生效一样)执行标记方法时会检查是否有对应的key存在缓存,有直接返回,没有返回并缓存
标记类
标记方法
@CachePut
执行标记方法时不会检查是否有对应的key存在缓存,每次都会执行目标方法
@CacheEvict
allEntries
true 清除所有缓存,默认 false
beforeInvocation
执行目标方法之前清除缓存
表示清除缓存
@Caching
在方法或者类上同时指定多个Spring Cache相关的注解
0 条评论
下一页