Skip to content
第 191 / 250 章中间件⏱ 14 分钟阅读

第 191 章:Redis 入门与数据结构

学习目标

  • 理解 Redis 是什么、为什么快
  • 掌握 5 种基础数据结构
  • 学会常用命令
  • 了解持久化机制

一、Redis 简介

Redis (Remote Dictionary Server) 是一个基于内存的键值数据库,常用于缓存、排行榜、计数器、分布式锁等场景。

二、为什么 Redis 这么快

特性说明
基于内存读写都是内存,ns 级
单线程无锁竞争,避免上下文切换
IO 多路复用epoll 模型,处理高并发
C 语言实现接近底层
数据结构优化自定义编码

单线程

Redis 6.0 后 IO 多线程化,但命令执行仍是单线程

三、安装

bash
# macOS
brew install redis
redis-server

# Docker
docker run -d -p 6379:6379 --name redis redis:7-alpine

# Ubuntu
sudo apt install redis-server

四、5 种基础数据结构

4.1 String(字符串)

最简单也最常用,最大 512MB。

bash
SET user:1:name "Tom"           # 设置
GET user:1:name                 # 获取
DEL user:1:name                 # 删除
EXISTS user:1:name              # 是否存在
EXPIRE user:1:name 60           # 60s 过期
INCR counter                    # +1
DECR counter                    # -1
INCRBY counter 5                # +5
APPEND user:1:name " Jr"        # 追加
STRLEN user:1:name              # 长度
MSET k1 v1 k2 v2                # 批量设
MGET k1 k2                      # 批量取

应用场景:

  • 缓存 JSON
  • 计数器(点赞、阅读量)
  • 分布式 ID (INCR)
  • 分布式锁

4.2 Hash(哈希)

键值对集合,适合存对象。

bash
HSET user:1 name "Tom" age 18
HGET user:1 name
HGETALL user:1                  # 所有字段
HMSET user:1 name "Jerry" age 20
HMGET user:1 name age
HINCRBY user:1 age 1
HDEL user:1 age
HEXISTS user:1 name
HKEYS user:1                    # 所有字段名
HVALS user:1                    # 所有值
HLEN user:1                     # 字段数量

应用场景:存用户对象(优于 JSON 字符串,可单独更新字段)

4.3 List(链表)

有序可重复,双向链表。

bash
LPUSH list 1 2 3                # 左压入
RPUSH list 4 5                  # 右压入
LRANGE list 0 -1                # 全取
LPOP list                       # 左弹出
RPOP list                       # 右弹出
LLEN list                       # 长度
LINDEX list 0                   # 按下标取
LSET list 0 "new"               # 按下标设
LREM list 1 "a"                 # 删除 1 个 "a"
LTRIM list 0 99                 # 保留 0-99
RPOPLPUSH src dst               # 原子迁移(经典)
BRPOP list 5                    # 阻塞弹出,5s 超时

应用场景:

  • 消息队列(简单场景)
  • 最新列表(微博时间线)
  • 栈/队列

4.4 Set(集合)

无序不重复,基于哈希表。

bash
SADD tags "java" "redis" "mysql"
SMEMBERS tags                   # 所有元素
SISMEMBER tags "java"           # 是否存在
SCARD tags                      # 数量
SREM tags "java"                # 删除
SPOP tags                       # 随机弹出一个
SRANDMEMBER tags 2              # 随机取 2 个(不弹)
SINTER s1 s2                    # 交集
SUNION s1 s2                    # 并集
SDIFF s1 s2                     # 差集
SINTERSTORE dst s1 s2           # 交集存到 dst

应用场景:

  • 标签
  • 共同好友(交集)
  • 去重

4.5 Sorted Set(ZSet)

有序集合,带 score 权重。

bash
ZADD rank 100 "Tom" 90 "Jerry" 95 "Bob"
ZRANGE rank 0 -1                # 按 score 升序
ZRANGE rank 0 -1 WITHSCORES
ZREVRANGE rank 0 2              # 按 score 降序前 3
ZSCORE rank "Tom"               # 查分数
ZINCRBY rank 10 "Tom"           # 加 10
ZCARD rank                      # 数量
ZRANK rank "Tom"                # 排名
ZREM rank "Tom"
ZCOUNT rank 80 100              # 80-100 分数段的数量
ZRANGEBYSCORE rank 80 100       # 分数段的所有成员

应用场景:

  • 排行榜(游戏分数)
  • 带权重的队列
  • 滑动窗口限流

五、3 种高级数据结构

5.1 Bitmap(位图)

bash
SETBIT signed:2024-01-01 1 1    # 用户 1 签到
GETBIT signed:2024-01-01 1
BITCOUNT signed:2024-01-01      # 签到数
BITOP AND dst key1 key2         # 位运算

场景:用户签到、日活统计

5.2 HyperLogLog(基数统计)

bash
PFADD uv:2024-01-01 "u1" "u2" "u3"
PFCOUNT uv:2024-01-01           # 不重复数(有 0.81% 误差)
PFMERGE uv:total uv:2024-01-01 uv:2024-01-02

场景:UV 统计,内存固定 12KB

5.3 GEO(地理位置)

bash
GEOADD cities 116.40 39.90 "北京" 121.47 31.23 "上海"
GEODIST cities 北京 上海 km
GEORADIUS cities 116.40 39.90 1000 km   # 北京 1000km 内城市
GEOSEARCH cities FROMLONLAT 116.40 39.90 BYRADIUS 1000 km

场景:附近的人、门店

六、Key 过期与淘汰

6.1 过期时间

bash
EXPIRE key 60                   # 秒
PEXPIRE key 60000               # 毫秒
EXPIREAT key 1700000000         # 绝对时间戳
TTL key                         # 剩余时间(-1 永久,-2 不存在)
PERSIST key                     # 取消过期

6.2 内存淘汰策略

redis.conf:

conf
# 内存上限
maxmemory 256mb

# 淘汰策略
# noeviction      默认,写命令报错
# allkeys-lru    所有 key 中 LRU 淘汰
# volatile-lru   仅过期 key 中 LRU
# allkeys-lfu    所有 key 中 LFU(更精确)
# volatile-ttl   优先淘汰快过期的
maxmemory-policy allkeys-lru

七、持久化

7.1 RDB(快照)

conf
# 900s 内至少 1 次修改 → 触发
save 900 1
save 300 10
save 60 10000

dbfilename dump.rdb
dir ./

特点:

  • ✅ 二进制压缩,体积小
  • ✅ 恢复快
  • ❌ 可能丢失最后一次快照后的数据

7.2 AOF(追加日志)

conf
appendonly yes
appendfilename "appendonly.aof"

# 同步策略
# always: 每次写都 fsync(最安全)
# everysec: 每秒(默认,推荐)
# no: 不主动
appendfsync everysec

# 自动重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

特点:

  • ✅ 数据丢失少
  • ❌ 文件大,恢复慢

7.3 混合持久化(Redis 4+)

conf
aof-use-rdb-preamble yes

AOF 文件 = RDB 头 + 增量 AOF,兼顾两者优点。

八、常用管理命令

bash
# 服务端
INFO                          # 服务器信息
DBSIZE                        # key 总数
CONFIG GET maxmemory          # 查配置
CONFIG SET maxmemory 512mb    # 改配置
MONITOR                       # 实时监控所有命令
SLOWLOG GET 10                # 慢日志
CLIENT LIST                   # 客户端连接

# 客户端
SELECT 0                      # 切换数据库(0-15)
FLUSHDB                       # 清当前库
FLUSHALL                      # 清所有库

九、本章小结

数据结构特点场景
String简单缓存、计数器
Hash字段独立对象
List有序可重复队列、最新列表
Set无序去重标签、共同好友
ZSet带权重排序排行榜
持久化优点缺点
RDB小、快可能丢数据
AOF安全大、慢

动手练习

  1. 用 Redis 实现文章阅读量统计
  2. 用 ZSet 实现游戏排行榜
  3. 用 Set 实现文章标签去重
  4. 配置 RDB + AOF 混合持久化

推荐阅读


下一章:第 192 章:Redis 高级特性

本站基于 VitePress 构建 · 由 Codebook 团队维护