簡介
- 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());
}
}