# 常见Redis数据结构详解
## 一、Redis数据结构概述
Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它支持多种数据结构,这使得Redis不仅仅是一个简单的键值存储,而是一个功能丰富的数据结构服务器。Redis的数据结构设计是其核心优势之一,每种数据结构都针对特定场景进行了优化,提供了高效的操作性能。
### 1.1 Redis数据结构的重要性
Redis之所以在众多NoSQL数据库中脱颖而出,很大程度上得益于其丰富的数据结构支持:
- **性能卓越**:内存存储+高效数据结构实现,使Redis能达到极高的吞吐量
- **操作原子性**:所有单个命令都是原子操作,无需担心并发问题
- **多功能性**:不同数据结构支持不同业务场景,从缓存到消息队列都能胜任
- **扩展性**:通过组合基本数据结构,可以构建更复杂的数据模型
### 1.2 Redis数据模型特点
Redis的数据模型具有以下显著特点:
1. **键值存储**:所有数据都通过唯一的key访问
2. **类型丰富**:value支持多种数据结构类型
3. **单线程模型**:命令顺序执行,避免锁竞争
4. **持久化支持**:可将内存数据保存到磁盘
5. **过期机制**:支持设置键的生存时间
## 二、String(字符串)
### 2.1 基本概念
String是Redis最基本的数据类型,可以存储任何形式的数据,包括文本、序列化的对象或二进制数据。一个String类型的值最大能存储512MB的内容。
**主要特性**:
- 二进制安全,可以包含任何数据
- 支持丰富的操作命令
- 常用于缓存、计数器等场景
### 2.2 常用命令
```redis
SET key value [EX seconds] [PX milliseconds] [NX|XX]
GET key
INCR key
DECR key
APPEND key value
STRLEN key
GETRANGE key start end
SETRANGE key offset value
MSET key1 value1 [key2 value2 ...]
MGET key1 [key2 ...]
缓存系统:存储热点数据
SET user:1001 "{name:'John', age:25}"
GET user:1001
计数器:实现原子递增/递减
INCR article:1001:views
DECR inventory:product1001
分布式锁:利用SETNX实现
SETNX lock:order123 true
EXPIRE lock:order123 30
位操作:实现位图功能
SETBIT user:1001:login 5 1
GETBIT user:1001:login 5
Redis的String类型在底层通过简单动态字符串(SDS, Simple Dynamic String)实现,相比C字符串有以下优势:
Redis的List是一个双向链表结构,可以高效地在两端进行插入和删除操作,最大长度为2^32-1个元素。
主要特性: - 插入和删除操作高效 - 支持范围查询 - 可用于实现多种数据结构
LPUSH key value1 [value2 ...]
RPUSH key value1 [value2 ...]
LPOP key
RPOP key
LRANGE key start stop
LLEN key
LINDEX key index
LINSERT key BEFORE|AFTER pivot value
LREM key count value
LTRIM key start stop
消息队列:实现简单的生产者消费者模型
# 生产者
LPUSH queue task1
# 消费者
RPOP queue
最新消息排行:如朋友圈时间线
LPUSH user:1001:timeline "New post"
LRANGE user:1001:timeline 0 9
历史记录:存储用户最近浏览
LPUSH history:user1001 item123
LTRIM history:user1001 0 49
栈/队列:通过不同命令组合实现
# 栈 (LPUSH+LPOP)
# 队列 (LPUSH+RPOP)
Redis的List在底层有两种实现方式:
压缩列表(ziplist):当元素数量较少且元素较小时使用,是一块连续的内存空间
双向链表(linkedlist):元素较多时使用
Redis 3.2后引入quicklist,结合了ziplist和linkedlist的优点,是默认实现。
Redis的Hash是一个string类型的field和value的映射表,特别适合存储对象。
主要特性: - 适合存储对象 - 可以单独操作字段 - 高效存储和访问
HSET key field value
HGET key field
HDEL key field1 [field2 ...]
HEXISTS key field
HGETALL key
HKEYS key
HVALS key
HINCRBY key field increment
HLEN key
HMSET key field1 value1 [field2 value2 ...]
HMGET key field1 [field2 ...]
对象存储:存储用户信息等结构化数据
HSET user:1001 name "John" age 25 email "john@example.com"
HGET user:1001 name
商品属性:存储商品的不同属性
HMSET product:1001 name "Phone" price 599 stock 100
HINCRBY product:1001 stock -1
配置管理:存储系统配置项
HSET config:system timeout 30 max_connections 1000
HGETALL config:system
计数器组合:多个相关计数器
HINCRBY article:1001 stats views 1
HINCRBY article:1001 stats likes 1
Redis的Hash类型有两种底层实现:
ziplist:当哈希元素较少且元素较小时使用
hashtable:元素较多时使用
Redis会根据以下配置自动切换实现: - hash-max-ziplist-entries (默认512) - hash-max-ziplist-value (默认64字节)
Redis的Set是string类型的无序集合,通过哈希表实现,不允许重复元素。
主要特性: - 元素唯一性 - 支持集合运算 - 高效的成员检查 - 无序存储
SADD key member1 [member2 ...]
SREM key member1 [member2 ...]
SMEMBERS key
SCARD key
SISMEMBER key member
SRANDMEMBER key [count]
SPOP key [count]
SINTER key1 [key2 ...]
SUNION key1 [key2 ...]
SDIFF key1 [key2 ...]
标签系统:给对象打标签
SADD article:1001:tags tech redis database
SADD tag:redis:articles 1001
好友关系:存储共同好友
SADD user:1001:friends 1002 1003
SADD user:1002:friends 1001 1003
SINTER user:1001:friends user:1002:friends
唯一计数器:统计独立IP
SADD website:visitors 192.168.1.1 SCARD website:visitors
随机元素:抽奖系统
SADD lottery:users user1 user2 user3
SRANDMEMBER lottery:users 1
Redis的Set底层有两种实现:
intset:当集合中所有元素都是整数且元素数量较少时使用
hashtable:默认实现
转换条件由以下配置控制: - set-max-intset-entries (默认512)
Sorted Set是Redis中最复杂也最强大的数据结构之一,它在Set的基础上为每个元素关联了一个分数(score),使得元素可以按分数排序。
主要特性: - 元素唯一 - 按分数排序 - 支持范围查询 - 高效的元素排名查询
ZADD key [NX|XX] [CH] [INCR] score1 member1 [score2 member2 ...]
ZREM key member [member ...]
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANK key member
ZREVRANK key member
ZSCORE key member
ZCOUNT key min max
ZCARD key
ZINCRBY key increment member
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
排行榜系统:游戏积分排行
ZADD leaderboard 1000 player1 2000 player2
ZREVRANGE leaderboard 0 9 WITHSCORES
带权重的队列:优先级任务队列
ZADD tasks 1 "task1" 3 "urgent_task" 2 "task2"
ZRANGE tasks 0 0 WITHSCORES
范围查询:时间线数据
ZADD user:1001:posts 1625097600 "post1" 1625184000 "post2"
ZRANGEBYSCORE user:1001:posts 1625097600 1625184000
延迟队列:使用时间戳作为score
ZADD delay_queue <future_timestamp> "task_data"
# 定期查询到期任务
ZRANGEBYSCORE delay_queue 0 <current_timestamp>
Sorted Set底层使用两种数据结构组合实现:
跳跃表(skiplist):
字典(hashtable):
同时,当元素较少时,Redis会使用ziplist来节省内存,由以下配置控制: - zset-max-ziplist-entries (默认128) - zset-max-ziplist-value (默认64字节)
除了五种基本数据结构外,Redis还支持一些特殊的数据结构:
本质:实际上是String类型的扩展,提供位级别操作
常用命令:
SETBIT key offset value
GETBIT key offset
BITCOUNT key [start end]
BITOP operation destkey key [key ...]
BITPOS key bit [start] [end]
应用场景: - 用户签到记录 - 活跃用户统计 - 布隆过滤器实现
示例:
# 记录用户1001第5天签到
SETBIT user:1001:sign 5 1
# 统计本月签到次数
BITCOUNT user:1001:sign 0 30
本质:用于基数统计的概率算法
常用命令:
PFADD key element [element ...]
PFCOUNT key [key ...]
PFMERGE destkey sourcekey [sourcekey ...]
特点: - 极小的空间计算极大基数 - 标准误差0.81% - 不存储实际元素
应用场景: - 网站UV统计 - 大规模去重计数
示例:
PFADD visitors 192.168.1.1 192.168.1.2 PFCOUNT visitors
本质:基于Sorted Set实现的地理位置功能
常用命令:
GEOADD key longitude latitude member [longitude latitude member ...]
GEODIST key member1 member2 [unit]
GEOPOS key member [member ...]
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
应用场景: - 附近的人 - 地理位置查询 - 距离计算
示例:
GEOADD cities 116.405285 39.904989 "Beijing"
GEOADD cities 121.474490 31.230416 "Shanghai"
GEODIST cities Beijing Shanghai km
引入版本:Redis 5.0
本质:类似日志的数据结构,用于实现消息队列
常用命令:
XADD key [NOMKSTREAM] [MAXLEN|MINID [=|~] threshold [LIMIT count]] *|ID field value [field value ...]
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
XRANGE key start end [COUNT count]
XREVRANGE key end start [COUNT count]
XGROUP CREATE key groupname ID|$ [MKSTREAM]
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
特点: - 消息持久化 - 消费者组支持 - 消息回溯 - 阻塞读取
应用场景: - 消息队列 - 事件溯源 - 日志收集
示例:
# 生产者
XADD mystream * sensor-id 1234 temperature 19.8
# 消费者
XREAD BLOCK 0 STREAMS mystream $
数据特征:
操作模式:
性能需求:
内存效率:
数据结构 | 时间复杂度 | 主要优势 | 典型应用场景 |
---|---|---|---|
String | O(1) | 简单键值、位操作 | 缓存、计数器 |
List | 头尾操作O(1) | 顺序性、双端操作 | 队列、时间线 |
Hash | O(1) | 结构化数据存储 | 对象存储、配置 |
Set | O(1) | 唯一性、集合运算 | 标签、好友关系 |
Sorted Set | O(logN) | 排序、范围查询 | 排行榜、优先级队列 |
Bitmap | O(1) | 位操作、节省空间 | 签到、特征标记 |
HyperLogLog | O(1) | 基数统计、极小空间 | UV统计 |
Geo | O(logN) | 地理位置查询 | 附近的人 |
Stream | O(1)添加 O(N)读取 | 消息持久化、消费者组 | 消息队列 |
String:
List:
Hash:
Set:
Sorted Set:
Bitmap:
HyperLogLog:
Geo:
Stream:
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。