Redis 命令及数据类型 -- String

摘要

String 核心详解

  • 在 Redis 中,String(字符串) 是最基础、也是使用最广泛的数据类型。它并不只表示“文本字符串”,而是一种二进制安全(binary-safe)的值类型,可以存储多种形式的数据。

  • Redis 的 String 类型本质上是一个 key → value 的映射,key 和 value 本质上是二进制安全的字节数组。

  • Redis 不关心 key 和 value 的语义,只当作字节数组处理,可存储文本、数字、序列化对象、图片等

数据形式 示例
普通字符串 "hello redis"
数字(整型/浮点) "100", "3.14"
JSON {"id":1,"name":"Tom"}
序列化对象 Java / JSON / ProtoBuf
Base64 / 二进制 图片、Token 等
  • 单个 key 和 value 最大都是 512 MB,但实际使用中及其不推荐将其设置为这么大,推荐如下

分类 最大存储大小(MB)
Key < 1k
Value < 1MB
  • String 数据类型的主要应用场景

1
2
3
4
5
6
# 单值缓存
SET k1 v1
# 对象缓存
SET user:1 '{"name":"zhangsan","age":20}'
# 分布式锁,为了保证可重入,现在更推荐使用 hash 类型
SET lock uuid:threadId NX EX 10

Redis String 的编码类型

编码类型是针对 value 的编码方式

编码类型 OBJECT ENCODING 触发条件 内部存储 是否可变 典型命令/场景 备注
整数编码 int value 是纯数字字符串且在 [-2^63, 2^63-1] 范围 long SET k 1INCR k 最省内存、数值运算最快
嵌入式字符串 embstr 字符串长度 ≤ 44 字节(Redis 7.x)且直接 SET redisObject + SDS 一次性分配 ⚠️(会升级) SET k "ok" 不支持扩容
原始字符串 raw 字符串长度 > 44 字节,或发生增量修改 redisObject → SDS APPENDSETRANGE 最通用
  • 可以用命令查看指定key的 value 的编码类型

1
OBJECT ENCODING key
  • 示例

1
2
3
4
5
6
7
set k1 123
OBJECT ENCODING k1 # int
APPEND k1 "4" # 自动升级为 raw,这是因为 APPEND 会强制使用 raw,即使最终字符串长度 ≤ 44 字节

SET k "short"
OBJECT ENCODING k # embstr
APPEND k "this-is-a-long-string" # 自动升级为 raw
  • Redis String 根据“值的形态 + 操作语义”在 int / embstr / raw 之间自动选择;

  • 这种编码自适应机制,是 Redis 高性能与低内存占用的重要基础。

String 命令

  • SpringBoot 的 RedisTemplate<K,V>.opsForValue() 中 String 数据类型 的操作方法与 Redis 原生命令的对应关系如下:

普通设置

方法功能 方法 Redis 原始命令 备注
设置 key 的值 set(K key, V value) SET key value

条件写入(NX / XX)

方法功能 方法 Redis 原始命令 命令备注
key 不存在时设置 setIfAbsent(K key, V value) SET key value NX NX:key 不存在才设置
key 存在时设置 setIfPresent(K key, V value) SET key value XX XX:key 存在才设置

条件写入 + 过期时间

方法功能 方法 Redis 原始命令 命令备注
key 不存在时设置并指定过期时间 setIfAbsent(K key, V value, timeout, unit) SET key value NX EX seconds EX 秒 / PX 毫秒
key 存在时设置并指定过期时间 setIfPresent(K key, V value, timeout, unit) SET key value XX EX seconds

直接设置并指定过期时间

方法功能 方法 Redis 原始命令 命令备注 / 推荐替代
设置值并指定过期时间 set(K key, V value, timeout, unit) SETEX key seconds value 即将废弃 推荐SET key value EX seconds

保留 TTL 写入(KEEP_TTL)

方法功能 方法 Redis 原始命令 备注
设置新值并保留原 TTL 无直接方法 SET key value KEEPTTL Redis ≥ 6.0
1
2
3
4
5
6
7
8
9
10
public void setKeepTtl(String key, Object value) {
redisTemplate.execute((RedisCallback<Boolean>) connection ->
connection.stringCommands().set(
Objects.requireNonNull(redisTemplate.getStringSerializer().serialize(key)),
Objects.requireNonNull(((RedisSerializer<Object>) redisTemplate.getValueSerializer()).serialize(value)),
Expiration.keepTtl(),
RedisStringCommands.SetOption.UPSERT
)
);
}

普通读取

方法功能 方法 Redis 原始命令 备注
获取 key 的值 get(K key) GET key

读改写原子操作(GETEX / GETDEL)

方法功能 方法 Redis 原始命令 备注
获取值并重置过期时间 getAndExpire(K key, timeout, unit) GETEX key EX seconds Redis ≥ 6.2
GET + EXPIRE(非原子)
获取 key 的当前值并移除过期时间 getAndPersist(K key) GETEX key PERSIST Redis ≥ 6.2
GET + PERSIST(非原子)
获取值并删除 key getAndDelete(K key) GETDEL key Redis ≥ 6.2
GET + DEL(非原子)
获取旧值并设置新值 getAndSet(K key, V value) GETSET key value 即将废弃 推荐SET key value GET

字符串区间读取

方法功能 方法 Redis 原始命令 备注
获取字符串指定区间 get(K key, start, end) GETRANGE key start end
获取字符串长度 size(K key) STRLEN key

数值运算(计数器场景)

方法功能 方法 Redis 原始命令 备注
数值自增 1 increment(K key) INCR key value 必须是整数
数值增加指定值 increment(K key, delta) INCRBY key increment
数值自减 1 decrement(K key) DECR key
数值减少指定值 decrement(K key, delta) DECRBY key decrement

批量写入 / 读取

方法功能 方法 Redis 原始命令 备注
批量设置 key-value multiSet(map) MSET key value ... 非原子
批量获取 key 的值 multiGet(keys) MGET key ... 不存在返回 null

批量条件写入(原子)

方法功能 方法 Redis 原始命令 备注
批量设置(仅当全部不存在) multiSetIfAbsent(map) MSETNX key value ... 全成功 / 全失败

字符串追加操作

方法功能 方法 Redis 原始命令 备注
追加字符串并返回新长度 append(K key, String value) APPEND key value key 不存在等价于 SET