802 lines
23 KiB
Markdown
802 lines
23 KiB
Markdown
# Memcached分布式缓存系统
|
||
|
||
# Memcached介绍
|
||
|
||
## 什么是Memcached缓存数据库
|
||
|
||
**Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。**
|
||
|
||
Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。
|
||
|
||
Memcached是一种基于**内存的key-value存储**,用来存储**小**块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。
|
||
|
||
Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。
|
||
|
||
本质上,它是一个简洁的key-value存储系统。
|
||
|
||
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
|
||
|
||
<img src="Memcached/web_6.jpg" alt="web_6" />
|
||
|
||
Memcached 官网:https://memcached.org
|
||
|
||
## Memcached和Redis对比
|
||
|
||
我们都知道,把一些热数据存到缓存中可以极大的提高速度,那么问题来了,是用Redis好还是Memcached好呢,以下是它们两者之间一些简单的区别与比较:
|
||
|
||
1. Redis不仅支持简单的k/v类型的数据,同时还支持list、set、zset(sorted set)、hash等**丰富数据结构**的存储,使得它拥有更广阔的应用场景。
|
||
|
||
2. Redis最大的亮点是支持**数据持久化**,它在运行的时候可以将数据备份在磁盘中,断电或重启后,缓存数据可以再次加载到内存中,只要Redis配置的合理,基本上不会丢失数据。
|
||
|
||
3. Redis支持**主从模式**的应用。
|
||
|
||
4. Redis单个value的最大限制是1GB,而Memcached则只能保存**1MB**内的数据。
|
||
|
||
5. Memcache在并发场景下,能用cas保证一致性,而Redis事务支持比较弱,只能保证事务中的每个操作连续执行。
|
||
|
||
6. 性能方面,根据网友提供的测试,**Redis**在读操作和写操作上是略**领先**Memcached的。
|
||
|
||
7. Memcached的内存管理不像Redis那么复杂,元数据metadata更小,相对来说额外**开销就很少**。Memcached唯一支持的数据类型是**字符串string**,非常适合缓存只读数据,因为字符串不需要额外的处理。
|
||
|
||
# 快速开始
|
||
|
||
## Memcached部署
|
||
|
||
1. 通过yum安装memcache软件包
|
||
|
||
```bash
|
||
# 先安装一些依赖包
|
||
[root@localhost ~]# yum install libevent libevent-devel -y
|
||
# 安装memcached
|
||
[root@localhost ~]# yum install -y memcached
|
||
```
|
||
|
||
2. 命令行启动测试
|
||
|
||
```bash
|
||
[root@localhost ~]# memcached -d -m 1024 -u memcached -l 127.0.0.1 -p 11211 -c 1024 -P /tmp/memcached.pid
|
||
```
|
||
|
||
- memcached启动参数说明:
|
||
- -d是启动一个守护进程;
|
||
- -m是分配给Memcache使用的内存数量,单位是MB;
|
||
- -u是运行Memcache的用户;
|
||
- -l是监听的服务器IP地址,可以有多个地址;
|
||
- -p是设置Memcache监听的端口,最好是1024以上的端口;
|
||
- -c是最大运行的并发连接数,默认是1024;
|
||
- -P是设置保存Memcache的pid文件。
|
||
|
||
3. 查看端口号是否启动成功
|
||
|
||
```bash
|
||
[root@localhost ~]# ss -nlt
|
||
State Recv-Q Send-Q Local Address:Port Peer Address:Port
|
||
LISTEN 0 128 *:11211 *:*
|
||
LISTEN 0 128 *:22 *:*
|
||
LISTEN 0 100 127.0.0.1:25 *:*
|
||
LISTEN 0 128 :::11211 :::*
|
||
LISTEN 0 128 :::22 :::*
|
||
LISTEN 0 100 ::1:25 :::*
|
||
```
|
||
|
||
memcached的端口号为:**11211**
|
||
|
||
4. 关闭服务
|
||
|
||
```bash
|
||
[root@localhost ~]# pkill memcached
|
||
```
|
||
|
||
5. 服务自启动(systemd)
|
||
|
||
```bash
|
||
[root@localhost ~]# systemctl start memcached
|
||
```
|
||
|
||
## Memcached连接
|
||
|
||
对于Memcached的连接,这里要使用到一个协议:telnet(远程连接协议)
|
||
|
||
Telnet 是一种用于远程访问和控制计算机系统的网络协议。它允许用户从一台计算机连接到另一台计算机,并在远程系统上执行命令和操作。
|
||
|
||
**Telnet 的主要特点如下:**
|
||
|
||
1. 远程访问:Telnet 协议可以让用户远程登录到其他计算机系统,就像直接在那台机器上工作一样。这对于管理远程服务器或设备非常有用。
|
||
2. 文本界面:Telnet 使用纯文本界面进行交互,不需要图形界面。这使它适用于各种类型的终端设备和操作系统。
|
||
3. 简单易用:Telnet 客户端通常内置在操作系统中,或者可以很容易地下载安装。建立连接只需输入远程主机的 IP 地址或主机名即可。
|
||
4. 功能丰富:Telnet 协议支持各种命令和操作,如文件传输、远程执行命令等。用户可以在 Telnet 会话中执行系统管理任务。
|
||
5. 不安全:Telnet 使用明文传输数据,包括用户名和密码,存在严重的安全隐患。因此在现代网络环境下,Telnet 逐步被更安全的 SSH 协议所取代。
|
||
|
||
**Telnet和ssh对比:**
|
||
|
||
| 特性 | Telnet | SSH |
|
||
| :------- | :---------------------------------------- | :------------------------------------------ |
|
||
| 安全性 | 使用明文传输数据,非常不安全 | 使用强大的加密技术,提供高度安全性 |
|
||
| 加密 | 不提供任何加密功能 | 支持多种加密算法,如 AES、3DES 等 |
|
||
| 认证 | 仅依赖用户名和密码进行身份验证 | 支持多种认证方式,如用户名/密码、公钥/私钥等 |
|
||
| 端口 | 默认使用 23 号端口 | 默认使用 22 号端口 |
|
||
| 应用场景 | 用于简单的远程控制和诊断任务,但已很少使用 | 广泛用于企业和个人的远程管理和数据传输 |
|
||
|
||
```bash
|
||
[root@localhost ~]# yum install telnet -y
|
||
[root@localhost ~]# telnet localhost 11211
|
||
Trying ::1...
|
||
Connected to localhost.
|
||
Escape character is '^]'.
|
||
|
||
# 连接以后并不会给出明确提示,我们可以直接输入命令进行测试
|
||
```
|
||
|
||
## 查看Memcached信息
|
||
|
||
Memcached stats 命令用于返回统计信息例如 PID(进程号)、版本号、连接数等。
|
||
|
||
```bash
|
||
[root@localhost ~]# telnet localhost 11211
|
||
Trying ::1...
|
||
Connected to localhost.
|
||
Escape character is '^]'.
|
||
stats
|
||
STAT pid 16509
|
||
STAT uptime 8793
|
||
STAT time 1723623164
|
||
STAT version 1.4.15
|
||
STAT libevent 2.0.21-stable
|
||
STAT pointer_size 64
|
||
STAT rusage_user 0.219841
|
||
STAT rusage_system 0.109920
|
||
STAT curr_connections 10
|
||
STAT total_connections 12
|
||
STAT connection_structures 11
|
||
STAT reserved_fds 20
|
||
STAT cmd_get 8
|
||
STAT cmd_set 2
|
||
STAT cmd_flush 0
|
||
STAT cmd_touch 0
|
||
STAT get_hits 1
|
||
STAT get_misses 7
|
||
STAT delete_misses 0
|
||
STAT delete_hits 2
|
||
STAT incr_misses 0
|
||
STAT incr_hits 0
|
||
STAT decr_misses 0
|
||
STAT decr_hits 0
|
||
STAT cas_misses 0
|
||
STAT cas_hits 0
|
||
STAT cas_badval 0
|
||
STAT touch_hits 0
|
||
STAT touch_misses 0
|
||
STAT auth_cmds 0
|
||
STAT auth_errors 0
|
||
STAT bytes_read 222
|
||
STAT bytes_written 1197
|
||
STAT limit_maxbytes 67108864
|
||
STAT accepting_conns 1
|
||
STAT listen_disabled_num 0
|
||
STAT threads 4
|
||
STAT conn_yields 0
|
||
STAT hash_power_level 16
|
||
STAT hash_bytes 524288
|
||
STAT hash_is_expanding 0
|
||
STAT bytes 0
|
||
STAT curr_items 0
|
||
STAT total_items 2
|
||
STAT expired_unfetched 0
|
||
STAT evicted_unfetched 0
|
||
STAT evictions 0
|
||
STAT reclaimed 0
|
||
END
|
||
```
|
||
|
||
如果可以看到以上输出,说明安装并且连接成功,至于具体解释,后面再说....
|
||
|
||
# slab存储机制
|
||
|
||
memcached接收来此客户端的存储请求,那么服务端是如何存储来自客户端的存储内容的呢,这里就涉及到了slabs存储机制,在此之前首先介绍memcached中关于内存管理的几个重要的概念
|
||
|
||
## item数据存储节点
|
||
|
||
items:客户端传送的键-值包装成items结构体,其内存通过slab分配
|
||
|
||
源码说明:
|
||
|
||
```c
|
||
typedef struct _stritem {
|
||
/* Protected by LRU locks */
|
||
//一个item的地址, 主要用于LRU链和freelist链
|
||
struct _stritem *next;
|
||
//下一个item的地址,主要用于LRU链和freelist链
|
||
struct _stritem *prev;
|
||
|
||
/* Rest are protected by an item lock */
|
||
//用于记录哈希表槽中下一个item节点的地址
|
||
struct _stritem *h_next; /* hash chain next */
|
||
//最近访问时间
|
||
rel_time_t time; /* least recent access */
|
||
//缓存过期时间
|
||
rel_time_t exptime; /* expire time */
|
||
int nbytes; /* size of data */
|
||
//当前item被引用的次数,用于判断item是否被其它的线程在操作中
|
||
//refcount == 1的情况下该节点才可以被删除
|
||
unsigned short refcount;
|
||
uint8_t nsuffix; /* length of flags-and-length string */
|
||
uint8_t it_flags; /* ITEM_* above */
|
||
//记录该item节点位于哪个slabclass_t中
|
||
uint8_t slabs_clsid;/* which slab class we're in */
|
||
uint8_t nkey; /* key length, w/terminating null and padding */
|
||
/* this odd type prevents type-punning issues when we do
|
||
* the little shuffle to save space when not using CAS. */
|
||
union {
|
||
uint64_t cas;
|
||
char end;
|
||
} data[];
|
||
/* if it_flags & ITEM_CAS we have 8 bytes CAS */
|
||
/* then null-terminated key */
|
||
/* then " flags length\r\n" (no terminating null) */
|
||
/* then data with terminating \r\n (no terminating null; it's binary!) */
|
||
} item;
|
||
```
|
||
|
||
## slab与chunk
|
||
|
||
slab是一块内存空间,默认大小为1M,memcached会把一个slab分割成一个个chunk, 这些被切割的小的内存块,主要用来存储item
|
||
|
||
## slabclass
|
||
|
||
每个item的大小都可能不一样,item存储于chunk,如果chunk大小不够,则不足以分配给item使用,如果chunk过大,则太过于浪费内存空间。因此memcached采取的做法是,将slab切割成不同大小的chunk,这样就满足了不同大小item的存储。被划分不同大小chunk的slab的内存在memcached就是用slabclass这个结构体来表现的
|
||
|
||
**slabclass结构体源码:**
|
||
|
||
```c
|
||
typedef struct {
|
||
//chunk大小
|
||
unsigned int size; /* sizes of items */
|
||
//1M内存大小被分割为多少个chunck
|
||
unsigned int perslab; /* how many items per slab */
|
||
|
||
//空闲chunk链表
|
||
void *slots; /* list of item ptrs */
|
||
//空闲chunk的个数
|
||
unsigned int sl_curr; /* total free items in list */
|
||
|
||
//当前slabclass已经分配了所少个1M空间的slab
|
||
unsigned int slabs; /* how many slabs were allocated for this class */
|
||
|
||
//slab指针数组
|
||
void **slab_list; /* array of slab pointers */
|
||
//slab指针数组的大小
|
||
unsigned int list_size; /* size of prev array */
|
||
|
||
size_t requested; /* The number of requested bytes */
|
||
} slabclass_t;
|
||
```
|
||
|
||
1. slabclass数组初始化的时候,每个slabclass_t都会分配一个1M大小的slab,slab会被切分为N个小的内存块,这个小的内存块的大小取决于slabclass_t结构上的size的大小
|
||
2. 每个slabclass_t都只存储一定大小范围的数据,并且下一个slabclass切割的chunk块大于前一个slabclass切割的chunk块大小
|
||
3. memcached中slabclass数组默认大小为64,slabclass切割块大小的增长因子默认是1.25
|
||
例如:slabclass[1]切割的chunk块大小为100字节,slabclass[2]为125,如果需要存储一个110字节的缓存,那么就需要到slabclass[2] 的空闲链表中获取一个空闲节点进行存储
|
||
|
||
## item节点分配流程
|
||
|
||
1. 根据大小,找到合适的slabclass
|
||
2. slabclass空闲列表中是否有空闲的item节点,如果有直接分配item,用于存储内容
|
||
3. 空闲列表没有空闲的item可以分配,会重新开辟一个slab(默认大小为1M)的内存块,然后切割slab并放入到空闲列表中,然后从空闲列表中获取节点
|
||
|
||
## item节点的释放
|
||
|
||
释放一个item节点,并不会free内存空间,而是将item节点归还到slabclass的空闲列表中
|
||
|
||
# Memcached常用操作
|
||
|
||
## 数据存储
|
||
|
||
### set命令
|
||
|
||
语法:
|
||
|
||
```bash
|
||
set key flags exptime bytes [noreply]
|
||
value
|
||
```
|
||
|
||
相关参数说明:
|
||
|
||
- **key:**键值 key-value 结构中的 key,用于查找缓存值。
|
||
- **flags**:flags 是一个整型参数,用于存储关于键值对的额外信息。这些信息可以被客户端用来解释或处理存储的数据。通过 flags,客户端可以在存储数据时为该数据打上一些标记,以便后续处理时能够正确识别数据的类型或属性。
|
||
- **exptime**:在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
|
||
- **bytes**:在缓存中存储的字节数
|
||
- **noreply(可选)**: 该参数告知服务器不需要返回数据
|
||
- **value**:存储的值(始终位于第二行)(可直接理解为key-value结构中的value)
|
||
|
||
示例:
|
||
|
||
```bash
|
||
set name 0 0 8
|
||
zhangsan
|
||
STORED
|
||
|
||
get name
|
||
VALUE name 0 8
|
||
zhangsan
|
||
END
|
||
```
|
||
|
||
### add命令
|
||
|
||
Memcached add 命令用于将 **value(数据值)** 存储在**不存在的** **key(键)** 中。
|
||
|
||
如果 add 的 key 已经存在,则不会更新数据(过期的 key 会更新),之前的值将仍然保持相同,并且您将获得响应 **NOT_STORED**
|
||
|
||
语法:
|
||
|
||
```bash
|
||
add key flags exptime bytes [noreply]
|
||
value
|
||
```
|
||
|
||
示例:
|
||
|
||
```bash
|
||
add name 0 0 10
|
||
zhangsan
|
||
NOT_STORED
|
||
|
||
get name
|
||
VALUE name 0 8
|
||
zhangsan
|
||
END
|
||
|
||
# 加入一个不存在的key就可以成功
|
||
add age 1 0 10
|
||
18
|
||
STORED
|
||
get age
|
||
VALUE age 1 10
|
||
18
|
||
END
|
||
```
|
||
|
||
### replace命令
|
||
|
||
Memcached replace 命令用于替换已存在的 **key(键)** 的 **value(数据值)**。
|
||
|
||
如果 key 不存在,则替换失败,并且您将获得响应 **NOT_STORED**。
|
||
|
||
语法:
|
||
|
||
```bash
|
||
replace key flags exptime bytes [noreply]
|
||
value
|
||
```
|
||
|
||
示例:
|
||
|
||
```bash
|
||
replace name 0 900 8
|
||
lisilisi
|
||
replace gender 0 900 4
|
||
male
|
||
```
|
||
|
||
### append命令
|
||
|
||
Memcached append 命令用于向已存在 **key(键)** 的 **value(数据值)** 后面追加数据 。
|
||
|
||
示例:
|
||
|
||
```bash
|
||
get key1
|
||
END
|
||
set key1 0 900 9
|
||
memcached
|
||
STORED
|
||
get key1
|
||
VALUE key1 0 9
|
||
memcached
|
||
END
|
||
append key1 0 900 5
|
||
redis
|
||
STORED
|
||
get key1
|
||
VALUE key1 0 14
|
||
memcachedredis
|
||
END
|
||
```
|
||
|
||
### prepend命令
|
||
|
||
Memcached prepend 命令用于向已存在 **key(键)** 的 **value(数据值)** 前面追加数据 。
|
||
|
||
语法:
|
||
|
||
```bash
|
||
prepend key flags exptime bytes [noreply]
|
||
value
|
||
```
|
||
|
||
示例:
|
||
|
||
```bash
|
||
prepend key1 0 900 5
|
||
hello
|
||
STORED
|
||
get key1
|
||
VALUE key1 0 19
|
||
hellomemcachedredis
|
||
END
|
||
```
|
||
|
||
## CAS命令
|
||
|
||
CAS (Check-And-Set) 是 Memcached 中一个非常有用的原子操作特性。它可以帮助我们解决多客户端并发更新同一数据的问题。
|
||
|
||
### CAS 命令格式
|
||
|
||
CAS 命令的完整格式为:
|
||
|
||
复制
|
||
|
||
```
|
||
cas key flags exptime bytes casunique
|
||
```
|
||
|
||
其中:
|
||
|
||
- `key`: 缓存数据的键
|
||
- `flags`: 缓存数据的标志位
|
||
- `exptime`: 缓存数据的过期时间(单位为秒)
|
||
- `bytes`: 缓存数据的长度
|
||
- `casunique`: 一个唯一标识符,用于检查值是否被修改过
|
||
|
||
### CAS 操作流程
|
||
|
||
CAS 操作的流程如下:
|
||
|
||
1. 客户端先使用 `get` 命令获取某个 key 的值,并记录下返回的 `casunique`。
|
||
2. 客户端准备更新这个值时,会使用 `cas` 命令,并附带之前获取的 `casunique`。
|
||
3. Memcached 服务器收到 `cas` 命令后,会先检查当前值的 `casunique` 是否与客户端传来的一致。
|
||
4. 如果一致,说明这个值自从客户端获取后就没有被其他人修改过,服务器会接受这次更新。
|
||
5. 如果不一致,说明这个值在客户端获取后已经被其他人修改过了,服务器会拒绝这次更新。
|
||
|
||
### CAS 的应用场景
|
||
|
||
CAS 命令主要用于解决多客户端并发更新同一缓存数据的问题,避免出现"丢失更新"的情况。
|
||
|
||
例如,在一个电商网站上,多个用户可能同时操作同一个购物车。这时就可以使用 CAS 来确保只有最后一个更新成功的客户端的修改生效。
|
||
|
||
假设我们有一个电商网站,需要缓存用户的购物车信息。多个用户可能同时操作同一个购物车,此时就需要使用 CAS 来避免"丢失更新"的问题。
|
||
|
||
**案例流程如下:**
|
||
|
||
1. 用户 A 访问网站,获取自己的购物车信息:
|
||
- 使用 `get` 命令从 Memcached 中获取购物车数据
|
||
- 同时记录下返回的 `casunique` 值
|
||
2. 用户 A 添加一件商品到购物车:
|
||
- 使用 `cas` 命令更新购物车数据
|
||
- 同时带上之前获取的 `casunique` 值
|
||
3. 与此同时,用户 B 也访问网站,获取自己的购物车信息:
|
||
- 同样使用 `get` 命令从 Memcached 中获取购物车数据
|
||
- 记录下返回的 `casunique` 值
|
||
4. 用户 B 也想修改购物车中的商品:
|
||
- 使用 `cas` 命令尝试更新购物车数据
|
||
- 但此时 Memcached 检查发现 `casunique` 已经不一致了
|
||
- 因此拒绝了用户 B 的更新请求
|
||
5. 最终只有用户 A 的更新生效,用户 B 的更新被拒绝。
|
||
|
||
**示例:**
|
||
|
||
```shell
|
||
set name 0 0 3
|
||
nls
|
||
STORED
|
||
get name
|
||
VALUE name 0 3
|
||
nls
|
||
END
|
||
gets name
|
||
VALUE name 0 3 12
|
||
nls
|
||
END
|
||
cas name 0 0 3 12
|
||
xls
|
||
STORED
|
||
get name
|
||
VALUE name 0 3
|
||
xls
|
||
END
|
||
cas name 0 0 2 12
|
||
cs
|
||
EXISTS
|
||
```
|
||
|
||
输出信息说明:
|
||
|
||
- **STORED**:保存成功后输出。
|
||
- **ERROR**:保存出错或语法错误。
|
||
- **EXISTS**:在最后一次取值后另外一个用户也在更新该数据。
|
||
- **NOT_FOUND**:Memcached 服务上不存在该键值。
|
||
|
||
## 数据查找
|
||
|
||
### get命令
|
||
|
||
get 命令的基本语法格式如下:
|
||
|
||
```shell
|
||
get key
|
||
```
|
||
|
||
多个 key 使用空格隔开,如下:
|
||
|
||
```shell
|
||
get key1 key2 key3
|
||
```
|
||
|
||
参数说明如下:
|
||
|
||
- **key:**键值 key-value 结构中的 key,用于查找缓存值。
|
||
|
||
### gets命令
|
||
|
||
Memcached gets 命令获取带有 CAS 令牌存 的 **value(数据值)** ,如果 key 不存在,则返回空。不带的也可以正常获取
|
||
|
||
语法
|
||
|
||
gets 命令的基本语法格式如下:
|
||
|
||
```shell
|
||
gets key
|
||
```
|
||
|
||
多个 key 使用空格隔开,如下:
|
||
|
||
```shell
|
||
gets key1 key2 key3
|
||
```
|
||
|
||
参数说明如下:
|
||
|
||
- **key:**键值 key-value 结构中的 key,用于查找缓存值。
|
||
|
||
### delete命令
|
||
|
||
Memcached delete 命令用于删除已存在的 key(键)。
|
||
|
||
语法
|
||
|
||
delete 命令的基本语法格式如下:
|
||
|
||
```
|
||
delete key [noreply]
|
||
```
|
||
|
||
参数说明如下:
|
||
|
||
- **key:**键值 key-value 结构中的 key,用于查找缓存值。
|
||
- **noreply(可选)**: 该参数告知服务器不需要返回数据
|
||
|
||
输出信息说明:
|
||
|
||
- **DELETED**:删除成功。
|
||
- **ERROR**:语法错误或删除失败。
|
||
- **NOT_FOUND**:key 不存在。
|
||
|
||
## 统计命令
|
||
|
||
### stat命令
|
||
|
||
Memcached stats 命令用于返回统计信息例如 PID(进程号)、版本号、连接数等。
|
||
|
||
```shell
|
||
stats
|
||
```
|
||
|
||
```shell
|
||
stats
|
||
STAT pid 1162
|
||
STAT uptime 5022
|
||
STAT time 1415208270
|
||
STAT version 1.4.14
|
||
STAT libevent 2.0.19-stable
|
||
STAT pointer_size 64
|
||
STAT rusage_user 0.096006
|
||
STAT rusage_system 0.152009
|
||
STAT curr_connections 5
|
||
STAT total_connections 6
|
||
STAT connection_structures 6
|
||
STAT reserved_fds 20
|
||
STAT cmd_get 6
|
||
STAT cmd_set 4
|
||
STAT cmd_flush 0
|
||
STAT cmd_touch 0
|
||
STAT get_hits 4
|
||
STAT get_misses 2
|
||
STAT delete_misses 1
|
||
STAT delete_hits 1
|
||
STAT incr_misses 2
|
||
STAT incr_hits 1
|
||
STAT decr_misses 0
|
||
STAT decr_hits 1
|
||
STAT cas_misses 0
|
||
STAT cas_hits 0
|
||
STAT cas_badval 0
|
||
STAT touch_hits 0
|
||
STAT touch_misses 0
|
||
STAT auth_cmds 0
|
||
STAT auth_errors 0
|
||
STAT bytes_read 262
|
||
STAT bytes_written 313
|
||
STAT limit_maxbytes 67108864
|
||
STAT accepting_conns 1
|
||
STAT listen_disabled_num 0
|
||
STAT threads 4
|
||
STAT conn_yields 0
|
||
STAT hash_power_level 16
|
||
STAT hash_bytes 524288
|
||
STAT hash_is_expanding 0
|
||
STAT expired_unfetched 1
|
||
STAT evicted_unfetched 0
|
||
STAT bytes 142
|
||
STAT curr_items 2
|
||
STAT total_items 6
|
||
STAT evictions 0
|
||
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
|
||
|
||
Memcached stats items 命令用于显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)。
|
||
|
||
语法
|
||
|
||
```shell
|
||
stats items
|
||
```
|
||
|
||
示例
|
||
|
||
```shell
|
||
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
|
||
```
|
||
|
||
### stats slab
|
||
|
||
Memcached stats slabs 命令用于显示各个slab的信息,包括chunk的大小、数目、使用情况等。
|
||
|
||
```shell
|
||
stats slabs
|
||
```
|
||
|
||
示例
|
||
|
||
```shell
|
||
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 1
|
||
STAT 1:free_chunks 10921
|
||
STAT 1:free_chunks_end 0
|
||
STAT 1:mem_requested 71
|
||
STAT 1:get_hits 0
|
||
STAT 1:cmd_set 1
|
||
STAT 1:delete_hits 0
|
||
STAT 1:incr_hits 0
|
||
STAT 1:decr_hits 0
|
||
STAT 1:cas_hits 0
|
||
STAT 1:cas_badval 0
|
||
STAT 1:touch_hits 0
|
||
STAT active_slabs 1
|
||
STAT total_malloced 1048512
|
||
END
|
||
```
|
||
|
||
### stats sizes
|
||
|
||
Memcached stats sizes 命令用于显示所有item的大小和个数。
|
||
|
||
该信息返回两列,第一列是 item 的大小,第二列是 item 的个数。
|
||
|
||
语法:stats sizes 命令的基本语法格式如下:
|
||
|
||
```shell
|
||
stats sizes
|
||
```
|
||
|
||
实例:
|
||
|
||
```shell
|
||
stats sizes
|
||
STAT 96 1
|
||
END
|
||
```
|
||
|
||
### flush_all命令
|
||
|
||
Memcached flush_all 命令用于清理缓存中的所有 **key=>value(键=>值)** 对。
|
||
|
||
该命令提供了一个可选参数 **time**,用于在制定的时间后执行清理缓存操作。
|
||
|
||
语法:
|
||
|
||
flush_all 命令的基本语法格式如下:
|
||
|
||
```shell
|
||
flush_all [time] [noreply]
|
||
```
|
||
|
||
实例
|
||
|
||
清理缓存:
|
||
|
||
```shell
|
||
set runoob 0 900 9
|
||
memcached
|
||
STORED
|
||
get runoob
|
||
VALUE runoob 0 9
|
||
memcached
|
||
END
|
||
flush_all
|
||
OK
|
||
get runoob
|
||
END
|
||
```
|
||
|
||
|
||
|