跳到主要内容
Redis 常用数据结构操作指令与场景应用详解 | 极客日志
编程语言 算法
Redis 常用数据结构操作指令与场景应用详解 Redis 作为 KV 数据库提供五种基础数据结构及扩展结构。String 用于存储文本或二进制数据,支持原子计数和过期控制;List 基于双向链表实现队列和栈;Hash 适合存储对象属性;Set 用于去重和集合运算;ZSet 基于跳表实现有序集合和排行榜。此外还包括 Bitmap 位图和 Geo 地理空间扩展。Key 管理推荐使用 SCAN 而非 KEYS 以避免阻塞。内容涵盖各结构的原理、核心指令、存储机制及典型应用场景。
监控大屏 发布于 2026/3/16 更新于 2026/4/29 14 浏览Redis 概述
key:string
value:5 大基础核心结构 String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Sorted Set/ZSet(有序集合)。
【另外还有 位图(Bitmap) 、地理空间(Geo) 等常用扩展结构(基于基础结构实现)】
String
结构说明
Redis 最基础、最常用的数据结构,值可以是字符串、数字(整数 / 浮点数)、二进制数据(如图片、序列化对象),单个 String 最大支持 512MB。
特点:
字符数组,该字符串是动态字符串 raw,字符串长度小于 1M 时加倍扩容;超过 1M 每次只多扩 1M;字符串最大长度为 512M;
(注意:redis 字符串是二进制安全字符串(通过 len 来判断结尾而非 '\0' );可以存储图片、二进制协议等二进制数据)
**存储结构:**字符串长度小于等于 20 且能转成整数,则使用 int 存储;字符串长度小于等于 44,则使用 embstr 存储;字符串长度大于 44,则使用 raw 存储;
核心操作指令
指令 语法格式 指令说明 SET `SET key value [EX seconds] [PX milliseconds] [NX XX]` (EX、PX、NX、XX 顺序可以打乱) GET GET key获取指定键的值,键不存在返回 nil INCR INCR key对键的整数值进行原子自增 1 ,键不存在则先初始化为 0 再自增 DECR DECR key对键的整数值进行原子自减 1 ,键不存在则先初始化为 0 再自减 INCRBY INCRBY key increment原子自增指定数值(increment 可为正 / 负,等效于批量 INCR/DECR) DECRBY DECRBY key decrement原子自减指定数值 SETEX SETEX key seconds value简化版:设置键值对并指定过期时间(秒),等效于 SET + EX SETNX SETNX key value简化版:仅当键不存在时设置值,等效于 SET + NX MSET MSET key1 value1 key2 value2 ...批量设置多个键值对,原子操作 MGET MGET key1 key2 ...批量获取多个键的值,提升查询效率(减少网络请求)
典型应用场景
分布式锁 :
SETEX sms:138xxxx1234 300 "123456"
计数器系统(累加器) :文章阅读量、视频播放量、接口调用次数。
单值数据缓存 :缓存商品详情、用户基本信息、首页热点数据。如果数据不常改动,可以设置多个属性(json 格式)
SET role:10002 '{["name"]:"dcf",["sex"]:"male",["age"]:3}'
List
结构说明 有序、可重复的元素集合,基于双向链表 实现,两端操作(头部 / 尾部)性能极高,中间插入 / 删除性能较差,适合存储有序的序列数据。
特点:
双向链表实现,列表首尾操作(删除和增加)时间复杂度 O(1);查找中间元素时间复杂度为 O(n);
存储结构:
列表中数据是否压缩的依据:元素长度小于 48,不压缩;元素压缩前后长度差不超过 8,不压缩;
核心操作指令 指令 语法格式 指令说明 LPUSH LPUSH key value1 [value2 ...]从列表 头部(左侧) 插入一个 / 多个元素 RPUSH RPUSH key value1 [value2 ...]从列表 尾部(右侧) 插入一个 / 多个元素 LPOP LPOP key从列表头部 弹出并删除一个元素,列表为空返回 nil RPOP RPOP key从列表尾部 弹出并删除一个元素,列表为空返回 nil LRANGE LRANGE key start stop获取列表中「start 到 stop」区间的元素(索引从 0 开始,stop=-1 表示获取所有元素) LLEN LLEN key获取列表的元素总个数 BRPOP BRPOP key [key2 ...] timeout阻塞式从列表尾部弹出元素(列表为空时,阻塞等待 timeout 秒,timeout=0 表示永久阻塞),适合消息队列 LREM LREM key count value删除列表中 count 个值为 value 的元素(count>0 从头部删,count<0 从尾部删,count=0 删除所有) LTRIM LTRIM key start stop裁剪列表,仅保留「start 到 stop」区间的元素,删除其他元素(用于限制列表长度)
典型应用场景
异步消息队列 :操作与队列一样,但是在不同系统间;生成者和消费者;
分页查询(旧数据) :对于无需复杂筛选的历史数据(如用户历史订单列表),可通过 LRANGE 实现简单分页(不适合高频更新、大数据量的分页场景)。
最新消息 / 动态列表 :朋友圈动态、文章评论列表、系统通知列表。
RPUSH moments:1001 "动态 1" "动态 2" ltrim moments:1001 0 99
Hash
结构说明 用于存储键值对集合 (类似 Java 中的 Map、Python 中的 dict),适合存储单个对象的多个属性,可单独操作对象的某个字段,无需修改整个对象。
特点:
散列表,在很多高级语言当中包含这种数据结构;c++ unordered_map 通过 key 快速索引 value;
**存储结构:**节点数量大于 512(hash-max-ziplist-entries)或所有字符串长度大于 64(hash-max-ziplist-value),则使用 dict 实现;节点数量小于等于 512 且有一个字符串长度小于 64,则使用 ziplist 实现
核心操作指令 指令 语法格式 指令说明 HSET HSET key field value [field2 value2 ...]给指定哈希表设置一个 / 多个字段 - 值对,字段不存在则新增,存在则更新 HGET HGET key field获取哈希表中指定字段的值 HMSET HMSET key field value [field2 value2 ...]批量设置哈希表字段(Redis 3.0 后可直接用 HSET 替代) HMGET HMGET key field [field2 ...]批量获取哈希表中多个字段的值 HGETALL HGETALL key获取哈希表中所有字段和对应的值(返回键值对列表) HDEL HDEL key field [field2 ...]删除哈希表中一个 / 多个字段 HLEN HLEN key获取哈希表中字段的总个数 HKEYS HKEYS key获取哈希表中所有字段名 HVALS HVALS key获取哈希表中所有字段对应的值 HEXISTS HEXISTS key field判断哈希表中指定字段是否存在,返回 1(存在)/ 0(不存在)
典型应用场景 对比 string 存储 json 格式 ,hash 存储的对象使用于频繁更改属性的场景
hmset user name dcf age 18 sex male
对象数据存储 :存储用户信息、商品属性、购物车功能、配置信息存储
Set
结构说明 无序、不可重复的元素集合,基于哈希表实现,支持高效的去重和集合运算(交集、并集、差集),单个元素最大支持 512MB。
**特点:**集合;用来存储唯一性字段,不要求有序;存储不需要有序,操作(交并差集的时候排序)
**存储结构:**元素都为整数且节点数量小于等于 512(set-max-intset-entries),则使用整数数组存储;元素当中有一个不是整数或者节点数量大于 512,则使用字典存储
核心操作指令 指令 语法格式 指令说明 SADD SADD key member1 [member2 ...]向集合中添加一个 / 多个元素,重复元素自动去重 SMEMBERS SMEMBERS key获取集合中所有元素(无序返回) SISMEMBER SISMEMBER key member判断元素是否在集合中,返回 1(存在)/ 0(不存在) SREM SREM key member1 [member2 ...]从集合中删除一个 / 多个元素 SCARD SCARD key获取集合中元素的总个数 SINTER SINTER key1 [key2 ...]获取多个集合的交集 (所有集合中都存在的元素) SUNION SUNION key1 [key2 ...]获取多个集合的并集 (所有集合中的不重复元素) SDIFF SDIFF key1 [key2 ...]获取多个集合的差集 (在 key1 中存在,在其他集合中不存在的元素) SRANDMEMBER SRANDMEMBER key [count]从集合中随机获取 count 个元素(不删除元素,count 缺省为 1) SPOP SPOP key [count]从集合中随机弹出并删除 count 个元素
典型应用场景 SADD lottery:2026 1001 1002 ...,SPOP lottery:2026 3
SINTER user:friends:1001 user:friends:1002
数据去重 :用户点赞列表、文章收藏列表、签到记录去重、黑白名单系统
SADD article:like:1001 1001 1002
ZSet
结构说明 有序、不可重复的元素集合,每个元素关联一个浮点型分数(score) ,Redis 按 score 从小到大排序(可反向排序),支持按 score 范围和排名查询,兼顾了 Set 的去重特性和 List 的有序特性。
特点:
有序集合;用来实现排行榜;它是一个有序唯一;
**存储结构:**节点数量大于 128 或者有一个字符串长度大于 64,则使用跳表(skiplist);节点数量小于等于 128(zset-max-ziplist-entries)且所有字符串长度小于等于 64(zset-max-ziplist-value),则使用 ziplist 存储;
**复杂度:**数据少的时候,节省空间;O(n) 数量多的时候,访问性能;O(1) or O(log_{2}{n})
核心操作指令 指令 语法格式 指令说明 ZADD ZADD key score1 member1 [score2 member2 ...]向有序集合中添加一个 / 多个元素,score 为排序依据,重复 member 会更新其 score ZRANGE ZRANGE key start stop [WITHSCORES]按 score从小到大 获取「start 到 stop」区间的元素,WITHSCORES 同时返回元素和对应的 score ZREVRANGE ZREVRANGE key start stop [WITHSCORES]按 score从大到小 获取区间元素(适合排行榜倒序查询) ZRANGEBYSCORE ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]按 score 范围获取元素(min/max 可使用 ( 表示开区间,如 (100 表示大于 100) ZINCRBY ZINCRBY key increment member给指定元素的 score 原子增减指定数值(increment 可为正 / 负) ZREM ZREM key member1 [member2 ...]从有序集合中删除一个 / 多个元素 ZCARD ZCARD key获取有序集合中元素的总个数 ZSCORE ZSCORE key member获取指定元素对应的 score 值 ZRANK ZRANK key member获取指定元素的排名(从小到大,排名从 0 开始) ZREVRANK ZREVRANK key member获取指定元素的排名(从大到小,排名从 0 开始)
典型应用场景 时间窗口限流 :
系统限定用户的某个行为在指定的时间范围内(动态)只能发生 N 次;
local function is_action_allowed (red, userid, action, period, max_count)
local key = tab_concat({"hist" , userid, action}, ":" )
local now = redis.time ()[1 ]
red:init_pipeline()
red:zadd(key, now, now)
red:zremrangebyscore(key, 0 , now - period *100 )
red:zcard(key)
red:expire(key, period + 1 )
local res = red:commit_pipeline()
return res[3 ] <= max_count
end
分布式定时器 :
生产者将定时任务 hash 到不同的 redis 实体中,为每一个 redis 实体分配一个 dispatcher 进程,用来定时获取 redis 中超时事件并发布到不同的消费者中;
延时队列 :将任务的执行时间戳作为 score,消费者定期通过 ZRANGEBYSCORE 获取当前时间之前的任务执行。
ZADD delay:queue 1735660800 task:1001
各类排行榜系统 :销量榜、积分榜、热度榜、游戏天梯榜
ZADD goods:sales 100 goods:1001 200 goods:1002 ZREVRANGE goods:sales 0 9 WITHSCORES
常用扩展数据结构
位图(Bitmap)
结构说明 并非独立数据结构,基于 String 实现 ,按「位」存储数据,每个位只能是 0 或 1,极大节省内存空间(1 个字节 = 8 位,可存储 8 个状态)。
核心操作指令 指令 语法格式 指令说明 SETBIT SETBIT key offset value设置指定偏移量(offset,从 0 开始)的位值(0/1) GETBIT GETBIT key offset获取指定偏移量的位值 BITCOUNT BITCOUNT key [start end]统计位图中 1 的个数(start/end 为字节索引,可选) BITOP BITOP operation destkey key1 [key2 ...]位图运算(AND/OR/XOR/NOT),结果存入 destkey
典型应用场景
批量状态判断(如判断用户是否领取过某类优惠券,1 表示已领取,0 表示未领取)。
活跃度统计
SETBIT user:sign:1001 0 1
地理空间(Geo)
结构说明 并非独立数据结构,基于 ZSet 实现 ,用于存储经纬度坐标,支持距离计算、附近地点查询等地理空间操作。
核心操作指令 指令 语法格式 指令说明 GEOADD GEOADD key longitude latitude member [lon2 lat2 member2 ...]添加地理位置(经度、纬度、地点名称) GEOPOS GEOPOS key member1 [member2 ...]获取指定地点的经纬度坐标 GEODIST GEODIST key member1 member2 [unit]计算两个地点之间的距离(unit 可选:m 米、km 千米,默认 m) GEORADIUS GEORADIUS key longitude latitude radius unit [WITHDIST] [WITHCOORD]根据指定经纬度,查询半径范围内的地点(WITHDIST 返回距离,WITHCOORD 返回坐标) GEOSEARCH `GEOSEARCH key FROMMEMBER member BYRADIUS radius unit [ASC DESC]`
指令 语法格式 指令说明 GEOADD GEOADD key longitude latitude member [lon2 lat2 member2 ...]添加地理位置(经度、纬度、地点名称) ・限制:经度范围 -180~180,纬度范围 -85.05112878~85.05112878(超出会报错) ・返回值:成功添加的 member 数量 GEOPOS GEOPOS key member1 [member2 ...]获取指定地点的经纬度坐标 ・返回值:每个 member 对应 [经度,纬度] 数组;不存在的 member 返回 nil GEODIST GEODIST key member1 member2 [unit]计算两个地点之间的距离 • unit 可选值:m(米,默认)、km(千米)、mi(英里)、ft(英尺) • 返回值:距离字符串(如 "1.5210");任意 member 不存在则返回 nil GEORADIUS `GEORADIUS key longitude latitude radius unit [WITHDIST] [WITHCOORD] [WITHHASH] [COUNT count] [ASC DESC]` GEOSEARCH `GEOSEARCH key [FROMMEMBER member FROMLONLAT lon lat] [BYRADIUS radius unit GEOSEARCHSTORE `GEOSEARCHSTORE destkey sourcekey [FROMMEMBER member FROMLONLAT lon lat] [BYRADIUS radius unit
补充说明: GEORADIUS 是旧版指令(Redis <6.2),GEOSEARCH 是新版替代指令(更推荐);单位支持 m(米)、km(公里)、mi(英里)、ft(英尺);WITHDIST 会返回距离数值,ASC 表示按距离由近到远排序(DESC 是由远到近)。
典型应用场景 配送范围判断(如判断用户是否在商家的配送范围内,通过 GEODIST 计算距离是否小于配送阈值)。
地理位置排序(如旅游平台按距离远近排序景点、酒店)。
查找 Key Redis 中用于查找 / 列出 key 的核心命令主要是 KEYS 和 SCAN,其中 SCAN 是更推荐在生产环境使用的方式。下面我会详细介绍这些命令的用法、区别和最佳实践。
KEYS 命令(简单但不推荐生产使用) KEYS 是最基础的查找 key 的命令,支持通配符匹配,但会阻塞 Redis 主线程 ,在数据量大时可能导致服务卡顿,因此仅建议在开发 / 调试环境使用。
*:匹配任意数量的任意字符(包括 0 个)
?:匹配单个任意字符
[]:匹配括号内的单个字符(如 [abc] 匹配 a、b 或 c)
\:转义特殊字符
SCAN 命令(生产环境推荐) SCAN 是迭代式查找 key 的命令,非阻塞 (分批返回结果),适合在生产环境遍历大量 key,避免阻塞 Redis。
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type ]
cursor:游标,初始值为 0,每次返回结果会包含下一个游标,直到返回 0 表示遍历完成
MATCH pattern:可选,通配符匹配规则(同 KEYS)
COUNT count:可选,指定每次迭代返回的 key 数量(非精确值,默认 10)
TYPE type:可选,按数据类型过滤(如 string、hash、list、set、zset)
辅助命令 TYPE :查看指定 key 的数据类型(配合查找结果使用)
EXISTS :检查指定 key 是否存在(可批量检查)
DBSIZE :快速获取当前数据库的 key 总数(无需遍历,性能极高)
使用建议
开发 / 调试环境 :可临时使用 KEYS,操作简单。
生产环境 :必须使用 SCAN,避免阻塞主线程;如果需要统计 key 总数,优先用 DBSIZE 而非 KEYS *。
通配符优化 :尽量缩小匹配范围(如 user:* 而非 *),减少迭代次数。
集群环境 :KEYS/SCAN 仅作用于当前连接的节点,如需遍历整个集群,需逐个节点执行。
总结
Redis 查找 key 的核心命令是 KEYS(简单但阻塞)和 SCAN(非阻塞,生产推荐),均支持通配符匹配。
SCAN 通过游标分批迭代,搭配 MATCH/TYPE/COUNT 参数可精准过滤 key,避免服务卡顿。
辅助命令 DBSIZE/EXISTS/TYPE 可配合查找操作,提升效率和准确性。
细节补充
key 的设计
单一功能一个 key:取有意义的就行相同功能多个 key:以" : "作为分割
(tips:为什么使用冒号,业内常用,界面客户端的工具也常用:来表示子目录)
怎么删除 key
del key:删除该键值对当 value 为空的时候,会自动移除该 key
怎么创建 key
添加的时候,如果不存在 key,那么 redis 会自动创建
业务中常用组合数据结构
hash 的 value 存放 list/set/zset 的 keyhash + listhash + sethash + zet
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online