Memcache 是一种高性能的分布式内存对象缓存系统,常用于减轻数据库负载,通过在内存中缓存频繁访问的数据来提高应用响应速度,其命令行工具提供了直接与 Memcache 服务器交互的能力,set 命令是最基础且常用的操作之一,用于向 Memcache 服务器中存储键值对数据,本文将详细介绍 set 命令的语法、参数、使用场景及注意事项,并结合实际案例帮助读者全面掌握其应用。

set 命令的基本语法与参数
set 命令用于将指定的键值对存储到 Memcache 服务器中,如果键已存在,则其值会被覆盖,其基本语法格式如下:
set key flags exptime bytes [noreply]
value
各参数的具体含义如下:
| 参数 | 说明 |
|---|---|
key |
键名,必须是唯一的字符串,且长度不超过 250 字节。 |
flags |
32 位无符号整数,用于存储额外的元数据(如数据类型、压缩标志等),客户端可自行定义用途,Memcache 服务器本身不解析该字段。 |
exptime |
数据的过期时间(单位:秒)。 - 设置为 0 表示永不过期; - 设置不超过 30 天的秒数(如 3600 表示 1 小时后过期); - 设置超过 30 天的秒数时,Memcache 会将其视为 UNIX 时间戳(即具体过期时间点)。 |
bytes |
数据值的字节数(不包括换行符),需与实际发送的数据长度严格一致,否则会导致存储失败。 |
noreply |
可选参数,如果指定,服务器不会返回任何响应(适用于不需要确认结果的批量写入场景)。 |
value |
实际存储的数据内容,需紧跟在命令行后单独一行输入,且以换行符结束。 |
set 命令的使用示例
示例 1:存储简单字符串数据
假设要存储键为 username、值为 Alice 的数据,过期时间为 3600 秒(1 小时),flags 设置为 0:
set username 0 3600 5
Alice
执行后,服务器返回 STORED,表示存储成功,若键已存在,则返回 NOT_STORED(需确保 flags 和 exptime 与原数据一致,否则可能覆盖失败)。

示例 2:使用 flags 标记数据类型
如果希望区分数据类型(如 JSON、序列化对象等),可通过 flags 传递标识,存储 JSON 数据时,将 flags 设为 1(自定义标识):
set user_data 1 0 23
{"name":"Bob","age":25}
客户端读取时,可根据 flags 值决定如何解析数据(如反序列化 JSON)。
示例 3:永不过期的数据
对于需要长期缓存的数据(如配置信息),将 exptime 设为 0:
set config 0 0 15
debug_mode=on
示例 4:批量写入与 noreply 参数
在批量写入场景中,可使用 noreply 减少网络往返时间,存储 1000 条数据时,每条命令后添加 noreply:

set key1 0 60 10 noreply
value1
set key2 0 60 10 noreply
value2
此时服务器不会返回响应,需通过其他方式(如后续 get 命令)验证结果。
set 命令的注意事项
- 键的唯一性:
set命令会覆盖已存在的键,若需避免覆盖,可先用add命令检查键是否存在。 - 数据长度限制:单个键值对的总大小(包括键、
flags、exptime、bytes和值)通常不超过 1MB(具体取决于 Memcache 服务器配置)。 - 过期时间精度:Memcache 不会精确到毫秒,过期时间可能存在几秒的误差;对于高精度过期需求,需结合业务逻辑处理。
- 网络稳定性:在分布式环境中,若网络不稳定,
noreply模式可能导致数据丢失,需确保网络可靠性或使用重试机制。 - 内存管理:Memcache 采用 LRU(最近最少使用)策略淘汰数据,即使未达到过期时间,内存不足时也可能被删除,需合理设置
exptime和监控内存使用情况。
set 命令与其他存储命令的区别
Memcache 提供了多个存储命令,set 是最基础的覆盖式写入,其他命令有特定用途:
| 命令 | 功能 | 与 set 的区别 |
|---|---|---|
add |
仅在键不存在时存储数据 | 若键已存在,返回 NOT_STORED,不会覆盖 |
replace |
仅在键存在时更新数据 | 若键不存在,返回 NOT_STORED,不会新建 |
cas |
基于版本号(cas unique)的原子操作,仅在数据未被修改时更新 | 需配合 gets 命令获取版本号,适合并发场景 |
append |
在现有数据末尾追加内容 | 要求键必须已存在,否则返回 NOT_STORED |
prepend |
在现有数据开头插入内容 | 同 append,但操作方向相反 |
相关问答 FAQs
问题 1:set 命令中的 flags 参数有什么实际用途?如何正确使用?
解答:flags 是一个 32 位无符号整数,用于客户端自定义数据标识,Memcache 服务器本身不解析该字段,其典型用途包括:
- 标记数据类型(如 0 表示字符串,1 表示 JSON,2 表示序列化对象);
- 传递压缩标志(如 1 表示数据已压缩,客户端读取时需解压);
- 版本控制(如配合
cas命令使用)。
使用时,需在客户端读取数据后根据flags值进行相应处理,例如通过flags判断是否需要反序列化或解压。
问题 2:为什么 set 命令存储的数据有时会提前消失,即使未达到设定的 exptime?
解答:这种情况通常由以下原因导致:
- 内存不足:Memcache 采用 LRU 策略淘汰数据,当内存使用达到阈值时,会优先删除最近最少使用的数据,即使其未过期,可通过
stats命令监控evictions指标确认是否因内存淘汰导致数据丢失。 - 服务器重启:Memcache 是内存型数据库,服务器重启后所有数据会丢失,需结合持久化方案(如定期将数据同步到数据库)或使用支持持久化的缓存工具(如 Redis)。
- 过期时间设置错误:若
exptime设置为超过 30 天的秒数,Memcache 会将其视为 UNIX 时间戳,需确保时间戳正确,当前时间为 2023-01-01,设置exptime为 1700000000(对应 2023-11-14)会导致数据提前过期。
