Memcached gets 命令

Memcached gets 命令详解(2025 版)

getsget增强版唯一区别是:

gets 会额外返回一个 cas_token(版本号),用于 CAS 乐观锁


1. 核心区别:get vs gets

命令返回 cas_token用途
get普通读取
gets并发更新、乐观锁

2. 语法

gets <key> [<key> ...]\r\n

支持 批量,最多 100 个 key(建议 ≤ 50)


3. 响应格式

VALUE <key> <flags> <bytes> <cas_token>\r\n
<value>\r\n
...
END\r\n
字段说明
<cas_token>64 位整数,每次写入递增
END结束标志

4. telnet 完整示例

telnet 127.0.0.1 11211
# 1. 写入数据
set user:1001 0 0 8
zhangsan
STORED

# 2. gets 读取(带 cas_token)
gets user:1001
VALUE user:1001 0 8 1
zhangsan
END

1 = 当前 cas_token

# 3. 修改后再次 gets
replace user:1001 0 0 5
lisi
STORED

gets user:1001
VALUE user:1001 0 5 2
lisi
END

cas_token12


5. 客户端使用 gets

Python(pymemcache)

from pymemcache.client.base import Client

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

# 初始化
client.set('counter:likes', '100')

# gets 返回 (value, cas_token)
value, cas_token = client.gets('counter:likes')
print(value, cas_token)  # b'100' 1

# 批量 gets
results = client.gets_many(['counter:likes', 'config:db'])
# {b'counter:likes': (b'100', 1), b'config:db': (b'127.0.0.1', 3)}

PHP

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

$mc->set('visits', 100);

// gets + cas
$result = $mc->get('visits', null, $cas_token);
echo "Value: $result, CAS: $cas_token\n";

// 批量 gets
$keys = ['visits', 'users'];
$cas_tokens = [];
$data = $mc->getMulti($keys, $cas_tokens);
print_r($data);
print_r($cas_tokens);

Java(XMemcached)

CASValue<String> casValue = client.gets("counter");
String value = casValue.getValue();
long cas = casValue.getCas();

System.out.println("Value: " + value + ", CAS: " + cas);

6. CAS 完整流程(gets + cas

1. gets key
   → VALUE key flags bytes cas_token
   → 修改 value

2. cas key flags exptime bytes cas_token
   → STORED(成功)
   → EXISTS(冲突,需重试)

Python CAS 示例

def cas_increment(key, delta=1, max_retries=5):
    for _ in range(max_retries):
        result = client.gets(key)
        if not result:
            return False

        value_bytes, cas_token = result
        try:
            old_value = int(value_bytes)
        except:
            return False

        new_value = old_value + delta

        if client.cas(key, str(new_value), cas_token):
            return True  # 成功

    return False  # 重试失败

7. 经典应用场景

场景为什么用 gets
点赞计数器多线程并发 +1
库存扣减防止超卖
购物车修改并发添加商品
订单状态流转待支付 → 已支付
配置热更新多节点同步

8. cas_token 变化规则

操作cas_token 变化
set / add / replace+1
append / prepend+1
incr / decr+1
delete失效
get / gets不变

9. 批量 gets 注意事项

# 推荐:批量 gets + 批量 cas
keys = ['user:1', 'user:2', 'user:3']
results = client.gets_many(keys)  # {key: (value, cas)}

# 批量更新
for key, (value, cas) in results.items():
    new_value = modify(value)
    client.cas(key, new_value, cas)

避免:单个 gets + cas 循环(性能差)


10. 性能与监控

echo "stats" | nc 127.0.0.1 11211
指标说明
cmd_getsgets 总次数
get_hits命中次数
cas_hitscas 成功次数
cas_badvalcas 失败(版本冲突)

高并发下 cas_badval 增多 → 说明冲突严重


11. 常见错误

错误原因解决
EXISTScas 时版本不一致重新 gets → 修改 → cas
NOT_FOUNDkey 不存在初始化
cas_token 错误使用了 get 的结果必须用 gets

12. 小结:gets 速查

gets key1 [key2 ...]
└─> VALUE key flags bytes cas_token
    <value>
    END
项目推荐
用途并发写场景
配合cas 命令
批量≤ 50 个 key
重试EXISTS 时循环

练习建议

  1. 用 telnet 实现 两个客户端并发点赞
  2. 用 Python 实现 库存扣减(支持 1000 并发)
  3. 实现 配置中心热更新(多节点同步)

需要 cas 命令详解、incr/decr 原子操作、delete 失效?继续问我!

文章已创建 2481

发表回复

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

相关文章

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

返回顶部