memcached 使用 / go 操作memcached (gomemcache) / python 操作 memcached (python-memcached)

簡介

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

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