memcached安装与使用

作为一个工作将近三年的Java程序猿,因为一直做一些应用系统,且大多都是数据管理类的单系统应用,很少接触一些比较好的技术,比如缓存、负载均衡以及WebService等。经过和朋友聊天,确定了一些要攻克的技术,作为这一阶段的学习内容。

之前没有接触过memcached时,总觉得缓存应该是一项非常复杂的技术,其入门难道也一定很高。偶尔看一下,也总有一种丈二和尚摸不着头脑的感觉。不过,认真学习起来,发现它还是很容易就能学会并且掌握的。

这里摘抄一些来自于百度百科的介绍:

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

一、在win7中安装Memcached

Memcached分为服务器端和客户端,在使用Memcached之前,需要安装Memcached服务。下面介绍如何在win7中安装Memcached。

下载Memcached:http://www.urielkatz.com/projects/memcached-win64/memcached-win64.zip 

解压后得到一个Memcached.exe文件。启动命令行,将目录切换到Memcached.exe所在目录,在命令行中输入如下命令并回车:

D:\dev\memcached-win64>memcached.exe -d install

至此Memcached服务就安装成功了。在安装Memcached的过程中,你可能会遇到如下问题:

D:\dev\memcached-win64>memcached.exe -d install
failed to install service or service already installed
造成这个错误的原因可能有以下两个:

  1. 在此之前,你已经安装过Memcached。你可以通过 控制面板——管理工具——服务,查看是否已经存在memcached服务;
  2. 如果你之前没有安装过Memcached,那么可能是因为你当前系统用户没有权限安装服务。解决办法是,在C:\Windows\System32下找到cmd.exe,右键以管理员身份运行即可。
安装完成后,可以通过控制面板——管理工具——服务,查看是否成功安装了Memcached服务。如下图:


二、启动Memcached服务
  1. 以守护进程方式启动:memcached.exe -m 1024 -d start
  2. 指定端口启动:memcached.exe -p 11211 -m 1024
以上两种方式都可以启动Memcached服务,不同的是,第一种启动方式不能指定服务端口,默认的端口号为11211。其中,-m指定缓存大小为1024M,-p指定端口号为11211。下面是一些其它Memcached可用的参数:
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务  www.2cto.com  
 
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助

如下图,表示Memcached已经启动:



接下来可以测试一下是否能够与Memcached通讯。还是使用命令行,这里使用telnet命令。如下:

telnet 127.0.0.1 11211

telnet的格式为telnet ipaddress port,刚才以指定端口11211的方式启动Memcached服务,所以这里可以telnet这个端口。输入以上命令并回车后,DOS窗口会变成空白,表示通讯成功。此时回车,会得到一个ERROR,不用担心,这是因为该命令不存在。如下:



接下来可以通过stats命令查看一下Memcached的相关状态:



下面是这些状态的具体含义:

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:被请求的工作线程的总数量。这个解释是协议文档给的,具体什么意思,我目前还没搞明白。

在这一步,你有可能遇到的问题是,在输入telnet命令时,发现它是一个无效的命令。这是因为默认情况下,win7并没有安装此服务。你可用通过控制面板——程序与功能——打开或关闭windows功能,勾选telnet服务器、telnet客户端并点击确定来安装telnet服务,如下图:



三、在程序中使用Memcached

安装并启动Memcached后,就可用在项目中使用Memcached了。许多语言都实现了连接memcached的客户端,仅仅在memcached网站上列出的语言就有perl、php、python、ruby、c#、c/c++、lua等等。这里以java作为示例,演示如何在程序中使用Memcached。

要在Java中使用Memcached,需要用到以下jar包:

  • commons-pool-1.5.6.jar
  • java_memcached-release_2.6.3.jar
  • slf4j-api-1.6.1.jar
  • slf4j-simple-1.6.1.jar

首先用eclipse新建一个普通的java项目,将上面的jar包添加到项目中,新建一个class如下:

package com.tang;

import java.util.Date;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

/**
 * 演示Memcached缓存框架 
 *
 * @author tang
 */
public class MemcachedDemo {
    public static void main(String[] args) {
        MemCachedClient client = new MemCachedClient();
        // 指定memcached服务地址 
        String[] servers = { "127.0.0.1:11211" };
        // 指定memcached服务器负载量
        Integer[] weights = { 3 };
        // 从连接池获取一个连接实例
        SockIOPool pool = SockIOPool.getInstance();
        // 设置服务器和服务器负载量
        pool.setServers(servers);
        pool.setWeights(weights);
        /* 设置基本参数 */
        // 设置初始连接数5
        pool.setInitConn(5);
        // 最小连接数 5
        pool.setMinConn(5);
        // 最大连接数 250
        pool.setMaxConn(250);
        // 最大空闲时间5小时
        pool.setMaxIdle(1000 * 60 * 60 * 5);
        // 设置主线程睡眠时间
        // 每隔30秒醒来  然后
        // 开始维护 连接数大小
        pool.setMaintSleep( 30 );
        // 设置tcp 相关的树形
        // 关闭nagle算法
        pool.setNagle( false );
        // 设置读取超时3秒
        pool.setSocketTO(3000);
        // 不设置连接超时
        pool.setSocketConnectTO( 0 );
        // 开始初始化 连接池
        pool.initialize();
        
        // 设置压缩模式(该方法已过时)
        // client.setCompressEnable( true );
        // 如果超过64k压缩数据(该方法已过时)
        // client.setCompressThreshold( 64 * 1024 );
        
        // 写入缓存数据
        client.set("key", "value");
        client.set("timeout", "10秒后失效的数据", new Date(10 * 1000));
        
        // 读取缓存数据
        System.out.println(client.get("key"));
        System.out.println(client.get("timeout"));
        
        try {
            Thread.sleep(12 * 1000);
            System.out.println("12秒过后,key为timeout的缓存数据已经失效");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        // 12秒后读取缓存数据
        System.out.println(client.get("key"));
        System.out.println(client.get("timeout"));
        
    }
}

运行程序,结果如下:



value
10秒后失效的数据
12秒过后,key为timeout的缓存数据已经失效
value
null

以上示例可以看出,Memcached通过set向缓存中写入数据,通过get读取缓存中的数据。set同时还可以提供其它参数,比如缓存过期时间等。设置缓存过期时间的缓存,会在指定时间后失效,失效后再读取改缓存,就会得到一个null。


四、Memcached的其它参数

MemCachedClient 类 常用的方法说明

创建 client对象 设置参数:

MemCachedClient mc = new MemCachedClient();
//压缩模式
mc.setCompressEnable(true);
// 如果 cache数据 大于4 KB 就启用压缩
mc.setCompressThreshold(4096);
// 基本类型tostring方法
// 通常不需要设置
mc.setPrimitiveAsString(true);
存储一个对象:

MemCachedClient mc = new MemCachedClient();

String key = "cacheKey1";

Object value = SomeClass.getObject();

mc.set(key, value);
用客户端hashcode 存储一个对象:


MemCachedClient mc = new MemCachedClient();

String key = "cacheKey1";

Object value = SomeClass.getObject();

Integer hash = new Integer(45);

mc.set(key, value, hash);

set方法:在cache中存储一个指定对象

add 和replace 方法功能差不多

add -- 如果不存在 这个key的对象,将会存储一个对象到cache中
replace --只有当存在指定key对象的时候 会覆盖已有对象
删除一个对象:

MemCachedClient mc = new MemCachedClient();

String key = "cacheKey1";

mc.delete(key);
结合hashcode 删除一个对象:

MemCachedClient mc = new MemCachedClient();

String key = "cacheKey1";

Integer hash = new Integer(45);

mc.delete(key, hashCode);
怎么cache计数,增 减计数:

MemCachedClient mc = new MemCachedClient();

String key = "counterKey";

mc.storeCounter(key, new Integer(100));

System.out.println("counter after adding 1: " mc.incr(key));

System.out.println("counter after adding 5: " mc.incr(key, 5));

System.out.println("counter after subtracting 4: " mc.decr(key, 4));

System.out.println("counter after subtracting 1: " mc.decr(key));
利用客户端的hashcode存储计数 增减 计数:

MemCachedClient mc = new MemCachedClient();

String key = "counterKey";

Integer hash = new Integer(45);

mc.storeCounter(key, new Integer(100), hash);

System.out.println("counter after adding 1: " mc.incr(key, 1, hash));

System.out.println("counter after adding 5: " mc.incr(key, 5, hash));

System.out.println("counter after subtracting 4: " mc.decr(key, 4, hash));

System.out.println("counter after subtracting 1: " mc.decr(key, 1, hash));
获取一个对象:

MemCachedClient mc = new MemCachedClient();

String key = "key";

Object value = mc.get(key);
用客户端hashcode获取一个对象:

MemCachedClient mc = new MemCachedClient();

String key = "key";

Integer hash = new Integer(45);

Object value = mc.get(key, hash);
MemCachedClient mc = new MemCachedClient();

String key = "key";

Integer hash = new Integer(45);

Object value = mc.get(key, hash);
从cache 中获取多个对象

MemCachedClient mc = new MemCachedClient();

String[] keys ={ "key", "key1", "key2" };Mapvalues = mc.getMulti(keys);
用客户端hashcode 从cache中获取多个对象
MemCachedClient mc = new MemCachedClient();
String[] keys = { "key", "key1", "key2" };

Integer[] hashes =
{ new Integer(45), new Integer(32), new Integer(44) };
Mapvalues = mc.getMulti(keys, hashes);
清空所有的对象
MemCachedClient mc = new MemCachedClient();

mc.flushAll();
得到服务器memcached的状态信息
MemCachedClient mc = new MemCachedClient();

Map stats = mc.stats();
注意点
1:Failover/Failback
当一个memcached服务器失效的时候客户端默认会failover另一个服务去.

如果失效的服务器 恢复运行,客户端会返回到原来连接的服务器.
如果你不想用这个功能 设置下面的参数
pool.setFailover( false );
pool.setFailback( false );

2:序列化

Boolean
Byte
String
Character
StringBuffer
StringBuilder
Short
Long
Double
Float
Date
java默认的类型没有实现序列化 可以设置
mcc.setPrimitiveAsString( true )替代.
Meetup.com实践过程中得出的一个经验 ,项目中model 对象implement Externalizable 实现序列化,
可以节省cache 对象的大小。从而节省网络带宽和内存空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值