天天看點

Memcached簡介特征Memcached 存儲指令查找指令統計指令Java 連接配接 Memcached 服務

簡介

  • Memcached是一個自由開源的,高性能,分布式記憶體對象緩存系統。
  • Memcached是一種基于記憶體的key-value存儲,用來存儲小塊的任意資料(字元串、對象)。這些資料可以是資料庫調用、API調用或者是頁面渲染的結果
  • 一般的使用目的是,通過緩存資料庫查詢結果,減少資料庫通路次數,以提高動态Web應用的速度、提高可擴充性。

特征

  • memcached作為高速運作的分布式緩存伺服器,具有以下的特點。

    協定簡單

    基于libevent的事件處理

    内置記憶體存儲方式

    memcached不互相通信的分布式

Memcached 存儲指令

set 指令

該指令用于将 value 存儲在指定的 key(鍵) 中。如果set的key已經存在,該指令可以更新該key所對應的原來的資料,也就是實作更新的作用。

  • 文法:

    set key flags exptime bytes [noreply]

    value

    參數說明如下:

    flags:可以包括鍵值對的整型參數,客戶機使用它存儲關于鍵值對的額外資訊 。

    exptime:在緩存中儲存鍵值對的時間長度(以秒為機關,0 表示永遠)

    bytes:在緩存中存儲的位元組數

    noreply(可選): 該參數告知伺服器不需要傳回資料

    value:存儲的值(始終位于第二行)

  • 執行個體
set runoob 0 900 9
memcached
STORED

get runoob
VALUE runoob 0 9
memcached

END
           
  • 輸出

    成功,則輸出:STORED。失敗,則輸出:ERROR

add 指令

該指令用于将 value(資料值) 存儲在指定的 key(鍵) 中。

如果 add 的 key 已經存在,則不會更新資料(過期的 key 會更新),之前的值将仍然保持相同,并且您将獲得響應 NOT_STORED。

  • 文法:

    add key flags exptime bytes [noreply]

    value

  • 執行個體
add new_key 0 900 10
data_value

STORED

get new_key
VALUE new_key 0 10
data_value
END
           
  • 輸出

    如果添加成功,輸出:STORED。如果失敗,輸出:NOT_STORED 。

replace 指令

該指令用于替換已存在的 key(鍵) 的 value(資料值)。

如果 key 不存在,則替換失敗,并且您将獲得響應 NOT_STORED。

  • 文法:

    replace key flags exptime bytes [noreply]

    value

  • 執行個體

    以下執行個體中我們使用的鍵位 ‘mykey’ 并存儲對應的值 data_value。執行後我們替換相同的 key 的值為 ‘some_other_value’。

add mykey 0 900 10
data_value

STORED
get mykey
VALUE mykey 0 10
data_value
END

replace mykey 0 900 16
some_other_value
get mykey
VALUE mykey 0 16
some_other_value
END
           
  • 輸出

    如果資料添加成功,則輸出:STORED。如果資料添加失敗,則輸出:NOT_STORED。

append 指令

該指令用于向已存在 key(鍵) 的 value(資料值) 後面追加資料 。

  • 文法:

    append key flags exptime bytes [noreply]

    value

  • 執行個體
set runoob 0 900 9
memcached
STORED

get runoob
VALUE runoob 0 9
memcached
END

append runoob 0 900 5
redis
STORED

get runoob
VALUE runoob 0 14
memcachedredis
END
           
  • 輸出

    如果資料添加成功,則輸出:STORED

    如果該鍵在 Memcached 上不存在,則輸出:NOT_STORED

    如果執行錯誤,則輸出CLIENT_ERROR。

prepend 指令

該指令用于向已存在 key(鍵) 的 value(資料值) 前面追加資料 。

  • 文法:

    prepend key flags exptime bytes [noreply]

    value

  • 執行個體
set runoob 0 900 9
memcached
STORED
get runoob
VALUE runoob 0 14
memcached
END

prepend runoob 0 900 5
redis
STORED
get runoob
VALUE runoob 0 14
redismemcached
END
           
  • 輸出

    如果資料添加成功,則輸出:STORED

    如果該鍵在 Memcached 上不存在,則輸出:NOT_STORED

    如果執行錯誤,則輸出CLIENT_ERROR。

CAS(Check-And-Set 或 Compare-And-Swap)

該 指令用于執行一個"檢查并設定"的操作

它僅在目前用戶端最後一次取值後,該key 對應的值沒有被其他用戶端修改的情況下, 才能夠将值寫入。

檢查是通過cas_token參數進行的, 這個參數是Memcach指定給已經存在的元素的一個唯一的64位值。

文法:

  • 基本文法格式:

    cas key flags exptime bytes unique_cas_token [noreply]

    value

    參數說明如下:

    bytes:在緩存中存儲的位元組數

    unique_cas_token通過 gets 指令擷取的一個唯一的64位值。

  • 執行個體

    要在 Memcached 上使用 CAS 指令,你需要從 Memcached 服務商通過 gets 指令擷取令牌(token)。

    gets 指令的功能類似于基本的 get 指令。兩個指令之間的差異在于,gets 傳回的資訊稍微多一些:64 位的整型值非常像名稱/值對的 “版本” 辨別符。

  • 執行個體步驟如下:

    如果沒有設定唯一令牌,則 CAS 指令執行錯誤。

    如果鍵 key 不存在,執行失敗。

    添加鍵值對。

    通過 gets 指令擷取唯一令牌。

    使用 cas 指令更新資料

    使用 get 指令檢視資料是否更新

cas tp 0 900 9
ERROR             <− 缺少 token

cas tp 0 900 9 2
memcached
NOT_FOUND         <− 鍵 tp 不存在

set tp 0 900 9
memcached
STORED

gets tp
VALUE tp 0 9 1
memcached
END

cas tp 0 900 5 1
redis
STORED

get tp
VALUE tp 0 5
redis
END
           
  • 輸出

    如果資料添加成功,則輸出:STORED

    如果儲存出錯或文法錯誤:ERROR。

    如果在最後一次取值後另外一個使用者也在更新該資料:EXISTS。

    如果Memcached 服務上不存在該鍵值:NOT_FOUND:

查找指令

get 指令

該指令擷取存儲在 key(鍵) 中的 value(資料值) ,如果 key 不存在,則傳回空。

  • 文法:

    get key

    多個 key 使用空格隔開,如下:

    get key1 key2 key3

  • 執行個體
set runoob 0 900 9
memcached
STORED

get runoob
VALUE runoob 0 9
memcached
END
           

gets 指令

該指令擷取帶有 CAS 令牌存 的 value(資料值) ,如果 key 不存在,則傳回空。

  • 文法:

    gets key

    多個 key 使用空格隔開,如下:

    gets key1 key2 key3

  • 執行個體
set runoob 0 900 9
memcached
STORED

gets runoob
VALUE runoob 0 9 1
memcached
END
           

在 使用 gets 指令的輸出結果中,在最後一列的數字 1 代表了 key 為 runoob 的 CAS 令牌。

delete 指令

該指令用于删除已存在的 key(鍵)。

  • 文法:

    delete key [noreply]

  • 執行個體

    在以下執行個體中,我們使用 runoob 作為 key,過期時間設定為 900 秒。之後我們使用 delete 指令删除該 key。

set runoob 0 900 9
memcached
STORED
get runoob
VALUE runoob 0 9
memcached
END

delete runoob
DELETED
get runoob
END

delete runoob
NOT_FOUND
           
  • 輸出

    DELETED:删除成功。

    ERROR:文法錯誤或删除失敗。

    NOT_FOUND:key 不存在。

incr

該指令用于對已存在的 key(鍵) 的數字值進行自增或自減操作。

incr 與 decr 指令操作的資料必須是十進制的32位無符号整數。

  • 文法:

    incr key increment_value

  • 參數說明如下:

    key:鍵值 key-value 結構中的 key,用于查找緩存值。

    increment_value: 增加的數值。

  • 執行個體

    在以下執行個體中,我們使用 visitors 作為 key,初始值為 10,之後進行加 5 操作。

set visitors 0 900 2
10
STORED
get visitors
VALUE visitors 0 2
10
END 

incr visitors 5
15
get visitors
VALUE visitors 0 2
15
END
           
  • 輸出資訊說明:

    NOT_FOUND:key 不存在。

    CLIENT_ERROR:自增值不是對象。

    ERROR其他錯誤,如文法錯誤等。

decr 指令

  • 基本文法格式:

    decr key decrement_value

  • 參數說明如下:

    key:鍵值 key-value 結構中的 key,用于查找緩存值。

    decrement_value: 減少的數值。

  • 執行個體
set visitors 0 900 2
10
STORED
get visitors
VALUE visitors 0 2
10
END

decr visitors 5
5
get visitors
VALUE visitors 0 1
5
END
           

在以上執行個體中,我們使用 visitors 作為 key,初始值為 10,之後進行減 5 操作。

  • 輸出

    NOT_FOUND:key 不存在。

    CLIENT_ERROR:自增值不是對象。

    ERROR其他錯誤,如文法錯誤等。

統計指令

stats 指令

該指令用于傳回統計資訊例如 PID(程序号)、版本号、連接配接數等。

  • 執行個體

    在以下執行個體中,我們使用了 stats 指令來輸出 Memcached 服務資訊。

stats
STAT pid 1162
。。。。。
STAT reclaimed 1
END
           
  • 詳細解釋:

    pid: memcache伺服器程序ID

    uptime:伺服器已運作秒數

    time:伺服器目前Unix時間戳

    version:memcache版本

    pointer_size:作業系統指針大小

    rusage_user:程序累計使用者時間

    rusage_system:程序累計系統時間

    curr_connections:目前連接配接數量

    total_connections:Memcached運作以來連接配接總數

    connection_structures:Memcached配置設定的連接配接結構數量

    cmd_get:get指令請求次數

    cmd_set:set指令請求次數

    cmd_flush:flush指令請求次數

    get_hits:get指令命中次數

    get_misses:get指令未命中次數

    delete_misses:delete指令未命中次數

    delete_hits:delete指令命中次數

    incr_misses:incr指令未命中次數

    incr_hits:incr指令命中次數

    decr_misses:decr指令未命中次數

    decr_hits:decr指令命中次數

    cas_misses:cas指令未命中次數

    cas_hits:cas指令命中次數

    cas_badval:使用擦拭次數

    auth_cmds:認證指令處理的次數

    auth_errors:認證失敗數目

    bytes_read:讀取總位元組數

    bytes_written:發送總位元組數

    limit_maxbytes:配置設定的記憶體總大小(位元組)

    accepting_conns:伺服器是否達到過最大連接配接(0/1)

    listen_disabled_num:失效的監聽數

    threads:目前線程數

    conn_yields:連接配接操作主動放棄數目

    bytes:目前存儲占用的位元組數

    curr_items:目前存儲的資料總數

    total_items:啟動以來存儲的資料總數

    evictions:LRU釋放的對象數目

    reclaimed:已過期的資料條目來存儲新資料的數目

stats items 指令

該指令用于顯示各個 slab 中 item 的數目和存儲時長(最後一次通路距離現在的秒數)。

  • 執行個體

    stats items

    STAT items:1:number 1

    STAT items:1:age 7

    STAT items:1:evicted 0

    STAT items:1:evicted_nonzero 0

    STAT items:1:evicted_time 0

    STAT items:1:outofmemory 0

    STAT items:1:tailrepairs 0

    STAT items:1:reclaimed 0

    STAT items:1:expired_unfetched 0

    STAT items:1:evicted_unfetched 0

    END

flush_all 指令

該指令用于用于清理緩存中的所有 key=>value(鍵=>值) 對。

該指令提供了一個可選參數 time,用于在制定的時間後執行清理緩存操作。

文法:

flush_all [time] [noreply]

執行個體

清理緩存:

set runoob 0 900 9
memcached
STORED
get runoob
VALUE runoob 0 9
memcached
END
flush_all
OK
get runoob
END
           

Java 連接配接 Memcached 服務

  • set 操作執行個體

    以下使用 java.util.concurrent.Future 來存儲資料

public class MemcachedJava {
   public static void main(String[] args) {
      try{
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
        // 存儲資料
         Future fo = mcc.set("runoob", 900, "Free Education");
         // 檢視存儲狀态
         System.out.println("set status:" + fo.get());
         
         // 輸出值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println( ex.getMessage() );
      }
   }
}
           

add 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加資料
         Future fo = mcc.set("runoob", 900, "Free Education");

         // 列印狀态
         System.out.println("set status:" + fo.get());//true

         // 輸出
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 添加
         Future fo = mcc.add("runoob", 900, "memcached");

         // 列印狀态
         System.out.println("add status:" + fo.get());

         // 添加新key
         fo = mcc.add("codingground", 900, "All Free Compilers");

         // 列印狀态
         System.out.println("add status:" + fo.get());
         
         // 輸出
         System.out.println("codingground value in cache - " + mcc.get("codingground"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println(ex.getMessage());
      }
   }
}
           

replace 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
      try {
         //連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加第一個 key=》value 對
         Future fo = mcc.set("runoob", 900, "Free Education");

         // 輸出執行 add 方法後的狀态
         System.out.println("add status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 添加新的 key
         fo = mcc.replace("runoob", 900, "Largest Tutorials' Library");

         // 輸出執行 set 方法後的狀态
         System.out.println("replace status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex){
         System.out.println( ex.getMessage() );
      }
   }
}
           

append 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
        // 添加資料
         Future fo = mcc.set("runoob", 900, "Free Education");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 對存在的key進行資料添加操作
         Future fo = mcc.append("runoob", 900, " for All");

         // 輸出執行 set 方法後的狀态
         System.out.println("append status:" + fo.get());
         
         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("codingground"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}
           

prepend 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加資料
         Future fo = mcc.set("runoob", 900, "Education for All");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 對存在的key進行資料添加操作
         Future fo = mcc.prepend("runoob", 900, "Free ");

         // 輸出執行 set 方法後的狀态
         System.out.println("prepend status:" + fo.get());
         
         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("codingground"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}
           

CAS 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加資料
         Future fo = mcc.set("runoob", 900, "Free Education");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());
            
         // 使用 get 方法擷取資料
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 通過 gets 方法擷取 CAS token(令牌)
         CASValue casValue = mcc.gets("runoob");

         // 輸出 CAS token(令牌) 值
         System.out.println("CAS token - " + casValue);

         // 嘗試使用cas方法來更新資料
         CASResponse casresp = mcc.cas("runoob", casValue.getCas(), 900, "Largest Tutorials-Library");
         
         // 輸出 CAS 響應資訊
         System.out.println("CAS Response - " + casresp);

         // 輸出值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}
           

get 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加資料
         Future fo = mcc.set("runoob", 900, "Free Education");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());

         // 使用 get 方法擷取資料
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}
           

gets 操作執行個體、CAS

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加資料
         Future fo = mcc.set("runoob", 900, "Free Education");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());
            
         // 從緩存中擷取鍵為 runoob 的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 通過 gets 方法擷取 CAS token(令牌)
         CASValue casValue = mcc.gets("runoob");

         // 輸出 CAS token(令牌) 值
         System.out.println("CAS value in cache - " + casValue);

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}
           

delete 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加資料
         Future fo = mcc.set("runoob", 900, "World's largest online tutorials library");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("runoob"));

         // 對存在的key進行資料添加操作
         Future fo = mcc.delete("runoob");

         // 輸出執行 delete 方法後的狀态
         System.out.println("delete status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("runoob value in cache - " + mcc.get("codingground"));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}
           

Incr/Decr 操作執行個體

public class MemcachedJava {
   public static void main(String[] args) {
   
      try{
   
         // 連接配接本地的 Memcached 服務
         MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211));
         // 添加數字值
         Future fo = mcc.set("number", 900, "1000");

         // 輸出執行 set 方法後的狀态
         System.out.println("set status:" + fo.get());

         // 擷取鍵對應的值
         System.out.println("value in cache - " + mcc.get("number"));

         // 自增并輸出
         System.out.println("value in cache after increment - " + mcc.incr("number", 111));

         // 自減并輸出
         System.out.println("value in cache after decrement - " + mcc.decr("number", 112));

         // 關閉連接配接
         mcc.shutdown();
         
      }catch(Exception ex)
         System.out.println(ex.getMessage());
   }
}