字段级原子计数
Hash 提供了一套原子更新命令:HINCRBY 对整数字段做原子递增或递减,HINCRBYFLOAT 处理浮点数,HSETNX 只在字段不存在时写入。这些命令都在服务端单线程内完成,天然避免了「先读再写」的并发竞态,适合计数、库存、积分这类场景。需要注意字段在存储上仍是字符串,只有做递增时才按整数解析:字段不存在按 0 处理,字段值不是合法整数会直接报错,不会静默转换。
基本信息
| 整数递增 | HINCRBY key field delta,delta 可为负 |
|---|---|
| 浮点递增 | HINCRBYFLOAT key field delta |
| 条件写入 | HSETNX key field value,仅字段不存在时写入 |
| 返回值 | HINCRBY 返回递增后的值 |
| 边界 | 字段值非整数会报错,不自动转换 |
典型使用场景
- 页面或接口访问量按日期分字段累计,便于按天统计
- 用户积分增减,用负数实现扣减
- 传感器与指标类数据的浮点累加
- 幂等初始化:用 HSETNX 写入「已处理」标记,重复请求不会覆盖
- 把同一实体的多个计数放进一个 Hash,减少键数量与过期管理成本
示例
示例
redis-cli HINCRBY stats:page 20261012 1 # 当日计数加一
redis-cli HINCRBY user:1001 points -50 # 支持负数,实现扣减
redis-cli HINCRBYFLOAT metric:temp sensor1 0.5 # 浮点累加
redis-cli HSETNX task:9:lock owner worker1 # 字段不存在才写入,用于幂等
redis-cli HGETALL stats:page # 查看全部字段
redis-cli OBJECT ENCODING stats:page # 字段变多后会从 listpack 转成 hashtable命令对照
| 命令 | 返回值 | 典型用途 |
|---|---|---|
| HINCRBY | 递增后的整数值 | 计数与库存 |
| HINCRBYFLOAT | 递增后的浮点值 | 指标累加 |
| HSETNX | 1 表示写入成功,0 表示已存在 | 幂等标记 |
| HGET / HGETALL | 单字段或全部字段 | 查询与巡检 |
一个 Hash 的所有操作都在单线程上执行,字段数达到数万后,HGETALL、HDEL 这类全量操作的阻塞时间会变得可观。大 Hash 要么按业务维度拆分,要么改用 HSCAN 分批处理。
计数字段持续追加(例如每个用户每天一个新字段)会让 Hash 不断膨胀,字段维度需要有上限或者独立的清理机制,否则内存与单次操作耗时都会随维度增长而上升。