Redis 字符串(String)
Redis 的字符串类型是最基本的数据类型,可以存储任何形式的字符串,包括文本、数字、二进制数据等。下面是一些使用字符串的常见场景及其底层实现。
场景示例
-
存储简单的键值对
- 示例:
SET key "value" GET key
- 说明:将键
key
的值设置为value
,然后获取该值。
- 示例:
-
计数器
- 示例:
INCR page_view_count GET page_view_count
- 说明:将键
page_view_count
的值增加 1,用于记录页面浏览次数。
- 示例:
-
存储二进制数据
- 示例:
SET image_data "\x89PNG..." GET image_data
- 说明:可以存储二进制数据,如图像或文件。
- 示例:
-
过期时间的键值
- 示例:
SET session_token "abc123" EX 3600 GET session_token
- 说明:设置键
session_token
的值并设置过期时间为 3600 秒。
- 示例:
-
批量操作
- 示例:
MSET key1 "value1" key2 "value2" MGET key1 key2
- 说明:一次性设置多个键值对,并获取多个键的值。
- 示例:
-
字符串操作
- 示例:
APPEND key "suffix" GETRANGE key 0 4
- 说明:将字符串
suffix
附加到key
的值末尾,并获取key
的部分值。
- 示例:
-
位操作
- 示例:
SETBIT bitkey 7 1 GETBIT bitkey 7 BITCOUNT bitkey
- 说明:使用位操作设置、获取和统计位。
- 示例:
-
数值操作
- 示例:
INCRBYFLOAT price 12.34 DECR quantity
- 说明:对数值进行增减操作。
- 示例:
底层实现
Redis 字符串类型的底层实现主要依赖于 SDS
(Simple Dynamic String,简单动态字符串)。SDS
是 Redis 对 C 语言 char
数组的封装,提供了更安全、更高效的字符串操作。以下是 SDS
的实现特点:
-
动态扩展:
SDS
支持动态扩展,字符串增长时会自动分配足够的空间,减少内存分配次数。- 示例代码:
struct sdshdr { int len; // 已使用长度 int free; // 可用空间 char buf[]; // 数据缓冲区 };
-
二进制安全:
SDS
可以存储任意二进制数据,包括空字符,因为它通过len
属性记录字符串长度,而不是以空字符结尾。
-
预分配:
SDS
在扩展时会预分配空间,减少后续扩展的内存分配开销。- 扩展规则:如果新长度小于 1MB,则分配两倍的新长度;否则分配 1MB 的增量空间。
-
兼容 C 字符串:
SDS
可以与 C 字符串兼容,buf
末尾始终保留一个空字符,但不计入len
。
-
内存效率:
SDS
通过合理的内存管理和扩展策略,减少了内存碎片,提高了内存利用效率。
SDS
使得 Redis 在处理字符串时既能保持高性能,又能避免 C 语言 char
数组的常见问题,如缓冲区溢出和频繁的内存分配。通过这些特性,Redis 能够高效地处理各种字符串操作,包括存储、获取、计数、字符串拼接、位操作和数值操作。