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 '^]'.
Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中。
如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用。
语法:
set 命令的基本语法格式如下:
set key flags exptime bytes [noreply]
value
例如:
set l1 0 10000 1
a
STORED # 返回结果
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
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
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
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
Memcached CAS(Check-And-Set 或 Compare-And-Swap) 命令用于执行一个"检查并设置"的操作
它仅在当前客户端最后一次取值后,该key 对应的值没有被其他客户端修改的情况下, 才能够将值写入。
检查是通过cas_token参数进行的, 这个参数是Memcach指定给已经存在的元素的一个唯一的64位值。
语法:
CAS 命令的基本语法格式如下:
cas key flags exptime bytes unique_cas_token [noreply]
value
例如:
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
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
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
Memcached delete 命令用于删除已存在的 key(键)。
delete 命令的基本语法格式如下:
delete key [noreply]
例如:
set l3 0 10000 1
e
STORED
delete l3
DELETED
get l3
END
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
github 地址:github.com/bradfitz/gomemcache
文档地址: https://pkg.go.dev/mod/github.com/bradfitz/gomemcache@v0.0.0-20190913173617-a41fca850d0b
环境:
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")
)
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