redis整理:常用命令,雪崩击穿穿透原因及方案,分布式锁实现思路,分布式锁redission(更新中)
redis个人整理笔记
reids常见数据结构
- 基本类型
- String: 普通key-value
- Hash: 类似hashMap
- List: 双向链表
- Set: 不可重复
- SortedSet: 不可重复,有序,hash+跳表
- 特殊类型
- GEO:地理位置
- BitMap:
- HyperLog
redis通用命令
- keys:所有key
- del:删除
- exists:判断是否存在
- expire: 设置有效期
- ttl:查看key剩余失效时间
数据类型
string类型
- 特性:
- string:普通字符串
- int:可以自增自减
- float:可以自增自减
- 最大空间不能超过512m
- 常见命令:
- set:无则添加,有则覆盖
- get:获取key的值
- mset:批量添加键值对
- mget:批量获取key的值
- incr:让一个整形自增
- incrBy:让整形自增指定步长
- incrByFloat:让一个浮点类型的数字自增并指定步长
- setNx:无则新增,有则不执行
- setEx:添加一个string类型的键值对,并且指定有效期
hash类型
- 特性:
- hash类型,也叫散列,其value是一个无序字典,类似java中hashMap
- 常见命令:
- hset:添加或则修改hash类型的key的值
- hget:获取value值
- hmset:批量hash新增
- hmget:批量hash查询
- hgetAll:获取一个hash类型中的所有key-vlues键值对
- hkeys:获取一个hash类型的key中所有的key
- hvals:获取一个hash类型的key中所有的值
- hincrby:让一个hash类型的key的字段值自增并指定步长
- hsetnx:添加一个hash类型的值,有则不添加,前提这个key不存在,否则不知想
list类型
- 特性:
- 类似java中的linkedList,可以看作一个双向链表,既可以支持正向检索,也可反向
- 有序
- 元素可以重复
- 插入和删除块
- 查询速度一般
- 常用来存储一个有序数据例如,点赞,评论列表
- 常见命令
- lpush:向列表左侧插入一个或多个元素
- lpop:移除并返回左侧第一个元素,没有则返回nil
- rpush:列表右侧插入一个或者多个元素
- lrange 返回一个角标范围内的所有元素
- blpop和brpop,没有元素时等待指点时间,而不是之家返回nil
- 场景
- 1.模拟栈
- 入口和出口在同一边,先进后出
- 2.模拟队列
- 入口和出口不在同一边,先进先出
- 3.阻塞队列
- 入口出口不在同一边,出队时候才有blpop或者brpop
set类型
- 特性:
- 可以看作value为null的hashMap
- 无序
- 元素不可重复
- 查找快
- 支持交并差
- 常见命令
- sadd:添加一个或者多个元素
- srem:移除指定元素
- scard:返回个数
- sismember,判断元素是否存在
- smembers:获取所有元素
- sinter k1 k2 :求交集
- sdiff k1 k2 :求差集
- sunion k1 k2 : 求并集
sortedSet类型
- 特性
- 可排序的set集合,每个元素有个score属性,可以基于score对元素进行排序,底层是跳表加hash表
- 可排序
- 元素不重复
- 查询速度块
- 常用来实现排行榜
- 常见命令
- zadd: 添加一个或多个如果已存在则更新score值
- zrem :删除指定一个元素
- zscore:获取指定key的分值
- zrank:获取指定元素的排名
- zcard,获取元素个数
- zcount key min mak:统计分值在指定范围内的所有元素的个数
- zincrby:指定步长自增
- zrange:获取指定排名范围内元素
- zrangebyscore:获取指定分值范围内的元素
- zdiff,zinter,zunion:求差集,交集并集
- 所有的排名默认都是升序
redis应用场景
- 基于list实现点赞列表
- 基于sortedset实现排行榜
- 基于set实现共同关注,共同好友
- 基于bitmap实现签到数据统计
- 基于hyperLogLog实现Uv统计
- geohash实现地理位置
- Lua脚本+setnx实现分布式锁
- 计数器
- 热点数据查询缓存
- 共享session
- 时效性数据,短信验证码
- 全局唯一id
- 分布式锁
缓存作用及成本
- 作用:
- 降低后端负载
- 提高读写效率,降低响应时间
- 成本:
- 数据一致性成本
- 代码维护性成本
- 运维成本
缓存更新策略
- 低一致性:
超时时间机制,内存默认淘汰机制
- 高一致性:
主动更新,超时剔除作为兜底,修改直接删除缓存,提高一致性,先删除数据库数据,再删除缓存数据,查询时候在添加缓存
缓存穿透,击穿,雪崩
- 穿透:
出现原因:
请求缓存数据库中不存在的值
解决方案:
缓存短时间空值/布隆过滤器/增加id复杂度/做好基础格式校验/加强用户权限校验/做好限流
- 击穿:
出现原因:
热点数据失效,大并发打入数据库
解决方案
互斥锁:
互斥更新只允许一个线程去查库重建缓存,其他等待递归,没有额外的内存消耗,保证一致性,实现简单,线程需要等待性能影响,可能会死锁
逻辑过期:
线程无序等待,但是不保证一致性,有额外的内存消耗,实现复杂
- 雪崩:
出现原因:
大批量key同时失效,并发同时打入数据库/reids宕机
解决方案:
随机秒数稀释缓存失效时间
redis高可用
分布式锁
- 实现思路
- 利用setnx获取锁,并设置过期时间,保存线程标识
- 释放锁先判断线程标识是否与自己一致,一致则删除(原因:不加标识如果线程阻塞,锁超时释放,则其他线程获取到该锁,如果没有唯一标识则可能会删别人的锁,造成并发问题)
- 特性
- 利用setNx满足互斥
- 利用超时时间避免死锁
- 利用redis集群保证高可用高并发
- 出现问题
- 不可重入:同一个线程无法多次获取同一把锁
- 不可重试:获取锁只尝试一次没有重试机制的话会造成500人1秒并发进行抢购100商品,可能会出现商品还有剩余
- 超时释放:如果线程执行较长,导致锁释放,存在隐患
- 主从一致性:如果redis主从存在延迟,当主节点宕机,如果存在数据部分未同步,主从出现了切换,存在隐患.