簡介
Memcached是一個自由開源的,高性能,分佈式內存對象緩存系統。
Memcached是一種基於內存的key-value存儲,用來存儲小塊的任意數據(字符串、對象)。這些數據可以是數據庫調用、API調用或者是頁面渲染的結果
安裝
這裏使用docker安裝
docker-compose.yaml
version: "3.7"
services:
memcached:
image: memcached
ports:
- 21211:11211
healthcheck:
test: ["CMD", "echo", "stats", "|", "nc", "127.0.0.1", "11211"]
interval: 20s
timeout: 1s
retries: 20
使用
使用telnet 鏈接 memcached, 並測試其方法:
luslin@local:~$ telnet 127.0.0.1 21211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
1. 存儲命令
a. set
Memcached set 命令用於將 value(數據值) 存儲在指定的 key(鍵) 中。
如果set的key已經存在,該命令可以更新該key所對應的原來的數據,也就是實現更新的作用。
語法:
set 命令的基本語法格式如下:
set key flags exptime bytes [noreply]
value
- key:鍵值 key-value 結構中的 key,用於查找緩存值。
- flags:可以包括鍵值對的整型參數,客戶機使用它存儲額外信息 。
- exptime:在緩存中保存鍵值對的時間長度(以秒爲單位,0 表示永遠)
- bytes:在緩存中存儲的字節數
- noreply(可選): 該參數告知服務器不需要返回數據
- value:存儲的值(始終位於第二行)(可直接理解爲key-value結構中的value)
例如:
set l1 0 10000 1
a
STORED # 返回結果
b. add
Memcached add 命令用於將 value(數據值) 存儲在指定的 key(鍵) 中。
如果 add 的 key 已經存在,則不會更新數據(過期的 key 會更新),之前的值將仍然保持相同,並獲得響應 NOT_STORED。
語法:
add 命令的基本語法格式如下:
add key flags exptime bytes [noreply]
value
例如:
add l1 0 10000 2
aa
NOT_STORED # 沒有設置成功
add l2 0 10000 1
b
STORED
get l1 l2
VALUE l1 0 1
a
VALUE l2 0 1
b
c. replace
Memcached replace 命令用於替換已存在的 key(鍵) 的 value(數據值)。
如果 key 不存在,則替換失敗,並且您將獲得響應 NOT_STORED。
語法:
replace 命令的基本語法格式如下:
replace key flags exptime bytes [noreply]
value
例如:
replace l1 0 10000 2
aa
STORED
replace l3 0 10000 1
a
NOT_STORED
get l1 l3
VALUE l1 0 2
aa
END
d. append
Memcached append 命令用於向已存在 key(鍵) 的 value(數據值) 後面追加數據 。
語法:
append 命令的基本語法格式如下:
append key flags exptime bytes [noreply]
value
例如:
append l1 0 10000 1
b
STORED
append l3 0 10000 1
c
NOT_STORED
get l1 l3
VALUE l1 0 3
aab
END
e. prepend
Memcached prepend 命令用於向已存在 key(鍵) 的 value(數據值) 前面追加數據 。
語法:
prepend 命令的基本語法格式如下:
prepend key flags exptime bytes [noreply]
value
例如:
prepend l1 0 10000 1
p
STORED
get l1
VALUE l1 0 4
paab
END
f. CAS 命令
Memcached CAS(Check-And-Set 或 Compare-And-Swap) 命令用於執行一個"檢查並設置"的操作
它僅在當前客戶端最後一次取值後,該key 對應的值沒有被其他客戶端修改的情況下, 才能夠將值寫入。
檢查是通過cas_token參數進行的, 這個參數是Memcach指定給已經存在的元素的一個唯一的64位值。
語法:
CAS 命令的基本語法格式如下:
cas key flags exptime bytes unique_cas_token [noreply]
value
- unique_cas_token通過 gets 命令獲取的一個唯一的64位值。
例如:
12 爲 cas_token, 當使用命令修改值後, token改爲17。這時再用 12 去修改就不會起效果了
VALUE l1 0 4 12
paab
END
set l1 0 10000 1
a
STORED
gets l1
VALUE l1 0 1 17
a
END
cas l1 0 100000 1 12
b
EXISTS
gets l1
VALUE l1 0 1 17
a
END
cas l1 0 100000 1 17
b
STORED
gets l1
VALUE l1 0 1 18
b
END
2. 查找命令
a. get
Memcached get 命令獲取存儲在 key(鍵) 中的 value(數據值) ,如果 key 不存在,則返回空。
語法:
get 命令的基本語法格式如下:
get key
多個 key 使用空格隔開,如下:
get key1 key2 key3
例如:
get l1 l2
VALUE l1 0 4
paab
VALUE l2 0 1
b
END
b. gets
Memcached gets 命令獲取帶有 CAS 令牌存 的 value(數據值) ,如果 key 不存在,則返回空。
語法:
gets 命令的基本語法格式如下:
gets key
多個 key 使用空格隔開,如下:
gets key1 key2 key3
例如:
gets l1 l2
VALUE l1 0 4 12 # 這裏的12 代表 cas令牌
paab
VALUE l2 0 1 8
b
END
c. delete
Memcached delete 命令用於刪除已存在的 key(鍵)。
delete 命令的基本語法格式如下:
delete key [noreply]
例如:
set l3 0 10000 1
e
STORED
delete l3
DELETED
get l3
END
d. delete
Memcached incr 與 decr 命令
Memcached incr 與 decr 命令用於對已存在的 key(鍵) 的數字值進行自增或自減操作。
incr 與 decr 命令操作的數據必須是十進制的32位無符號整數。
如果 key 不存在返回 NOT_FOUND,如果鍵的值不爲數字,則返回 CLIENT_ERROR,其他錯誤返回 ERROR
語法:
incr 命令的基本語法格式如下:
incr key increment_value
例如:
set l3 0 10000 1
0
STORED
incr l3 1
1
get l3
VALUE l3 0 1
1
END
decr l3 2
0
get l3
VALUE l3 0 1
0
END
incr l1 1
CLIENT_ERROR cannot increment or decrement non-numeric value
incr l4 1
NOT_FOUND
gomemcache
github 地址:github.com/bradfitz/gomemcache
文檔地址: https://pkg.go.dev/mod/github.com/bradfitz/[email protected]
環境:
go | gomemcache |
---|---|
go1.13.5 | v0.0.0-20190913173617-a41fca850d0b |
簡單使用:
func painc_err(err error) {
if err != nil {
panic(err)
}
}
func TestSetAndGet(t *testing.T) {
client := memcache.New("127.0.0.1:21211")
err := client.Ping()
painc_err(err)
err = client.Set(&memcache.Item{Key: "a1", Value: []byte("a"),Flags: 0, Expiration: 100000})
painc_err(err)
item, err := client.Get("a1")
painc_err(err)
fmt.Println(string(item.Value))
item, err = client.Get("a2")
if err != nil {
fmt.Println(err)
} else {
fmt.Println(string(item.Value))
}
}
結果
a
memcache: cache miss
常用方法
type Client
func New(server ...string) *Client
func (c *Client) Add(item *Item) error
func (c *Client) CompareAndSwap(item *Item) error # CAS
func (c *Client) Decrement(key string, delta uint64) (newValue uint64, err error)
func (c *Client) Delete(key string) error
func (c *Client) DeleteAll() error
func (c *Client) FlushAll() error
func (c *Client) Get(key string) (item *Item, err error)
func (c *Client) GetMulti(keys []string) (map[string]*Item, error)
func (c *Client) Increment(key string, delta uint64) (newValue uint64, err error)
func (c *Client) Ping() error
func (c *Client) Replace(item *Item) error
func (c *Client) Set(item *Item) error
常見錯誤:
var (
// ErrCacheMiss means that a Get failed because the item wasn't present.
ErrCacheMiss = errors.New("memcache: cache miss")
// ErrCASConflict means that a CompareAndSwap call failed due to the
// cached value being modified between the Get and the CompareAndSwap.
// If the cached value was simply evicted rather than replaced,
// ErrNotStored will be returned instead.
ErrCASConflict = errors.New("memcache: compare-and-swap conflict")
// ErrNotStored means that a conditional write operation (i.e. Add or
// CompareAndSwap) failed because the condition was not satisfied.
ErrNotStored = errors.New("memcache: item not stored")
// ErrServer means that a server error occurred.
ErrServerError = errors.New("memcache: server error")
// ErrNoStats means that no statistics were available.
ErrNoStats = errors.New("memcache: no statistics available")
// ErrMalformedKey is returned when an invalid key is used.
// Keys must be at maximum 250 bytes long and not
// contain whitespace or control characters.
ErrMalformedKey = errors.New("malformed: key is too long or contains invalid characters")
// ErrNoServers is returned when no servers are configured or available.
ErrNoServers = errors.New("memcache: no servers configured or available")
)
python-memcached
github 地址:github.com/linsomniac/python-memcached
安裝:
pip install -i https://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com python-memcached
測試:
class FooStruct(object):
def __init__(self):
self.bar = "baz"
def __str__(self):
return "A FooStruct"
def __eq__(self, other):
if isinstance(other, FooStruct):
return self.bar == other.bar
return 0
class TestMemcache(unittest.TestCase):
def setUp(self):
# TODO(): unix socket server stuff
servers = ["127.0.0.1:21211"]
self.mc = Client(servers, debug=1)
def tearDown(self):
self.mc.flush_all()
self.mc.disconnect_all()
def check_setget(self, key, val, noreply=False):
self.mc.set(key, val, noreply=noreply)
newval = self.mc.get(key)
self.assertEqual(newval, val)
def test_setget(self):
self.check_setget("a_string", "some random string")
self.check_setget("a_string_2", "some random string", noreply=True)
self.check_setget("an_integer", 42)
self.check_setget("an_integer_2", 42, noreply=True)
其他詳細方法可參考:https://github.com/linsomniac/python-memcached/blob/master/tests/test_memcache.py