咸宁市网站建设,wordpress 最新教程视频,八年级信技做网站,建设企业网站官网下载目录
前言#xff1a;
为什么说关系型数据库性能不高
如何提高MySQL并发量
缓存更新策略
定期更新
实时更新
内存淘汰策略
Redis内置的淘汰策略
缓存常见问题
缓存预热
缓存穿透
缓存雪崩
缓存击穿 前言#xff1a; 对于缓存的理解#xff0c;缓存目的就是为了…目录
前言
为什么说关系型数据库性能不高
如何提高MySQL并发量
缓存更新策略
定期更新
实时更新
内存淘汰策略
Redis内置的淘汰策略
缓存常见问题
缓存预热
缓存穿透
缓存雪崩
缓存击穿 前言 对于缓存的理解缓存目的就是为了提供更快速的访问效率。一般会使用访问迅速的为访问较为缓慢的作为缓存。例如使用内存作为硬盘的缓存硬盘作为网络的缓存。使用缓存可以减轻被缓存服务请求数量一定程度上提供了系统高可用性能。
为什么说关系型数据库性能不高
1数据库把数据存储在硬盘上硬盘IO速度并不快尤其是随机访问。
2如果查询不能命中索引就需要进行表遍历这会大量增加硬盘IO次数。
3关系型数据库会对SQL进行一系列的解析优化校验等工作。
4一些复杂查询联表查询会进行笛卡尔积操作效率会降低很多。
注意 因为mysql等数据库效率比较低所承担的并发量就有限一旦请求数量多了数据库压力就会很大就很容易宕机。
如何提高MySQL并发量
开源 引入更多机器构成MySQL集群。
节流 引入缓存把一些频繁读取的热点数据保存在缓存上。后续查询数据的时候如果缓存中存在就不去MySQL中进行查询了。
注意 数据是存在二八原则的20%的数据可以满足80%的请求虽然redis是内存数据库只能存储少量数据但基于这个原则可以大大减少MySQL数据库压力。
缓存更新策略 如何知道redis中应该存储哪些数据如何知道哪些数据是热点数据呢
定期更新 会把访问的数据以日志形式记录下来然后就可以分析这些日志数据得到一些频繁出现的词那么这些词所对应的数据就算热点数据了就可以存储在redis中。 这里redis中的数据可以按照一天一更新或者一周一更新定期的进行热点数据统计更新redis中的数据。
优点 上述过程实现起来比较简单过程更加可控缓存中有什么数据比较固定方便排查问题。
缺点 实时性不够如果出发一些特殊事件有一些本来不是热词的数据成了热词新热词查询就可能给后面数据库带来比较大的压力。
实时更新
1先从redis中查询如果查到数据直接返回。
2如果redis中不存在则去数据库查然后把数据插入redis中。
3这样不停的往redis中插入数据就会使redis的内存占用越来越多逐渐达到上限。此时如果继续往redis中插入数据就会触发问题。为了解决此问题redis引入了内存淘汰策略。
内存淘汰策略
1FIFO(First In First Out)先进先出 把缓存中存在时间最久的(也就是先来的数据)淘汰掉。
2LRU (Least Recently Used)淘汰最久未使用的 记录每个key的最近访问时间.把最近访问时间最老的key淘汰掉。
3LFU(Least Frequently Used)淘汰访问次数最少的 记录每个key最近⼀段时间的访问次数。把访问次数最少的淘汰掉.。
4Random随机淘汰 从所有的key中抽取幸运儿被随机淘汰掉。
注意
1经过一段时间的动态平衡redis中的数据逐渐就成为了热点数据。
2具体采用哪种内存淘汰策略需要根据业务具体问题具体分析。
Redis内置的淘汰策略 volatile-lru 当内存不足以容纳新写⼊数据时从设置了过期时间的key中使用LRU最近最少使用算法进行淘汰。 allkeys-lru 当内存不足以容纳新写⼊数据时从所有key中使⽤LRU最近最少使用算法进 进行淘汰。 volatile-lfu 4.0版本新增当内存不足以容纳新写⼊数据时在过期的key中使用LFU算法 进行删除key。 allkeys-lfu 4.0版本新增当内存不足以容纳新写⼊数据时从所有key中使用LFU算法进行淘汰。 volatile-random 当内存不足以容纳新写入数据时从设置了过期时间的key中随机淘汰数据。 allkeys-random 当内存不足以容纳新写入数据时从所有key中随机淘汰数据。 volatile-ttl 在设置了过期时间的key中根据过期时间进行淘汰越早过期的优先被淘汰.。(相当于FIFO只不过是局限于过期的key) noeviction 默认策略当内存不足以容纳新写入数据时新写入操作会报错。
注意 整体来说redis提供的策略和上述介绍的通用策略是基本⼀致的。只不过redis这里会针对 过期key 和 全部key 做分别处理。
缓存常见问题
缓存预热
1定期更新缓存数据不存在缓存预热情况首次启动缓存也会存在一些热点数据不会给mysql服务造成太大压力。
2实时更新缓存数据缓存服务首次启动缓存中是没有数据的这个时候mysql服务承载的压力就比较大。
解决方案 通过离线的方式向缓存服务导入一些热点数据首次启动mysql服务就不会有太大压力。随着时间推移缓存中数据逐渐就都成为热点数据了。
缓存穿透 查询某个keyredis中不存在MySQL中也不存在那么就不会在redis中进行存储。如果存在大量的这些查询同样会给MySQL造成太大压力。
问题出现场景
1业务设计不合理不如缺少必要的参数校验导致非法key也被查询了。
2开发/运维误操作不小心把部分数据从MySQL中删除了。
3黑客恶意攻击。
解决方案
1如果发现这个key在redis和MySQL中都不存在仍然写入redis中value可设置一个非法值比如“”那么后续这些key的查询在缓存中就可以查询到就可以执行非法校验逻辑。
2引入布隆过滤器每次查询redis/MySQL时都先判断一下key是否在布隆过滤器中存在。把所有key都插入到布隆过滤器中如果布隆过滤器不存在就不需要查询redis或MySQLMySQL就不会有太大压力。
3布隆过滤器本质是结合了 hash bitmap 不会存储真实数据但可以判断是否存在。以比较小的空间开销比较快的时间速度实现争对key是否存在的判定。
缓存雪崩 由于在短时间内redis上大规模的key失效导致缓存命中率陡然下降导致MySQL服务压力迅速上升甚至直接宕机。
问题出现场景
1redis直接挂了redis宕机 / redis集群模式下大量节点宕机。
2redis没问题但可能之前短时间内设置很多key到redis中并且设置的过期时间都是相同的。
解决方案
1加强监控报警保证redis集群的可用性。
2不给key设置过期时间。
3key设置过期时间的时候添加随机因子避免同一时刻同时失效。
缓存击穿 相当于缓存雪崩的特殊情况针对热点key突然过期了导致大量请求直接访问数据库甚至引起数据库直接宕机热点key的访问频率高请求数就多影响更大
解决方案
1基于统计的方式发现热点key并且设置永不过期。
2进行必要的服务降级例如访问数据库的时候使用分布式锁限制同时请求数据库的并发数。客户端响应时间会比较长但不至于数据库服务直接挂了。
小结 redis作为缓存场景是非常常见的需要因地制宜选择适合自己业务的功能。