雪崩

性能优化之缓存篇

夙愿已清 提交于 2020-01-27 08:06:28
1. 前言:为什么要用缓存? 用户数增长,架构演变,数据量增大,开始考虑怎么去做性能优化。 而性能优化的第一定律就是:优先考虑使用缓存。 2. 缓存的基本原理 2.1 缓存的作用 1、加快数据访问速度; 2、减轻后端应用和数据存储的负载压力。 2.2 缓存的特征 1、命中率:命中率 = 命中数 / 请求数。 这是衡量缓存有效性的重要指标。命中率越高,表明缓存的使用率越高。 2、最大元素(最大空间)。 一旦缓存中元素数量超过这个值(或者缓存数据空间超过其最大支 持空间),将会触发淘汰策略 3、淘汰策略。 这个我前文其实已经说过。 FIFO(First In First Out) 先进先出,淘汰最早数据。 判断存储时间,离目前最远的数据优先淘汰。 LRU (Least Recently Used)剔除最近最少使用。 判断最近使用时间,离目前最远的数据优先淘汰。 LFU (Least Frequently Used)剔除最近使用频率最低的数据。 在一段时间内,数据被使用次数最少的,优先淘汰。 具体可以看这篇文章 常见的缓存剔除策略 & LRU与LFU的区别 。 3. 缓存的分类 缓存的主要手段有:浏览器缓存、CDN、反向代理、本地缓存、分布式缓存、数据库缓存。 在 解读《大型网站技术架构》一文 中,其实已经说到过。 我们一般说做性能优化时是指后三个:本地缓存、分布式缓存、数据库缓存。

缓存雪崩、缓存击穿、缓存穿透

半世苍凉 提交于 2020-01-26 11:31:03
1.缓存雪崩 通常我们在数据量请求大或者热点数据都会做缓存,通常情况缓存的数据是通过定时任务刷新,或者查询不到后,通过数据库查询后更新的,定时任务刷新的场景就会有问题,因为所有的key会在同一时间失效,那么在秒杀的场景中,如果缓存失效,大量的请求全部落入数据库,数据库必然是扛不住的,可能还没收到报警,实际上数据库已经宕机了 应对这种场景的处理方法是:1)在批量往redis中存数据的时候,把每个key的失效时间都加一个随机值,这样可以保证不会在同一时间大面积失效。2)电商应用目前使用redis都是集群部署,将热点数据均匀分布在不同的redis分片中也能避免全部失效的问题。3)设置热点数据永不过期,有数据更新时候,就同步更新缓存 2.缓存穿透 如果查询缓存和数据库中都没有的数据,用户不断的发起请求,可能这种用户是攻击者,这种攻击会导致数据库压力过大,严重时会击垮数据库,比如说数据库中的编号都是正数,用户一直用小于0 的参数去请求,每次都是能够绕开缓存世界查库的,数据库也查不到数据,一直这么高并发的请求,通常就很容易挂掉。 应用这种场景的处理方法是:1)接口服务层要增加对参数合法性的校验,不要信任所有的调用者,该防范的还是需要防范 2)对不存在的数据的查询接口也增加缓存,缓存时间可相对控制较短,比如5s等等,这样做可以一定程度的减轻并发情况下的数据库压力 3

《【面试突击】— Redis篇》--Redis Cluster及缓存使用和架构设计的常见问题

隐身守侯 提交于 2020-01-25 11:13:21
《【 面试 突击】— Redis篇》--Redis Cluster及缓存使用和架构设计的常见问题 在这个系列里,我会整理一些 面试题 与大家分享,帮助年后和我一样想要在金三银四准备跳槽的同学。 我们一起巩固、突击面试官常问的一些面试题,加油!! 《【面试突击】— Redis篇》--Redis数据类型?适用于哪些场景? 《【面试突击】— Redis篇》--Redis的线程模型了解吗?为啥单线程效率还这么高? 《【面试突击】— Redis篇》-- Redis的主从复制?哨兵机制? 《【面试突击】— Redis篇》-- Redis哨兵原理及持久化机制 说说Redis cluster 在redis cluster集群架构中,可以由N个redis master node组成,每个master node都可以挂载多个slave node。 可以自动将数据进行分片,每个master上放一部分数据; 还提供内置的高可用支持,部分master不可用时,还是可以继续工作的,因为每个master都有salve节点,那么如果mater挂掉,redis cluster这套机制,就会自动将某个slave切换成master; 支持读写分离:对于每个master来说,都负责写请求,写就写到master,然后读就从mater对应的slave去读; 总结:redis cluster(多master + 读写分离 +

缓存在高并发场景下的常见问题

流过昼夜 提交于 2020-01-24 08:31:40
转自:https://blog.csdn.net/dinglang_2009/article/details/53464196 缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。这就比较依赖缓存的过期和更新策略。一般会在数据发生更改的时,主动更新缓存中的数据或者移除对应的缓存。 缓存并发问题 缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程。但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致 “雪崩”现象。此外,当某个缓存key在被更新时,同时也可能被大量请求在获取,这也会导致一致性的问题。那如何避免类似问题呢?我们会想到类似“锁”的机制,在缓存更新或者过期的情况下,先尝试获取到锁,当更新或者从数据库获取完成后再释放锁,其他的请求只需要牺牲一定的等待时间,即可直接从缓存中继续获取数据。 缓存穿透问题 缓存穿透在有些地方也称为“击穿”。很多朋友对缓存穿透的理解是:由于缓存故障或者缓存过期导致大量请求穿透到后端数据库服务器,从而对数据库造成巨大冲击。 这其实是一种误解。真正的缓存穿透应该是这样的: 在高并发场景下,如果某一个key被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库

《【面试突击】— Redis篇》--Redis Cluster及缓存使用和架构设计的常见问题

烈酒焚心 提交于 2020-01-19 15:49:09
能坚持别人不能坚持的,才能拥有别人未曾拥有的。 关注 编程大道 公众号,让我们一同坚持心中所想,一起成长!! 《【面试突击】— Redis篇》--Redis Cluster及缓存使用和架构设计的常见问题 在这个系列里,我会整理一些面试题与大家分享,帮助年后和我一样想要在金三银四准备跳槽的同学。 我们一起巩固、突击面试官常问的一些面试题,加油!! 《【面试突击】— Redis篇》--Redis数据类型?适用于哪些场景? 《【面试突击】— Redis篇》--Redis的线程模型了解吗?为啥单线程效率还这么高? 《【面试突击】— Redis篇》-- Redis的主从复制?哨兵机制? 《【面试突击】— Redis篇》-- Redis哨兵原理及持久化机制 说说Redis cluster 在redis cluster集群架构中,可以由N个redis master node组成,每个master node都可以挂载多个slave node。 可以自动将数据进行分片,每个master上放一部分数据; 还提供内置的高可用支持,部分master不可用时,还是可以继续工作的,因为每个master都有salve节点,那么如果mater挂掉,redis cluster这套机制,就会自动将某个slave切换成master; 支持读写分离:对于每个master来说,都负责写请求,写就写到master

缓存雪崩

故事扮演 提交于 2020-01-10 01:22:58
缓存雪崩 缓存雪崩是指缓存不可用或者大量缓存由于超时时间相同在同一时间段失效,大量请求直接访问数据库,数据库压力过大导致系统雪崩。 解决方案: 1、给缓存加上一定区间内的随机生效时间,不同的key设置不同的失效时间,避免同一时间集体失效。比如以前是设置10分钟的超时时间,那每个Key都可以随机8-13分钟过期,尽量让不同Key的过期时间不同。 2、采用多级缓存,不同级别缓存设置的超时时间不同,及时某个级别缓存都过期,也有其他级别缓存兜底。 3、利用加锁或者队列方式避免过多请求同时对服务器进行读写操作。 来源: CSDN 作者: 阳光_你好 链接: https://blog.csdn.net/weixin_45805339/article/details/103913579

解决或缓解服务雪崩的方案

老子叫甜甜 提交于 2020-01-05 11:07:09
雪崩效应 1 服务雪崩的原因 (1)某几个机器故障:例如机器的硬驱动引起的错误,或者一些特定的机器上出现一些的bug(如,内存中断或者死锁)。 (2)服务器负载发生变化:某些时候服务会因为用户行为造成请求无法及时处理从而导致雪崩,例如阿里的双十一活动,若没有提前增加机器预估流量则会造服务器压力会骤然增大二挂掉。 (3)人为因素:比如代码中的路径在某个时候出现bug 2 解决或缓解服务雪崩的方案 一般情况对于服务依赖的保护主要有3中解决方案: (1)熔断模式:这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。 (2)隔离模式:这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火少光了,不会影响到其他的小岛。例如可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。这种模式使用场景非常多,例如将一个服务拆开,对于重要的服务使用单独服务器来部署,再或者公司最近推广的多中心。 (3)限流模式:上述的熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式

击穿

自古美人都是妖i 提交于 2019-12-31 17:05:07
Redis缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。 另外的一些典型问题就是,缓存穿透、缓存雪崩和缓存击穿。目前,业界也都有比较流行的解决方案。本篇文章,并不是要更加完美的解决这三个问题,也不是要颠覆业界流行的解决方案。而是,从实际代码操作,来演示这三个问题现象。之所以要这么做,是因为,仅仅看这些问题的学术解释,脑袋里很难有一个很形象的概念,有了实际的代码演示,可以加深对这些问题的理解和认识。 缓存穿透 缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。 Redis缓存流程 代码流程 参数传入对象主键ID 根据key从缓存中获取对象 如果对象不为空,直接返回 如果对象为空,进行数据库查询 如果从数据库查询出的对象不为空,则放入缓存(设定过期时间) 想象一下这个情况,如果传入的参数为-1,会是怎么样?这个-1,就是一定不存在的对象。就会每次都去查询数据库,而每次查询都是空,每次又都不会进行缓存。假如有恶意攻击,就可以利用这个漏洞,对数据库造成压力

高并发场景下使用缓存需要注意那些问题?

一笑奈何 提交于 2019-12-29 23:12:00
一、缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。这就比较依赖缓存的过期和更新策略。一般会在数据发生更改的时,主动更新缓存中的数据或者移除对应的缓存。 二、缓存并发问题 缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程。但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致 “雪崩”现象。此外,当某个缓存key在被更新时,同时也可能被大量请求在获取,这也会导致一致性的问题。那如何避免类似问题呢?我们会想到类似“锁”的机制,在缓存更新或者过期的情况下,先尝试获取到锁,当更新或者从数据库获取完成后再释放锁,其他的请求只需要牺牲一定的等待时间,即可直接从缓存中继续获取数据。 三、缓存穿透问题 缓存穿透在有些地方也称为“击穿”。很多朋友对缓存穿透的理解是:由于缓存故障或者缓存过期导致大量请求穿透到后端数据库服务器,从而对数据库造成巨大冲击。 这其实是一种误解。真正的缓存穿透应该是这样的: 在高并发场景下,如果某一个key被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库,而当该key对应的数据本身就是空的情况下,这就导致数据库中并发的去执行了很多不必要的查询操作,从而导致巨大冲击和压力。

高并发场景下使用缓存需要注意那些问题?

僤鯓⒐⒋嵵緔 提交于 2019-12-27 16:03:40
一、缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。这就比较依赖缓存的过期和更新策略。一般会在数据发生更改的时,主动更新缓存中的数据或者移除对应的缓存。 二、缓存并发问题 缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程。但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致 “雪崩”现象。此外,当某个缓存key在被更新时,同时也可能被大量请求在获取,这也会导致一致性的问题。那如何避免类似问题呢?我们会想到类似“锁”的机制,在缓存更新或者过期的情况下,先尝试获取到锁,当更新或者从数据库获取完成后再释放锁,其他的请求只需要牺牲一定的等待时间,即可直接从缓存中继续获取数据。 三、缓存穿透问题 缓存穿透在有些地方也称为“击穿”。很多朋友对缓存穿透的理解是:由于缓存故障或者缓存过期导致大量请求穿透到后端数据库服务器,从而对数据库造成巨大冲击。 这其实是一种误解。真正的缓存穿透应该是这样的: 在高并发场景下,如果某一个key被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库,而当该key对应的数据本身就是空的情况下,这就导致数据库中并发的去执行了很多不必要的查询操作,从而导致巨大冲击和压力。