Memcached append 命令

Memcached append 命令详解(2025 版)

append 是 Memcached 的 追加写入 命令,用于 在已有 value 末尾追加数据,常用于 日志、队列、构建大对象

关键点:

  • 仅当 key 已存在 时生效
  • 不改变 flags 和 exptime
  • 原子操作,线程安全

1. 基本语法

append <key> <flags> <exptime> <bytes> [noreply]\r\n
<value>\r\n

注意flagsexptime 被忽略,仅为兼容性保留

参数说明
<key>已有键名
<flags>被忽略
<exptime>被忽略
<bytes>要追加的数据字节数
[noreply]可选,异步
<value>要追加的内容

响应:

  • STORED\r\n → 成功(key 存在)
  • NOT_STORED\r\n → 失败(key 不存在)

2. telnet 操作示例

telnet 127.0.0.1 11211

示例 1:首次创建 + 多次 append

# 1. 先 set 初始值
set log:access 0 0 11
2025-11-13
STORED

# 2. 追加访问记录
append log:access 0 0 20
 | user:1001 | GET /
STORED

# 3. 再次追加
append log:access 0 0 21
 | user:1002 | POST /login
STORED

# 4. 查看完整日志
get log:access
VALUE log:access 0 52
2025-11-13 | user:1001 | GET / | user:1002 | POST /login
END

3. 客户端使用 append

Python(pymemcache)

from pymemcache.client.base import Client

client = Client(('127.0.0.1', 11211))

# 初始化
client.set('queue:jobs', 'task1')

# 追加任务
client.append('queue:jobs', ',task2')
client.append('queue:jobs', ',task3')

print(client.get('queue:jobs'))  # b'task1,task2,task3'

PHP

$mc = new Memcached();
$mc->addServer('127.0.0.1', 11211);

$mc->set('chat:room1', 'Alice: Hello');

$mc->append('chat:room1', "\nBob: Hi!");
$mc->append('chat:room1', "\nAlice: How are you?");

echo $mc->get('chat:room1');

Java(XMemcached)

client.set("buffer:data", 0, "part1");
client.append("buffer:data", "part2");
client.append("buffer:data", "part3");

System.out.println(client.get("buffer:data")); // part1part2part3

4. append vs prepend

命令行为
append追加到末尾
prepend插入到开头
set msg 0 0 5
hello
STORED

append msg 0 0 6
 world
STORED
# → "hello world"

prepend msg 0 0 8
dear 
STORED
# → "dear hello world"

5. 经典应用场景

5.1 实时日志收集

def log_access(user, action):
    entry = f" | {user} | {action}"
    client.append('log:daily', entry)

所有服务器追加到同一 key,定期落盘


5.2 构建大对象(分片写入)

# 分片上传大文件
client.set('file:123:chunks', '')
for i, chunk in enumerate(chunks):
    client.append('file:123:chunks', chunk)

避免单次写超 1MB 限制


5.3 简单消息队列(FIFO)

# 生产者
client.append('queue:jobs', json.dumps(task) + '\n')

# 消费者(配合 get + delete)
data = client.get('queue:jobs')
if data:
    tasks = data.split(b'\n')
    task = tasks[0]
    # 处理完删除(需 CAS 或重建)

注意:非线程安全消费,推荐用 Redis List


5.4 聊天室消息历史

client.append('chat:room1', f"{user}: {msg}\n")

6. 重要限制与注意事项

限制说明
key 必须存在否则 NOT_STORED
value ≤ 1MB追加后总大小不能超 1MB(可通过 -I 调整)
不改变过期时间exptime 保持不变
不改变 flags原 flags 保持不变
二进制安全支持任意字节(包括 \0

超 1MB 报错示例

# 假设当前 0.9MB
append bigkey 0 0 200000
<200KB 数据>
ERROR  # 或 SERVER_ERROR object too large

解决:分 key 存储,如 bigkey:1, bigkey:2


7. 最佳实践

建议说明
set 空值初始化set key 0 0 0 + ""
控制单 key 大小 < 800KB留出追加空间
定期归档get → 落盘 → delete
避免高并发 append 同一 key可能导致热点
\n 分隔结构化数据方便解析

8. 调试与监控

# 查看 append 统计
echo "stats" | nc 127.0.0.1 11211 | grep cmd_append
# cmd_append: 100
# append_hits: 95
# append_misses: 5
# 查看当前 value 长度
value = client.get('log:daily')
print(len(value))  # 字节数

9. 常见错误

错误原因解决
NOT_STOREDkey 不存在set
SERVER_ERROR object too large超 1MB分片或增大 -I
数据错乱未加分隔符\n, 分隔

10. 小结:append 命令速查

append key 0 0 bytes [noreply]
<value>
└─> STORED(key 存在)
   └─> NOT_STORED(key 不存在)
项目推荐值
flags0(被忽略)
exptime0(被忽略)
bytes< 100KB
初始化set key 0 0 0 + ""

练习建议

  1. 用 telnet 实现“访问日志追加”
  2. 用 Python 实现 聊天室消息推送
  3. 模拟分片上传 1.5MB 文件(用 append

需要 prepend 命令、CAS 安全更新、大对象存储方案?继续问我!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部