Redis作为缓存
关系性数据库为什么性能不高:
关系性数据库存储在硬盘上面,所有相对内存而言IO速度并不快。
关系型数据库对于sql语句的的校验工作约束很多,一次查询很复杂。
一些复杂的查询,比如联合查询,笛卡尔积查询,效率降低更多。
为什么高并发就会宕机
服务器每次处理一个请求,都要消耗硬件资源包括cup,宽带,内存,硬盘,本身的资源就是有限的,而关系型数据库这种复杂sql的查询消耗资源相对于redis的操错大很多,一旦高并发上来,就会把资源消耗完,从而导致宕机
如何结局按高并发问题?
开源:多部署几台服务器,集群部署
节流:引入缓存,二八原则,把经常访问的热点数据放在缓存中
利用redis缓存保护MySQL
缓存的更新策略(那些是热点数据)
定时更新
每个一段时间,对于访问数据的频次进行统计挑选访问最高的前N%的数据,具体根据业务的情况来顶,然后会把这些搜索词的数据放在缓存中
问题:这样实时性不是很高,比如春晚这个词,一般只有过节那几天搜索频率变高,而平时几乎不会去搜索。
实时更新
每次查询会在redis查询,如歌查询到就返回,如果查询不到,就从数据库里面查询,查询到后返回同时也会写入redis缓存。一段时间后结合这淘汰策略,redis基本村粗的数据就是热点数据
问题: redis容易内存满
内存淘汰策略:
给key设置过期时间
FIFO(first in first out) 当新写入数据时候,内存不够,先进先出,优先把存储事件最久的先淘汰
LRU (Least Recently Used)当新写入数据时候,内存不够,淘汰最久未使用的,记录每次key访问最近的时间,根据最近访问时间最久来淘汰
LFU(Least Frequently Used)当新写入数据时候,内存不够, 淘汰访问次数最少的,记录每次key被访问的次数,把访问次数最少的淘汰掉
Random 当新写入数据时候,内存不够, 随机淘汰。
缓存预热, 缓存穿透, 缓存雪崩 和 缓存击穿
缓存预热
:使用redis作为mysql缓存时候,当redis刚刚启动动或者redis大批的key失效,这时候由于redis是空的,为了避免大量请求直接打入mysql中,因此会提前把一些热点数据准备好,放入redis中,这些热点数据不一定精准,但是可以后期慢慢调整,可以为mysql挡住大多数的请求。
缓存穿透
访问的数据在redis和mysql上面都没有,此时也不会向redis上面放入数据,如果这种请求短时间大量访问,就会访问数据库,造成数据库请求太多,造成崩溃。
产生原因:黑客攻击,运维开发误把数据库部分数据删除,业务设计不合理,导致非法key被查询
解决方案:
把查询不到的数据,在缓存也设置key-value值,value设置为一个空字符串,避免后续频繁查询
使用布隆过滤器先判定key是否存在,再真实查询。
对于查询的参数进行校验,比如查询的key是用户手机号,就校验这个手机号是否有效。
缓存雪崩:
1.redis宕机了挂带了,2,大量的key在同一时间过期,导致数据库,压力倍增。
解决方法:对于redis的监控加强,加入哨兵,挂了后立马通知,多部署几台redis,一个挂了别的顶上, 对于热点key不设置过期时间,或者过期时间随机,避免同时过期。
缓存击穿
是缓存雪崩的特殊情况,针对热点数据,突然过期,这时候又有大量请求,直接访问到数据库上面,导致数据库宕机。
解决方法:基于热点key不过期,进行服务降级处理,适当关闭一些不重要的功能的服务器,把资源都分配在访问数据库上面,比如访问数据库时候,使用分布式锁,限制同时请求的并发数。