GETRANGE / SETRANGE 是什么
两个命令把字符串当字节数组操作:GETRANGE 按下标区间截取子串,支持负下标(-1 表示最后一个字节),SETRANGE 从指定偏移开始覆写内容。它们都是二进制安全接口,因此既能存文本片段也能存图片切片等二进制数据。由于下标按字节计算,中文等多字节字符按字节截断会出现半个字符的乱码。
基本信息
| 适用版本 | Redis 2.0+(GETRANGE 在 2.0 前叫 SUBSTR) |
|---|---|
| 下标规则 | 按字节,0 起;负数从尾部计,-1 为最后一个字节 |
| GETRANGE 返回 | 指定区间的子串;越界部分自动裁剪 |
| SETRANGE 返回 | 写入后的新字符串长度 |
| 扩展行为 | 超出现有长度时自动用零字节填充 |
| 时间复杂度 | GETRANGE O(N)(N 为返回长度)、SETRANGE O(N)(N 为写入长度) |
典型使用场景
- 截取定长协议头的字段,如固定宽度编码里的前缀与状态位
- 原地更新定长记录中的某段内容,避免整体重写
- 取日志或消息的前若干字节做摘要与展示
- 二进制片段拼接:把分片上传的数据按偏移写入同一键
- 与 BITFIELD 配合做紧凑结构存储
示例
示例
SET msg "Hello World"
GETRANGE msg 0 4 # "Hello"
GETRANGE msg -5 -1 # "World"
GETRANGE msg 0 -1 # 整个值
GETRANGE msg 6 99 # "World":越界自动裁剪
SETRANGE msg 6 "Redis" # 返回 11,值变 "Hello Redis"
SETRANGE pad 5 "x" # 自动补 \x00 零字节,返回 6行为对照
| 场景 | 行为 | 注意 |
|---|---|---|
| 区间越界读取 | 自动裁剪到实际范围,不报错 | 结果长度可能小于预期 |
| 偏移超长写入 | 中间用 \x00 填充至偏移位置 | 键长度被悄悄放大,内存随之增长 |
| 中文按字节截取 | 可能截断成半个字符,输出乱码 | 文本场景应在应用层按字符处理 |
| 对不存在的键 SETRANGE | 相当于新建并以零字节填充 | 容易写出意外的大键 |
取整个值就是 GET 的行为,用 GETRANGE key 0 -1 与 GET 结果一致;但只要取部分内容,用 GETRANGE 就比 GET 再在应用里截断更省带宽。
SETRANGE 的偏移量由业务传入时要做上限校验:传入一个很大的偏移会立刻把键扩到该长度并用零字节填充,瞬间占用大量内存,构成典型的大键风险。