在日常工作中,开发者经常利用缓存来进行优化站点或优化应用程序。但在实际应用中,在使用缓存时,总是那么不尽如意。这什么原因呢?

本文,笔者收集了最为常见的十大缓存误区以及使用建议:

1.  依赖默认的序列化。

默认的序列化处理方式可能会消耗大量的CPU资源,特别是处理复杂类型数据时。所以建议要根据业务和环境的不同,采用最优化的序列化和反序列化方式。

2.  在单一缓存中存储大对象数据。

由于序列化和反序列化需要一定的资源开销,处于并发负载时,大对象图形数据的频繁读取有可能会让服务器的CPU崩溃。相反,不妨考虑把大对象数据打散为较小的子对象,之后再各自进行缓存。根据你的需求读取最小的数据单元。

3.  在不同进程间使用缓存共享对象。

出现竞态条件(Race conditions)时,当写进程也参与其中,同时刚好程序的某部分也访问同一缓冲对象,情况会变得更坏。采取外部锁机制是有必要的。

4.  储存数据后立马进行缓存。

千万不要仓促行事,即使是刚写入不久,当存储资源紧张时,一个缓存足以阻碍程序运行。所以用代码来进行缓存空值返回检查是很有必要的

5.  使用嵌套对象存储全集合。

由于序列化的影响,执行一次全集合存储会导致程序运行变慢。有鉴于此,单独对独立对象进行缓存可以实现分开读取,减少序列化影响。

6.  对父子对象采取统一与单独混用的存储方式。

有时候一个对象可能拥有两个或更多的父对象。根据统一对象本身的键进行缓存以便不会把同一对象存储于不同地方,这样父对象可以按需访问子对象。

7.  对配置信息进行缓存。

使用进程的本地静态变量来存储配置数据。缓存数据访问是有代价的,所以要尽可能把影响减到最低。

8.  对活性对象进行缓存,例如:流,文件,注册信息或者网络。

不要尝试对上述等包含引用信息的活性对象进行缓存。因为当缓存数据被删除后,之前缓存的活性对象不会被删除,这样会造成系统资源泄漏。

9.  对同一对象采取多键存储。

这样或许在使用一个键和索引号来进行访问时带来便利。如果一个缓存是in-memory的,这样做是可行的,因为缓存中包含了同一对象的引用信息,也就是说一旦该对象发生变更,都可以透过两边的访问路径进行查看。如果是远程(外部)缓存,任何变更的发生都是不可见的,所以这样会导致同步问题的产生。

10. 在连续存储中进行更新或删除后没有及时更新相应缓存对象。

在一个远程缓存中,数据以拷贝方式存储,所以当更新对象时,缓存不会被同步更新。缓存必须被明确指定,才能根据变更而进行更新。在in-memory缓存中,一个对象发生的变更是对所有人可见的。在删除时情况类似,删除一个对象时,在缓存中不会被同步删除。这取决于程序本身如何确保缓存对象被正确删除。

原文: highscalability