Redis string字符串底层结构SDS与常用命令详解

iPython
iPython
发布时间:2026-10-15| 4人浏览过
原创

Redis string 是最基础的数据类型,底层采用自定义的 SDS(简单动态字符串)实现。通过解析 SDS 的 len、free 与 buf 字段,可以清晰理解其内存布局与动态扩容机制。结合常用命令与典型场景,开发者能够更准确地选择数据类型并规避性能陷阱。

SDS 动态字符串结构解析

Redis 使用标准 C 语言编写,但在存储字符时并未直接使用 C 语言的字符数组,而是自定义了 SDS(Simple Dynamic String,简单动态字符串)。该结构可动态修改,行为类似于 Java 的 ArrayList。

SDS 的结构定义如下:

struct sdshdr{
     //记录buf数组中已使用字符的数量,等于 SDS 保存字符串的长度
     int len;
     //记录 buf 数组中未使用的字符数量
     int free;
     //字符数组,用于保存字符串
     char buf[];
};

从结构体可以看出,Redis string 将实际字符串内容存储在 buf[] 字符数组中,并通过 len 记录已使用长度,通过 free 记录未使用的预留空间。

下图展示了 SDS 字符串的结构示意图:

redis string结构

图1 中存储了一个 len 为 4 的字符串,buf 数组中按顺序保存字符数据,末尾以空字符 \0 结尾,以便兼容部分 C 语言字符串函数。

SDS 相比 C 字符串的优势

传统 C 字符串以 \0 判断结尾,获取长度需遍历整个数组,时间复杂度为 O(n)。SDS 通过 len 字段直接记录长度,获取字符串长度的时间复杂度降为 O(1)。

此外,free 字段提供了预分配空间的能力。当字符串需要追加内容时,若 free 足够,可直接写入而无需重新分配内存;若不足,SDS 会按策略扩容并更新 len 与 free。这种机制有效减少了内存重分配次数,提升了频繁修改场景下的性能。

Redis string 常用命令

Redis string 支持丰富的操作命令,覆盖基础存取、数值运算与批量处理:

  • SET key value:设置键值对
  • GET key:获取键对应的值
  • INCR key:将键值作为整数自增 1
  • DECR key:将键值作为整数自减 1
  • INCRBY key increment:按指定步长自增
  • DECRBY key decrement:按指定步长自减
  • MSET key1 value1 key2 value2:批量设置多个键值
  • MGET key1 key2:批量获取多个键的值
  • APPEND key value:在字符串末尾追加内容
  • STRLEN key:返回字符串长度

典型应用场景与注意事项

Redis string 适用于缓存简单对象、计数器、会话标识、分布式锁等场景。由于底层采用 SDS 并支持原子递增递减,string 类型在高并发计数与限流场景中表现稳定。

使用时需注意以下要点:

  • 单个 string 值的最大长度为 512MB,超大文本建议拆分或改用其他存储方案。
  • INCR 与 DECR 仅对可解析为整数的值有效,若值包含非数字字符将返回错误。
  • 频繁追加内容时,SDS 的预分配机制可降低内存碎片,但仍需关注整体内存使用量与淘汰策略。
  • 若需存储结构化数据,可考虑使用 Hash 类型而非将 JSON 字符串整体存入 string,以便按字段更新与节省内存。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。