缓存击穿
缓存击穿,是指一个key很是热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。redis
那么如何解决这个问题呢?数据库
有不少种思路能够解决这样的问题,好比使缓存常驻内存,采用异步刷新等方法,这里介绍使用分布式锁来解决这样的问题。缓存
大致思路
- 1.咱们从缓存中获取数据,若是获取到数据则直接返回。
- 2.若是未从缓存中获取到数据,就须要从数据库中读取,为了防止大量并发直接访问数据库,就须要加上分布式锁,确保只有一个请求访问数据库。
- 3.当加锁成功,作一下三步:1)从数据库中读取数据, 2)把数据写入缓存, 3)删除分布式锁。
- 4.若是加锁没有成功,则让进程休眠一段时间,重复1步骤。
- 5.为了防止意外状况的发生,咱们须要设置一个阀值,当获取缓存中的次数超过阀值时,直接退出程序,防止大量的并发被阻塞。
redis实现分布式锁
咱们这里使用redis实现分布式锁,使用下面的语句实现bash
SET [KEY] [RAND_NUM] EX [LOCK_TIME] NX
复制代码
- KEY: 锁的键,根据实际状况指定。
- RAND_NUM: 随机数,防止因执行时间过长锁失效,致使误删锁的操做。
- EX: 表示设置此锁的失效时间防止过时后死锁。
- LOCK_TIME: 多少秒后过时。
- NX:表示若是次锁不存在,则建立此锁。
当锁不存在时,redis会返回"ok",表示锁建立成功,当锁存在时,redis返回"NULL",咱们能够根据返回值来肯定是否有建立成功。并发
使用场景
咱们从流程图上能看到,更新缓存会致使并发线程阻塞。异步
这里有两个关键点会影响系统性能:分布式
- 1.单个缓存并发数量越大,对系统性能影响越大。
- 2.更新单个缓存时间越长,对系统性能影响越大。
因此使用此方法使用场景是:非热点的简单缓存数据(并发小,更新时间短)。性能