-
Spring Boot 更新、清除多个缓存
2020-10-21 17:57:37} //更新多个 @Caching(put = { @CachePut(value = "user",key = "#key"), @CachePut(value = "user",key = "#key2") }) //删除多个 @Caching(evict = { @CacheEvict(value = "user",key = "#key"), @CacheEvict...使用 注解 @Caching ,源码如下
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Caching { Cacheable[] cacheable() default {}; CachePut[] put() default {}; CacheEvict[] evict() default {}; }
//更新多个 @Caching(put = { @CachePut(value = "user",key = "#key"), @CachePut(value = "user",key = "#key2") }) //删除多个 @Caching(evict = { @CacheEvict(value = "user",key = "#key"), @CacheEvict(value = "user",key = "#key2") })
-
Redis之缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级
2021-03-18 11:40:292)给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。 3)一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。 2、缓存穿透 发生场景:是指查询一个数据库...Redis之缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级
1、缓存雪崩
发生场景:当Redis服务器重启或者大量缓存在同一时期失效时,此时大量的流量会全部冲击到数据库上面,数据库有可能会因为承受不住而宕机
解决办法:
1)缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
2)给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
3)一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。
2、缓存穿透
发生场景:是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。此时,若攻击者抓住这个漏洞不断请求数据库,就会对数据库造成压力,甚至压垮数据库。
解决办法:采用缓存空值的方式,也就是从数据库查询的对象为空,也放入缓存,只是设定的缓存过期时间较短,比如设置为60秒。
1. 接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
2. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
3.采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力
3、缓存预热
是一种机制, 就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题。
4、缓存更新
是一种机制,怎么样保证缓存中的key是实时有效的,以及及时的更新数据资源
解决办法:
1)缓存服务器自带的缓存失效策略
2)自定义:定时去清理过期的缓存;当用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
5、缓存降级
发生场景:当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。
解决办法:
在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:
(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
(2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
(3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。
-
更新缓存的一个设计方案
2021-02-02 11:23:52通常更新缓存的线程为一个,而读取缓存的线程有多个。 这正好符合读者写者模型,实际中可以用读写锁来处理。c++中也是推荐这个用法的。 实际操作中,有需要注意的细节。比如缓存不大而生成又耗时的情况下,可以...经常遇到后台线程定期更新缓存,而service线程却要实时查询缓存的功能。通常更新缓存的线程为一个,而读取缓存的线程有多个。
这正好符合读者写者模型,实际中可以用读写锁来处理。c++中也是推荐这个用法的。
实际操作中,有需要注意的细节。比如缓存不大而生成又耗时的情况下,可以先生成缓存对象,此时不需要加锁,然后在加锁的情况下去更新指针。这个指针可以是智能指针也可以是非智能指针,无论哪种情况都需要加锁。
对于智能指针情况,智能指针的拷贝、赋值以及析构等操作是线程安全的,这是因为拷贝和赋值只改变了引用计数,而析构根据引用计数可以确保是最后一个持有线程,因而也是线程安全的。reset操作需要修改指向对象的指针,因而不是线程安全。
如果是智能指针时,读取缓存的线程,只需要获zai得一个智能指针的拷贝。而如果是非智能指针模式,则需要拷贝整个对象。因为如果仍然只获得一个指针,那么谁将销毁这个指针指向对象的内容是个很大问题。
如果由写线程在更新时候销毁,那么此时可能别的读进程正持有这个指针,这个线程可能访问到delete后的内存区域,这造成了未定义行为。如果由读取线程来释放,这更不可能,因为读取线程不唯一。故如果对象很大,为了避免拷贝开销,
那么引用计数几乎是必然的选择。
至于java中,jdk5以后另有另外一种巧妙的办法:
采用一个volatile的引用保存缓存对象,这个缓存对象是不可变的,所有的字段都是final的,这保证了多线程下的构造安全性。由于java不需要考虑对象删除问题,所以有新数据时候,写线程构造一个新对象,然后直接更新这个volatile引用即可。
优点是不需要加锁操作。这也是java一个优势。这个模式一般都是应用单写多读,因为volatile不保证原子性。但是对象引用是32位,而且只牵涉到写,并不存在读改写,所以应用多写也是满足原子性的。
-
缓存更新顺序
2019-07-24 11:45:53多线程下先删除缓存再更新DB会导致,一个线程更新缓存,一个线程进行查询,如果缓存中查询不到就会去DB中查询旧数据并放到缓存中,这样及时之后DB中是新数据,缓存中也是旧数据,就会导致脏数据的出现 2.先更新DB...考虑多线程的场景
1.先删除缓存再更新DB
多线程下先删除缓存再更新DB会导致,一个线程更新缓存,一个线程进行查询,如果缓存中查询不到就会去DB中查询旧数据并放到缓存中,这样及时之后DB中是新数据,缓存中也是旧数据,就会导致脏数据的出现
2.先更新DB再更新缓存
多线程下一个线程更新DB,一个线程查询缓存,这样即使缓存查到的是旧数据之后更新完DB之后缓存也会更新,只会有短暂的数据不一致的问题
-
谈谈缓存更新
2019-11-27 17:09:56试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的... -
版本更新带来的缓存问题_讲讲 Redis 缓存更新一致性
2021-01-14 14:41:11作者:Finleywww.cnblogs....在设计更新策略时,我们需要考虑多个方面的问题:对系统吞吐量的影响:比如更新缓存策略产生的数据库负载小于删除缓存策略的负载并发安全性:并发读写时某些异常操作... -
缓存如何更新
2020-08-09 00:08:54在看很多博客上介绍如何更新缓存,都会说先删缓存再更新数据库,但是仔细一想会出现数据不一致的问题,比如一个线程A更新数据,一个线程B查询数据,那么就会出现下面的步骤: A线程先删除缓存 B去请求缓存时,发现... -
大行缓存更新之道
2021-03-24 22:27:34很多同学写更新缓存时,先删除缓存...所以特此总结一下几个缓存更新的Design Pattern。 先不讨论更新缓存和更新数据这两个事是一个事务的事,或是会有失败的可能,先假设更新数据库和更新缓存都可以成功的情况。 1 Cach -
缓存更新机制
2018-07-16 10:22:46试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的... -
缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级的说明及处理策略
2020-10-22 16:48:11给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓 存。 为 key 设置不同的缓存失效时间。 缓存穿透: 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有 -
缓存穿透、缓存更新、缓存雪崩、缓存预热、缓存降级等问题
2019-04-16 16:43:33一、缓存穿透 缓存穿透是指用户查询数据,在数据库没有,...有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这... -
更新网站 图片缓存_web缓存的了解
2020-11-18 00:16:55这个服务器可能是源服务器(资源所驻留的服务器Add),数量可能是1个或多个;这个客户端也可能是1个或多个。Web缓存就在服务器-客户端之间搞监控,监控请求,并且把请求输出的内容(例如html页面、 图片和文件)(统称为... -
【缓存】缓存更新策略
2019-06-15 15:43:28缓存用于缓解后端db的压力,策略指的是更新缓存以及db的方式。 主要可以分为两个大类: 调用方主动更新缓存以及db: 这种是最最常见也是最最容易想到的方式。即调用端需要同时维护db和缓存的调用,调用端逻辑比较... -
缓存更新的套路
2020-11-07 13:47:27看到好些人在写更新缓存数据代码时,先删除缓存,然后...我不知道为什么这么多人用的都是这个逻辑,当我在微博上发了这个贴以后,我发现好些人给了好多非常复杂和诡异的方案,所以,我想写这篇文章说一下几个缓存更新的 -
样式缓存没更新_缓存常见问题总结
2021-01-13 21:48:10关于缓存的知识太多了,先整理一点,慢慢补充吧。缓存同步策略首先需要明确,除了把整个缓存和持久化存储都做串行化,或者操作一个的时候直接锁死另一个,不然必然会有产生数据不一致的可能。选择哪种缓存策略是根据... -
关于缓存更新操作
2019-09-18 11:11:36试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的... -
缓存回收策略跟缓存更新策略
2021-03-24 20:17:53互联网时代的飞速发展,用户的体验度是判断一个软件好坏的重要原因,所以缓存就是必不可少的一个神器。缓存的种类有很多,需要根据不同的应用场景来需要选择不同的cache,比如分布式缓存如redis跟本地缓存如... -
常见缓存更新策略
2017-10-02 00:51:28试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的...