Loading... > ⚠️ **请注意**:本内容部分由 AI 生成,请读者自行判断其准确性与适用性。 ## 一、Redis 简介 ### 1.1 什么是 Redis? Redis(Remote Dictionary Server)是一个开源的、基于内存的高性能键值对(Key-Value)数据库。它由 Salvatore Sanfilippo 于 2009 年开发,使用 ANSI C 语言编写。 ### 1.2 Redis 的核心特点 - **基于内存**:数据存储在内存中,读写速度极快 - **持久化支持**:可将内存中的数据保存到磁盘 - **多种数据结构**:支持字符串、列表、集合、哈希表等 - **原子性操作**:所有操作都是原子性的 - **丰富的特性**:支持发布/订阅、事务、Lua脚本等 ### 1.3 Redis 的主要优势 #### 性能优势 - **超高速度**:读速度可达 110000 次/秒,写速度可达 81000 次/秒 - **低延迟**:单次操作耗时通常在微秒级别 - **高并发**:支持数万并发连接 #### 功能优势 - **数据结构丰富**:不仅仅是简单的 Key-Value 存储 - **持久化机制**:RDB 快照和 AOF 日志两种方式 - **主从复制**:支持数据的备份和读写分离 - **哨兵模式**:实现高可用性 - **集群模式**:支持数据分片和横向扩展 #### 应用场景优势 缓存系统(最常用)、会话存储(Session)、排行榜/计数器、消息队列、实时分析、分布式锁、地理位置应用 --- ## 二、Redis 数据类型详解 ### 2.1 String(字符串) 最基本的数据类型,一个 key 对应一个 value。 **特点:** - 二进制安全,可以包含任何数据 - 最大值为 512MB - 可以存储字符串、整数、浮点数 **应用场景:** 缓存对象、计数器、分布式锁、Session 共享 ### 2.2 Hash(哈希) 键值对集合,特别适合存储对象。 **特点:** - 类似于 Map<String, String> - 适合存储对象的属性 **应用场景:** 存储用户信息、存储商品详情、存储配置信息 ### 2.3 List(列表) 有序的字符串列表,按照插入顺序排序。 **特点:** - 双向链表实现 - 支持正向/反向遍历 - 最多可存储 2^32 - 1 个元素 **应用场景:** 消息队列、最新消息列表、评论列表、关注列表 ### 2.4 Set(集合) 无序的、不重复的字符串集合。 **特点:** - 自动去重 - 支持集合运算(交集、并集、差集) **应用场景:** 标签系统、共同好友、去重、随机抽奖 ### 2.5 Sorted Set(有序集合) 在 Set 基础上,每个元素关联一个分数(score)。 **特点:** - 元素不重复,但 score 可以重复 - 按 score 自动排序 **应用场景:** 排行榜、优先级队列、带权重的消息队列、范围查询 ### 2.6 其他高级数据类型 #### Bitmap(位图) - 基于 String 类型 - 适用于大规模数据的去重、统计 #### HyperLogLog - 用于基数统计 - 占用空间极小(12KB) - 统计误差约 0.81% #### Geospatial(地理位置) - 存储地理位置信息 - 支持范围查询、距离计算 #### Stream(流) - Redis 5.0 新增 - 用于消息队列 - 支持消费者组 --- ## 三、Redis 核心命令详解 ### 3.1 通用命令 **🎯 适用场景:** 所有数据类型的基础操作,用于键的管理、过期控制、数据库切换等通用功能。 ```bash # 查看所有键 KEYS * KEYS user:* # 查看符合模式的键 # 检查键是否存在 EXISTS key # 返回 1 表示存在,0 表示不存在 # 删除键 DEL key [key ...] # 删除一个或多个键 # 设置过期时间 EXPIRE key seconds # 设置秒级过期 EXPIREAT key timestamp # 设置过期时间戳 PEXPIRE key milliseconds # 设置毫秒级过期 TTL key # 查看剩余生存时间(秒) PTTL key # 查看剩余生存时间(毫秒) PERSIST key # 移除过期时间 # 重命名键 RENAME key newkey RENAMENX key newkey # 仅当 newkey 不存在时 # 查看键的类型 TYPE key # 随机返回一个键 RANDOMKEY # 数据库操作 SELECT index # 切换数据库(0-15) DBSIZE # 返回当前数据库键的数量 FLUSHDB # 清空当前数据库 FLUSHALL # 清空所有数据库 ``` ### 3.2 String 类型命令 **🎯 适用场景:** - **缓存数据**:缓存用户信息、商品详情、配置信息等序列化对象 - **计数器**:网站访问量、视频播放次数、点赞数、库存数量 - **分布式锁**:利用 SETNX 实现简单的分布式锁 - **Session共享**:分布式系统中的用户会话存储 - **限流控制**:基于时间窗口的访问频率限制 ```bash # 基本操作 SET key value [EX seconds] [PX milliseconds] [NX|XX] GET key MSET key1 value1 key2 value2 ... # 批量设置 MGET key1 key2 ... # 批量获取 GETSET key value # 设置新值并返回旧值 # 条件设置 SETNX key value # 仅当键不存在时设置 SETEX key seconds value # 设置值和过期时间 PSETEX key milliseconds value # 追加和获取长度 APPEND key value # 追加字符串 STRLEN key # 获取值的长度 GETRANGE key start end # 获取子串 SETRANGE key offset value # 替换子串 # 数值操作 INCR key # 自增 1 INCRBY key increment # 增加指定值 INCRBYFLOAT key increment # 增加浮点数 DECR key # 自减 1 DECRBY key decrement # 减少指定值 # 示例 SET counter 10 INCR counter # 结果: 11 INCRBY counter 5 # 结果: 16 SET price 19.99 INCRBYFLOAT price 0.01 # 结果: 20.00 ``` ### 3.3 Hash 类型命令 **🎯 适用场景:** - **用户信息存储**:存储用户的多个属性(昵称、年龄、性别、城市等),避免多次序列化 - **商品详情**:商品的各种属性(名称、价格、库存、描述等) - **购物车**:用户ID作为key,商品ID作为field,数量作为value - **配置中心**:应用的各项配置参数 - **对象缓存**:相比String存储整个对象,Hash可以只更新部分字段,更节省网络开销 ```bash # 基本操作 HSET key field value # 设置单个字段 HGET key field # 获取单个字段 HMSET key field1 value1 field2 value2 ... # 批量设置 HMGET key field1 field2 ... # 批量获取 HGETALL key # 获取所有字段和值 HDEL key field [field ...] # 删除字段 # 检查和计数 HEXISTS key field # 检查字段是否存在 HLEN key # 获取字段数量 HKEYS key # 获取所有字段名 HVALS key # 获取所有值 # 数值操作 HINCRBY key field increment HINCRBYFLOAT key field increment # 条件设置 HSETNX key field value # 仅当字段不存在时设置 # 示例 HMSET user:1001 name "张三" age 25 city "北京" HGET user:1001 name # 结果: "张三" HGETALL user:1001 # 返回所有字段和值 HINCRBY user:1001 age 1 # 年龄加 1 ``` ### 3.4 List 类型命令 **🎯 适用场景:** - **消息队列**:利用 LPUSH + BRPOP 实现简单的生产者-消费者模式 - **最新列表**:朋友圈动态、微博时间线、文章列表(最新发布在前) - **评论列表**:文章或帖子的评论按时间排序 - **操作日志**:记录用户的操作历史,保留最近N条 - **任务队列**:异步任务的排队处理 - **粉丝/关注列表**:按关注时间排序的用户列表 ```bash # 插入操作 LPUSH key value [value ...] # 左侧插入(头部) RPUSH key value [value ...] # 右侧插入(尾部) LINSERT key BEFORE|AFTER pivot value # 在指定元素前/后插入 # 删除操作 LPOP key # 左侧弹出 RPOP key # 右侧弹出 LREM key count value # 删除指定元素 LTRIM key start stop # 保留指定范围的元素 # 查询操作 LRANGE key start stop # 获取范围内的元素 LINDEX key index # 获取指定索引的元素 LLEN key # 获取列表长度 # 修改操作 LSET key index value # 设置指定索引的值 # 阻塞操作 BLPOP key [key ...] timeout # 阻塞式左侧弹出 BRPOP key [key ...] timeout # 阻塞式右侧弹出 BRPOPLPUSH source destination timeout # 列表间操作 RPOPLPUSH source destination # 从源列表尾部弹出并插入目标列表头部 # 示例 RPUSH mylist "a" "b" "c" # 列表: a, b, c LPUSH mylist "0" # 列表: 0, a, b, c LRANGE mylist 0 -1 # 获取所有元素 LINDEX mylist 1 # 结果: "a" LTRIM mylist 0 1 # 仅保留前两个元素 ``` ### 3.5 Set 类型命令 **🎯 适用场景:** - **标签系统**:文章标签、商品分类标签,支持多标签查询 - **共同好友/关注**:利用交集运算找出共同好友、共同关注 - **抽奖系统**:利用 SPOP 随机抽取中奖用户,自动去重 - **去重统计**:UV统计、IP去重、用户去重 - **黑白名单**:IP黑名单、用户白名单等权限控制 - **社交关系**:关注列表、粉丝列表的集合运算 ```bash # 基本操作 SADD key member [member ...] # 添加元素 SREM key member [member ...] # 删除元素 SMEMBERS key # 获取所有元素 SISMEMBER key member # 检查元素是否存在 SCARD key # 获取元素数量 # 随机操作 SRANDMEMBER key [count] # 随机获取元素 SPOP key [count] # 随机弹出元素 # 集合运算 SINTER key [key ...] # 交集 SINTERSTORE destination key [key ...] # 交集并存储 SUNION key [key ...] # 并集 SUNIONSTORE destination key [key ...] # 并集并存储 SDIFF key [key ...] # 差集 SDIFFSTORE destination key [key ...] # 差集并存储 # 移动元素 SMOVE source destination member # 示例 SADD tags:1 "redis" "database" "cache" SADD tags:2 "redis" "nosql" "memory" SINTER tags:1 tags:2 # 结果: "redis" SUNION tags:1 tags:2 # 结果: redis, database, cache, nosql, memory SCARD tags:1 # 结果: 3 ``` ### 3.6 Sorted Set 类型命令 **🎯 适用场景:** - **排行榜系统**:游戏积分榜、音乐热度榜、销售排行榜、学生成绩排名 - **优先级队列**:任务按优先级排序执行 - **延时队列**:使用时间戳作为score,实现定时任务 - **热搜榜单**:微博热搜、抖音热榜,按热度值排序 - **范围查询**:工资范围查询、年龄段筛选 - **时间线排序**:按时间戳排序的消息流、事件流 ```bash # 基本操作 ZADD key score member [score member ...] # 添加元素 ZREM key member [member ...] # 删除元素 ZSCORE key member # 获取元素分数 ZINCRBY key increment member # 增加分数 ZCARD key # 获取元素数量 # 范围查询 ZRANGE key start stop [WITHSCORES] # 按索引范围获取(升序) ZREVRANGE key start stop [WITHSCORES] # 按索引范围获取(降序) ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] # 按分数范围 ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] # 排名查询 ZRANK key member # 获取排名(升序,从 0 开始) ZREVRANK key member # 获取排名(降序) # 计数操作 ZCOUNT key min max # 统计分数范围内的元素数量 ZLEXCOUNT key min max # 字典序统计 # 删除操作 ZREMRANGEBYRANK key start stop # 按排名范围删除 ZREMRANGEBYSCORE key min max # 按分数范围删除 ZREMRANGEBYLEX key min max # 按字典序范围删除 # 集合运算 ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX] ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX] # 示例 ZADD ranking 100 "user1" 200 "user2" 150 "user3" ZRANGE ranking 0 -1 WITHSCORES # 获取所有,按分数升序 ZREVRANGE ranking 0 2 # 获取前三名 ZRANK ranking "user1" # 获取排名 ZINCRBY ranking 50 "user1" # 增加分数 ``` ### 3.7 Bitmap 命令 **🎯 适用场景:** - **签到统计**:用户每日签到记录,统计连续签到天数、总签到天数 - **在线状态**:标记用户在线/离线状态,亿级用户只需几十MB内存 - **活跃用户统计**:每日活跃、每周活跃、每月活跃用户数(DAU/WAU/MAU) - **权限管理**:使用bit位表示不同权限,一个整数即可表示32种权限 - **布隆过滤器**:配合多个bitmap实现简单的布隆过滤器,判断元素是否存在 - **AB测试**:标记用户是否参与某个实验组 ```bash # 位操作 SETBIT key offset value # 设置位值(0 或 1) GETBIT key offset # 获取位值 BITCOUNT key [start end] # 统计为 1 的位数 BITPOS key bit [start] [end] # 查找第一个指定位值的位置 # 位运算 BITOP operation destkey key [key ...] # AND, OR, XOR, NOT # 示例 - 统计用户签到 SETBIT user:1001:2024:12 1 1 # 12月1日签到 SETBIT user:1001:2024:12 2 1 # 12月2日签到 BITCOUNT user:1001:2024:12 # 统计本月签到天数 ``` ### 3.8 HyperLogLog 命令 **🎯 适用场景:** - **UV统计**:网站独立访客数、页面访问用户数,海量数据去重统计 - **搜索引擎**:统计搜索关键词的独立用户数 - **APP统计**:日活、月活等独立设备数统计 - **大数据去重**:亿级数据的基数统计,只需12KB内存,误差0.81% - **IP统计**:独立IP访问数统计 - **用户行为分析**:统计执行某个操作的独立用户数 ```bash PFADD key element [element ...] # 添加元素 PFCOUNT key [key ...] # 获取基数估算值 PFMERGE destkey sourcekey [sourcekey ...] # 合并 # 示例 - 统计网站 UV PFADD page:index:uv user1 user2 user3 PFCOUNT page:index:uv # 估算独立访客数 ``` ### 3.9 Geospatial 命令 **🎯 适用场景:** - **LBS应用**:附近的人、附近的商家、附近的美食 - **打车软件**:计算司机与乘客的距离,查找附近的司机 - **外卖配送**:查找附近的骑手,计算配送距离 - **社交应用**:基于地理位置的交友、动态展示 - **O2O服务**:门店位置查询、服务范围判断 - **地理围栏**:判断用户是否进入/离开某个区域 ```bash # 添加地理位置 GEOADD key longitude latitude member [longitude latitude member ...] # 获取位置 GEOPOS key member [member ...] # 计算距离 GEODIST key member1 member2 [unit] # unit: m, km, mi, ft # 范围查询 GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [COUNT count] GEORADIUSBYMEMBER key member radius unit [WITHCOORD] [WITHDIST] [COUNT count] # 获取 GeoHash GEOHASH key member [member ...] # 示例 - 查找附近的人 GEOADD locations 116.40 39.90 "北京" GEOADD locations 121.47 31.23 "上海" GEODIST locations "北京" "上海" km # 计算距离 GEORADIUS locations 116.40 39.90 1000 km # 查找1000公里内的城市 ``` ### 3.10 Stream 命令 **🎯 适用场景:** - **消息队列**:比List更强大的消息队列,支持消费者组、消息确认、重试机制 - **事件溯源**:记录系统中发生的所有事件,支持事件回放 - **日志收集**:应用日志、操作日志的实时收集和分发 - **实时数据流**:物联网设备数据流、传感器数据采集 - **订单处理**:订单事件流,支持多个服务消费同一订单数据 - **消息通知**:系统通知、用户消息的可靠传递,确保消息不丢失 ```bash # 添加消息 XADD key 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 XREADGROUP GROUP group consumer [COUNT count] STREAMS key [key ...] ID [ID ...] XACK key group ID [ID ...] # 其他操作 XLEN key # 获取流长度 XDEL key ID [ID ...] # 删除消息 XTRIM key MAXLEN count # 修剪流 ``` --- ## 四、Redis 高级特性 ### 4.1 事务 Redis 事务允许一次执行多个命令,具有以下特点: - 批量操作在发送 EXEC 命令前被放入队列 - 收到 EXEC 命令后按顺序执行 - 事务执行过程中,不会被其他客户端的命令打断 ```bash MULTI # 开始事务 ... # 命令入队 EXEC # 执行事务 DISCARD # 取消事务 # 监视键 WATCH key [key ...] # 监视键,如果键被修改则事务失败 UNWATCH # 取消监视 # 示例 MULTI SET account1 100 SET account2 200 EXEC ``` ### 4.2 发布/订阅 ```bash # 订阅频道 SUBSCRIBE channel [channel ...] PSUBSCRIBE pattern [pattern ...] # 模式订阅 # 发布消息 PUBLISH channel message # 取消订阅 UNSUBSCRIBE [channel [channel ...]] PUNSUBSCRIBE [pattern [pattern ...]] # 示例 # 客户端1 SUBSCRIBE news.tech # 客户端2 PUBLISH news.tech "Redis 7.0 发布了!" ``` ### 4.3 Lua 脚本 Redis 支持 Lua 脚本,实现复杂的原子操作。 ```bash # 执行脚本 EVAL script numkeys key [key ...] arg [arg ...] # 脚本管理 SCRIPT LOAD script # 加载脚本 EVALSHA sha1 numkeys key [key ...] arg [arg ...] SCRIPT EXISTS sha1 [sha1 ...] SCRIPT FLUSH # 清空脚本缓存 SCRIPT KILL # 终止脚本 # 示例 - 限流脚本 EVAL "local current = redis.call('incr', KEYS[1]); if current == 1 then redis.call('expire', KEYS[1], ARGV[1]) end; if current > tonumber(ARGV[2]) then return 0 else return 1 end" 1 rate_limit:user1 60 100 ``` ### 4.4 持久化 #### RDB(快照) ```bash SAVE # 同步保存(阻塞) BGSAVE # 异步保存(后台) LASTSAVE # 最后一次保存时间 # 配置文件 save 900 1 # 900秒内至少1个键变化 save 300 10 # 300秒内至少10个键变化 save 60 10000 # 60秒内至少10000个键变化 ``` #### AOF(追加文件) ```bash # 配置文件 appendonly yes appendfsync always # 每次写入都同步 appendfsync everysec # 每秒同步(推荐) appendfsync no # 由操作系统决定 # 重写 BGREWRITEAOF # 异步重写 AOF 文件 ``` ### 4.5 主从复制 ```bash # 从服务器配置 REPLICAOF host port # 设置主服务器 REPLICAOF NO ONE # 取消复制,成为主服务器 # 查看复制信息 INFO replication # 只读模式 replica-read-only yes ``` ### 4.6 哨兵模式 哨兵(Sentinel)用于实现高可用性: - 监控主从服务器 - 自动故障转移 - 通知客户端新的主服务器地址 ```bash # 启动哨兵 redis-sentinel /path/to/sentinel.conf # 哨兵命令 SENTINEL masters SENTINEL slaves <master-name> SENTINEL get-master-addr-by-name <master-name> SENTINEL failover <master-name> ``` --- ## 五、Redis 实践建议 ### 5.1 键命名规范 ```bash # 推荐格式 object-type:id:field user:1001:name product:2001:price order:3001:status # 使用分隔符 user:session:abc123 cache:article:12345 ``` ### 5.2 性能优化 1. **使用批量操作** - 使用 MGET/MSET 代替多次 GET/SET - 使用 Pipeline 减少网络往返 2. **避免大键** - 单个 String 不超过 10KB - 单个集合不超过 10000 个元素 3. **设置过期时间** - 避免内存无限增长 - 自动清理过期数据 4. **选择合适的数据结构** - 小数据量用 Hash 代替 String - 使用 Bitmap 统计大规模数据 ### 5.3 安全建议 ```bash # 设置密码 requirepass your_strong_password AUTH your_strong_password # 禁用危险命令 rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command CONFIG "" # 绑定 IP bind 127.0.0.1 # 保护模式 protected-mode yes ``` ### 5.4 监控命令 ```bash # 服务器信息 INFO # 所有信息 INFO server # 服务器信息 INFO clients # 客户端信息 INFO memory # 内存信息 INFO stats # 统计信息 INFO replication # 复制信息 # 实时监控 MONITOR # 实时显示所有命令 # 慢查询日志 SLOWLOG GET [count] # 获取慢查询日志 SLOWLOG LEN # 慢查询日志数量 SLOWLOG RESET # 清空慢查询日志 # 客户端连接 CLIENT LIST # 所有客户端连接 CLIENT KILL ip:port # 关闭客户端连接 CLIENT SETNAME name # 设置客户端名称 CLIENT GETNAME # 获取客户端名称 ``` --- ## 六、常见应用场景示例 ### 6.1 缓存系统 ```bash # 查询缓存 GET cache:user:1001 # 不存在则查询数据库,然后设置缓存 SET cache:user:1001 "user_data" EX 3600 # 1小时过期 ``` ### 6.2 分布式锁 ```bash # 获取锁 SET lock:resource NX EX 30 # 释放锁 DEL lock:resource # 使用 Lua 脚本安全释放锁 EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 lock:resource token ``` ### 6.3 计数器 ```bash # 文章浏览量 INCR article:1001:views # 点赞数 INCR post:2001:likes # 限流(每分钟100次) INCR rate:user:1001 EXPIRE rate:user:1001 60 ``` ### 6.4 排行榜 ```bash # 添加分数 ZADD leaderboard 9500 "player1" ZADD leaderboard 8800 "player2" # 获取排名前10 ZREVRANGE leaderboard 0 9 WITHSCORES # 获取某用户排名 ZREVRANK leaderboard "player1" # 分数增加 ZINCRBY leaderboard 100 "player1" ``` ### 6.5 消息队列 ```bash # 生产者 LPUSH queue:tasks "task1" LPUSH queue:tasks "task2" # 消费者 BRPOP queue:tasks 0 # 阻塞等待 ``` ### 6.6 Session 存储 ```bash # 存储 Session HMSET session:abc123 user_id 1001 username "zhangsan" login_time 1638360000 EXPIRE session:abc123 1800 # 30分钟 # 读取 Session HGETALL session:abc123 ``` --- ## 七、总结 Redis 是一个功能强大、性能卓越的内存数据库,掌握其核心命令和应用场景对于现代应用开发至关重要。 ### 学习建议: 1. 从基础数据类型开始,熟练掌握常用命令 2. 理解每种数据类型的应用场景 3. 实践中学习持久化、主从复制等高级特性 4. 关注性能优化和安全配置 5. 结合实际项目场景应用 Redis ### 进阶方向: - Redis 集群(Cluster) - Redis 6.0 多线程 - Redis 模块开发 - RedisJSON、RedisSearch 等扩展 - Redis 性能调优 --- **参考资源:** - 官方文档:https://redis.io/documentation - 官方命令参考:https://redis.io/commands - Redis 中文网:http://www.redis.cn/ 最后修改:2025 年 12 月 02 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏