Redis 基础入门与核心概念【第一部分】

前面将多线程、锁、线程安全部分内容完整了解了一遍,接下来准备点啥呢?发现最开始Redis部分的内容写的有些凌乱,想着趁着这次机会把Redis部分从头到尾梳理一遍,如果想了解或者梳理Redis知识的小伙伴,看这个系列的几篇Redis文章就够了~

第1章:Redis 简介与概览

1.1 什么是Redis?

如果把传统的关系型数据库(如MySQL)比作一个"大型仓库"------数据存放有序但存取较慢,那么Redis就是一个"超高速工作台"------所有常用工具都摆在手边,随取随用!

Redis(Remote Dictionary Server) 是一个开源的、基于内存的键值对存储系统。它不仅仅支持简单的Key-Value,还提供了丰富的数据结构,可以用作数据库、缓存和消息中间件。

1.2 Redis为什么这么快?核心优势解析

1. 基于内存操作

就像从书架上拿书(硬盘) vs 从桌面上拿便签(内存),Redis基于内存的操作让它拥有惊人的速度:

python 复制代码
# 速度对比
硬盘读取速度:    约 100MB/s
内存读取速度:    约 10GB/s  
Redis读取速度:   约 100,000次/秒

2. 单线程架构

听起来反直觉?但正是Redis的"独门绝技"!想象一下:银行只有一个超级高效的柜员,但他能同时处理多个窗口的客户请求,没有内部协调的混乱。这就是Redis的单线程+IO多路复用模型:

  • 避免了线程切换和锁竞争的开销
  • 一个线程同时处理多个客户端请求

3. 高效的数据结构

Redis不是简单的Key-Value,而是为不同场景量身定制的数据结构服务器,就像多功能工具箱,每种数据结构都是不同的专用工具。

1.3 Redis vs 其他数据库:什么时候该用Redis?

场景 推荐使用 不推荐使用
热点数据缓存 完美适合
会话存储(Session) 完美适合
排行榜/计数器 完美适合
交易记录存储 ✅ 用MySQL
复杂关联查询 ✅ 用MySQL

简单判断法则 :如果你的数据需要快速读写不要求100%持久化安全,就用Redis!


第2章:Redis 安装与配置

2.1 Linux (Ubuntu) 安装

bash 复制代码
# 1. 更新包管理器
sudo apt update

# 2. 安装Redis
sudo apt install redis-server

# 3. 启动Redis服务
sudo systemctl start redis-server

# 4. 设置开机自启
sudo systemctl enable redis-server

# 5. 检查状态
sudo systemctl status redis-server

# 6. 测试连接
redis-cli ping
# 如果返回 PONG,恭喜安装成功!

2.2 macOS 安装

bash 复制代码
# 1. 使用Homebrew安装
brew install redis

# 2. 启动Redis服务(后台运行)
brew services start redis

# 3. 或者手动启动(前台运行,方便调试)
redis-server /usr/local/etc/redis.conf

# 4. 测试连接
redis-cli ping

2.3 Windows 安装

注意:官方不支持Windows,但有以下选择:

方案一:WSL2(推荐)

bash 复制代码
# 在Windows Terminal中开启WSL Ubuntu,然后按照Linux步骤安装

方案二:Microsoft维护的Windows版本

  1. 访问:https://github.com/microsoftarchive/redis/releases
  2. 下载 Redis-x64-3.2.100.msi
  3. 双击安装,Redis会作为Windows服务运行

2.4 Docker 安装(跨平台通用)

bash 复制代码
# 1. 拉取最新Redis镜像
docker pull redis:latest

# 2. 运行Redis容器
docker run -d --name my-redis \
  -p 6379:6379 \
  -v /path/on/host:/data \
  redis:latest
  
# 参数解释:
# -d : 后台运行
# --name : 容器名称
# -p 6379:6379 : 端口映射(主机:容器)
# -v : 数据卷挂载,持久化数据

# 3. 进入容器执行命令
docker exec -it my-redis redis-cli

# 4. 或者直接在主机连接
redis-cli -h 127.0.0.1 -p 6379

2.5 核心配置文件解读

Redis的"大脑"是redis.conf文件,让我们看看关键配置:

bash 复制代码
# 找到配置文件位置
find / -name redis.conf 2>/dev/null
# 通常位置:/etc/redis/redis.conf

# 查看关键配置
cat /etc/redis/redis.conf | grep -v "^#" | grep -v "^$"

重要配置项详解

conf 复制代码
# 网络相关
bind 127.0.0.1                    # 只允许本地连接,远程访问改为 0.0.0.0
port 6379                         # 默认端口号
protected-mode yes                # 保护模式,生产环境建议yes

# 持久化相关
dir /var/lib/redis               # 数据存储目录
dbfilename dump.rdb              # RDB文件名

# 内存管理
maxmemory 100mb                  # 最大内存限制
maxmemory-policy allkeys-lru     # 内存满时的淘汰策略

# 安全相关
requirepass your_strong_password # 设置访问密码

第3章:Redis 核心数据结构 (上) - 基础五虎将

数据结构总览

Redis不是简单的Key-Value,而是数据结构服务器!就像一个多功能工具箱,每种数据结构都是不同的工具:

数据结构 比喻 典型应用
String 📝 便利贴 缓存、计数器
Hash 📋 表格 用户信息、对象存储
List 📚 书架 消息队列、最新列表
Set 🎯 集合 标签、共同好友
Sorted Set 🏆 排行榜 排行榜、延迟队列

3.1 String(字符串) - 万能选手

就像办公室的便利贴,简单直接,什么都能记!

bash 复制代码
# ========== 基础操作 ==========

# 设置键值对
SET username "redis_learner"
# ✅ 结果:OK
# 💡 使用建议:最简单的缓存用法
# ⚠️ 雷点:如果key已存在会覆盖,慎用!

# 获取值
GET username  
# ✅ 结果:"redis_learner"
# ⚠️ 雷点:如果key不存在返回nil,注意空值处理

# 设置并获取原值(原子操作)
GETSET username "new_learner"
# ✅ 结果:"redis_learner" (返回旧值)
# ✅ 现在username的值是:"new_learner"

# ========== 数字操作 ==========

# 设置数字
SET page_views 100
# 递增
INCR page_views
# ✅ 结果:101
# 💡 使用建议:完美用于计数器,原子操作不怕并发

# 增加指定数值
INCRBY page_views 5
# ✅ 结果:106

# 递减
DECR page_views
# ✅ 结果:105

# ========== 批量操作 ==========

# 批量设置
MSET user:1000:name "Alice" user:1000:age 25 user:1000:city "Beijing"
# ✅ 结果:OK
# 💡 使用建议:减少网络开销,提升性能

# 批量获取
MGET user:1000:name user:1000:age user:1000:city
# ✅ 结果:1) "Alice" 2) "25" 3) "Beijing"

# ========== 生存时间 ==========

# 设置值并指定10秒后过期
SETEX session_token 10 "abc123"
# ✅ 结果:OK
# 💡 使用建议:Session管理、验证码场景

# 设置key的生存时间(秒)
EXPIRE username 60
# ✅ 结果:(integer) 1 (设置成功)

# 查看剩余生存时间
TTL username
# ✅ 结果:(integer) 57 (剩余57秒)

String使用场景

  • 🔥 缓存HTML片段、API响应
  • 🔢 文章阅读量、点赞数计数器
  • 🔑 Session存储、临时令牌
  • ⏰ 验证码、限流器

3.2 Hash(哈希) - 对象存储器

就像Excel表格,一个key对应多个字段,完美存储对象!

bash 复制代码
# ========== 基本操作 ==========

# 设置单个字段
HSET user:1000 name "Alice"
# ✅ 结果:(integer) 1 (新增字段数)

# 同时设置多个字段
HSET user:1000 age 25 city "Beijing" profession "Engineer"
# ✅ 结果:(integer) 3

# 获取单个字段
HGET user:1000 name
# ✅ 结果:"Alice"

# 获取所有字段和值
HGETALL user:1000
# ✅ 结果:
# 1) "name"
# 2) "Alice" 
# 3) "age"
# 4) "25"
# 5) "city"
# 6) "Beijing"
# 7) "profession"
# 8) "Engineer"
# 💡 使用建议:适合存储对象,但字段不宜过多(建议<1000)
# ⚠️ 雷点:字段太多会占用大量内存,考虑分拆

# ========== 批量操作 ==========

# 批量获取指定字段
HMGET user:1000 name age
# ✅ 结果:1) "Alice" 2) "25"

# ========== 数字操作 ==========

# 字段值递增
HINCRBY user:1000 age 1
# ✅ 结果:(integer) 26
# 💡 使用建议:用户年龄更新、积分变动等

# ========== 查询操作 ==========

# 获取所有字段名
HKEYS user:1000
# ✅ 结果:1) "name" 2) "age" 3) "city" 4) "profession"

# 获取所有字段值
HVALS user:1000  
# ✅ 结果:1) "Alice" 2) "26" 3) "Beijing" 4) "Engineer"

# 获取字段数量
HLEN user:1000
# ✅ 结果:(integer) 4

# 检查字段是否存在
HEXISTS user:1000 email
# ✅ 结果:(integer) 0 (不存在)

Hash使用场景

  • 👥 用户信息存储
  • 🛒 购物车商品信息
  • 📊 对象属性缓存

3.3 List(列表) - 有序队列

就像排队的人群,可以从队头或队尾加入,保持顺序!

bash 复制代码
# ========== 从左侧操作 ==========

# 从左侧插入(类似队列头部)
LPUSH tasks "task1"
# ✅ 结果:(integer) 1
LPUSH tasks "task2" "task3"
# ✅ 结果:(integer) 3
# 💡 当前列表:["task3", "task2", "task1"]

# 从左侧弹出
LPOP tasks
# ✅ 结果:"task3"
# 💡 剩余列表:["task2", "task1"]

# ========== 从右侧操作 ==========

# 从右侧插入(类似队列尾部)
RPUSH tasks "task4"
# ✅ 结果:(integer) 3  
# 💡 当前列表:["task2", "task1", "task4"]

# 从右侧弹出
RPOP tasks
# ✅ 结果:"task4"
# 💡 剩余列表:["task2", "task1"]

# ========== 查询操作 ==========

# 获取列表长度
LLEN tasks
# ✅ 结果:(integer) 2

# 获取指定范围的元素
LRANGE tasks 0 -1  # 0到-1表示获取所有
# ✅ 结果:1) "task2" 2) "task1"

LRANGE tasks 0 0   # 获取第一个元素
# ✅ 结果:1) "task2"

# ========== 高级操作 ==========

# 阻塞式弹出(等待任务,超时时间5秒)
BLPOP new_tasks 5
# 💡 使用建议:消息队列场景,队列为空时等待
# ✅ 结果:如果5秒内有元素返回元素,否则返回nil

# 修剪列表,只保留指定范围
LPUSH numbers 1 2 3 4 5
LTRIM numbers 0 2  # 只保留前3个元素
LRANGE numbers 0 -1
# ✅ 结果:1) "5" 2) "4" 3) "3"

List使用场景

  • 📨 消息队列(LPUSH + BRPOP)
  • 🆕 最新文章列表
  • 📝 操作日志记录

3.4 Set(集合) - 无序唯一

就像数学里的集合,元素无序但唯一,适合做关系运算!

bash 复制代码
# ========== 基本操作 ==========

# 添加元素
SADD tags "redis" "database" "cache"
# ✅ 结果:(integer) 3

# 添加重复元素(自动去重)
SADD tags "redis" "new_tag"
# ✅ 结果:(integer) 1 (只新增了1个)

# 获取所有元素
SMEMBERS tags
# ✅ 结果:1) "cache" 2) "database" 3) "redis" 4) "new_tag"
# ⚠️ 雷点:元素无序!不要依赖返回顺序

# 检查元素是否存在
SISMEMBER tags "redis"
# ✅ 结果:(integer) 1 (存在)

# 获取集合大小
SCARD tags
# ✅ 结果:(integer) 4

# 随机弹出一个元素
SPOP tags
# ✅ 结果:"new_tag" (随机)
# 💡 使用建议:抽奖场景

# ========== 集合运算 ==========

# 创建两个集合
SADD group_A "user1" "user2" "user3"
SADD group_B "user3" "user4" "user5"

# 交集 - 共同好友
SINTER group_A group_B
# ✅ 结果:1) "user3"

# 并集 - 所有用户
SUNION group_A group_B  
# ✅ 结果:1) "user1" 2) "user2" 3) "user3" 4) "user4" 5) "user5"

# 差集 - A有B没有
SDIFF group_A group_B
# ✅ 结果:1) "user1" 2) "user2"

# 将交集存储到新集合
SINTERSTORE common_users group_A group_B
SMEMBERS common_users
# ✅ 结果:1) "user3"

Set使用场景

  • 🏷️ 文章标签系统
  • 👥 社交网络共同好友
  • 🎲 随机抽奖、唯一值存储

3.5 Sorted Set(有序集合) - 带分队的集合

就像游戏排行榜,每个玩家都有分数,可以按分数排序!

bash 复制代码
# ========== 基本操作 ==========

# 添加带分数的成员
ZADD leaderboard 1000 "Alice"
ZADD leaderboard 850 "Bob" 1200 "Charlie" 900 "David"
# ✅ 结果:(integer) 3

# 按分数升序获取(从小到大)
ZRANGE leaderboard 0 -1 WITHSCORES
# ✅ 结果:
# 1) "Bob"    2) "850"
# 3) "David"  4) "900" 
# 5) "Alice"  6) "1000"
# 7) "Charlie" 8) "1200"

# 按分数降序获取(从大到小)
ZREVRANGE leaderboard 0 -1 WITHSCORES
# ✅ 结果:
# 1) "Charlie" 2) "1200"
# 3) "Alice"   4) "1000"
# 5) "David"   6) "900"
# 7) "Bob"     8) "850"

# ========== 分数操作 ==========

# 增加成员分数
ZINCRBY leaderboard 50 "Bob"
# ✅ 结果:"900"
# 💡 使用建议:实时更新排行榜分数

# 获取成员分数
ZSCORE leaderboard "Alice"
# ✅ 结果:"1000"

# 获取成员排名(从0开始,按分数升序)
ZRANK leaderboard "Alice"
# ✅ 结果:(integer) 2 (第三名)

# 获取成员排名(按分数降序)
ZREVRANK leaderboard "Alice"  
# ✅ 结果:(integer) 1 (第二名)

# ========== 范围查询 ==========

# 按分数范围查询
ZRANGEBYSCORE leaderboard 900 1100 WITHSCORES
# ✅ 结果:
# 1) "David" 2) "900"
# 3) "Alice" 4) "1000"

# 查询分数大于1000的成员
ZRANGEBYSCORE leaderboard (1000 +inf WITHSCORES
# ✅ 结果:1) "Charlie" 2) "1200"

# 查询前3名
ZREVRANGE leaderboard 0 2 WITHSCORES
# ✅ 结果:
# 1) "Charlie" 2) "1200"
# 3) "Alice"   4) "1000" 
# 5) "David"   6) "900"

# ========== 统计操作 ==========

# 统计成员数量
ZCARD leaderboard
# ✅ 结果:(integer) 4

# 统计分数范围内的成员数量
ZCOUNT leaderboard 800 1000
# ✅ 结果:(integer) 3

Sorted Set使用场景

  • 🏆 游戏排行榜、热度排名
  • ⏰ 延迟队列(用时间戳作为分数)
  • 📈 带权重的任务调度

本章总结

Redis的"基础五虎将"各有绝活:

  1. String - 简单直接,万能型选手
  2. Hash - 对象存储,结构化专家
  3. List - 有序队列,消息传递高手
  4. Set - 无序唯一,关系运算大师
  5. Sorted Set - 带分排序,排行榜王者

选择数据结构的心法

  • 要存单个值? → String
  • 要存对象? → Hash
  • 要维护顺序列表? → List
  • 要保证唯一性? → Set
  • 要按分数排序? → Sorted Set

记住:选择合适的数据结构,性能提升立竿见影!

在接下来的章节中,我们将深入Redis的持久化、高可用等高级特性。准备好迎接更精彩的Redis世界吧!

相关推荐
big_noob1 年前
centos7安装Redis单机版
数据库·redis·缓存·redis安装·redis安装教程·redis安装步骤·centos安装redis
DieSnowK1 年前
[Redis][Hash]详细讲解
redis·分布式·缓存·hash·使用场景·新手向·redis数据类型