Memcached prepend 命令

Memcached prepend 命令详解(2025 版)

prepend 是 Memcached 的 前置写入 命令,用于 在已有 value 开头插入数据,常用于 日志倒序、队列头部插入、构建大对象

append 区别:

  • append:追加到 末尾
  • prepend:插入到 开头

1. 基本语法

prepend <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:初始化 + 多次 prepend

# 1. 初始化
set log:events 0 0 7
oldest
STORED

# 2. 前置新事件(倒序日志)
prepend log:events 0 0 8
event3
STORED

prepend log:events 0 0 8
event2
STORED

prepend log:events 0 0 8
event1
STORED

# 3. 查看结果(最新事件在前)
get log:events
VALUE log:events 0 31
event1event2event3oldest
END

结果:event1event2event3oldest最新在前


3. 客户端使用 prepend

Python(pymemcache)

from pymemcache.client.base import Client

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

# 初始化队列
client.set('queue:priority', 'low')

# 高优先级任务前插
client.prepend('queue:priority', 'high,')
client.prepend('queue:priority', 'urgent,')

print(client.get('queue:priority'))  # b'urgent,high,low'

PHP

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

$mc->set('timeline:user1', 'post:old');

$mc->prepend('timeline:user1', 'post:new3|');
$mc->prepend('timeline:user1', 'post:new2|');
$mc->prepend('timeline:user1', 'post:new1|');

echo $mc->get('timeline:user1');
// post:new1|post:new2|post:new3|post:old

Java(XMemcached)

client.set("buffer", 0, "end");
client.prepend("buffer", "middle");
client.prepend("buffer", "start");

System.out.println(client.get("buffer")); // startmiddleend

4. prepend vs append 对比

命令插入位置典型用途
prepend开头倒序日志、优先队列头部
append末尾正序日志、队列尾部
set msg 0 0 6
center
STORED

prepend msg 0 0 6
left
STORED
# → "leftcenter"

append msg 0 0 7
right
STORED
# → "leftcenterright"

5. 经典应用场景

5.1 倒序事件日志(最新在前)

def log_event(event):
    entry = f"{event}|"
    client.prepend('log:realtime', entry)

读取时直接 get 即可看到最新事件


5.2 优先级队列(高优先级在前)

# 高优先级任务
client.prepend('queue:jobs', json.dumps(task) + '\n')

# 低优先级任务
client.append('queue:jobs', json.dumps(task) + '\n')

5.3 构建大对象(分片前插)

# 分片上传,用户最新上传在前
client.set('file:123', '')
for chunk in reversed(chunks):  # 从新到旧
    client.prepend('file:123', chunk)

5.4 用户动态时间线

client.prepend('timeline:user:1001', f"{post_id}|")

6. 重要限制与注意事项

限制说明
key 必须存在否则 NOT_STORED
总大小 ≤ 1MB追加后不能超限
不修改 flags / exptime原值保持不变
二进制安全支持任意字节
性能开销略高需内存移动数据

超限示例

# 当前 0.9MB
prepend bigkey 0 0 200000
<200KB 数据>
ERROR  # object too large for cache

解决:分片存储 bigkey:part1, bigkey:part2


7. 最佳实践

建议说明
set 空值初始化set key 0 0 0 + ""
控制单 key < 800KB预留空间
用分隔符|, \n, ,
定期归档get → 落盘 → delete
避免热点 key高频 prepend 可能影响性能

8. 调试与监控

# 查看 prepend 统计
echo "stats" | nc 127.0.0.1 11211 | grep cmd_prepend
# cmd_prepend: 50
# prepend_hits: 48
# prepend_misses: 2
# 检查长度
value = client.get('log:events')
print(f"当前长度: {len(value)} 字节")

9. 常见错误

错误原因解决
NOT_STOREDkey 不存在set
SERVER_ERROR object too large超 1MB分片
数据错位无分隔符|\n

10. 小结:prepend 命令速查

prepend 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 文件(用 prepend 倒序组装)

需要 CAS 安全更新、delete 命令、大对象分片方案?继续问我!

文章已创建 2481

发表回复

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

相关文章

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

返回顶部