目录
1.多级缓存架构
目标:让数据尽量在前端就直接返回不会打到后端数据库。
主要分为nginx缓存,本地缓存,web层ehcache缓存,redis缓存
2.缓存设计
缓存穿透:数据在缓存层查不到,直接到数据库层,当大量查不到的数据绕到数据库层后会造成数据库崩溃的场景。
解决方案如下,伪代码设计:当缓存查不到以后会缓存到一个value为null的对象并且设置过期时间。
第二种解决方案:布隆过滤器,当get值时如果不存在一定不存在,存在的可能不一定存在值。
缓存失效(击穿):秒杀场景下大量数据设置了过期时间,数据过期失效以后大量请求请求到数据库,导致数据库压力过大挂掉。
解决方案:将过期时间设置为随机时间,这样当大量数据失效的时候不会都同一时间时间,减轻数据库请求。伪代码如下。
缓存雪崩:当redis因为异常情况崩溃,导致前端大量请求直接请求到数据库,导致数据库挂掉。异常情况包括超过redis服务请求范围。
解决方案:
1.保证redis集群高可用
2.使用限流组件比如sentinel或者hytrix,或者使用队列提示前边等待多少人。
3.提前演练,当缓存层泵机以后,后端出现的问题提前做一些预案。
热点缓存key重建优化:当特殊情况一个冷数据突然变成热数据,导致缓存层不能支持过大请求量直接请求到数据库,导致数据库挂掉。
解决方案:使用redis做一个分布式锁,从数据库中查找数据并设置过期时间删除分布式锁,这样缓存就会重建,下次查询之前先休眠一段时间并获取缓存中的key值。
缓存数据库双写不一致:线程更新缓存由于时间轴不同导致结果不一致
解决方案:
1.对于并发量很小数据几乎不用考虑这个问题
2.对于并发量很大数据,缓存加上过期时间依然可以解决业务需求
3. 改造为串行化,但代价太大。
4. 推荐方案加上分布式锁,加读写锁
5.也可以使用阿里开源的canal通过监听binlog日志及时修改缓存
对于读多写少场景基本加一个缓存过期时间即可,对于写多读多的场景建议放弃缓存,直接操作数据库。
3.键值设计
千兆网卡一般要除以8大约128MB/S
3.1 命令使用
3.2 客户端使用
最重要的三个参数:maxTotoal,maxIdle,minIdle
根据应用场景选择淘汰算法。
热点数据采用LFU算法。其他大多数场景使用LRU算法。