redis详细介绍(对redis的实战理解)
把黑马的redis实战看了将近一半 ,自己也做了挺多思考 ,现在对于Redis的使用 ,以及业务方面的思考 ,有了更深刻的理解 。
使用缓存能够加快数据的查询速度 ,提高用户的使用感受 ,对于经常需要访问的数据 ,都可以放到缓存中 ,这样也能给数据库减少压力 。 但是 ,使用缓存之后,就有许多问题需要解决 ,包括业务场景的考虑。 1. 缓存和数据库一致性的问题 这个问题是确保用户能够从缓存中访问到最新的数据 。
-- 一般需要考虑的场景就是:更新了数据库 ,那么我们的缓存也要更新 。否则用户去查数据走缓存,那么拿到的数据就可能是假的 。 如何去更新也是有技巧 ,能够确保不做过多的无效操作 ,也要确保用户能拿到最新数据 。 根据学习,我理解的就是采用:先更新数据库 ,再删除缓存这么一个策略
-- 相较于每次更新完数据库都去更新缓存 。这个策略就能避免很多无效的写操作 。也能确保缓存是最新的(这其中就涉及到一些并发的业务逻辑) 。 2. 缓存击穿问题 这个问题就是热点key失效了 ,而重构这个key又需要比较久的时间 。
-- 而在这个重构的时间段里面 ,如果并发访问数据 ,那么就又会给数据库造成很大压力 。 如何去解决这个问题。我理解的就是加锁 。
-- 如果用户进来查询数据 ,后台发现未命中缓存 ,那么就去尝试获取锁 ,而这个锁 ,是redis中的一个分布式锁 ,setnx这个命令 。拿到了锁,那么就去执行缓存重建逻辑。
-- 而如果这时候 ,其他用户也进来查数据 ,此时肯定拿不到锁,那么就会休眠一会 ,然后尝试重新去查询数据 。 这就是1一个解决方案 ,这个方案能避免给数据库造成很大压力,但是也可能会影响用户体验 ,因为需要进行等待 。 还有一个解决方案就是逻辑超时 ,也就是不给key设置过期时间 ,但是给他设置一个逻辑超时时间 ,这个方案的话就是给k-v的v中存储一个key的有效期。这个方式的话 ,在缓存重建之前 ,用户会拿到脏数据 。 还得根据具体业务去选择 3. 缓存穿透问题 这个问题就是客户端发来了很多请求 ,但是这些请求需要的数据在缓存 、数据库都没有 ,给数据库造成了很大的压力 。 解决方案:1.缓存空数据 2.布隆过滤器(对这个不是很了解 ,没用过) 4. 缓存雪崩问题 这个问题是redis宕机,或者说大量的key失效 解决方案:搭建redis集群分析一个具体的业务场景
用户抢优惠券 ,要满足条件:一人一单
要考虑并发时出现的问题 。
1.首先要查该用户是否有券 ,如果没有就能让它去抢,否则就不允许 2.如果该用户没券 ,就去执行抢券逻辑在查券的时候 ,如果同一个用户发来了很多请求,这是一个并发问题 。
如果说线程1判断无券 ,那么就去执行抢券逻辑 。如果这时候线程2进来了 ,也会判断无券 ,又会执行它的抢券逻辑 。
所以需要加一个锁 ,即使同一个用户发来多次请求 ,此时也是串行的 ,只有等他执行完抢券逻辑 ,才会释放锁 。那么如果该用户的其他的抢券请求进来 ,也不会去执行抢券 。
同时 ,抢券逻辑也在这个锁的锁定范围内,也避免了超卖的问题 。这里的锁需要使用分布式锁 ,比如redis的setnx()。
分析:我们采用的锁对象是 ,user.getId() 。在单体项目之下,对于一个用户的多个请求进来 ,该锁对象确实是唯一的 。
但是如果将该项目做成集群的形式 ,由于每个Tomcat都有自己的JVM,那么此时的锁就不是同一吧了 ,而是这台服务器认为他的这把锁是唯一的 ,那台服务器认为他的这把锁是唯一的。这样子就做不到唯一锁 。所以我们这里需要使用分布式锁 。
但是分布式锁也会遇到一些问题 ,比如说误删锁问题 ,以及删锁时的原子性问题。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!