网站建设那个网站好,网站建设的目的及效益分析,企业管理培训课程游戏,wordpress链接过期需求引入一般在项目的开发中,都是使用关系型数据库来进行数据的存储#xff0c;通常不会存在什么高并发的情况#xff0c;可是一旦涉及大数据量的需求#xff0c;比如商品抢购#xff0c;网页活动导致的主页访问量瞬间增大#xff0c;单一使用关系型数据库来保存数据的系统…需求引入一般在项目的开发中,都是使用关系型数据库来进行数据的存储通常不会存在什么高并发的情况可是一旦涉及大数据量的需求比如商品抢购网页活动导致的主页访问量瞬间增大单一使用关系型数据库来保存数据的系统会因为面向磁盘导致磁盘读/写速度比较慢一瞬间成千上万的请求到来系统在极短的时间内完成成千上万次的读/写操作这个时候数据库一般不能够承受极其容易造成数据库系统瘫痪最终导致服务宕机等严重性能弊端为了解决上述问题项目通常会引入NoSQL数据库这是一种基于内存的数据库并且提供一定的持久化功能redis就是NoSQL数据库中的一种可以将 Redis 作为数据库的缓存,用与缓解关系型数据库的压力但是引入redis有可能会出现缓存穿透缓存击穿缓存雪崩等问题缓存穿透(1).什么是缓存穿透缓存穿透是指查询一个缓存中和数据库中都不存在的数据导致每次查询这条数据都会发生缓存缺失从而透过缓存直接访问数据库发现数据库中也没有要访问的数据最后返回空。如果用户使用这条不存在的数据疯狂发起请求就会同时给缓存和数据库带来巨大压力从而可能压垮数据库导致数据库宕机(2).产生缓存穿透的原因业务层误操作缓存中的数据和数据库中的数据都被误删除所以缓存和数据库中都没有数据 恶意攻击专门访问数据库中没有的数据(3).解决方案1).对请求参数进行校验对于请求的参数应该要先进行校验请求的参数应该要在规定范围内过滤掉一些无效的请求避免请求进入缓存或者数据库2).采用布隆过滤器使用布隆过滤器快速判断数据是否存在避免从数据库中查询数据是否存在减轻数据库压力布隆过滤器就是一种BitMap数据结构将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中哈希计算当一个请求来临的时候先进行布隆过滤器的判断如果有那么才进行放行否则就直接拦截它是由一个长度为m bit的位数组与n个hash函数组成的数据结构位数组中每个元素的初始值都是0。在初始化布隆过滤器时会先将所有key进行n次hash运算这样就可以得到n个位置然后将这n个位置上的元素改为1。这样就相当于把所有的key保存到了布隆过滤器中了。举个例子比如我们一共有3个key我们对这3个key分别进行3次hash运算key1经过三次hash运算后的结果分别为2/6/10那么就把布隆过滤器中下标为2/6/10的元素值更新为1然后再分别对key2和key3做同样操作结果如下图这样当客户端查询时也对查询的key做3次hash运算得到3个位置然后看布隆过滤器中对应位置元素的值是否为1如果所有对应位置元素的值都为1就证明key在库中存在则继续向下查询如果3个位置中有任意一个位置的值不为1那么就证明key在库中不存在直接返回客户端空即可。如下图当客户端查询key4时key4的3次hash运算中有一个位置8的值为0就说明key4在库中不存在直接返回客户端空即可。所以布隆过滤器就相当于一个位于客户端与缓存层中间的拦截器一样负责判断key是否在集合中存在。如下图布隆过滤器的好处就是解决了第一种缓存空值的不足但布隆过滤器也存在缺陷它不能完全保证请求过来的 key 通过布隆过滤器的校验就一定有这个数据。 但是只要没有通过布隆过滤器的校验那么这个 key 就一定不存在。 其实这样就已经可以过滤掉大部分不存在的 key 请求了。如果布隆过滤器的哈希槽过短很有可能导致大部分的位置都为 1 那么此时布隆过滤器就失去了它的意义。 所以当我们发现布隆过滤器大部分位置都为1了就要扩宽哈希槽 3).对空值进行缓存一旦发生缓存穿透当查询返回的数据为空不管是数据不存在还是系统故障的时候在Redis缓存一个空值或者业务层协商确定的缺省值然后给这个空对象的缓存设置一个很短的过期时间最长不超过五分钟应用发生后续请求在进行查询时就可以直接从缓存中拿到返回给业务应用避免大量请求发送给数据库处理保持数据库的正常运行这种解决方式有两个缺点1需要缓存层提供更多的内存空间来缓存这些空对象当这种空对象很多的时候就会浪费更多的内存2会导致缓存层和存储层的数据不一致即使在缓存空对象时给它设置了一个很短的过期时间那也会导致这一段时间内的数据不一致问题//伪代码
public function GetShopList() {var cache_time  60;var cache_key  shop_list;var cache_value  Cache::Get(cacheKey);if (cache_value ! null) {return cache_value;} else {//数据库查询不到为空cache_value  GetShopListData();if (cache_value  null) {//如果发现为空设置个默认值也缓存起来cache_value  null;}//增加缓存Cache::Add(cache_key, cache_value, cache_time);return cache_value;}
}(4).注意事项1).使用空值作为缓存的时候key设置的过期时间不能太长防止占用太多redis资源2).使用空值作为缓存只能防止黑客重复使用相同的id暴力攻击但是如果黑客使用动态的无效id攻击就没有效果需要配合网警3).使用布隆过滤器可能会存在哈希冲突缓存击穿(1).什么是缓存击穿针对某个访问非常频繁的热点数据请求突然在缓存中失效(数据过期)在该热点数据重新载入缓存之前,有大量的访问该数据请求穿过缓存一下子都发送到后端数据库导致数据库压力激增影响数据库处理其他请求造成大量请求阻塞这个时候大并发的请求可能会瞬间把后端DB压垮。缓存击穿一般是热点 key 在 Redis 中过期了导致的最直接的方法就是对于热点 key 不设置过期时间 (2).解决方案1).第一种是设置key永不过期a.在设置热点key的时候不给key设置过期时间即可b.正常给key设置过期时间不过在后台同时启一个定时任务去定时地更新这个缓存c.提前对热点数据进行设置:类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中d.监控数据适时调整:监控哪些数据是热门数据实时的调整key的过期时长2).第二种是使用分布式锁锁的对象就是key,当大量查询同一个key的请求并发进来时,保证同一时刻只能有一个请求获取到锁,然后获取到锁的线程查询数据库,然后将结果放入到缓存中这样其他的线程只需等待该线程运行完毕即可重新从Redis中获取数据业界比较常用的做法是使用mutex,简单地来说就是在缓存失效的时候判断拿出来的值为空不是立即去加载请求数据库而是先使用缓存工具的某些带成功操作返回值的操作比如Redis的SETNX或者Memcache的ADD去set一个mutex key当操作返回成功时再进行加载请求数据库的操作并回设缓存否则就重试整个get缓存的方法SETNX是SET if Not eXists 的缩写也就是只有不存在的时候才设置可以利用它来实现锁的效果public function get(key) {var value  redis.get(key);if (value  null) { //代表缓存值过期//设置3min的超时防止del操作失败的时候下次缓存过期一直不能请求加载数据库if (redis.setnx(key_mutex, 1, 3 * 60)  1) {  //代表设置成功value  db.get(key);redis.set(key, value, expire_secs);redis.del(key_mutex);} else {  //这个时候代表同时候的其他线程已经请求加载数据库并回设到缓存了这时候重试获取缓存值即可sleep(50);get(key);  //重试}} else {return value;      }}
4.缓存雪崩(1).什么是缓存雪崩与缓存击穿的区别在于缓存雪崩针对的是很多key缓存缓存击穿则是某一个key缓存正常从Redis中获取示意图缓存失效瞬间示意图缓存雪崩指的是缓存中有大量的key在同一时刻过期或者Redis直接宕机了然后大量请求发送到了数据库导致数据库的压力激增甚至可能导致数据库崩溃从而导致整个系统崩溃引发雪崩一样的连锁效应 (2).产生缓存雪崩的原因1).缓存中大量 key 同时过期当redis中的大量key集体过期可以理解为redis中的大部分数据都被清空了失效了那么这时候如果有大量并发的请求来到那么redis就无法进行有效的响应命中率急剧下降请求就直接去数据库访问了可能导致素剧看直接崩溃2).Redis 实例挂掉了无法处理请求(3).解决方案a.将失效时间分散开:  在实际应用中应当避免大量 key 同时过期的场景。如果确实有这种业务场景可以微调这批 key 过期的时间使其能有一定的相差间隔,防止集体过期b.使用多级架构:  使用nginx缓存redis缓存其他缓存不同层使用不同的缓存可靠性更强,Redis 主从集群其实可以比较好地实现主 Redis 实例挂掉后能有其他从库快速切换为主库继续提供服务c.设置缓存标记:  记录缓存数据是否过期如果过期会触发通知另外的线程在后台去跟新实际的keyd.使用锁或者队列的方式: 如果查不到就加上排它锁其他请求只能进行等待以上都是预防的措施如果已经发生了 缓存雪崩为了防止数据库被大量的请求搞崩溃,可以采用 服务熔断 或者 请求限流服务熔断就是暂停对业务提供 Redis 服务直到 Redis 恢复正常再向外提供服务。 当然这种情况下业务也会整个停摆了。 另外一种比较温和的办法就是请求限流。请求限流顾名思义就是限制请求的流量随机丢弃一部分的请求以保证不会同时有太多请求压入数据库除了上面的解决方式还可以使用其他策略比如设置key永不过期、加分布式锁等缓存失效时的雪崩效应对底层系统的冲击非常可怕大多数系统设计者考虑用加锁或者队列的方式保证来保证不会有大量的线程对数据库一次性进行读写从而避免失效时大量的并发请求落到底层存储系统上。还有一个简单方案就时讲缓存失效时间分散开比如我们可以在原有的失效时间基础上增加一个随机值比如1-5分钟随机这样每一个缓存的过期时间的重复率就会降低就很难引发集体失效的事件加锁排队伪代码如下
public function GetList() {$cache_time  30;$cache_key  product_list;$lock_key  $cache_key;$cache_value  Cache::get($cache_key);if ($cache_value ! null) {return $cache_value;} else {synchronized($lock_key) {$cache_value  Cache::get($cache_key);if ($cache_value ! null) {return $cache_value;} else {//这里一般是sql查询数据$cache_value  GetList(); Cache::Add($cache_key, $cache_value, $cache_time);}}return $cache_value;}
}加锁排队只是为了减轻数据库的压力并没有提高系统吞吐量。假设在高并发下缓存重建期间key是锁着的这是过来1000个请求999个都在阻塞的。同样会导致用户等待超时这是个治标不治本的方法注意加锁排队的解决方式分布式环境的并发问题有可能还要解决分布式锁的问题线程还会被阻塞用户体验很差因此在真正的高并发场景下很少使用随机值伪代码//伪代码
public object GetProductListNew() {$cacheTime  30;$cacheKey  product_list;//缓存标记$cacheSign  cacheKey  _sign;$sign  Cache::Get($cacheSign);//获取缓存值$cacheValue  Cache::Get($cacheKey);if ($sign ! null) {return $cacheValue; //未过期直接返回} else {Cache::Add($cacheSign, 1, $cacheTime);ThreadPool.QueueUserWorkItem((arg) - {//这里一般是 sql查询数据$cacheValue  GeList(); //日期设缓存时间的2倍用于脏读CacheHelper.Add($cacheKey, $cacheValue, $cacheTime * 2);                 });return $cacheValue;}
} (4).Redis实例发生宕机产生缓存雪崩1. 业务系统中实现服务熔断或者请求限流机制  服务熔断发生缓存雪崩时为了防止发生连锁的数据库雪崩甚至整个系统崩溃暂停业务应用对缓存系统的接口访问。 具体实现业务调用缓存接口时缓存客户端不再请求Redis而是直接返回等到Redis缓存实例重新恢复服务以后在允许应用请求发送到缓存系统。  优点避免了大量请求因缓存缺失而积压到数据库系统保证了数据库系统的正常运行。2.事先预防搭建主从节点构建Redis缓存高可用集群当Redis缓存的主节点故障宕机了从节点切换为主节点继续提供缓存服务避免缓存实例宕机造成的缓存雪崩问题
 文章转载自: http://www.morning.xctdn.cn.gov.cn.xctdn.cn http://www.morning.wkgyz.cn.gov.cn.wkgyz.cn http://www.morning.mjmtm.cn.gov.cn.mjmtm.cn http://www.morning.btwlp.cn.gov.cn.btwlp.cn http://www.morning.tlnbg.cn.gov.cn.tlnbg.cn http://www.morning.gcftl.cn.gov.cn.gcftl.cn http://www.morning.mcjxq.cn.gov.cn.mcjxq.cn http://www.morning.pjxw.cn.gov.cn.pjxw.cn http://www.morning.bzqnp.cn.gov.cn.bzqnp.cn http://www.morning.sjwzz.cn.gov.cn.sjwzz.cn http://www.morning.ptzf.cn.gov.cn.ptzf.cn http://www.morning.zwmjq.cn.gov.cn.zwmjq.cn http://www.morning.gjsjt.cn.gov.cn.gjsjt.cn http://www.morning.lstmq.cn.gov.cn.lstmq.cn http://www.morning.nlrp.cn.gov.cn.nlrp.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.cniedu.com.gov.cn.cniedu.com http://www.morning.wgxtz.cn.gov.cn.wgxtz.cn http://www.morning.thrtt.cn.gov.cn.thrtt.cn http://www.morning.fxkgp.cn.gov.cn.fxkgp.cn http://www.morning.npbnc.cn.gov.cn.npbnc.cn http://www.morning.zwznz.cn.gov.cn.zwznz.cn http://www.morning.rntyn.cn.gov.cn.rntyn.cn http://www.morning.tbqxh.cn.gov.cn.tbqxh.cn http://www.morning.rjrlx.cn.gov.cn.rjrlx.cn http://www.morning.fpxms.cn.gov.cn.fpxms.cn http://www.morning.xinyishufa.cn.gov.cn.xinyishufa.cn http://www.morning.joinyun.com.gov.cn.joinyun.com http://www.morning.bykqg.cn.gov.cn.bykqg.cn http://www.morning.wbllx.cn.gov.cn.wbllx.cn http://www.morning.tcfhs.cn.gov.cn.tcfhs.cn http://www.morning.gthgf.cn.gov.cn.gthgf.cn http://www.morning.mzcsp.cn.gov.cn.mzcsp.cn http://www.morning.rtkgc.cn.gov.cn.rtkgc.cn http://www.morning.gyjld.cn.gov.cn.gyjld.cn http://www.morning.mstrb.cn.gov.cn.mstrb.cn http://www.morning.jyfrz.cn.gov.cn.jyfrz.cn http://www.morning.splkk.cn.gov.cn.splkk.cn http://www.morning.wprxm.cn.gov.cn.wprxm.cn http://www.morning.rshkh.cn.gov.cn.rshkh.cn http://www.morning.gidmag.com.gov.cn.gidmag.com http://www.morning.ygth.cn.gov.cn.ygth.cn http://www.morning.rythy.cn.gov.cn.rythy.cn http://www.morning.scrnt.cn.gov.cn.scrnt.cn http://www.morning.rqqct.cn.gov.cn.rqqct.cn http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.mplld.cn.gov.cn.mplld.cn http://www.morning.rzbgn.cn.gov.cn.rzbgn.cn http://www.morning.pxbrg.cn.gov.cn.pxbrg.cn http://www.morning.ywpwg.cn.gov.cn.ywpwg.cn http://www.morning.kbqqn.cn.gov.cn.kbqqn.cn http://www.morning.qdlnw.cn.gov.cn.qdlnw.cn http://www.morning.elbae.cn.gov.cn.elbae.cn http://www.morning.lxhrq.cn.gov.cn.lxhrq.cn http://www.morning.ybqlb.cn.gov.cn.ybqlb.cn http://www.morning.zxqyd.cn.gov.cn.zxqyd.cn http://www.morning.xkwyk.cn.gov.cn.xkwyk.cn http://www.morning.wjrq.cn.gov.cn.wjrq.cn http://www.morning.qgqck.cn.gov.cn.qgqck.cn http://www.morning.lbzgt.cn.gov.cn.lbzgt.cn http://www.morning.qggm.cn.gov.cn.qggm.cn http://www.morning.nppml.cn.gov.cn.nppml.cn http://www.morning.dcmnl.cn.gov.cn.dcmnl.cn http://www.morning.plcyq.cn.gov.cn.plcyq.cn http://www.morning.kjyhh.cn.gov.cn.kjyhh.cn http://www.morning.wzwyz.cn.gov.cn.wzwyz.cn http://www.morning.dlurfdo.cn.gov.cn.dlurfdo.cn http://www.morning.bwznl.cn.gov.cn.bwznl.cn http://www.morning.bnlsd.cn.gov.cn.bnlsd.cn http://www.morning.hqlnp.cn.gov.cn.hqlnp.cn http://www.morning.qbjgw.cn.gov.cn.qbjgw.cn http://www.morning.bkylg.cn.gov.cn.bkylg.cn http://www.morning.rmxgk.cn.gov.cn.rmxgk.cn http://www.morning.mxnhq.cn.gov.cn.mxnhq.cn http://www.morning.rrwft.cn.gov.cn.rrwft.cn http://www.morning.jzmqk.cn.gov.cn.jzmqk.cn http://www.morning.ryjqh.cn.gov.cn.ryjqh.cn http://www.morning.rsnd.cn.gov.cn.rsnd.cn http://www.morning.xysxj.com.gov.cn.xysxj.com http://www.morning.rnkq.cn.gov.cn.rnkq.cn