Memcached存储命令 #
一、存储命令概述 #
1.1 存储命令列表 #
text
Memcached提供以下存储命令:
set - 存储,存在则覆盖
add - 添加,存在则失败
replace - 替换,不存在则失败
append - 追加到末尾
prepend - 添加到开头
cas - 检查并设置(Compare And Swap)
1.2 命令格式 #
text
基本格式:
<command> <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
参数说明:
command - 命令名称
key - 键名(最大250字节)
flags - 标志位(32位整数,客户端自定义)
exptime - 过期时间(秒,0表示永不过期)
bytes - 数据字节数
noreply - 可选,不返回响应
data - 数据内容
二、set命令 #
2.1 命令说明 #
text
set命令:
- 存储数据
- 键存在则覆盖
- 键不存在则创建
语法:
set <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
响应:
STORED - 存储成功
NOT_STORED - 存储失败(一般不会出现)
2.2 基本使用 #
bash
# 存储简单字符串
set greeting 0 3600 5
hello
STORED
# 获取验证
get greeting
VALUE greeting 0 5
hello
END
# 覆盖已存在的数据
set greeting 0 3600 5
world
STORED
get greeting
VALUE greeting 0 5
world
END
2.3 存储JSON数据 #
bash
# 存储JSON对象
set user:1001 0 3600 45
{"id":1001,"name":"John","email":"john@example.com"}
STORED
# 存储JSON数组
set users:list 0 3600 95
[{"id":1001,"name":"John"},{"id":1002,"name":"Jane"}]
STORED
# 使用flags标识JSON
set user:1001 2 3600 45
{"id":1001,"name":"John","email":"john@example.com"}
STORED
2.4 设置过期时间 #
bash
# 1小时后过期
set key1 0 3600 5
hello
# 永不过期
set key2 0 0 5
hello
# Unix时间戳过期(2024-01-01 00:00:00)
set key3 0 1704067200 5
hello
# 30天后过期(作为Unix时间戳)
set key4 0 2592000 5
hello
2.5 使用noreply #
bash
# 不等待响应,提高性能
set key 0 3600 5 noreply
hello
# 适用于批量操作
set key1 0 3600 5 noreply
hello
set key2 0 3600 5 noreply
world
set key3 0 3600 5 noreply
!
三、add命令 #
3.1 命令说明 #
text
add命令:
- 添加数据
- 键不存在时才成功
- 键存在则失败
语法:
add <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
响应:
STORED - 存储成功(键不存在)
NOT_STORED - 存储失败(键已存在)
3.2 基本使用 #
bash
# 添加新数据
add newkey 0 3600 5
hello
STORED
# 键已存在,添加失败
add newkey 0 3600 5
world
NOT_STORED
3.3 应用场景 #
bash
# 分布式锁
add lock:resource:1001 0 30 1
1
STORED
# 锁已被占用
add lock:resource:1001 0 30 1
1
NOT_STORED
# 防止重复创建
add user:1001:profile 0 3600 45
{"name":"John","age":25}
STORED
# 重复创建失败
add user:1001:profile 0 3600 45
{"name":"Jane","age":28}
NOT_STORED
3.4 实现幂等性 #
bash
# 使用add实现幂等操作
add request:order:12345 0 3600 1
1
STORED
# 重复请求被拒绝
add request:order:12345 0 3600 1
1
NOT_STORED
四、replace命令 #
4.1 命令说明 #
text
replace命令:
- 替换数据
- 键存在时才成功
- 键不存在则失败
语法:
replace <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
响应:
STORED - 替换成功(键存在)
NOT_STORED - 替换失败(键不存在)
4.2 基本使用 #
bash
# 先存储数据
set user:1001 0 3600 27
{"name":"John","age":25}
STORED
# 替换数据
replace user:1001 0 3600 27
{"name":"John","age":26}
STORED
# 键不存在,替换失败
replace user:9999 0 3600 5
hello
NOT_STORED
4.3 应用场景 #
bash
# 更新用户信息
set user:1001 0 3600 45
{"id":1001,"name":"John","email":"john@example.com"}
STORED
replace user:1001 0 3600 55
{"id":1001,"name":"John","email":"john@example.com","age":25}
STORED
# 更新配置
set config:app 0 0 32
{"theme":"light","lang":"en"}
STORED
replace config:app 0 0 32
{"theme":"dark","lang":"zh"}
STORED
五、append命令 #
5.1 命令说明 #
text
append命令:
- 追加数据到末尾
- 键不存在则失败
语法:
append <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
响应:
STORED - 追加成功
NOT_STORED - 追加失败(键不存在)
5.2 基本使用 #
bash
# 存储初始数据
set message 0 3600 5
hello
STORED
# 追加数据
append message 0 3600 6
world
STORED
# 查看结果
get message
VALUE message 0 11
hello world
END
5.3 应用场景 #
bash
# 日志追加
set log:app 0 0 20
2024-01-01 INFO: Start
STORED
append log:app 0 0 25
\n2024-01-01 INFO: Running
STORED
# 列表追加(需要自行处理分隔符)
set list:items 0 3600 3
one
STORED
append list:items 0 3600 4
,two
STORED
append list:items 0 3600 6
,three
STORED
get list:items
VALUE list:items 0 13
one,two,three
END
六、prepend命令 #
6.1 命令说明 #
text
prepend命令:
- 添加数据到开头
- 键不存在则失败
语法:
prepend <key> <flags> <exptime> <bytes> [noreply]\r\n
<data block>\r\n
响应:
STORED - 添加成功
NOT_STORED - 添加失败(键不存在)
6.2 基本使用 #
bash
# 存储初始数据
set message 0 3600 5
world
STORED
# 添加到开头
prepend message 0 3600 6
hello
STORED
# 查看结果
get message
VALUE message 0 11
hello world
END
6.3 应用场景 #
bash
# 添加前缀
set path 0 3600 8
/bin/bash
STORED
prepend path 0 3600 1
/
STORED
get path
VALUE path 0 9
//bin/bash
END
# 链表头部插入(需要自行处理分隔符)
set list:items 0 3600 5
three
STORED
prepend list:items 0 3600 4
two,
STORED
prepend list:items 0 3600 4
one,
STORED
get list:items
VALUE list:items 0 13
one,two,three
END
七、cas命令 #
7.1 命令说明 #
text
cas命令(Compare And Swap):
- 检查并设置
- 需要提供CAS ID
- CAS ID匹配才更新
语法:
cas <key> <flags> <exptime> <bytes> <cas unique> [noreply]\r\n
<data block>\r\n
响应:
STORED - 更新成功
EXISTS - CAS ID不匹配
NOT_FOUND - 键不存在
7.2 基本使用 #
bash
# 先获取数据和CAS ID
gets user:1001
VALUE user:1001 0 27 123
{"name":"John","age":25}
END
# 使用CAS更新
cas user:1001 0 3600 27 123
{"name":"John","age":26}
STORED
# 再次获取新的CAS ID
gets user:1001
VALUE user:1001 0 27 124
{"name":"John","age":26}
END
# 使用旧的CAS ID更新失败
cas user:1001 0 3600 27 123
{"name":"John","age":27}
EXISTS
7.3 实现乐观锁 #
bash
# 场景:更新商品库存
# 1. 获取当前库存和CAS ID
gets product:1001:stock
VALUE product:1001:stock 0 2 100
50
END
# 2. 计算新库存(客户端处理)
new_stock = 50 - 1 # 减1
# 3. 使用CAS更新
cas product:1001:stock 0 3600 2 100
49
STORED
# 如果其他客户端同时更新,CAS会失败
cas product:1001:stock 0 3600 2 100
48
EXISTS
# 需要重新获取最新的CAS ID
gets product:1001:stock
VALUE product:1001:stock 0 2 101
49
END
# 使用新的CAS ID重试
cas product:1001:stock 0 3600 2 101
48
STORED
7.4 并发更新示例 #
bash
# 客户端A
gets counter
VALUE counter 0 1 10
5
END
# 客户端B
gets counter
VALUE counter 0 1 10
5
END
# 客户端A更新成功
cas counter 0 3600 1 10
6
STORED
# 客户端B更新失败(CAS ID已变)
cas counter 0 3600 1 10
6
EXISTS
八、存储命令对比 #
8.1 命令对比表 #
| 命令 | 键存在 | 键不存在 | 用途 |
|---|---|---|---|
| set | 覆盖 | 创建 | 通用存储 |
| add | 失败 | 创建 | 分布式锁、幂等 |
| replace | 替换 | 失败 | 条件更新 |
| append | 追加 | 失败 | 日志追加 |
| prepend | 前置 | 失败 | 添加前缀 |
| cas | 检查CAS | 失败 | 乐观锁 |
8.2 响应状态对比 #
text
响应状态说明:
STORED - 操作成功
NOT_STORED - 操作失败(条件不满足)
EXISTS - CAS ID不匹配
NOT_FOUND - 键不存在
ERROR - 命令格式错误
九、最佳实践 #
9.1 选择合适的命令 #
text
场景选择:
1. 简单缓存
使用 set 命令
2. 分布式锁
使用 add 命令
3. 条件更新
使用 replace 命令
4. 并发安全更新
使用 cas 命令
5. 日志追加
使用 append 命令
9.2 键命名规范 #
bash
# 使用命名空间
set user:info:1001 0 3600 45
{"id":1001,"name":"John"}
set user:profile:1001 0 3600 55
{"id":1001,"name":"John","age":25}
# 使用层级结构
set cache:db:users:1001 0 3600 45
{"id":1001,"name":"John"}
# 包含过期信息
set session:web:abc123 0 1800 64
{"user_id":1001,"login_time":1704067200}
9.3 flags使用建议 #
bash
# 标识数据类型
set key 0 0 5 # 默认(字符串)
set key 1 0 5 # 序列化对象
set key 2 0 5 # JSON
set key 3 0 5 # 压缩数据
set key 4 0 5 # 二进制数据
# 客户端根据flags解析
9.4 过期时间设置 #
bash
# 根据数据特性设置
set static:config 0 0 100 # 永不过期
set session:user:1001 0 1800 64 # 30分钟
set cache:api:weather 0 3600 128 # 1小时
set temp:code:abc123 0 300 6 # 5分钟
# 避免缓存雪崩
base_time = 3600
random_time = random(0, 300)
exptime = base_time + random_time
十、错误处理 #
10.1 常见错误 #
bash
# 数据长度不匹配
set key 0 0 5
hello world
CLIENT_ERROR bad data chunk
# 键名过长
set aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0 0 5
hello
CLIENT_ERROR bad command line format
# 数据过大
set key 0 0 2000000
<2MB data>
SERVER_ERROR object too large for cache
10.2 错误处理建议 #
bash
# 1. 检查数据长度
data = "hello"
length = len(data)
command = f"set key 0 3600 {length}"
# 2. 处理响应
response = send_command(command, data)
if response == "STORED":
# 成功
pass
elif response == "NOT_STORED":
# 失败
pass
elif response == "EXISTS":
# CAS冲突
pass
# 3. 重试机制
max_retries = 3
for i in range(max_retries):
response = cas_with_retry(key, value)
if response == "STORED":
break
十一、总结 #
存储命令要点:
| 命令 | 说明 | 典型场景 |
|---|---|---|
| set | 存储覆盖 | 通用缓存 |
| add | 仅新增 | 分布式锁 |
| replace | 仅替换 | 条件更新 |
| append | 追加 | 日志追加 |
| prepend | 前置 | 添加前缀 |
| cas | 检查更新 | 并发安全 |
下一步,让我们学习Memcached的读取命令!
最后更新:2026-03-27