Redis实战
黑马点评项目
一.短信登录
导入黑马点评项目
基于session实现登录
发送短信验证码
短信验证码登录
登录验证功能
集群的session共享问题
基于Redis实现共享session登录
总结:
登录拦截器的优化
二.商户查询缓存
什么是缓存
添加Redis缓存
缓存更新策略
在黑马点评项目中用于商铺更新操作
线程安全问题
两者都存在问题,但是先操作数据库的操作,只有在线程一查询时缓存刚好失效才会出现问题。因此先操作数据库再删除缓存的出现问题的可能性极低,因此更推荐使用先操作数据库
总结:
案例
缓存穿透
存在误判的可能是因为数据会存在hash冲突,布隆过滤器时将数据库数据通过哈希算法存在哈希表里面
总结:
缓存雪崩
缓存击穿
解决方案
案例一——互斥锁
案例二——逻辑过期
缓存工具封装
案例
视频在黑马Redis46话,涉及知识点比较多
三.优惠券秒杀
全局ID生成器
实现优惠券秒杀下单
超卖问题
乐观锁
版本号法
CAS法
但是乐观锁存在问题,如果判断与库存是否相同,虽然解决了线程安全问题,但是当库存大于0时,仍然满足可以抢购券,因此条件要改为库存是否>0
一人一单
一人一单并发安全问题
集群式分布的话,不同的jvm就会导致不同的常量池,因此锁也就不同,因此有线程安全问题
分布式锁
基于Redis的分布式锁
将SETNX和EXPIRE合成一步操作,保证了SETNX和EXPIRE同时操作,避免了SETNX操作后宕机没来得及加过期时间这种极小概率事件
基于Redis实现分布式锁初级版本
改进Redis分布式锁
由于线程一在执行时出现业务阻塞,导致在中途其锁就释放,而其他线程此时又进入且获取了锁,当线程一业务完成时释放锁,但是自己的锁已经释放,所以会误删其他线程的锁,因此改进方法就是对锁进行标识,让每个线程只能删自己的锁
不同的jvm可能产生的递增的线程id是会冲突的,因此用uuid比较合适
再改进Redis分布式锁
问题
显然,对锁标识后,分布式锁的性能已经是相当优秀,但是仍然存在问题。
当线程一在执行业务,在要释放锁时遇到了阻塞(虽然这中间并没有其他代码,但是jvm有回收机制,在锁释放时也可能有回收,此时会阻塞所有的代码,不过这个是极小概率事件,但是考虑到锁的完美性能,仍要改进),当阻塞完后,锁已经被释放,此时其他线程进来执行业务,但是业务尚未完成就被线程一将其锁释放,因此又导致了误删
综上,其原因就是判断锁标识和释放是两个动作,这两个动作之间产生了阻塞,从而导致问题,因此要想解决问题,只需要将判断和释放两个动作组成一个原子性的操作即可
解决办法
Lua语言的数组角标是从1开始的
再再改进Redis分布锁,使用Redisson框架
Redisson入门
Redisson可重入锁原理
可重入锁lua脚本获取锁
hincrby和后面的’1’代表自增1
可重入锁lua脚本释放锁
Redisson分布式锁原理
满足了锁的可重入、可重试、超市续约
Redisson分布式锁主从一致性问题
问题
解决方法
要每一个节点都拿到锁才能获取成功
总结
Redis优化秒杀
优化前
优化后
案例
总结
Redis消息队列
基于List结构模拟消息队列
总结
基于PubSub的消息队列
基于Stream的消息队列
总结
基于Stream的消息队列-消费者组
未经确认的消息会存放在pending list当中 通过XPENDING key group 空闲(这里一般取最小到最大, 即- +) number ,通过将读取信息最后的 >改为0
java代码
总结
案例
四.达人探店
发布探店笔记
查看探店笔记
点赞功能
案例
点赞排行榜
案例:对点赞功能优化,从而达到可以查询点赞排行榜
五.好有关注
关注和取关
案例
共同关注
案例
关注推送
Feed流的Timeline实现方式
案例一——实现关注推送功能
案例二——实现查询关注推送页面
六.附近商户
GEO数据结构
案例
附近商户搜索
七.用户签到
BitMap用法
案例
签到统计
案例
八.UV统计
HyperLogLog用法