Redis
2020-08-01 22:39:21 1 举报
AI智能生成
Redis
作者其他创作
大纲/内容
缓存穿透
场景
查询大量根本不存在的数据,使得请求直达存储层,导致其负载过大,甚至宕机
解决方案
1.缓存空对象
存储层为命中后,仍将空值存入缓存层,再次访问该数据时,缓存层会直接返回空值
2.布隆过滤器
先将所有存在的key提前存入布隆过滤器,在访问缓存层之前,先通过过滤器拦截,若请求的是不存在的key,则直接返回空值
缓存击穿
场景
一份热点数据,它的访问量非常大。在其缓存失效瞬间,大量请求直达存储层,导致服务崩溃
解决方案
1.加互斥锁
对数据的访问加互斥锁,当有一个线程访问该数据时,其他线程只能等待
2.永不过期
不设置过期时间
为每个value设置逻辑过期时间,当发现该值逻辑过期时,使用单独的线程重建缓存
缓存雪崩
场景
由于某些原因,缓存层不能提供服务,导致所有的请求直达存储层,造成存储层宕机
解决方案
1.避免同时过期
设置过期时间时,附加一个随机数,避免大量的key同时过期
2.构建高可用的Redis缓存
部署多个Redis实例,个别节点宕机,依然可以保持服务的整体可用
3.构建多级缓存
增加本地缓存,在存储层前面多加一级屏障,降低请求直达存储层的几率
4.启用限流和降级措施
对存储层增加限流措施,当请求超出限制时,对其提供降级服务
数据类型
key
512M
string
512M
hash
2^32-1
list
2^32-1
set
2^32-1
sorted set
bitmap
512M
hypeloglog
12k
过期策略
惰性删除
客户端访问某个key时,Redis会检查该key是否过期,若过期则删除。
定期扫描
Redis默认每秒执行10次过期扫描(配置hz选项)
1.从过期字典中随机选择20个key;
2.删除这20个key中已过期的key;
如果过期的key的比例超过20%,则重复步骤1;
淘汰策略
noevication
对可能导致增大内存的命令返回错误(大多数写命令,DEL除外)
volatile-ttl
在设置了过期时间的key中,选择剩余寿命(TTL)最短的key,将其淘汰
volatile-lru
在设置了过期时间的key中,选择最少使用的key(LRU),将其淘汰
volatile-random
在设置了过期时间的key中,随机选择一些key,将其淘汰
allkeys-lru
在所有的key中,选择最少使用的key(LRU),将其淘汰
allkeys-random
在所有的key中,随机选择一些key,将其淘汰
分布式锁
场景
修改时,经常需要先将数据读取到内存,在内存中修改后再存回去。在分布式应用中,可能多个线程同时执行上述操作,而读取和修改非原子操作,所以会产生冲突。增加分布式锁,可以解决此类问题
基本原理
同步锁
在多个线程都能访问到的地方,做一个标记,标志该数据的访问权限
分布式锁
在多个线程都能访问到的地方,做一个标记,标志该数据的访问权限
实现方式
1.基于数据库实现分布式锁
2.基于Redis实现分布式锁
3.基于Zookeeper实现分布式锁
Redis实现分布式锁的原则
1.安全属性
独享。在任意时刻,只有一个客户端持有锁
2.活性A
无死锁。即便持有锁的客户端崩溃或者网络被分裂,锁依然可以被获取
3.活性B
容错。只要大部分Redis节点都活着,客户端就可以获取和释放锁
单Redis实例实现分布式锁
1.获取锁使用命令
set resource_name my_random_value NX PX 30000
NX:仅在key不存在时才能执行 PX:设置锁的自动过期时间
2.通过Lua脚本释放锁
A加锁——>A阻塞——>因超时释放锁——>B加锁——>A恢复——>释放锁
多Redis实现分布式锁
Redlock算法,该算法有现成的实现
1.获取房前Unix时间,以毫秒为单位
2.依次尝试从N个实例,使用相同的key和随机值获取锁,并设置响应超时时间。如果服务器没有在规定时间内响应,客户端应该尽快尝试另外一个Redis实例
3.客户端使用当前时间减去开始获取锁的时间,得到获取锁使用的时间。当且仅当大多数的Redis节点都获取到锁,并且使用的时间小于锁失效时间时,锁才算取得成功
4.如果取到了锁,key的真正有效时间等于有限时间减去获取锁使用的时间
5.如果获取锁失败,客户端应该在所有的Redis实例上进行解锁
0 条评论
下一页
为你推荐
查看更多