尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Redis String 数据类型详解

Redis String 数据类型详解 Redis String 数据类型详解String 是 Redis 中最基础、使用最广泛的数据类型其余 4 种核心数据结构Hash、List、Set、ZSet均构建于 String 类型之上。它以 key-value 键值对形式存储value 层对外表现为字符串底层支持整数、浮点数、普通文本、二进制数据等多种形态具备高性能、原子性、二进制安全等核心优势。一、核心基础特性1. 二进制安全Redis String 不依赖 C 语言的\0作为字符串结束标志存储与读取完全按照字节长度处理因此可以安全存储图片、序列化对象、加密串等任意二进制数据不会因特殊字符出现内容截断。2. 容量上限单个 key 对应的 value 最大支持512MB存储但工程实践中强烈不建议存储过大的 value通常控制在 10KB 以内避免阻塞 Redis 主线程。3. 多语义自动适配同一个 String 类型会根据 value 内容自动适配存储语义纯整数64位有符号范围内支持原子加减运算浮点数支持浮点原子增量普通字符串/二进制支持拼接、截取、位操作4. 三种编码模式内存优化核心Redis 会根据 value 的内容和长度自动选择三种编码方式存储最大化节省内存可通过OBJECT ENCODING key命令查看当前编码。编码类型触发条件存储特点intvalue 为 64 位有符号整数范围内的数字直接将数值存储在 redisObject 的ptr字段无需额外 SDS 内存内存占用最小、访问最快embstr嵌入式字符串字符串长度 ≤ 44 字节Redis 3.2旧版为 39 字节redisObject 与 SDS 结构体在同一块连续内存中分配仅需一次内存申请减少内存碎片访问速度快属于只读优化修改时会自动转为 raw 编码raw原始字符串字符串长度 44 字节redisObject 与 SDS 分离存储两次内存分配支持灵活修改编码转换规则int 编码的 key若追加字符串、修改为非整数会转为 raw/embstrembstr 编码的 key执行任何修改操作如 APPEND、SETRANGE都会转为 raw 编码数值超过 long 范围如超长数字字符串会自动转为 embstr/raw 编码。二、核心命令分类详解1. 基础读写命令SET设置键值对最核心命令SETkey value[EXseconds][PXmilliseconds][EXATtimestamp][PXATms-timestamp][NX|XX][KEEPTTL]常用参数说明EX seconds设置过期时间秒PX milliseconds设置过期时间毫秒NX仅当 key不存在时才设置成功原子性创建常用于分布式锁XX仅当 key已存在时才设置成功原子性更新KEEPTTL保留该 key 原有的过期时间不被新 SET 覆盖示例# 普通设置SETusernamezhangsan# 设置值并指定1小时过期SETuser:1001{id:1001,age:20}EX3600# 原子加锁key不存在才创建30秒自动过期SETlock:order:1001random_uuidNXEX30GET获取值GET keyGET 是 String 类型专属的读取命令只能读取类型为 String 的 key。key 不存在时返回nil若 value 非字符串类型会报错。nil是 Redis 的空值标记代表这个 key 不存在没有对应的数据。GETSET设置新值并返回旧值语法GETSETkey newValue 例子127.0.0.1:6379getset testhello(nil)因为从未设置过 test所以返回结果是nil但是此时已经设置了 test 值为 hello127.0.0.1:6379get testhello127.0.0.1:6379getset testhellwhello127.0.0.1:6379get testhellw127.0.0.1:6379原子操作常用于「获取当前值并重置」场景例如计数器清零。APPEND字符串追加APPENDkey appendValue在字符串末尾追加内容返回追加后的总字节长度key 不存在时等同于 SETString 类型专属命令非 String 类型的 key 执行会报类型错误STRLEN获取字符串长度STRLENkey返回字节数注意 UTF-8 中文每个字符占 3 字节。GETRANGE / SETRANGE子串操作# 获取[start,end]闭区间子串支持负数索引-1表示最后一个字节 语法GETRANGEkey start end补充end 超过最大索引时Redis会自动截断到字符串末尾不会报错。 例子SETdemoHelloRedisGETRANGEdemo-5-1-1最后一个字节末尾的 s-5代表倒数第5个字节开头的R-----------------------------------------# 从 offset 位置开始覆盖写入 value返回修改后总长度 语法SETRANGEkey offset value 例子SETdemoHelloSETRANGEdemo3123456返回结果(integer)9GETdemo 返回结果Hel123456注意SETname你好GETRANGEname03会返回乱码因为 “你” 占0~2字节第3字节是 “好” 的第一个字节被截断了。2. 数值原子操作单线程保证原子性Redis 单线程模型保证所有数值命令都是原子操作并发场景下不会出现竞态问题是实现计数器的核心方案。命令作用示例INCR key值自增 1key 不存在则从 0 开始自增返回自增后结果INCR article:100:viewsDECR key值自减 1DECR stock:1001INCRBY key increment增加指定整数增量INCRBY score:user:1001 10DECRBY key decrement减少指定整数减量DECRBY stock:1001 5INCRBYFLOAT key increment增加浮点数增量支持正负值INCRBYFLOAT price 0.5注意不存在对应DECRBYFLOAT可通过传入负增量实现减法。3. 批量操作命令减少网络IO批量命令可一次网络往返完成多个 key 的操作大幅降低 RTT 开销提升性能。MSET批量设置MSETkey1 value1 key2 value2 key3 value3...原子操作所有 key 要么全部设置成功要么全部失败。MGET批量获取MGETkey1 key2 key3...按顺序返回对应 value不存在的 key 返回nil。MSETNX批量不存在时设置MSETNXkey1 value1 key2 value2...仅当所有 key 都不存在时才全部设置成功具备原子性可用于批量分布式锁抢占。4. 位图 Bitmap 操作String 类型支持按位操作即 Bitmap位图将 value 的每个字节拆分为 8 个二进制位可实现海量布尔状态的极低内存存储1 亿个布尔状态仅需约 12MB 内存。命令作用SETBIT key offset value设置第 offset 位的值0 或 1GETBIT key offset获取第 offset 位的值BITCOUNT key [start end]统计指定字节范围内值为 1 的位总数BITOP operation destkey key1 key2...对多个 key 执行位运算AND/OR/XOR/NOT结果存入 destkeyBITPOS key bit [start end]查找第一个值为 0/1 的位的偏移量四、典型业务应用场景1. 热点数据缓存最主流的用法缓存用户信息、商品详情、配置参数、页面片段等热点数据降低数据库访问压力。SETproduct:2001{id:2001,name:手机,price:3999}EX18002. 计数器与统计利用 INCR 原子性实现文章阅读量、点赞数、接口调用量、库存计数等场景天然支持高并发。# 文章阅读量1INCRarticle:500:views3. 分布式锁基于SET key value NX EX timeout实现原子加锁配合随机 value 实现安全解锁是轻量级分布式锁的标准实现方案。4. 会话共享Session 存储分布式系统中将用户登录态、Token 存入 Redis String设置过期时间实现多服务实例共享会话。SETtoken:abc123xyz user:1001EX72005. 接口限流以「用户ID 接口 时间窗口」为 key通过 INCR 累加访问次数超过阈值则拒绝访问配合过期时间实现固定窗口限流。6. 海量布尔状态统计利用 Bitmap 实现用户签到、在线状态、日活/月活统计、用户标签等场景内存占用极低。例如按用户 ID 作为偏移量记录每日签到# 用户ID1001在2026年8月3日签到SETBITsign:20260810011# 统计8月全月签到天数BITCOUNTsign:202608五、最佳实践与注意事项1. 避免大 Key 问题单个 String value 建议控制在10KB 以内过大的 value 会导致网络传输慢、Redis 命令阻塞、内存碎片严重。若需存储大对象优先考虑拆分到 Hash 结构或进行压缩后存储。2. 利用编码优化内存数值类型直接存储为数字不要包裹引号或冗余前缀确保触发 int 编码最大化节省内存。短字符串场景尽量避免频繁修改防止 embstr 转 raw 带来的内存开销。3. 保障操作原子性计数场景必须使用 INCR/DECR 系列命令禁止使用「GET SET」的读写分离模式并发下会出现数据不一致。设置带过期时间的 key优先使用SET ... EX一条命令完成而非 SET EXPIRE 两条命令避免中间异常导致永久不过期。4. 批量操作注意边界多 key 读写优先使用 MSET/MGET 减少网络开销但单次批量 key 数量建议控制在 500 以内避免单条命令过大阻塞 Redis。批量操作仅适用于同类型 key不支持跨数据结构。5. Bitmap 使用注意SETBIT的 offset 是位偏移量过大的 offset 会触发一次性内存分配可能导致短时阻塞避免使用超大偏移量必要时提前分桶拆分。Bitmap 适合海量稀疏度低的场景稀疏度过高时内存收益反而下降。下面逐个命令给你跑一遍实际执行流程能直观看到命令输入、返回结果和最终效果例子1. INCR值自增 1场景统计文章浏览量每有一次访问就计数 1。初始状态Redis 中没有article:100:views这个 key。第一次执行INCRarticle:100:views返回结果(integer) 1说明key 不存在时默认从 0 开始自增自增后结果为 1。第二次执行再来一次访问INCRarticle:100:views返回结果(integer) 2验证当前值GETarticle:100:views返回22. DECR值自减 1场景商品库存扣减每卖出 1 件库存就 -1。先设置初始库存 100 件SETstock:1001100卖出 1 件执行自减DECRstock:1001返回结果(integer) 99说明在 100 的基础上减 1剩余库存 99。补充如果 key 不存在会自动从 0 开始减DECRtest:notexist返回(integer) -13. INCRBY增加指定整数增量场景给用户增加积分一次加 10 分。初始用户积分为 0key 不存在INCRBYscore:user:100110返回结果(integer) 10说明从 0 开始加 10当前积分为 10。再增加 20 积分INCRBYscore:user:100120返回结果(integer) 30说明10 20 30。4. DECRBY减少指定整数减量场景一次卖出 5 件商品批量扣减库存。先重置库存为 100SETstock:1001100一次性扣减 5 件DECRBYstock:10015返回结果(integer) 95说明100 - 5 95剩余库存 95。5. INCRBYFLOAT增加浮点数增量场景调整商品价格支持小数金额的增减。设置初始价格为 10.0SETprice10.0涨价 0.5 元INCRBYFLOATprice0.5返回结果10.5说明10.0 0.5 10.5注意返回的是字符串格式的浮点数。降价 1.2 元传负数即可实现减法INCRBYFLOATprice-1.2返回结果9.3说明10.5 - 1.2 9.3。Redis 没有专门的浮点数减法命令用负增量就能实现。补充注意以上所有命令都是原子操作高并发场景下不会出现计算错误如果 key 里存的不是数字比如存了abc执行这些命令会直接报错INCR/DECR/INCRBY/DECRBY 只能操作整数INCRBYFLOAT 可以操作整数和浮点数。
返回列表