windows下Memcached 架设及java应用

1  Memcached 介绍

  Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。

Memcached需要有缓存服务端,采用java编程的话还需要memcached.jar,这就是java中实现memcached服务的插件。

2 使用Memcached目的

研究这个东东主要是为了解决在项目中,由于信息过多,当用户查询数据时(目前当天查询的都是前一天的数据),由于数据量过大,并且大并发情况下数据库频繁读写造成速度慢的问题。所以就想通过使用Memcached解决这一问题。

3  memcached原理及工作机制

Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。

它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这些HashTable。

4 准备过程

在开发前,要准备有:

memcached-1.2.6-win32-bin.zip     windows下服务器

memcached-1.2.6-win32-src.zip     windows 下服务器源码(是C语言哦,亲)

memcached-1.2.6.tar.gz            linux 下服务器

java_memcached-release_2.5.1.jar   java 客户端 JAR包

5 服务器安装过程

首先解压memcached-1.2.6-win32-bin.zip到某一盘下,然后使用命令、或者直接双击,运行。相当于就已经安装好memcached服务器了。并且启动了服务。它的默认端口是:11211(不建议修改)

打开控制面板-管理工具-服务:

 此时可以访问一下服务器:打开-运行-cmd-telnet 127.0.0.1 11211

输入命令stats

 

这里显示了很多状态信息,下边详细解释每个状态项:

1.  pid: memcached服务进程的进程ID

2.  uptime: memcached服务从启动到当前所经过的时间,单位是秒。

3.  time: memcached服务器所在主机当前系统的时间,单位是秒。

4.  version: memcached组件的版本。这里是我当前使用的1.2.6。

5.  pointer_size:服务器所在主机操作系统的指针大小,一般为32或64.

6.  curr_items:表示当前缓存中存放的所有缓存对象的数量。不包括目前已经从缓存中删除的对象。

7.  total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括目前已经从缓存中删除的对象。

8.  bytes:表示系统存储缓存对象所使用的存储空间,单位为字节。

9.  curr_connections:表示当前系统打开的连接数。

10. total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数。

11. connection_structures:表示从memcached服务启动到当前时间,被服务器分配的连接结构的数量,这个解释是协议文档给的,具体什么意思,我目前还没搞明白。

12. cmd_get:累积获取数据的数量,这里是3,因为我测试过3次,第一次因为没有序列化对象,所以获取数据失败,是null,后边有2次是我用不同对象测试了2次。

13. cmd_set:累积保存数据的树立数量,这里是2.虽然我存储了3次,但是第一次因为没有序列化,所以没有保存到缓存,也就没有记录。

14. get_hits:表示获取数据成功的次数。

15. get_misses:表示获取数据失败的次数。

16. evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象。

17. bytes_read:memcached服务器从网络读取的总的字节数。

18. bytes_written:memcached服务器发送到网络的总的字节数。

19. limit_maxbytes:memcached服务缓存允许使用的最大字节数。这里为67108864字节,也就是是64M.与我们启动memcached服务设置的大小一致。

20. threads:被请求的工作线程的总数量。这个解释是协议文档给的,具体什么意思,我目前还没搞明白。

6 客户端开发过程(分为2种)

第1种:不使用spring(直接在static 里面初始化连接。)

1 加载java_memcached-release_2.5.1.jar包

2 编写MemcachedUtil 分布式缓存工具类

3 创建需要缓存的对象(必须要序列化对象)

对于普通的POJO而言,如果要进行存储的话,那么比如让其实现java.io.Serializable接口,因为memcached是一个分布式的缓存服务器,多台服务器间进行数据共享需要将对象序列化的,所以必须实现该接口,否则会报错的。缓存中获取的对象是存入对象的一个副本,对获取对象的修改并不能真正的修改缓存中的数据,而应该使用其提供的replace等方法来进行修改。

4 使用缓存(如果在缓存有效期内,则数据就从缓存中查询,如果不在缓存有效期内,意思就是过期了,则就从数据库中查询)

5 缓存过期时间的设置

过期时间有两种格式:

1. 相对时间:多长时间,给出过期的时间长度

2. 绝对时间:到期时间,给出过期的最后期限

相对时间时,返回的值是:服务器当前时间之后的exptime – process_started秒

绝对时间时,返回的值是:服务器当前时间之后的(exptime -服务器当前时间) -process_started秒。

可以看到,如果Client和Server时间不一致,使用绝对时间很容易导致缓存过期。

所以使用相对时间是比较安全的做法。

服务端的处理

时间处理源代码【memcached.c】如下:

#define REALTIME_MAXDELTA60*60*24*30                     //定义30天的秒数

static rel_time_t realtime(const time_texptime) {

       if(exptime == 0) return 0;

       if(exptime > REALTIME_MAXDELTA){                       //超过30天,是绝对时间

              if(exptime <=process_started)                         //小于进程启动日期

                      return(rel_time_t)1;                                  //

              return(rel_time_t)(exptime – process_started);   // 返回进程启动之后的时间差

       }else{                                                                   //不超过30天,是相对时间

              return(rel_time_t)(exptime +current_time);       // exptime + (tvsec -process_started)

       }

}

OK,结束!

第2种方法:(使用spring配置,方便之后扩展)

1 同样加载JAR包java_memcached-release_2.5.1.jar

2 封装memcached缓存。建立接口IMemcachedClient

实现类MemcachedClientImpl.java

3 在spring的核心配置文件applicationContext.xml中配置

4 创建需要缓存的对象。

5 使用memcached的缓存

OK,结束!

标签