`
gaojingsong
  • 浏览: 1181903 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

【缓存使用中的注意事项】

阅读更多

一、缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

黑客向目标系统查询一个必然不存在的数据。有可能是数据真的不存在,也有可能是第三方恶意攻击系统,刻意构建了大量不存在的id来攻击数据库。如果短时间内极大量的出现缓存穿透,那么系统的数据库将面临极大的压力,甚至宕机。

 

有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。在数据魔方里,我们采用了一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

 

解决方案:

(1) 存储空值:对不存在的值也在缓存中存储一个特殊的值表示Empty,并为这个id设置一个比较短的缓存过期的时间,这样,这个空的缓存失效之后还能到数据库查询这个id的对应的值是不是已经存在。

 

二、缓存并发

有时候如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

我现在的想法是再APP中对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。

 

解决方案:

在某个请求发现缓存没有数据时,此时需要获取一个排它锁,由此请求查询数据库并更新缓存。此步骤完成后释放此锁。在此请求操作的过程中,所有其他请求同一id的请求阻塞,待这个更新请求完成后直接从缓存重取数据。

 

三、缓存失效

引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置5分钟啊,10分钟这些;并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到DB,DB可能会压力过重。在系统启动批量装载数据缓存时,缓存的过期时间设置得过于一致;或者是在系统访问的高峰期更新或加载了一大批缓存,过期时间一致。缓存系统出现问题重启或者宕机了。

 

其中的一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

 

解决方案:

(1)缓存过期时间尽量散开,可以设置一个范围,比如1-200秒,把缓存的过期时间通过hash散列在这个区间,防止同一时间缓存大量过期。

 

(2)缓存双写策略,将同一个缓存同时写到两个缓存系统中。memcache有一个参数-b就是可以用来设置backup的缓存,当主缓存失效时还可以通过备份取到数据。

 

(3)缓存永不过期,在缓存系统中不设置过期时间,所有的缓存数据的更新都通过业务逻辑程序来完成。

 

 

总结:

1、缓存穿透:查询一个必然不存在的数据。比如文章表,查询一个不存在的id,每次都会访问DB,如果有人恶意破坏,很可能直接对DB造成影响。

2、缓存失效:如果缓存集中在一段时间内失效,DB的压力凸显。这个没有完美解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。

当发生大量的缓存穿透,例如对某个失效的缓存的大并发访问就造成了缓存雪崩。

 

四、多级缓存

将ehcache与redis做二级缓存

Hibernate中的二级缓存,二级缓存是属于SessionFactory级别的缓存机制。第一级别的缓存是Session级别的缓存,是属于事务范围的缓存,由Hibernate管理,一般无需进行干预。第二级别的缓存是SessionFactory级别的缓存,是属于进程范围的缓存。

MyBatis的一级缓存指的是在一个Session域内,session为关闭的时候执行的查询会根据SQL为key被缓存(跟mysql缓存一样,修改任何参数的值都会导致缓存失效)

mybatis的二级缓存,二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存。

 

在核心配置文件SqlMapConfig.xml中加入<setting name="cacheEnabled" value="true"/>

一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

 

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

 

 

 

适合放入二级缓存中数据

很少被修改

不是很重要的数据,允许出现偶尔的并发问题

不适合放入二级缓存中的数据

经常被修改

财务数据,绝对不允许出现并发问题

与其他应用数据共享的数据

0
0
分享到:
评论

相关推荐

    SuperMap_Deskpro_2008生成预缓存注意事项

    ### SuperMap Deskpro 2008生成预缓存注意事项详解 #### 一、概述 在WebGIS开发过程中,为了提高地图服务的响应速度及用户体验,预缓存技术的应用变得越来越广泛。SuperMap Deskpro 2008作为一款功能强大的GIS桌面...

    HBASE使用注意事项

    ### HBASE使用注意事项详解 #### 一、表设计注意事项 **1. 配置hostname** - **背景**:HBase依赖于Zookeeper进行服务管理,两者均基于域名解析来识别节点。 - **操作**:确保配置文件中正确设置了`hostname`,...

    spring简单的缓存

    参考链接提供的CSDN博客文章《[Spring简单缓存实现](http://blog.csdn.net/maoyeqiu/article/details/50238035)》中,作者详细介绍了如何在Spring项目中实现缓存,包括配置、注解使用以及注意事项,是一个很好的学习...

    C++数据结构与算法之双缓存队列实现方法详解

    本文主要介绍了C++数据结构与算法之双缓存队列实现方法,结合实例形式分析了双缓存队列的原理、实现方法与相关注意事项。 知识点一:双缓存队列的定义 双缓存队列是一种特殊的队列结构,它可以解决在发送端持续向...

    volley获取图片并缓存

    6. **优化与注意事项**: - 需要注意的是,内存缓存的大小有限,因此对于大图或者大量的图片,可能会迅速填满内存,这时需要考虑图片的压缩和尺寸适配,减少内存占用。 - 磁盘缓存虽然容量较大,但也要定期清理...

    Redis用作二级缓存

    通过以上步骤和注意事项,我们可以将Redis有效地整合到Mybatis的二级缓存中,实现高效的数据缓存,提高系统的响应速度和用户体验。同时,结合业务需求和系统负载情况,不断调整优化缓存策略,以达到最佳的性能效果。

    PHP 缓存 PHP 缓存

    - **注意事项:**当缓存中的数据发生变化时,必须及时更新缓存以保持数据一致性。 #### 六、页面缓存 - **作用:**不仅可以减轻数据库服务器的压力,还能减少应用服务器的工作量,提升页面加载速度。 - **难点:**...

    将缓存加载 IIS

    **安全注意事项**: 缓存策略虽然提高了效率,但也可能带来安全风险,如敏感数据被意外缓存、旧数据被错误地提供给新用户。因此,正确配置缓存策略,避免缓存敏感信息,定期清理无用缓存,是必要的安全措施。 综上...

    mybatis一级缓存和二级缓存简单示例

    ### 注意事项 - **并发问题**:在多线程环境中,一级缓存不会引起问题,因为每个 SqlSession 是线程局部的。而二级缓存可能引发并发问题,建议在更新数据后立即清空二级缓存,避免脏读。 - **缓存更新策略**:...

    Hibernate一级缓存和二级缓存

    **使用注意事项** 1. **并发控制**:在多线程环境下,二级缓存可能引发并发问题,需要合理配置并发策略。 2. **缓存同步**:数据库和缓存的数据同步是挑战,需要处理好缓存失效和更新的问题。 3. **性能优化**:...

    hibernate开启二级缓存和查询缓存

    注意事项 - 二级缓存和查询缓存都有可能导致数据一致性问题,因为它们都是基于最终一致性的。在高并发或需要强一致性的场景下,要谨慎使用。 - 对于更新频繁的数据,避免使用二级缓存,因为这可能导致脏读或丢失...

    如何清空缓存如何清空缓存

    #### 六、注意事项 1. **性能考虑**: - 虽然禁用缓存可以确保用户看到最新的内容,但可能会增加服务器的负担。因此,在实际应用中应权衡利弊。 2. **安全性考虑**: - 对于包含敏感信息的页面,禁用缓存是非常...

    winform简单缓存类实例

    缓存的使用也有一些注意事项: - **生命周期管理**:在上面的例子中,没有明确设置缓存项的过期时间。默认情况下,缓存项可能会因内存压力或系统需求被自动移除。为了确保数据的可用性,可以根据业务需求设置适当的...

    使用localStorage缓存js

    7. **其他注意事项** - 存储的数据必须是字符串类型,因此非字符串数据需要转换(如JSON对象使用 `JSON.stringify()` 和 `JSON.parse()`)。 - 如果有多个开发者协作,确保对 `localStorage` 的操作是同步的,避免...

    Android 高效编程注意事项

    ### Android高效编程注意事项 在Android应用开发过程中,为了提高应用程序的性能和响应速度,开发者需要注意以下几点关于高效编程的关键知识点: #### 概述 对于资源受限的系统(如移动设备),有两个基本准则...

    SSM整合Redis做缓存

    **注意事项**:在使用Redis做缓存时,需要注意数据的一致性问题,因为缓存和数据库可能存在短暂的数据不一致。另外,合理设置缓存容量和过期策略,避免内存溢出。 综上所述,SSM整合Redis做缓存是提高系统性能的...

    查看缓存 清除缓存

    9. **注意事项**:在清理系统重要应用的缓存前,如系统设置或邮件应用,确保了解清理可能带来的影响,因为某些应用的缓存数据可能会影响其正常运行。 综上所述,理解和有效地管理Android设备上的缓存是优化设备性能...

    缓存服务器memcached代码及使用文档

    **优化与注意事项** - **缓存策略**:使用适当的缓存替换策略(如LRU、LFU等)以保持高效的空间利用率。 - **数据分片**:根据业务需求,可以将数据分散到多个Memcached实例上,以提高并发性能和整体容量。 - **...

    显示所有缓存 清除所有缓存 Asp.net(C#)

    注意事项 - 在实际生产环境中,频繁地清空整个缓存可能会对性能造成负面影响,应该谨慎操作。 - 如果缓存项设置了依赖关系(例如依赖于某个文件或数据库表),则在删除该依赖项时,对应的缓存项也会自动被清除。 -...

Global site tag (gtag.js) - Google Analytics