详细介绍:Redis 零基础入门到实战教程(视频教程)

Redis 零基础入门到实战教程

  • Redis(Remote Dictionary Server)是一款开源、高性能、基于内存的键值对数据库,支持多种数据结构,广泛用于缓存、消息队列、分布式锁等场景。本教程从基础到实战,帮你快速掌握 Redis 核心用法。
  • 视频教程:https://pan.quark.cn/s/10e98d308913

一、Redis 安装与环境准备

1. 安装方式(推荐 3 种)

(1)Windows 安装(适合新手)
  • 下载地址:Redis 官方 Windows 版本(选择最新稳定版,如 3.2.100)
  • 安装步骤:
    1. 双击安装包,勾选“Add Redis to PATH”(自动配置环境变量)
    2. 默认端口 6379,无需修改,直接下一步完成安装
  • 验证:打开 CMD,输入 redis-cli,出现 127.0.0.1:6379> 表示成功
(2)Linux 安装(CentOS/Ubuntu)
  • CentOS:
    # 安装 EPEL 源
    yum install epel-release -y
    # 安装 Redis
    yum install redis -y
    # 启动 Redis 并设置开机自启
    systemctl start redis
    systemctl enable redis
  • Ubuntu:
    apt update
    apt install redis-server -y
    # 启动服务
    systemctl start redis-server
  • 验证:输入 redis-cli ping,返回 PONG 表示正常
(3)Docker 安装(推荐开发/测试环境)
# 拉取 Redis 镜像(默认最新稳定版)
docker pull redis
# 启动容器(映射端口 6379,设置密码 123456)
docker run -d -p 6379:6379 --name redis-demo redis --requirepass "123456"
# 进入容器操作 Redis
docker exec -it redis-demo redis-cli -a 123456

2. 核心配置文件(redis.conf)

关键配置项(修改后需重启 Redis):

  • bind 127.0.0.1:默认只允许本地访问,生产环境需改为服务器 IP 或 0.0.0.0(允许所有地址访问)
  • port 6379:默认端口,可自定义(如 6380)
  • requirepass 123456:设置密码(生产环境必须配置)
  • daemonize yes:Linux 下后台运行(默认 no,前台运行)
  • maxmemory 1gb:设置最大内存(避免内存溢出,需配合淘汰策略)
  • maxmemory-policy allkeys-lru:内存满时淘汰策略(优先删除最近最少使用的键)

二、Redis 核心数据结构(重点)

Redis 支持 5 种基础数据结构,以及 HyperLogLog、Geo 等高级结构,核心是键(key)- 值(value) 映射,键都是字符串类型,值支持多种结构。

1. 字符串(String):最基础的键值对

用途:

存储字符串、数字(计数器)、二进制数据(如图片 Base64),是最常用的结构。

核心命令:
命令功能示例
set key value设置键值(覆盖已有键)set name zhangsan
get key获取键值get name → “zhangsan”
setnx key value仅当键不存在时设置(分布式锁核心)setnx lock 1 → 1(成功)/ 0(失败)
mset key1 val1 key2 val2批量设置mset age 20 gender male
mget key1 key2批量获取mget name age → [“zhangsan”, “20”]
incr key数字自增 1incr count → 1(初始不存在时)
decr key数字自减 1decr count → 0
expire key seconds设置过期时间(秒)expire name 30(30 秒后过期)
setex key seconds value原子性设置值 + 过期时间setex code 60 123456(60 秒有效)
实战场景:
  • 缓存用户信息(set user:1001 '{"id":1001,"name":"张三"}'
  • 计数器(文章阅读量、接口访问次数)
  • 验证码存储(设置短期过期)

2. 哈希(Hash):适合存储对象

用途:

存储结构化数据(如用户、商品信息),相当于“键值对中的键值对”,支持单独修改某个字段,无需整体更新。

核心命令:
命令功能示例
hset hash-key field value设置哈希字段值hset user:1001 name 张三 age 20
hget hash-key field获取哈希字段值hget user:1001 name → “张三”
hgetall hash-key获取所有字段和值hgetall user:1001 → [“name”,“张三”,“age”,“20”]
hmset hash-key f1 v1 f2 v2批量设置字段hmset user:1001 gender 男 city 北京
hmget hash-key f1 f2批量获取字段hmget user:1001 name city → [“张三”,“北京”]
hdel hash-key field删除字段hdel user:1001 age
hexists hash-key field判断字段是否存在hexists user:1001 name → 1(存在)/ 0(不存在)
实战场景:
  • 存储用户信息(避免字符串 JSON 解析的开销)
  • 商品详情缓存(hset product:2001 name 手机 price 2999 stock 100

3. 列表(List):有序可重复的字符串集合

用途:

实现队列、栈、消息列表(如朋友圈动态),底层是双向链表,首尾操作效率极高(O(1)),中间操作效率低(O(n))。

核心命令:
命令功能示例
lpush list-key value1 value2从列表左侧插入元素lpush msg:list a b c → 列表:[c,b,a]
rpush list-key value1 value2从列表右侧插入元素rpush msg:list d e → 列表:[c,b,a,d,e]
lpop list-key从左侧弹出元素(删除并返回)lpop msg:list → “c”(列表变为 [b,a,d,e])
rpop list-key从右侧弹出元素rpop msg:list → “e”(列表变为 [b,a,d])
lrange list-key start end获取指定范围元素(0 开始,-1 表示末尾)lrange msg:list 0 -1 → [“b”,“a”,“d”]
llen list-key获取列表长度llen msg:list → 3
实战场景:
  • 消息队列(rpush 生产消息,lpop 消费消息,简单场景)
  • 最新消息列表(如“最近评论”,lpush 新增,lrange 分页查询)
  • 栈(lpush + lpop)/ 队列(lpush + rpop

4. 集合(Set):无序不可重复的字符串集合

用途:

去重、交集/并集/差集计算(如共同好友、标签筛选),底层是哈希表,查询、添加、删除效率均为 O(1)。

核心命令:
命令功能示例
sadd set-key value1 value2添加元素(重复元素自动去重)sadd tag:1001 运动 音乐 旅行
smembers set-key获取所有元素smembers tag:1001 → [“运动”,“音乐”,“旅行”]
sismember set-key value判断元素是否存在sismember tag:1001 电影 → 0(不存在)
scard set-key获取集合大小scard tag:1001 → 3
sinter set1 set2求两个集合的交集(共同元素)sadd tag:1002 音乐 阅读sinter tag:1001 tag:1002 → [“音乐”]
sunion set1 set2求并集(所有元素去重)sunion tag:1001 tag:1002 → [“运动”,“音乐”,“旅行”,“阅读”]
sdiff set1 set2求差集(set1 有但 set2 没有)sdiff tag:1001 tag:1002 → [“运动”,“旅行”]
实战场景:
  • 用户标签(去重存储)
  • 共同好友推荐(交集计算)
  • 抽奖活动(srandmember set-key 随机取元素,spop 随机删除元素)

5. 有序集合(Sorted Set/ZSet):有序不可重复的集合

用途:

排序场景(如排行榜、热搜榜),每个元素关联一个分数(score),按分数自动排序,底层是“跳表”,兼顾排序和查询效率。

核心命令:
命令功能示例
zadd zset-key score1 value1 score2 value2添加元素(分数决定顺序)zadd rank:article 100 文章1 200 文章2 150 文章3
zrange zset-key start end [withscores]按分数升序取元素(withscores 显示分数)zrange rank:article 0 -1 withscores → [“文章1”,100,“文章3”,150,“文章2”,200]
zrevrange zset-key start end按分数降序取元素(排行榜常用)zrevrange rank:article 0 1 → [“文章2”,“文章3”](前 2 名)
zscore zset-key value获取元素的分数zscore rank:article 文章2 → 200
zincrby zset-key increment value增加元素分数(计数器+排序)zincrby rank:article 50 文章1 → 150(文章1 分数变为 150)
zcard zset-key获取元素个数zcard rank:article → 3
实战场景:
  • 文章阅读量排行榜(分数=阅读量,zrevrange 取Top N)
  • 热搜榜(分数=搜索次数,定时更新)
  • 积分排名(用户积分作为分数)

三、Redis 高级特性

1. 过期键删除策略

Redis 采用“惰性删除 + 定期删除”结合的策略:

  • 惰性删除:访问过期键时才删除(节省 CPU,可能浪费内存)
  • 定期删除:每隔一段时间扫描部分过期键(平衡 CPU 和内存)
  • 配合内存淘汰策略(maxmemory-policy):内存满时自动删除键,常用策略:
    • allkeys-lru:删除所有键中最近最少使用的
    • volatile-lru:只删除带过期时间的键中最近最少使用的
    • noeviction:默认策略,内存满时拒绝写操作(推荐生产环境用 allkeys-lru

2. 持久化(避免数据丢失)

Redis 是内存数据库,默认数据仅存于内存,重启后丢失,需开启持久化将数据写入磁盘。

(1)RDB 持久化(默认开启)
  • 原理:在指定时间间隔内,将内存中的数据快照写入磁盘(生成 .rdb 文件)
  • 触发方式:
    • 自动触发:配置文件中 save 900 1(900 秒内至少 1 个键修改)、save 300 10
    • 手动触发:save(阻塞 Redis,不推荐)、bgsave(后台异步执行,推荐)
  • 优点:恢复速度快,适合备份
  • 缺点:可能丢失最近一次快照后的更新数据
(2)AOF 持久化(推荐生产环境开启)
  • 原理:记录每一条写命令(如 set、hset),重启时重新执行命令恢复数据
  • 开启方式:修改 redis.confappendonly yes,生成 .aof 文件
  • 同步策略(appendfsync):
    • always:每写一条命令同步到磁盘(最安全,性能略低)
    • everysec:每秒同步一次(推荐,平衡安全和性能)
    • no:由操作系统决定同步时机(性能高,风险高)
  • 优点:数据丢失少(最多丢失 1 秒数据)
  • 缺点:AOF 文件体积大,恢复速度比 RDB 慢
(3)最佳实践:
  • 生产环境开启 AOF + RDB 双持久化:AOF 保证数据安全性,RDB 用于快速恢复
  • 定期备份 .rdb 和 .aof 文件,防止磁盘损坏

3. 缓存常见问题与解决方案

(1)缓存穿透
  • 问题:请求不存在的键(如恶意查询 user:9999,而该用户不存在),导致请求直接穿透到数据库,压垮数据库
  • 解决方案:
    1. 缓存空值:对不存在的键,缓存 null 并设置短期过期时间(如 5 分钟)
    2. 布隆过滤器:提前过滤不存在的键(适合数据量大的场景)
(2)缓存击穿
  • 问题:某个热点键过期时,大量请求同时访问该键,穿透到数据库
  • 解决方案:
    1. 互斥锁:第一个请求获取锁,查询数据库并更新缓存,其他请求等待锁释放后查询缓存
    2. 热点键永不过期:定期后台更新缓存,不设置过期时间
(3)缓存雪崩
  • 问题:大量缓存键同时过期,或 Redis 服务宕机,导致所有请求穿透到数据库
  • 解决方案:
    1. 过期时间随机化:给每个键的过期时间加随机值(如 expire key 3600 + rand(0, 600)),避免同时过期
    2. 服务熔断/限流:数据库压力过大时,拒绝部分请求
    3. Redis 集群:避免单点故障(后续讲解)

四、Redis 集群(高可用与扩容)

单节点 Redis 存在单点故障和内存上限问题,生产环境需部署集群。

1. 主从复制(主从架构)

  • 原理:1 个主节点(Master)+ 多个从节点(Slave),主节点负责写操作,从节点负责读操作,主节点数据自动同步到从节点

  • 核心作用:

    • 读写分离:减轻主节点压力(读请求分发到从节点)
    • 容灾备份:主节点故障时,从节点可切换为主节点
  • 配置步骤(以 1 主 2 从为例):

    1. 准备 3 个 Redis 实例(端口 6379、6380、6381)
    2. 从节点配置文件添加:slaveof 主节点IP 主节点端口(如 slaveof 127.0.0.1 6379
    3. 主节点设置密码后,从节点需添加:masterauth 主节点密码
    4. 验证:主节点执行 info replication,查看从节点信息

2. 哨兵模式(Sentinel)

  • 问题:主从复制中,主节点故障后需手动切换从节点为主节点,不满足高可用
  • 原理:部署多个哨兵进程(Sentinel),监控主从节点,主节点故障时自动选举新主节点,实现故障自动切换
  • 核心功能:
    • 监控:检查主从节点是否正常运行
    • 自动故障转移:主节点宕机后,选举从节点为新主,其他从节点切换到新主
    • 通知:故障时通过脚本通知管理员

3. Redis Cluster(分片集群)

  • 问题:主从复制和哨兵模式无法解决“内存扩容”问题(单主节点内存有限)
  • 原理:将数据分片存储到多个主节点(默认 16384 个哈希槽),每个主节点负责一部分槽,配合从节点实现高可用
  • 核心特点:
    • 分片存储:突破单节点内存限制(如 3 主 3 从,总内存是 3 个主节点内存之和)
    • 自动路由:客户端请求根据键的哈希值自动路由到对应主节点
    • 容错性:单个主节点故障,其从节点自动切换为主节点

五、Redis 实战案例:实现分布式锁

分布式锁是 Redis 最常用的实战场景之一,用于解决分布式系统中并发竞争问题(如秒杀、库存扣减)。

核心思路:

  • 利用 setnx key value 原子性:多个进程同时抢锁,只有一个能成功(setnx 返回 1)
  • 给锁设置过期时间:防止持有锁的进程宕机导致锁无法释放
  • 释放锁时验证 value:避免误释放其他进程的锁(value 用唯一标识,如 UUID)

实现步骤(Python 示例):

  1. 安装 Redis 客户端:pip install redis
  2. 代码实现:
import redis
import uuid
import time
# 连接 Redis
redis_client = redis.Redis(
host="127.0.0.1",
port=6379,
password="123456",
decode_responses=True  # 自动解码为字符串
)
def acquire_lock(lock_key, expire_seconds=30):
"""获取分布式锁"""
lock_value = str(uuid.uuid4())  # 唯一标识,用于释放锁时验证
# setnx + expire 原子操作(避免设置锁后未设置过期时间进程宕机)
success = redis_client.set(
name=lock_key,
value=lock_value,
nx=True,  # 仅当键不存在时设置(等价于 setnx)
ex=expire_seconds  # 过期时间(秒)
)
return success, lock_value
def release_lock(lock_key, lock_value):
"""释放分布式锁(验证 value,避免误释放)"""
# 用 Lua 脚本保证原子性(查询 + 删除必须原子执行)
lua_script = """
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
"""
result = redis_client.eval(lua_script, 1, lock_key, lock_value)
return result == 1
# 测试:模拟 10 个进程抢锁
def task(thread_id):
lock_key = "distributed_lock"
success, lock_value = acquire_lock(lock_key)
if success:
print(f"线程 {thread_id} 成功获取锁,开始执行任务...")
time.sleep(2)  # 模拟任务执行
release_lock(lock_key, lock_value)
print(f"线程 {thread_id} 释放锁")
else:
print(f"线程 {thread_id} 抢锁失败,稍后重试")
# 模拟并发
if __name__ == "__main__":
import threading
for i in range(10):
t = threading.Thread(target=task, args=(i,))
t.start()

关键注意点:

  • 锁的过期时间:需大于任务执行时间,避免任务未完成锁已过期
  • 原子性:set nx ex 是原子操作,释放锁必须用 Lua 脚本保证原子性
  • 容错性:如果进程持有锁期间宕机,锁会因过期时间自动释放,不会死锁

六、总结与学习资源

1. 核心要点回顾

  • Redis 是基于内存的高性能键值数据库,支持 5 种核心数据结构
  • 重点掌握:String(缓存/计数)、Hash(对象存储)、ZSet(排序)
  • 生产环境必须配置:密码、持久化(AOF+RDB)、内存淘汰策略、集群(高可用)
  • 避坑点:缓存穿透/击穿/雪崩、分布式锁的原子性
posted @ 2025-12-11 19:15  yangykaifa  阅读(20)  评论(0)    收藏  举报