memcached总结文档

本文介绍Memcached缓存系统的基础知识,包括安装配置过程、运行原理及如何在Java环境中进行缓存操作。通过示例代码展示如何设置、获取及删除缓存数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Memcached总结文档

memcached简介:

概念:

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

Memcached与memcache

Memcachedanga的一个项目,最早是LiveJournal 服务的,最初为了加速 LiveJournal 访问速度而开发的,后来被很多大型的网站采用。

 

Memcached是以守护程序方式运行于一个或多个服务器中,随时会接收客户端的连接和操作

 

 

特点:

memcached作为高速运行的分布式缓存服务器,具有以下的特点。1.协议简单memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。因此,通过telnet也能在memcached上保存数据、取得数据。

2. 基于libevent的事件处理:ibevent是个程序库,它将LinuxepollBSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。memcached使用这个libevent库,因此能在LinuxBSDSolaris等操作系统上发挥其高性能。

3.存储方式:memcached默认情况下采用了名为Slab Allocatoion的机制分配,管理内存。内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存

4.通信分布式memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。而是基于客户端实现的。

Memcached运行原理示意图

 

linux安装memcached服务端

  下载memcached客户端:另外,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent,如果你的系统已经安装了libevent,可以不用安装如果没有也必须下载安装。

1.在linux中打开终端:分别把memcachedlibevent下载回来,放到 /tmp 目录下:

Linux终端输入语句:

 # cd  /tmp         进入tmp文件夹

# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz


# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz

 

自动下载memcached-1.2.0.tar.gzlibevent-1.2.tar.gz

如在虚拟机linux中无法下载,看错误中的解决方案

2.先安装libevent:依次执行下列语句

# tar  zxvf  libevent-1.2.tar.gz

# cd  libevent-1.2

# ./configure prefix=/usr

# make

# make install

3 测试libevent是否安装成功:

# ls -al /usr/lib | grep libevent

 

 如输出一下信息则安装成功

 

4.安装memcached,安装时需要指定libevent的安装位置:(顺序执行以下语句)

# cd /tmp

# tar zxvf memcached-1.2.0.tar.gz

# cd memcached-1.2.0

# ./configure –with-libevent=/usr

# make

# make install

安装完成后会把memcached放到 /usr/local/bin/memcached 

 

5.测试memcached是否安装成功

# ls -al /usr/local/bin/mem*

 

如果输出一下信息,则安装成功

 

启动memcached服务端

# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.141.64 -p 12000 -c 256 -P /tmp/memcached.pid

 

语句中各个参数的含义

 

如果要结束memcached,则执行: # kill ‘cat /tmp/memcached.pid’

 

查看memcached运行状态  

ps -ef|grep memcached

 

注意:可以启动多个守护进程,不过端口不能重复。

 

测试memcached

按照下图执行语句,如果可以输出信息,则表示正常

安装时遇到错误

下载时无法下载

解决方案:

windows里通过浏览器直接下载,然后通过ssh工具直接复制到 /tmp

步骤:1.linux里输入下面语句设置ip

ifconfig eth0 ip地址

2.在windows下通过ssh连接linux

  

连接成功之后点击如下按钮

会出现

在本地window中找到下载的文件复制到linux中的/tmp目录下

启动memcached时遇到的错:

解决方案

 

Memcached缓存简单字符串

1.引入commons-pool-1.5.6.jarjava_memcached-release_2.5.1.jarslf4j-api-1.6.1.jarslf4j-simple-1.6.1.jar

 

同时导入junit 包和 log4j包,若不使用junit测试或者打印日志信息可不导入

2.创建memcached工具类:

public class MemcachedUtil {

 

//log4j

    private static Logger logger = Logger.getLogger(MemcachedUtil.class);

 

    //实例化memcached客户端

    public static MemCachedClient mcc = null;

 

    //SockIOPool是Memcached客户端提供的一个套接字连接池,通俗讲,就是与Memcached服务器端交换数据的对象。

    private static SockIOPool pool = null;

//初始调用init方法

    static {

        init();

    }

 

    /**

     * 初始化连接池

     */

    public static void init() {

        String sockPoolName = "MEM_CAHCE";

        String serverlist = "";

//初始连接数

        int initConn = 5;

//最小连接数

        int minConn = 5;

//最大连接数

        int maxConn = 50;

 

        Properties properties = new Properties();

        try {

//加载配置文件

            properties.load(new FileInputStream(MemcachedUtil.class.getResource("/test/memcache.properties").getFile()));

            sockPoolName = properties.getProperty("memcache.poolName", sockPoolName);

            serverlist = properties.getProperty("memcache.serverlist", serverlist);

            initConn = Integer.parseInt(properties.getProperty("memcache.initConn", "5"));

            minConn = Integer.parseInt(properties.getProperty("memcache.minConn", "5"));

            maxConn = Integer.parseInt(properties.getProperty("memcache.maxConn", "50"));

        } catch (IOException e) {

            logger.warn("not found  finle memcache.properties in classpath", e);

        }

 

        logger.info("Initializing memcached pool");

        if (pool == null) {

            try {

                pool = SockIOPool.getInstance(sockPoolName);

                pool.setServers(serverlist.split(","));

                if (!pool.isInitialized()) {

                    pool.setInitConn(initConn);

                    pool.setMinConn(minConn);

                    pool.setMaxConn(maxConn);

                    pool.setMaintSleep(30);

                    pool.setNagle(false);

//最大处理时间

                    pool.setSocketTO(60 * 60);

//设置TCP参数,连接超时

                    pool.setSocketConnectTO(0);

  //初始化并启动连接池

                    pool.initialize();

                }

            } catch (Exception ex) {

                logger.error(ex.getMessage());

            }

        }

 

        if (mcc == null) {

            mcc = new MemCachedClient(sockPoolName);

            mcc.setClassLoader(MemcachedUtil.class.getClassLoader());

            mcc.setCompressEnable(false);

            mcc.setCompressThreshold(0);

        }

    }

 

    /**

     * 关闭连接池

     */

    public static void closePool() {

        pool.shutDown();

        mcc = null;

        pool = null;

        logger.info("Memcached pool closed");

    }

 

    /**

     * 设置缓存

     *

     * @param key 键

     * @param obj 值

     */

    public static boolean set(String key, Object obj) {

        try {

            return mcc.set(key, obj);

        } catch (Exception e) {

            logger.error("Pool set error!");

            e.printStackTrace();

        }

        return false;

    }

    

    

    /**

     * 设置缓存

     *

     * @param key 键

     * @param obj 值

     */

    public static boolean set(String key, Object obj, long time) {

        try {

            return mcc.set(key, obj, new Date(time));

        } catch (Exception e) {

            logger.error("Pool set error!");

            e.printStackTrace();

        }

        return false;

    }

    /**

     * 设置缓存

     *

     * @param key  键

     * @param obj  值

     * @param time 缓存时间(毫秒)

     */

    public static boolean set(String key, Serializable obj, long time) {

        try {

            return mcc.set(key, obj, new Date(time));

        } catch (Exception e) {

            logger.error("Pool set error!");

            e.printStackTrace();

        }

        return false;

    }

 

    public static void replace(String key, Serializable value, long cachelTime) {

        try {

            mcc.replace(key, value, new Date(cachelTime));

        } catch (Exception e) {

            logger.error(" pool set error!");

        }

    }

 

    /**

     * 获取缓存

     *

     * @param key 键

     * @return 值

     */

    public static Object get(String key) {

        Object result = null;

        try {

            result = mcc.get(key);

        } catch (Exception e) {

            e.printStackTrace();

        }

        return result;

    }

 

    /**

     * 缓存数值

     *

     * @param key   键

     * @param count 数值

     */

    public static void setCounter(String key, long count) {

        try {

            mcc.storeCounter(key, count);

        } catch (Exception e) {

            logger.error("Pool setCounter error!");

        }

    }

 

    /**

     * 缓存的数值加1

     *

     * @param key 键

     */

    public static void addCounter(String key) {

        try {

            mcc.incr(key);

        } catch (Exception e) {

            logger.error("Pool setCounter error!");

        }

    }

 

    /**

     * 增加缓存数值

     *

     * @param key      键

     * @param addValue 增加的值

     */

    public static void addCounter(String key, long addValue) {

        try {

            mcc.incr(key, addValue);

        } catch (Exception e) {

            logger.error(" pool setCounter error!");

        }

    }

 

    /**

     * 获取缓存数值

     *

     * @param key 键

     * @return 值

     */

    public static long getCounter(String key) {

        long result = 0;

        try {

            result = mcc.getCounter(key);

        } catch (Exception e) {

            logger.error(e.getMessage());

        }

        return result;

    }

 

    /**

     * 删除缓存

     *

     * @param key 键

     */

    public static boolean delete(String key) {

        try {

            return mcc.delete(key);

        } catch (Exception e) {

            logger.error(e.getMessage());

        }

        return false;

    }

 

    /**

     * 删除缓存数值

     *

     * @param key 键

     */

    public static long deleteCounter(String key) {

        try {

            return mcc.decr(key);

        } catch (Exception e) {

            logger.error(" pool setCounter error!");

        }

        return 0;

    }

}

数据写入操作方法的解释:

set方法

将数据保存到cache服务器,如果保存成功则返回true

如果cache服务器存在同样的key,则替换之

set5个重载方法,keyvalue是必须的参数,还有过期时间,hash码,value是否字符串三个可选参数

add方法

将数据添加到cache服务器,如果保存成功则返回true

如果cache服务器存在同样key,则返回false

add4个重载方法,keyvalue是必须的参数,还有过期时间,hash码两个可选参数

· replace方法

将数据替换cache服务器中相同的key,如果保存成功则返回true

如果cache服务器不存在同样key,则返回false

replace4个重载方法,keyvalue是必须的参数,还有过期时间,hash 码两个可选参数

其中过期时间的单位为毫秒

 

 

数据读取方法的解释:

cache数据读取操作方法

 

使用get方法从cache服务器获取一个数据

 

3.创建测试用例:

 

//调用工具类的set方法 往memcached里添加值(设置过期时间的时候不能低于1000毫秒)

 MemcachedUtil.set("hello", "world", 1000);

//调用工具类的get方法根据键获取值

        Object hello = MemcachedUtil.get("hello");

        //直接输出没有睡眠时间,即不超过缓存的过期时间System.out.println(hello+"--------------------------------");

//调用睡眠方法使程序停止运行2000毫秒

 try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

//再次调用get方法

        Object hello2 = MemcachedUtil.get("hello");

        System.out.println(hello2+"--------------------------------");

        Assert.assertEquals("world", hello);

Memcached缓存实体对象

1.创建JavaBean 对象并实现Serializable否则会缓存不到memcached中其他步骤与缓存简单字符一样

设置多个端口进行缓存:

在配置文件中,在serverlist中设置多个端口,不同端口之间用分割

附(配置文件):memcached.properties

memcache.poolName=MEM_CAHCE

#memcache.serverlist=127.0.0.1:11211

memcache.serverlist=192.168.192.128:12244,192.168.192.128:12233

memcache.initCon=5

memcache.minConn=5

memcache.maxConn=508

遇错总结:

1.windows中使用Java程序连接linux时必须保证linux的防火墙是关闭的否则会出现如下错误

com.schooner.MemCached.SchoonerSockIOPool Thu Aug 21 00:09:00 CST 2014 - ++++ failed to get SockIO obj for: 192.168.192.128:1223

com.schooner.MemCached.SchoonerSockIOPool Thu Aug 21 00:09:00 CST 2014 - ++++ failed to create connection to: 192.168.192.128:1223 -- only 0 created.

com.schooner.MemCached.SchoonerSockIOPool Thu Aug 21 00:09:01 CST 2014 - ++++ failed to get SockIO obj for: 192.168.192.128:1223

设置过期时间的时候必须保证过期时间大于1000毫秒,否则设置过期时间不起作用

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值