从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么
硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片、视频、各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里,不会无辜地消失掉。那内存是用来做什么的呢?我是不能准确的描述出来,所以我抄袭了下面描述内存作用的一段话:
内存就是暂时存储程序以及数据的地方,比如当我们在使用 WPS 处理文稿时,当你在键盘上敲入字符时,它就被存入内存中,当你选择存盘时,内存中的数据才会被存入硬(磁)盘。
为什么这么做?
由于硬盘 IO(读写)速度比较慢,CPU 如果运行程序的时候,所有数据都直接从硬盘中读写,会非常影响效率。所以, CPU 会将运行软件时要用的数据一次性从硬盘调用到运行速度很快的内存,然后, CPU 再与内存进行数据交换。内存是易失性存储器,只要你断了电,内存中的数据就没有了。
我们程序界有没有「内存」呢
当然有。一个简单的 Web 软件系统必须包含前端页面、后端程序、数据库、服务器等等这些最基础的东西,如果我们稍微对系统要求高一点的话,我们发现每次从数据库读取数据的时间都有些漫长,这时候的数据库可以理解为电脑中的硬盘,那我们能不能提高直接从数据库取数据的性能?或者说减少相同数据的次数。完全没问题的,因为电脑中有内存做这件事,我们程序中也有一种类似的东西叫缓存
。
在程序中缓存的实现方式根据不同语言、不同框架我们可以使用的缓存系统可以不相同,但是,最后他们要做的事情都是为了提高程序的性能而生的。
如果我们来详细分一下那就太多了,我们稍微数一下大的分类,如:页面缓存、静态资源缓存、数据库缓存、开发框架缓存、内存缓存系统等等这些大的分类,在这些大类上的具体实现就太多了,我们这里只讨论利用开源的内存缓存系统构建我们项目几乎都需要的缓存服务器。
比较常用的缓存系统应该就是 Redis 和 Memcached 了吧。这里不做任何这两个技术的比较与讨论,你只需要根据你使用场景选择合适自己的就好,或者你并没有选择能力的时候,什么都别说随便用一个就行。我这里使用的 Memcached ,请不要问为什么不用 Redis 。
程序中缓存的实现方式
由于我们是基于 Spring 框架下实现缓存,我大致把缓存在 Spring 下集成的方式分为了三种:
- 通过客户端代码实现。我称之为「最原始版」方式
- 利用 AOP 方式管理。就叫它「升级版」吧
- 注释驱动缓存方案。Spring 3.1 版本的新特性
要说哪种方式更好,我当然更偏向于注释驱动缓存方案
这种方式,因为你需要在你需要缓存的方法名上打@Cacheable、@CachePut、@CacheEvict
标签来实现返回数据缓存到服务器。这种方式对代码的侵入性是比较小的!这种方式有一个目前我无法解决的问题是:当你方法每次返回的数据都不一样的时候,你缓存命中率会是多少?
也有开源组件simple-spring-memcached
也是这种方式,但它的实现原理其实是 AOP 方式来管理,他也是用@ReadThroughSingleCache、@InvalidateSingleCache、@UpdateSingleCache
这类的标签来实现缓存,对程序来说也很友好,并且要比 Spring 的方式要更完美一些,但它依然没有解决我的上述问题。
那么我要解决的问题是:缓存命中率要高、缓存数据要尽量少,换句话说就是尽可能少的存储缓存数据并尽可能大的命中缓存。
如果解决我这种事儿逼的要求,那只能自己要实现缓存咯。这就是我们上述所说的「最原始版」方式,怎么理解这种方式,就是自己写代码定义一个缓存管理器,调用缓存客户端实现缓存管理,然后再定义你要缓存的 Model 类,接着新增一个这个类的缓存实现,就是对象的获取、增加、修改和删除,接着就是在你需要获取数据的时候通过缓存获取,修改数据的时候更新缓存,删除数据的时候删除缓存。这种方式好不好?不好,首先它对代码的侵入性已经到了令人发指的地步,你想想,如果你删除数据时不小心忘记调用删除缓存了,那后果是什么呢?但是,它唯一好处可能就是比较灵活了吧,可以缓存我们想缓存的内容,来解决我们上述问题,所以,思来想去最终还是决定采用最原始的方式来实现缓存,当然,首先还是要考虑我们怎么做到缓存对代码的侵入性,以及我们怎么更方便或者说不需要改代码就实现缓存了。
总结一下
这篇文章完全没有所谓的「干货」,整篇都是我关于缓存的思考与选择,如果你坚持看到这里,那你必有一个锦绣前程。但我认为这个过程很重要,甚至会比写出代码还要重要,所以我选择记录下来,大家一起探讨。
下一篇 从零开始学 Java - Spring 集成 Memcached 配置(二) 文章会写关于缓存客户端(Memcached Client for Java、SpyMemcached、XMemcached)的选择和一些配置及具体代码的实现,就是所谓的「干货」,如果你有兴趣可以去我的 GitHub 上关于 Spring 的示例项目看看:https://github.com/mafly/SpringDemo/tree/memcached。
好了,我睡了。
从零开始学 Java - Spring 集成 Memcached 缓存配置(一)的更多相关文章
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)
Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)
从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)
你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- 从零开始学 Java - Spring 支持 CORS 请求踩的坑
谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...
- 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求
论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 从零开始学 Java - Spring 一主多从、多主多从 数据库配置
待会苹果要开发布会 我写完这篇文章就准备去看发布会了,因为我买了好几包瓜子和啤酒.由于苹果的保密做的越来越差劲,该曝光的信息差不多全部曝光了,我们这种熬夜看发布会的只不过是让这些信息更加真实,或者说是 ...
- 从零开始学 Java - Spring 使用 Quartz 任务调度定时器
生活的味道 睁开眼看一看窗外的阳光,伸一个懒腰,拿起放在床一旁的水白开水,甜甜的味道,晃着尾巴东张西望的猫猫,在窗台上舞蹈.你向生活微笑,生活也向你微笑. 请你不要询问我的未来,这有些可笑.你问我你是 ...
随机推荐
- 使用python自动生成docker nginx反向代理配置
由于在测试环境上用docker部署了多个应用,而且他们的端口有的相同,有的又不相同,数量也比较多,在使用jenkins发版本的时候,不好配置,于是想要写一个脚本,能在docker 容器创建.停止的时候 ...
- BPM配置故事之案例9-根据表单数据调整审批线路2
老李:好久不见啊,小明. 小明:-- 老李:不少部门有物资着急使用,现在的审批流程太慢了,申请时增加一个是否加急的选项吧.如果选加急,金额1000以下的直接到我这里,我审批完就通过,超过1000的直接 ...
- μCos-ii学习笔记1_概述
一.μCos-ii _概述 网上关于μCosii的文章多不胜数,本人学习的过程中也参考了很多人的理解和想法,看的是卢有亮老师的<嵌入式实时操作系统-μC/OS原理与实践>(第2版),同时也 ...
- echo命令
linux的echo命令, 在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的, 因此有必要了解下echo的用法echo命令的功能是在显示器上显示一段文字,一般起到一个提示的 ...
- [css]实现垂直居中水平居中的几种方式
转自博客 http://blog.csdn.net/freshlover/article/details/11579669 居中方式: 一.容器内(Within Container) 内容块的父容器设 ...
- ubuntu14 安装及卸载vmware
原帖http://blog.sina.com.cn/s/blog_73dac6b50101gp4f.html 适用于ubuntu14和vmware player 12.5
- 从myeclipse导入eclipse,不能识别为web项目(java项目转为web项目)
1.进入项目目录,找到.project文件,打开. 2.找到<natures>...</natures>代码段. 3.在第2步的代码段中加入如下标签内容并保存: ...
- Xamarin.Android快速入门
一.准备工作 1.创建一个空的解决方案,并命名为Phoneword 2.右击解决方案 新建->新建项目 并命名为Phoneword_Droid 二.界面 1.打开Resources文件夹-> ...
- C#与C++的发展历程第四 - C#6的新时代
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- CSS样式表分类
1.内联样式表 <p style="font-size:11px;">内联样式表</p> 2.内嵌样式表 写在head标签里 <style typ ...