从零开始学 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 任务调度定时器
生活的味道 睁开眼看一看窗外的阳光,伸一个懒腰,拿起放在床一旁的水白开水,甜甜的味道,晃着尾巴东张西望的猫猫,在窗台上舞蹈.你向生活微笑,生活也向你微笑. 请你不要询问我的未来,这有些可笑.你问我你是 ...
随机推荐
- java统计字符串单词的个数
在一些项目中可能需要对一段字符串中的单词进行统计,我在这里写了一个简单的demo,有需要的同学可以拿去看一下. 本人没怎么写个播客,如果有啥说的不对的地方,你来打我啊 不说废话了直接贴代码: 实现代码 ...
- 关于MJRefresh的下拉加载数据bug
当没有更多数据的时候显示NoMoreData 我的理解是先结束刷新再显示没有更多 今天之前一直没发现有问题 贴之前的代码 [self.collectionView reloadData]; [self ...
- Quartz
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. eg: ja ...
- NYOJ 455
1.应该交代清楚,参加宴会的人不知道一共有多少顶帽子.假如知道有n顶帽子的话,第一次开灯看见有n-1只,自然就知道自己是第n顶黑帽子,所以应该是这n个人在第一次关灯就打自己脸,不过这么一来就没意思了, ...
- WPF - 属性系统 (3 of 4)
依赖项属性元数据 在前面的章节中,我们已经介绍了WPF依赖项属性元数据中的两个组成:CoerceValueCallback回调以及PropertyChangedCallback.而在本节中,我们将对其 ...
- Angular2学习笔记——NgModule
在Angular2中一个Module指的是使用@NgModule修饰的class.@NgModule利用一个元数据对象来告诉Angular如何去编译和运行代码.一个模块内部可以包含组件.指令.管道,并 ...
- 使用Maven+Nexus+Jenkins+Svn+Tomcat+Sonar搭建持续集成环境(一)
前言 但凡一个略有规模的项目都需要一个持续集成环境的支撑,为什么需要持续集成环境,我们来看一个例子.假如一个项目,由A.B两位程序员来协作开发,A负责前端模块,B负责后端模块,前端依赖后端.A ...
- 如何开发一个简单的HTML5 Canvas 小游戏
原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...
- How ASP.NET Web API 2.0 Works?[持续更新中…]
一.概述 RESTful Web API [Web标准篇]RESTful Web API [设计篇] 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用 二.路由 ...
- Go语言实战 - revel框架教程之缓存和Job
所有的网站应该都会有一个非常简单的需求,首页一秒之内打开. 满足的方式主要有两种: 页面静态化,效果最好,对服务器基本没负担,只要带宽足够就好了.我知道一个PV过亿的站点就是全站静态(以前新浪也是), ...