Redis有哪些数据类型,以及各自应用场景

一、数据类型

String(字符串)、Hash(哈希)、List(列表)、Set(集合)、zSet(有序集合)、HyperLogLog、Geo(地理信息)、Pub/Sub(发布订阅)
 

二、常用命令与常见应用场景

1、String(字符串)

set(设置键值)、setnx(键不存在时设置值,可实现分布式锁基础)、get(获取键值)、decr(数值减1)、incr(数值加1)、mget(批量获取多键值)、expire(设置键过期时间)

常见应用场景:

缓存层:作为MySQL等存储层的前置缓存,减轻数据库压力。例如缓存热门商品信息,需注意设置合理的过期时间,避免数据不一致。

计数器:适用于视频播放数、博客浏览数、商品销量等场景。通过incr/decr命令实现原子性计数,确保数据准确性。

共享Session:在分布式系统中,将用户Session数据存储到Redis,实现多服务间Session共享,需配合expire命令设置Session有效期。

限时短信验证码:通过set命令存储验证码,并使用expire命令设置60秒/120秒等过期时间,避免验证码重复使用,原文未提及过期时间设置,此处补充关键操作。

 

2、Hash(哈希)

hset(设置哈希表字段值)、hget(获取哈希表字段值)、hdel(删除哈希表字段)、hlen(获取哈希表字段数量)、hexists(判断哈希表字段是否存在)、hkeys(获取哈希表所有字段名)、hvals(获取哈希表所有字段值)、hgetall(获取哈希表所有字段和值)、hincrby(哈希表字段数值增减,补充命令,用于数值型字段)

常见应用场景:

存储用户信息或商品信息:相较于String存储整个用户JSON串,Hash可按字段(如username、age、phone)单独存储和修改用户属性,减少数据传输量和修改开销。例如存储用户个人资料,更新用户年龄时仅需执行hset key age 25,无需更新整个用户数据。

 

3、List(列表)

lpush(从列表左侧插入元素)、rpush(从列表右侧插入元素)、lpop(从列表左侧弹出元素)、rpop(从列表右侧弹出元素)、brpop(阻塞式从列表右侧弹出元素,无元素时阻塞等待)、lrange(获取列表指定范围元素)、lindex(获取列表指定索引元素)、llen(获取列表长度,原文“len”为命令错误,修正为“llen”)、lrem(删除列表中指定元素)、ltrim(截取列表指定范围元素,保留范围内元素)

常见应用场景:

关注列表/粉丝列表:例如用户A的关注列表,通过lpush将关注的用户ID加入列表,lrange获取分页的关注列表数据。

消息队列:

  • lpush + lpop = 栈(先进后出),适用于简单的任务栈场景。
  • lpush + rpop = 队列(先进先出),基础消息队列,但存在“消息丢失”风险(弹出元素后未处理完成服务宕机),需结合业务做消息确认机制。
  • lpush + ltrim = 有限集合,例如保留最近100条热门评论,超出部分通过ltrim截取。
  • lpush + brpop = 阻塞式消息队列,避免轮询空列表浪费资源,适用于需实时处理消息的场景。

简单分页查询:利用lrange key start end命令实现,例如lrange article_comments 0 9获取文章的前10条评论,但仅适用于数据量较小的分页场景,大数据量分页需结合其他方案(如zSet)。

 

4、Set(集合)

sadd(向集合添加元素)、spop(随机弹出集合一个元素)、sismember(判断元素是否在集合中)、srem(删除集合中指定元素)、sunion(求多个集合的并集)、sdiff(求多个集合的差集)、sinter(求多个集合的交集,原文未提及,补充关键命令)、scard(获取集合元素数量,补充命令)

常见应用场景:

标签系统:存储用户兴趣标签(如“篮球”“电影”),通过sinter获取多个用户的共同兴趣标签,实现个性化推荐(如推荐同标签用户喜欢的小说、视频)。

随机抽奖:通过spop随机弹出集合中的元素(如用户ID),确保抽奖公平性;也可使用srandmember命令(补充命令)随机获取元素且不删除,适用于“展示中奖用户但不立即移除”场景。

社交需求:例如“共同好友”功能,通过sinter计算两个用户粉丝集合的交集;“好友推荐”功能,通过sdiff计算“我关注的人关注的人”与“我的好友”的差集。

 

5、zSet(有序集合)

zadd(向有序集合添加元素,指定score)、zcard(获取有序集合元素数量)、zscore(获取元素的score值)、zrank(获取元素在有序集合中的排名,按score升序)、zrevrank(按score降序获取排名,原文未提及,补充常用命令)、zrem(删除有序集合中的元素)、zincrby(为元素的score值增减)、zrange(按score升序获取指定范围元素)、zrevrange(按score降序获取指定范围元素,补充命令,用于榜单场景)

常见应用场景:

各类榜单:例如视频播放量榜单(score为播放量)、文章获赞榜单(score为点赞数),通过zrevrange key 0 9获取Top10数据;也可通过zrangebyscore命令(补充命令)获取指定score范围内的元素(如“播放量大于1000的视频”)。

使用冒号(:)进行层级划分,格式建议为“业务模块:表名:主键:字段”,例如“user:info:1001:name”“video:rank:202409:play_count”,确保Key语义清晰,便于后续维护、统计与排查问题,避免Key命名混乱(如“user1001name”)。

 

6、HyperLogLog

pfadd(向HyperLogLog添加元素)、pfcount(估算HyperLogLog的基数)、pfmerge(合并多个HyperLogLog,计算总基数)

常见应用场景:

用户访问量统计(UV):统计某个页面的独立访客数,无需存储每个用户ID,仅需通过pfadd记录用户标识(如用户ID、CookieID),pfcount快速估算UV。

相较于Set,HyperLogLog固定占用约12KB内存(无论元素数量多少),而Set存储千万级用户ID会占用GB级内存,极大节省资源。需注意:HyperLogLog是“估算值”,误差约0.81%,适用于对精度要求不高的统计场景(如UV),不适用于精确统计(如订单数)

 

7、Geo(地理信息)

geoadd(添加地理位置坐标,格式:geoadd key 经度 纬度 地点标识)、geopos(获取地点的经纬度坐标)、geodist(计算两个地点的距离,支持m/km/mi/ft单位)、georadius(根据指定经纬度和半径,获取范围内的地点集合)、georadiusbymember(根据集合中已有地点,获取其周围指定半径内的地点,原文未提及,补充常用命令)、geohash(将经纬度转换为geohash字符串,便于存储和比较)

常见应用场景:

周边服务:如美团外卖“附近的商家”、高德地图“周边加油站”,在数据库中存储商家/加油站的经纬度,通过geoadd将数据导入Redis,再通过georadius(传入用户当前经纬度)获取5公里内的目标地点,并可按距离排序(结合zSet特性,geo底层基于zSet实现)。

 

8、Pub/Sub(发布订阅)

publish(向指定频道发布消息)、subscribe(订阅指定频道)、unsubscribe(取消订阅指定频道)、psubscribe(订阅符合模式的频道,如“news:*”,补充命令)

常见应用场景:

消息通知:实际应用场景较少,因存在“消息丢失”问题(订阅者离线后无法接收离线期间的消息),不适用于关键业务(如订单通知)。适用于非关键的实时通知场景(如“系统公告推送”)

内部机制支撑:Redis哨兵机制中,哨兵节点通过Pub/Sub订阅主从节点的频道,实时获取节点状态变化(如主节点故障),实现哨兵间的通信与协调。