Memcached基础语法 #
一、键命名规范 #
1.1 键的基本规则 #
text
键的规则:
1. 长度限制:最大250字节
2. 字符限制:不能包含空格和控制字符
3. 命名建议:使用有意义的前缀和分隔符
示例:
✓ user:1001
✓ session:abc123
✓ page:home:header
✓ api:weather:beijing
✗ key with spaces
✗ key\nwith\nnewlines
1.2 命名空间设计 #
text
命名空间设计模式:
<namespace>:<type>:<id>
示例:
user:info:1001 # 用户信息
user:profile:1001 # 用户资料
session:web:abc123 # Web会话
session:api:xyz789 # API会话
cache:db:users:1001 # 数据库缓存
page:html:home # 页面缓存
api:response:weather # API响应缓存
1.3 键命名最佳实践 #
text
推荐做法:
1. 使用统一前缀
app:user:1001
app:product:2001
2. 使用层级结构
user:1001:profile
user:1001:settings
3. 包含过期信息(可选)
cache:5min:api:data
cache:1h:page:home
4. 使用哈希缩短
长键名 → MD5/SHA1哈希
user:very:long:path:to:data → user:md5hash
二、数据类型 #
2.1 支持的数据类型 #
text
Memcached只支持一种数据类型:字符串
但可以存储:
- 文本数据
- JSON数据
- 序列化对象
- 二进制数据
- 数字(作为字符串)
示例:
set key1 0 0 5
hello # 文本
set key2 0 0 27
{"name":"John","age":25} # JSON
set key3 0 0 3
100 # 数字(字符串形式)
2.2 Flags标志 #
text
Flags是一个32位的整数,用于标识数据类型:
常用Flags值:
0 - 默认(字符串)
1 - 序列化对象
2 - JSON
3 - 压缩数据
4 - 二进制数据
示例:
# 存储JSON数据
set user:1001 2 3600 27
{"name":"John","age":25}
# 客户端可以根据Flags解析数据类型
2.3 数据大小限制 #
text
数据大小限制:
默认最大:1MB
可配置最大:128MB(需要重新编译)
建议:
- 单个Item不超过1MB
- 大数据分片存储
- 使用压缩减少大小
三、命令格式 #
3.1 文本协议格式 #
text
基本格式:
<command> <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
参数说明:
command - 命令名称
key - 键名
flags - 标志位(32位整数)
exptime - 过期时间(秒)
bytes - 数据字节数
noreply - 可选,不返回响应
data - 数据内容
示例:
set user:1001 0 3600 23
{"name":"John","age":25}
3.2 存储命令 #
text
存储命令列表:
set - 存储,存在则覆盖
add - 添加,存在则失败
replace - 替换,不存在则失败
append - 追加到末尾
prepend - 添加到开头
cas - 检查并设置
示例:
# set命令
set key 0 3600 5
hello
STORED
# add命令
add key 0 3600 5
world
NOT_STORED # 已存在,存储失败
# replace命令
replace key 0 3600 5
world
STORED
3.3 读取命令 #
text
读取命令列表:
get - 获取数据
gets - 获取数据和CAS ID
示例:
# get命令
get key
VALUE key 0 5
hello
END
# gets命令
gets key
VALUE key 0 5 123
hello
END
# 123是CAS ID
3.4 删除命令 #
text
删除命令:
delete <key> [noreply]
示例:
delete key
DELETED
delete notexist
NOT_FOUND
3.5 计数器命令 #
text
计数器命令:
incr <key> <value> [noreply]
decr <key> <value> [noreply]
示例:
# 初始化计数器
set counter 0 0 1
0
STORED
# 递增
incr counter 1
1
incr counter 5
6
# 递减
decr counter 2
4
四、过期时间 #
4.1 过期时间格式 #
text
过期时间格式:
exptime = 0 - 永不过期
exptime > 0 - 相对时间(秒)
exptime < 0 - Unix时间戳
示例:
# 1小时后过期
set key 0 3600 5
hello
# 永不过期
set key 0 0 5
hello
# Unix时间戳过期(2024-01-01 00:00:00)
set key 0 1704067200 5
hello
4.2 过期时间计算 #
text
过期时间计算规则:
1. Unix时间戳(小于30天)
exptime < 60*60*24*30
解释为相对时间(秒)
2. Unix时间戳(大于等于30天)
exptime >= 60*60*24*30
解释为绝对时间(Unix时间戳)
示例:
# 30天 = 2592000秒
# 2591999秒 → 相对时间
# 2592000秒 → 绝对时间
# 1小时后过期
set key 0 3600 5
hello
# 指定日期过期
set key 0 1704067200 5
hello
4.3 过期策略 #
text
Memcached过期策略:
1. 惰性删除
- 访问时检查是否过期
- 过期则删除并返回不存在
2. LRU淘汰
- 内存满时淘汰最近最少使用的数据
- 不区分是否过期
3. 后台清理
- 不主动清理过期数据
- 依赖惰性删除和LRU
五、响应状态 #
5.1 存储命令响应 #
text
存储命令响应状态:
STORED - 存储成功
NOT_STORED - 存储失败(add/replace条件不满足)
EXISTS - cas命令时,CAS ID不匹配
NOT_FOUND - cas命令时,键不存在
示例:
set key 0 0 5
hello
STORED
add key 0 0 5
world
NOT_STORED
cas key 0 0 5 999
hello
EXISTS
5.2 读取命令响应 #
text
读取命令响应格式:
VALUE <key> <flags> <bytes> [<cas unique>]
<data block>
END
示例:
get key
VALUE key 0 5
hello
END
gets key
VALUE key 0 5 123
hello
END
get notexist
END
5.3 删除命令响应 #
text
删除命令响应状态:
DELETED - 删除成功
NOT_FOUND - 键不存在
示例:
delete key
DELETED
delete notexist
NOT_FOUND
5.4 计数器命令响应 #
text
计数器命令响应:
成功:返回新值
失败:NOT_FOUND(键不存在)
ERROR(值不是数字)
示例:
incr counter 1
5
incr notexist 1
NOT_FOUND
set str 0 0 5
hello
STORED
incr str 1
ERROR
六、二进制协议 #
6.1 二进制协议优势 #
text
二进制协议优势:
1. 更高效
- 二进制格式,解析更快
- 更少的字符串处理
2. 更安全
- 不需要转义特殊字符
- 支持二进制键名
3. 功能更全
- 支持更多操作
- 支持SASL认证
6.2 二进制协议格式 #
text
请求头格式(24字节):
Byte/ 0 | 1 | 2 | 3 |
/ | | | |
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
+---------------+---------------+---------------+---------------+
| Magic | Opcode | Key length |
+---------------+---------------+---------------+---------------+
| Extras length | Data type | vbucket id |
+---------------+---------------+---------------+---------------+
| Total body length |
+---------------+---------------+---------------+---------------+
| Opaque |
+---------------+---------------+---------------+---------------+
| CAS |
+---------------+---------------+---------------+---------------+
响应头格式(24字节):
| Magic | Opcode | Key length |
+---------------+---------------+---------------+---------------+
| Extras length | Data type | Status |
+---------------+---------------+---------------+---------------+
| Total body length |
+---------------+---------------+---------------+---------------+
| Opaque |
+---------------+---------------+---------------+---------------+
| CAS |
+---------------+---------------+---------------+---------------+
七、命令规范 #
7.1 命令大小写 #
text
命令不区分大小写:
set = SET = Set
get = GET = Get
建议:统一使用小写
7.2 空格分隔 #
text
命令参数使用空格分隔:
set key flags exptime bytes
注意:
- 多个空格视为一个
- 数据块中的空格保留
7.3 换行符 #
text
换行符规范:
命令行:\r\n
数据块:\r\n
注意:
- 不同系统可能只有\n
- 建议统一使用\r\n
八、错误处理 #
8.1 错误响应 #
text
错误响应类型:
ERROR - 命令不存在
CLIENT_ERROR <error> - 客户端错误
SERVER_ERROR <error> - 服务器错误
示例:
unknowncommand
ERROR
set key 0 0 abc
CLIENT_ERROR bad command line format
set key 0 0 999999999999999999999999999
SERVER_ERROR out of memory
8.2 常见错误 #
text
常见错误及解决:
1. CLIENT_ERROR bad command line format
原因:命令格式错误
解决:检查命令语法
2. CLIENT_ERROR bad data chunk
原因:数据长度不匹配
解决:检查bytes参数
3. SERVER_ERROR out of memory
原因:内存不足
解决:增加内存或清理数据
4. SERVER_ERROR object too large for cache
原因:数据超过最大限制
解决:减小数据大小或增大配置
九、最佳实践 #
9.1 键命名规范 #
text
键命名规范:
1. 使用有意义的前缀
user:1001
product:2001
2. 使用分隔符
user:1001:profile
user:1001:settings
3. 避免特殊字符
✓ user_1001
✗ user-1001 (可能引起歧义)
4. 控制长度
键名不要太长,影响性能
9.2 数据序列化 #
text
数据序列化建议:
1. JSON格式
优点:可读性好,跨语言
缺点:体积较大
2. MessagePack
优点:体积小,速度快
缺点:需要额外库
3. Protobuf
优点:体积最小
缺点:需要定义schema
示例:
# JSON
set user:1001 0 3600 27
{"name":"John","age":25}
# MessagePack(二进制)
set user:1001 0 3600 18
<binary data>
9.3 过期时间设置 #
text
过期时间设置建议:
1. 根据数据更新频率设置
- 静态数据:较长过期时间
- 动态数据:较短过期时间
2. 避免缓存雪崩
- 过期时间加随机值
- base_time + random(0, 300)
3. 预热缓存
- 系统启动时加载热点数据
- 避免大量请求同时击穿
示例:
# 1小时过期,加随机值
exptime = 3600 + random(0, 300)
十、总结 #
Memcached语法要点:
| 要点 | 说明 |
|---|---|
| 键长度 | 最大250字节 |
| 数据大小 | 默认最大1MB |
| 数据类型 | 仅字符串 |
| 过期时间 | 0=永不过期 |
| 协议 | 文本/二进制 |
下一步,让我们学习Memcached CLI的使用!
最后更新:2026-03-27