关闭

Windows下java memcached 使用

标签: memcachedjava缓存
256人阅读 评论(0) 收藏 举报
分类:

一,Memcached介绍

memcached是被广泛使用的分布式缓存技术,使用它的目的是,通过它缓存数据库查询结果,减少数据库访问次数,提高动态Web应用的速度。
memcached作为分布式缓存服务器,具有如下的特点:
(1)协议简单:
memcached的服务器和客户端使用的通信协议是简单的基于文本行的协议,因此我们可以通过telnet也能在memcached服务器上保存/获取数据,如下:
这里写图片描述

这里写图片描述
(2)基于libevent的事件处理:
libevent是个程序库,memcached通过libevent能在linux、BSD等操作系统上发挥其高性能的特性。
(3)内置内存存储方式:
为了提高性能,memcached将数据保存在其内置的内存存储空间里,同样也是因为如此,所以当memcached重启、重启操作系统等操作会导致memcached存储的数据丢失。
另外,当内容的容量达到指定的值后,memcached会使用LRU算法自动删除不使用的缓存,以释放空间。
(4)memcached不互相通信的分布式:
经常说到memcached是分布式的缓存技术,但是它的分布式不是指服务器端的分布式,因为服务器端并没有分布式的功能。它的分布式是通过客户端来实现的,见下图
这里写图片描述

二,Windows下memcached的使用

1, 用到的jar包
这里写图片描述

其中Memcached-Java-Client-3.0.0.jar为memcached客户端,jar和源码下载地址http://search.maven.org/

2, 部分代码

public class MemcachedTest {

    protected static MemCachedClient mcc = new MemCachedClient();
    protected static MemcachedTest memcachedTest = new MemcachedTest();

    //设置与memcached服务器的连接信息
    static{
        /// 服务器列表和其权重
        String [] servers  = {"127.0.0.1:11211","192.168.0.101:11211"};
        Integer [] weights = {5,5};

        // 获取sock连接池的实例对象
        SockIOPool pool = SockIOPool.getInstance();

        pool.setServers(servers);
        pool.setWeights(weights);

        // 设置初始连接数、最小和最大连接数以及最大处理时间
        pool.setInitConn(5);
        pool.setMinConn(5);
        pool.setMaxConn(100);
        pool.setMaxIdle(1000*60*60*6);

        // 设置主线程的睡眠时间
        pool.setMaintSleep(30);

        // 设置TCP的参数,连接超时等
        pool.setNagle(false);
        pool.setSocketTO(3000);
        pool.setSocketConnectTO(0);

        pool.setHashingAlg(SockIOPool.CONSISTENT_HASH);

        // 初始化连接池
        pool.initialize();

    }

    /**
     * 保护型构造方法,不允许实例化!
     * 
     */
    protected MemcachedTest() {

    }

    /**
     * 获取唯一实例.
     * 
     * @return
     */
    public static MemcachedTest getInstance() {
        return memcachedTest;
    }

    /**
     * 添加数据
     * @param key
     * @param value
     * @return
     */
    public boolean add(String key, String value){
        return mcc.add(key, value);
    }

    public boolean add(String key, String value, Date expiry){
        return mcc.add(key, value, expiry);
    }

    public boolean replace(String key, String value){
        return mcc.replace(key,value);
    }

    public boolean replace(String key, String value, Date expiry){
        return mcc.replace(key, value, expiry);
    }

    public Object get(String key){
        return mcc.get(key);
    }

    public Object flush(){
        return mcc.flushAll();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MemcachedTest mt = MemcachedTest.getInstance();
        mt.flush();
        for (int i = 0; i < 10; i ++){
            mt.add("hello"+ i, "world" + i);
        }
        for(int i = 0; i < 10; i ++){
            System.out.println("the value of key Hello" + i +" is: " + mt.get("hello" + i));
        }
    }

}

首先,我们需要一个memcachedClient对象,该对象实现将数据添加到memcached服务器或者从服务器读取数据。然后初始化一个SockIOPool对象,该对象用来维护一个到memcached服务器的持续的连接池,连接池必须在使用前初始化。

3, memcached Client源码解读

在将数据添加到服务器这个过程,主要涉及到了客户端的下面的几个类:
MemCachedClient:生成客户端的入口
AscIIClient: memcachedClient的子类,负责具体的client的实例化
SchoonerSockIOPool
SockIOPool

(1) 初始化一个memcached client对象
protected static MemCachedClient mcc = new MemCachedClient();
查看client的源码发现它会通过解析参数,生成一个子类AscIIClient的对象。

    /**
     * Creates a new instance of MemCachedClient.
     */
    public MemCachedClient() {
        this(null, true, false);
    }

    /**
     * Create memcached client.
     * 
     * @param poolName
     *            name of SockIOPool
     * @param isTCP
     *            use tcp protocol
     * @param binaryProtocal
     *            use binary protocol.
     */
     public MemCachedClient(String poolName, boolean isTcp, boolean binaryProtocal) {
        if (binaryProtocal)
            client = new BinaryClient(poolName);
        else
            client = isTcp ? new AscIIClient(poolName) : new AscIIUDPClient(poolName);
    }

(2)在子类AscIIClient中,定义了一个pool的实例如下:

// pool instance
    private SchoonerSockIOPool pool;

根据上面第一点,在生成memcached client实例时,其实实际上生成的AscIIClient的实例,如下:

/**
     * Creates a new instance of MemCachedClient accepting a passed in pool
     * name.
     * 
     * @param poolName
     *            name of SockIOPool
     * @param binaryProtocal
     *            whether use binary protocol.
     */
    public AscIIClient(String poolName) {
        super((MemCachedClient) null);
        this.poolName = poolName;
        init();
    }

其中init()方法主要是完成一个默认的(default)client的初始化。

/**
     * Initializes client object to defaults.
     * 
     * This enables compression and sets compression threshhold to 15 KB.
     */
    private void init() {
        this.sanitizeKeys = true;
        this.primitiveAsString = false;
        this.compressEnable = false;
        this.compressThreshold = COMPRESS_THRESH;
        this.defaultEncoding = "UTF-8";
        this.poolName = (this.poolName == null) ? "default" : this.poolName;

        // get a pool instance to work with for the life of this instance
        this.pool = SchoonerSockIOPool.getInstance(poolName);
    }

(3)SockIOPool和SchoonerSockIOPool的关系:
在SockIOPool中,定义了一个SchoonerSockIOPool的实例,在初始化SockIOPool的时候,同时会获取一个SchoonerSockIOPool的对象。

// 获取sock连接池的实例对象
        SockIOPool pool = SockIOPool.getInstance();
/**
     * Single argument version of factory used for back compat. Simply creates a
     * pool named "default".
     * 
     * @return instance of SockIOPool
     */
    public static SockIOPool getInstance() {
        SockIOPool whalinSockIOPool = new SockIOPool();
        whalinSockIOPool.schoonerSockIOPool = SchoonerSockIOPool.getInstance("default");
        return whalinSockIOPool;
    }

(4) 通过SchoonerSockIOPool.getInstance方法获取一个SchoonerSockIOPool的实例时,程序会先检查连接池里面是否有名称为“default”的pool,若有,则取处理返回; 若无,生成名称为“default”的pool,并将该pool放置到连接池里面。

/**
     * Factory to create/retrieve new pools given a unique poolName.
     * 
     * @param poolName
     *            unique name of the pool
     * @return instance of SockIOPool
     */
    public static SchoonerSockIOPool getInstance(String poolName) {
        SchoonerSockIOPool pool;

        synchronized (pools) {
            if (!pools.containsKey(poolName)) {
                pool = new SchoonerSockIOPool(true);
                pools.putIfAbsent(poolName, pool);
            }
        }

        return pools.get(poolName);
    }

未完待续……

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10495次
    • 积分:233
    • 等级:
    • 排名:千里之外
    • 原创:13篇
    • 转载:4篇
    • 译文:0篇
    • 评论:0条
    文章分类