# Memcached 缓存服务器使用教程

`memcached 基本使用手册`

[GITHUB 项目🔗](https://github.com/memcached/memcached)

参考 [菜鸟教程](http://www.runoob.com/memcached/memcached-tutorial.html)

`Memcached` 是一种基于内存的 `key-value` 存储，用来存储小块的任意数据（字符串、对象）。这些数据可以是数据库调用、API调用或者是页面渲染的结果。

> 通过缓存数据库查询结果，减少数据库访问次数，以提高动态Web应用的速度、提高可扩展性。

![](https://ws1.sinaimg.cn/large/ecb0a9c3gy1fyulc24s1gj20ca0al3zf.jpg)

特点：

* 协议简单
* 基于libevent的事件处理
* 内置内存存储方式
* memcached不互相通信的分布式

***

### 存储命令

#### set

> Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中。如果 set 的 key 已经存在，该命令可以更新 key 所对应的 value

```sh
set key flags exptime bytes [noreply] 
value 
```

* key：键值 key-value 结构中的 key，用于查找缓存值。
* flags：可以包括键值对的整型参数，客户机使用它存储关于键值对的额外信息 。
* exptime：在缓存中保存键值对的时间长度（以秒为单位，0 表示永远）
* bytes：在缓存中存储的字节数
* noreply（可选）： 该参数告知服务器不需要返回数据
* value：存储的值（**始终位于第二行**）（可直接理解为key-value结构中的value）

输出信息说明：

`STORED`：保存成功后输出。 `ERROR`：在保存失败后输出。

#### add

> Memcached add 命令用于将 value(数据值) 存储在指定的 key(键) 中。如果 add 的 key 已经存在，则不会更新数据(过期的 key 会更新)，之前的值将仍然保持相同，并且您将获得响应 `NOT_STORED`。

```sh
add key flags exptime bytes [noreply]
value
```

输出信息说明：

* STORED：保存成功后输出。
* NOT\_STORED ：在保存失败后输出。

#### replace

> Memcached replace 命令用于替换已存在的 key(键) 的 value(数据值)。如果 key 不存在，则替换失败，并且您将获得响应 `NOT_STORED`。

```sh
replace key flags exptime bytes [noreply]
value
```

输出信息说明：

`STORED`：保存成功后输出。 `NOT_STORED`：执行替换失败后输出。

#### append

> Memcached append 命令用于向已存在 key(键) 的 value(数据值) 后面追加数据 。

```sh
append key flags exptime bytes [noreply]
value
```

输出信息说明：

`STORED`：保存成功后输出。 `NOT_STORED`：该键在 Memcached 上不存在。 `CLIENT_ERROR`：执行错误。

#### prepend

> Memcached prepend 命令用于向已存在 key(键) 的 value(数据值) 前面追加数据 。

```sh
prepend key flags exptime bytes [noreply]
value
```

输出信息说明：

`STORED`：保存成功后输出。 `NOT_STORED`：该键在 Memcached 上不存在。 `CLIENT_ERROR`：执行错误。

#### cas

```
Memcached CAS（Check-And-Set 或 Compare-And-Swap） 命令用于执行一个"检查并设置"的操作。

它仅在当前客户端最后一次取值后，该key 对应的值没有被其他客户端修改的情况下， 才能够将值写入。

检查是通过 cas_token 参数进行的， 这个参数是 Memcach 指定给已经存在的元素的一个唯一的64位值。
```

```sh
cas key flags exptime bytes unique_cas_token [noreply]
value
```

注意⚠️ `unique_cas_token` 通过 gets 命令获取的一个唯一的64位值。如果没有设置唯一令牌，则 CAS 命令执行错误。

输出信息说明：

`STORED`：保存成功后输出。 `ERROR`：保存出错或语法错误。 `EXISTS`：在最后一次取值后另外一个用户也在更新该数据。 `NOT_FOUND`：Memcached 服务上不存在该键值。

### 查找命令

#### get

> Memcached get 命令获取存储在 key(键) 中的 value(数据值) ，如果 key 不存在，则返回空。

* 单个 key `get key`
* 多个 key `get key1 key2 key3`

#### gets

> Memcached gets 命令获取带有 CAS 令牌存 的 value(数据值) ，如果 key 不存在，则返回空。

* 单个 key `gets key`
* 多个 key `gets key1 key2 key3`

```sh
gets a
VALUE a 0 4 78
xixi
END
```

在最后一列的数字 78 代表了 key 为 runoob 的 CAS 令牌。

#### delete

> Memcached delete 命令用于删除已存在的 key(键)。

```sh
delete key [noreply]
```

输出信息说明：

`DELETED`：删除成功。 `ERROR`：语法错误或删除失败。 `NOT_FOUND`：key 不存在。

#### incr 与 decr

> Memcached incr 与 decr 命令用于对已存在的 key(键) 的数字值进行自增或自减操作。incr 与 decr 命令操作的数据必须是十进制的32位无符号整数。(最小只能减小到 0 最大很迷 emm)

```sh
incr key increment_value
decr key decrement_value
```

* increment\_value： 增加的数值。
* decrement\_value： 减少的数值。

输出信息说明：

`NOT_FOUND`：key 不存在。 `CLIENT_ERROR`：自增值不是对象。

```sh
# a 为 数字 1
incr a ni
CLIENT_ERROR invalid numeric delta argument
# b 为 字符串 ni
incr b 1
CLIENT_ERROR cannot increment or decrement non-numeric value
```

`ERROR`：其他错误，如语法错误等。

### 统计命令

#### stats

> Memcached stats 命令用于返回统计信息例如 PID(进程号)、版本号、连接数等。

`stats`

```sh
stats
STAT pid 1
STAT uptime 9814
STAT time 1546591694
STAT version 1.5.12
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 2.230000
STAT rusage_system 2.430000
STAT max_connections 1024
STAT curr_connections 3
STAT total_connections 37
STAT rejected_connections 0
STAT connection_structures 4
STAT reserved_fds 20
STAT cmd_get 161
STAT cmd_set 102
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 146
STAT get_misses 15
STAT get_expired 2
STAT get_flushed 0
STAT delete_misses 3
STAT delete_hits 14
STAT incr_misses 0
STAT incr_hits 362
STAT decr_misses 0
STAT decr_hits 7
STAT cas_misses 1
STAT cas_hits 20
STAT cas_badval 8
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 15811
STAT bytes_written 12838
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT slab_reassign_rescues 0
STAT slab_reassign_chunk_rescues 0
STAT slab_reassign_evictions_nomem 0
STAT slab_reassign_inline_reclaim 0
STAT slab_reassign_busy_items 0
STAT slab_reassign_busy_deletes 0
STAT slab_reassign_running 0
STAT slabs_moved 0
STAT lru_crawler_running 0
STAT lru_crawler_starts 4593
STAT lru_maintainer_juggles 19636
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT bytes 218
STAT curr_items 3
STAT total_items 96
STAT slab_global_page_pool 0
STAT expired_unfetched 1
STAT evicted_unfetched 0
STAT evicted_active 0
STAT evictions 0
STAT reclaimed 3
STAT crawler_reclaimed 3
STAT crawler_items_checked 45
STAT lrutail_reflocked 20
STAT moves_to_cold 81
STAT moves_to_warm 25
STAT moves_within_lru 9
STAT direct_reclaims 0
STAT lru_bumps_dropped 0
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

> Memcached stats items 命令用于显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)。

```sh
stats items
STAT items:1:number 3
STAT items:1:number_hot 0
STAT items:1:number_warm 0
STAT items:1:number_cold 3
STAT items:1:age_hot 0
STAT items:1:age_warm 0
STAT items:1:age 8621
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 3
STAT items:1:expired_unfetched 1
STAT items:1:evicted_unfetched 0
STAT items:1:evicted_active 0
STAT items:1:crawler_reclaimed 3
STAT items:1:crawler_items_checked 48
STAT items:1:lrutail_reflocked 20
STAT items:1:moves_to_cold 81
STAT items:1:moves_to_warm 25
STAT items:1:moves_within_lru 9
STAT items:1:direct_reclaims 0
STAT items:1:hits_to_hot 67
STAT items:1:hits_to_warm 13
STAT items:1:hits_to_cold 66
STAT items:1:hits_to_temp 0
END
```

#### stats slabs

> Memcached stats slabs 命令用于显示各个slab的信息，包括chunk的大小、数目、使用情况等。

```sh
stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 3
STAT 1:free_chunks 10919
STAT 1:free_chunks_end 0
STAT 1:mem_requested 218
STAT 1:get_hits 146
STAT 1:cmd_set 102
STAT 1:delete_hits 14
STAT 1:incr_hits 362
STAT 1:decr_hits 7
STAT 1:cas_hits 20
STAT 1:cas_badval 8
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048576
END
```

#### stats sizes

> Memcached stats sizes 命令用于显示所有item的大小和个数。该信息返回两列，第一列是 item 的大小，第二列是 item 的个数。

```
Memcached 1.4.27 及以后的版本自动开启了 stats sizes 功能 这之前的版本需要在 Memcached 启动时带上 -o track_sizes 则来开启
```

不过虽然我的版本是 `1.5.12`

不过也没用。输入`stats sizes`后出现`STAT sizes_status disabled`

只好

`docker run --name my-memcache -p 11211:11211 -d memcached memcached -m 64 -o track_sizes`

```sh
flush_all
OK
set a 0 0 5
nihao
STORED
get a
VALUE a 0 5
nihao
END
stats sizes
STAT 96 1  # item 大小 96, 总共有 1 个key
END
```

#### flush\_all

> Memcached flush\_all 命令用于清理缓存中的所有 key=>value(键=>值) 对。该命令提供了一个可选参数 time，用于在制定的时间后执行清理缓存操作。

```sh
flush_all [time] [noreply]
```

```sh
set a 0 0 5 
nihao
STORED
get a
VALUE a 0 5
nihao
END
flush_all
OK
get a
END
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notes.ronething.cn/memcached-tutorial.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
