memcached總結文檔

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毫秒,否則設置過期時間不起作用

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章