分布式三大利器之《缓存》

缓存和分布式锁的演进(产生问题和解决方案)

分布式下考虑问题始终围绕:
1.单线程,多线程(所谓有无并发问题)
2.单服务器,多服务器(所谓分布式问题)
没有什么是加一层解决不了的,以下redis就是加一层,将多服务器问题降维为单机。
像springCache只是单服务器加锁加缓存,

一、缓存篇:缓存分为本地缓存分布式缓存

凡事有利弊
先要了解缓存的好处
1)减少数据库压力
2)内存级别,比数据库快得多

缺点
1)数据不一致问题
2)占用内存资源

应用场景:
1)读多写少
2)实时性不高

演进过程如下

1:如何解决循环查库,带来的性能低下

改造sql,一次查库,使用流式计算过滤各级分类信息!
这时,如果没有频繁调用此接口,其实不需要缓存

2.好了现在浏览商城首页,需要频繁调用此接口

加入缓存机制,使用最简单的本地缓存map!

3.但是本地缓存map带来的问题如下
1)分布式情况下,数据不一致问题!
2)分布式情况下,每个机子都需要额外维护map,数据冗余

使用redis分布式缓存!

4.分布式缓存随之而来的问题
1)缓存穿透:多次访问数据库不存在的值,使得每次绕过缓存,直接查询数据库
2)缓存雪崩:缓存设置key时,采用相同过期时间。多个缓存在同一时间集体失效,然后此刻遭到百万并发多方位冲击
3)缓存击穿:热点信息的key失效的时候,有百万并发单点冲击

分别解决:
 1)(缓存穿透)给访问数据库不存在的值,在redis设置一个值作为缓存
 2)(缓存雪崩)原有失效时间基础上,增加随机值
 3)(缓存击穿)**加锁**

二、因此进入锁篇

锁同样分为本地锁分布式锁
核心:加锁和解锁保证原子性
锁的问题:
1)锁内存不释放占用资源
2)。。

1.针对上面缓存击穿的问题,如何解决

使用Sychronized或者其他本地锁,显然分布式情况下不适用。
采用redis的setnx来实现分布式锁
底层:采用Lua脚本

2.由于是if语句判断的是否存在锁,倘若没有断电还未删锁怎么办

redis单独加上锁的自动过期时间

3.加上锁的自动过期时间之前断电怎么办

其实setnx可以同时设置加锁和过期时间
目的强调锁的原子性操作

4.Redis锁的过期时间小于业务的执行时间该如何续期?
现象:
当前业务耗时,判断锁还存在后,锁自动过期了,之后把别人的锁删了

redis配合使用Lua脚本,或者使用redission
其看门狗机制底层还是也是使用Lua脚本
本质:保证删除锁的原子性

回到缓存缺点如何解决

1)数据不一致问题

解决:
1.双写模式:操作完数据库,马上修改缓存

2.失效模式:操作完数据库,马上删除缓存

问题:两者都有并发问题
如果业务不需要强一致性,那么就此罢了。
如果需要
解决:
1.加锁,简单粗暴
2.使用canal订阅binlog的方式
canal:阿里开源中间件,伪装mysql从库,从biniog日志拿到mysql更新数据;

2)占用内存资源

必然会占用内存,只能设法减少内存的占用
如:优化redis的key
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值