第4章 Redis核心技术解析

原理、数据类型与数据操作 (纯理论篇)

面向大数据工程技术专业 · 理论精讲

本节课学习导航

1

Redis 概述与优势

认识这位“内存极速跑者”及四大特性

2

核心应用场景

会话、缓存、队列与排序

3

Redis vs MongoDB

两大NoSQL巨头大比拼

4

五大数据类型

掌握Redis的“收纳魔法”

4.1 Redis 概述

在敲代码之前,先来认识它的“灵魂”

什么是 Redis?

官方定义

Redis 是一个开源的、基于内存运行的 Key-Value (键值对) NoSQL 数据库。


  • NoSQL: Not Only SQL,非关系型数据库(没有表结构)。
  • Key-Value: 像查字典一样,通过名字(Key)找内容(Value)。

通俗理解

如果把我们之前学的 MySQL 数据库比作电脑的“机械硬盘”,容量大但找东西慢;

那么 Redis 就是电脑的“内存条”,容量有限,但速度快到飞起!

名字的由来

REmote DIctionary Server

翻译过来就是:远程字典服务器

想象一本放在网络上的超级字典,大家都可以用极快的速度去翻阅它。

Redis 的四大核心优点 (1/4)

1. 读写性能极高

Redis 是单机性能的天花板之一。


  • 读速度: 最高可达 110,000 次/秒。
  • 写速度: 最高可达 81,000 次/秒。

原因:完全基于内存操作,且使用单线程避免了上下文切换的损耗。

相当于一秒钟能翻完一整本新华字典!

Redis 的四大核心优点 (2/4)

2. 数据类型极其丰富

相比于其他简单的键值数据库(如 Memcached 只能存字符串),Redis 是一个“收纳大师”。


  • 支持 String (字符串)
  • 支持 List (列表/队列)
  • 支持 Hash (哈希/对象)
  • 支持 Set (无序集合)
  • 支持 ZSet (有序集合)

Redis 的四大核心优点 (3/4)

3. 具有“原子性”

什么是原子性?

“原子”在物理学中意为不可再分的最小单位。在计算机中,意思是一个操作要么彻底完成,要么完全不执行,绝不会停在中间状态。


生活比喻:
就像在食堂打饭排队,队伍是单行的。一旦轮到你,阿姨给你打饭的过程是连贯的,不会有人在中途插队打断她。

为什么原子性很重要?

假设双十一抢购,商品只剩 1 件,1000 个人同时点击“购买”。


因为 Redis 的操作是单线程排队的且具有原子性,系统绝对不会算错账把这 1 件商品卖给 2 个人(超卖现象)。

Redis 的四大核心优点 (4/4)

4. 支持丰富的个性化功能

除了当数据库用,Redis 还自带了很多“插件”功能:

发布与订阅

类似微信公众号,一个端发送消息,所有订阅的端都能立刻收到(常用于聊天室)。

持久化机制

虽然在内存运行,但它能定期把数据悄悄写到硬盘上,断电也不怕数据全丢。

地理位置计算

自带 Geospatial 功能,能瞬间算出两个经纬度之间的距离(如:附近的人)。

Redis 的四大经典应用场景

既然这么厉害,企业都在拿它干什么?

场景一:会话缓存 (Session Cache)

用户登录状态需要频繁读取,存在 MySQL 太慢,存在单台服务器上又无法实现分布式共享。

什么是会话?

就像你进入酒店办入住后拿到的房卡。你在酒店的各个设施游玩,刷房卡系统就知道是你。


为什么用 Redis?

大型网站有多台服务器,如果把房卡信息存在 Redis 这个统一的内存中心,用户无论访问哪台服务器,都能极速验证身份,且退出登录时能瞬间清空。

场景二:全页缓存 (FPC)

应对“双十一”级别的流量

有些网页非常复杂(比如淘宝首页),要从数据库里查商品、查推荐、查价格,拼装成一个完整的网页需要很久。


解决方案: 把拼装好的整个网页 HTML 代码,或者复杂的查询结果 JSON 字符串,直接塞进 Redis。


效果: 下一个用户再访问,直接从 Redis 内存里把这个页面“端”出来,速度提升百倍!

挡在 MySQL 前面的“盾牌”

90% 的查询请求都在 Redis 这里被拦截并直接返回了,保护了脆弱的 MySQL 数据库不被压垮。

场景三:消息队列 (Queues)

缓冲突发的请求

利用 List 列表特性

网站注册时,经常需要发送“激活邮件”或者“短信验证码”。这种操作很慢,如果让用户在网页上干等,体验极差。


做法:
把发送邮件的任务当成一个数据,塞进 Redis 的列表(队列)里。然后立刻告诉用户“注册成功”。

后台会有另一个程序,慢慢从 Redis 队列里把任务一个个拿出来去发邮件。这就叫“异步排队”。

场景四:计数与排序

海量高并发的计数

抖音热门视频,每秒钟可能有上千人同时点赞。

如果用关系型数据库,很容易锁死。Redis 利用其原子性的 INCR 命令,能在内存中轻松完成每秒数万次的加减法,绝不出错。

实时排行榜

Redis 独有的 ZSet (有序集合) 数据类型,天生就是为了排行榜而生的。

例如:游戏全服战力排行榜、微博热搜榜。只要把分数和名字扔给它,它永远在底层自动帮你排好序,查询第一名和第一万名速度一样快。

补充:Redis 不能做什么?

Redis 不是万能的,它也有自己的“软肋”

海量冷数据存储

内存非常昂贵!如果把几TB的历史聊天记录、日志文件存进Redis,老板会破产的。海量普通数据还是得靠硬盘。

复杂的关系查询

Redis没有表,没有主外键。无法执行类似 MySQL 中 JOIN 这种多表相互关联的复杂查询操作。

拓展:两大 NoSQL 巨头的大比拼

Redis

VS

MongoDB

先认识一下对手:MongoDB

什么是 MongoDB?

它也是一个 NoSQL(非关系型)数据库。但它的定位是“文档型数据库”


生活比喻:

如果说 Redis 是一个用来放高频使用物品的“桌面”,那么 MongoDB 就是一个极其灵活的大号文件柜

在这个文件柜里,你可以随便塞各种格式的纸张(JSON文档),不需要像 MySQL 那样必须提前规划好严格的表格(Schema)。

对比维度一:数据模型 (存什么格式)

Redis:键值对模型


严格的 Key-Value
无论你存的是字符串、列表还是集合,你永远只能通过 Key 去找到这个整体的 Value。

例如:找 key="user:1" 的值。

MongoDB:文档模型


存的是类似 JSON 的复杂文档。
文档里面可以嵌套文档、数组。而且你可以针对文档内部的某个小字段进行深度查询!

例如:查出所有“年龄大于20岁且城市在北京”的用户文档。

对比维度二:存储介质与速度

Redis:主打内存

数据主力放在内存中。
速度极快(微秒级),但断电易失,受限于服务器的内存条容量,成本非常高昂。

MongoDB:主打磁盘

数据主力存在硬盘上(通过内存映射加速)。
速度比 MySQL 快,但比 Redis 慢得多(毫秒级)。优势是能存海量数据(TB级),成本低。

对比总结:我们该怎么选?

在企业中,它们往往不是敌人,而是战友

选择 Redis 的情况:

  • 数据量不大,但读写极其频繁。
  • 做前置缓存,保护后端数据库。
  • 需要做排行榜、计数器、消息队列。
  • 对延迟要求苛刻(毫秒以内必须返回)。

选择 MongoDB 的情况:

  • 数据量极大,内存装不下。
  • 数据结构经常变动(无固定表结构)。
  • 需要存储大量复杂结构的数据(如:用户评论、商品爬虫数据)。
  • 需要通过各种字段进行条件检索。

4.3 Redis 基本命令

开始与 Redis 对话:指令就是我们的语言

通信测试:你在吗?

PING 命令

当我们在电脑上安装好客户端并连接后,第一件事应该是检查服务端是否活着,网络通不通。


这就像是在暗号对接:

  • 你发送:PING
  • Redis回应:PONG

127.0.0.1:6379> ping

PONG

※ 注:如果网络不通或服务未开启,这里会直接报错提示连接被拒绝。

库的切换:Redis 的 16 个房间

和 MySQL 可以自由创建 CREATE DATABASE db_name 不同,Redis 库是固定且预先创建好的。

  • 默认自带 16 个数据库。
  • 编号从 0 到 15
  • 客户端连上后,默认待在 0号库
  • 所有库共享Redis的内存,只是做了逻辑隔离。

SELECT 命令

用于在不同的数据库之间切换。


语法: SELECT 编号


127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> // 注意提示符变了,多了一个[1]

关于键(Key)的操作:查与看

不管数据存的是什么格式,Redis 永远是通过 Key 来找数据的。因此对 Key 的操作是基础中的基础。

1. 查看所有的 Key

命令: KEYS *

作用:列出当前库里的所有键名字。

⚠️ 警告:企业生产环境中严禁使用该命令!数据量大时会导致 Redis 假死(因为它是单线程排队的)。

2. 判断 Key 是否存在

命令: EXISTS 键名

作用:如果存在返回1,不存在返回0。

这个命令非常常用,在查询前先判断一下有没有这个数据,防止报错。

关于键(Key)的操作:删与类

3. 删除某个 Key

命令: DEL 键名

作用:将指定的 Key 连同它的 Value 一起从内存中彻底删除。如果删除成功返回1,不存在返回0。

4. 查看 Key 的数据类型

命令: TYPE 键名

作用:由于 Redis 里的值有五大类型,当我们忘记某个键存的是什么格式时,可以用此命令探测(返回 string, list, set, zset 或 hash)。

生命倒计时:最关键的过期策略

既然 Redis 是当“缓存”用的,而内存是有限的,就不能让数据永远占着茅坑不拉屎。必须给数据设定生命周期

设置过期时间

EXPIRE 键名 秒数


给已经存在的 Key 设置一个倒计时,时间一到,Redis 会自动把它“杀死”(删除)。

查看剩余时间

TTL 键名


TTL = Time To Live。返回剩余存活的秒数。

  • 返回 -1:永久存在
  • 返回 -2:已过期/不存在

现实场景

手机验证码


收到短信验证码提示“5分钟内有效”,底层其实就是执行了 EXPIRE code 300

4.4 支持的数据类型

Redis 的“收纳魔法”:五大经典数据结构

String, Hash, List, Set, ZSet

Redis 五大基本数据类型全景

注意:所谓的“类型”,其实都是指 Value(值) 的类型,Key 永远是字符串!

String

字符串

Hash

哈希/对象

List

列表/队列

Set

无序集合

ZSet

有序集合

4.4.1 String (字符串) - 概念

String 是 Redis 最基础、最常用 的数据类型。

比喻:一个贴了标签的纸盒子

  • 标签的名字就是 Key
  • 盒子里面装的唯一物品就是 Value
  • 这件物品可以是:一段普通文本、一个数字、甚至是一张图片的二进制流。
  • 规定:一个盒子最大只能装 512MB 的东西。
Key: "username"
"ZhangSan"

String - 基础读写

写入数据:SET

语法: SET key value

如果 Key 已经存在,则会覆盖原来的值。

127.0.0.1:6379> SET name "Tom"
OK
127.0.0.1:6379> SET age 20
OK

读取数据:GET

语法: GET key

如果 Key 不存在,则返回 nil(表示空)。

127.0.0.1:6379> GET name
"Tom"
127.0.0.1:6379> GET money
(nil)

String - 批量与自增

批量操作:MSET / MGET

嫌一条条写太慢?使用 M (Multiple) 指令。

  • MSET k1 v1 k2 v2
  • MGET k1 k2 k3

一次网络请求搞定多个数据,极大地提升效率。

数字自增减:INCR / DECR

如果字符串里存的是纯数字,可以使用自增命令。

  • INCR key:数值加 1
  • DECR key:数值减 1

这就是前面提到的“原子操作”,高并发下绝对不会算错(比如1000个人同时点赞)!

String - 典型应用场景

常规数据缓存

把数据库中查询出来的文章详情、商品信息转成 JSON 字符串,存入 Redis。下次用户访问直接从内存读,极大减轻 MySQL 压力。

计数器系统

利用 INCR 命令。比如贴吧的帖子浏览量、点赞数、或者限制某个API的一分钟访问次数(防刷防爬虫)。

短信验证码

将手机号作为 Key,验证码作为 Value,配合 EXPIRE 设置 5 分钟过期时间,实现完美闭环。

4.4.2 Hash (哈希) - 概念

如果说 String 是一个装了一样东西的纸盒子,那 Hash 就是一个带有很多抽屉的文件夹

本质:键值对的集合

  • 一个 Hash 的 Key 代表这个大文件夹的名字(比如:user:1001)。
  • 文件夹里面又分了很多“字段”(Field)和“值”(Value)。
  • 最适合存储“对象”(如一个人的姓名、年龄、性别)。

Key: "user:1001"

字段 (Field) 值 (Value)
name "张三"
age 20
city "北京"

Hash - 基本命令

存/取单个字段:HSET / HGET

在指定的哈希表里操作具体字段。

  • HSET key field value
  • HGET key field
127.0.0.1:6379> HSET user:1 name "Tom"
(integer) 1
127.0.0.1:6379> HGET user:1 name
"Tom"

获取全部/删除:HGETALL / HDEL

一次性取出全部字段和值,或删除指定字段。

  • HGETALL key
  • HDEL key field
127.0.0.1:6379> HGETALL user:1
1) "name"
2) "Tom"
3) "age"
4) "20"

4.4.3 List (列表) - 概念

List 是一个简单的字符串列表,按照插入顺序排序

比喻:一根两端开口的管子

  • 你可以从左边(Left)往里塞球。
  • 也可以从右边(Right)往里塞球。
  • 可以包含重复的元素。
  • 底层结构:实际上是一个双向链表。对两端的操作极快,但查询中间的元素较慢。

[ L : 左端 ]                       [ R : 右端 ]

C
B
A

想象排队买票:有人从前面插队,有人从后面排队。

List - 基本推入与弹出

塞入数据:LPUSH / RPUSH

  • LPUSH key value:从左侧(头部)塞入
  • RPUSH key value:从右侧(尾部)塞入
// 依次把 1, 2 放入左侧
127.0.0.1:6379> LPUSH list1 1 2
(integer) 2
// 此时管子里的顺序是:[2, 1]

取出并删除:LPOP / RPOP

  • LPOP key:从左侧吐出一个并删除
  • RPOP key:从右侧吐出一个并删除

注意:POP操作就像把球拿走了,管子里就没这个球了!如果管子空了,连 Key 都会被系统自动删除。

List - 范围查看与应用

只看不删:LRANGE

如果我只想看看管子里有哪些数据,不拿走怎么办?

  • LRANGE key start stop
  • 查全部:LRANGE key 0 -1

注:-1 代表列表的最后一个元素。

应用场景:简单的消息队列

利用一头进、另一头出的特性(FIFO 先进先出),非常适合处理前面提到过的发送邮件任务排队。


应用场景:最新动态浏览

利用 LPUSH 将最新的文章ID推入列表头部,用户总是使用 LRANGE 0 9 获取最新的10条动态(朋友圈、微博时间线)。

4.4.4 Set (集合) - 概念

Set 是一个无序不重复的元素桶。

比喻:一个魔法收纳桶

你往里面扔相同的乒乓球,它会自动帮你把重复的变消失,保证桶里的每一个球都是独一无二的。且球在里面是打乱的,没有先后顺序。

与 List 的对比

  • List:有序,允许重复。
  • Set:无序,绝对不允许重复

Set - 基本操作

添加与查看

  • SADD key value1 value2:往集合里加元素。如果加了重复的,会被自动忽略。
  • SMEMBERS key:查看集合里所有的元素(查出来的顺序可能是乱的)。
127.0.0.1:6379> SADD myset a b c a
(integer) 3 // 最后一个a重复了,没加进去

判断是否存在

  • SISMEMBER key value:判断某元素是否在集合内。存在返回1,不存在返回0。

这个命令速度极快,不管桶里有十万还是百万个球,瞬间就能告诉你某个球在不在里面。

Set - 典型应用:社交与标签

1. 标签系统 (Tags)

给用户打标签。一个用户不能有同一个标签两次。
例如:张三被打了 "程序员", "宅男", "游戏迷" 标签。用 Set 的去重特性来存再合适不过。

2. 社交“交集” (共同好友)

Set 支持强大的数学集合运算!

  • 张三的好友集合:A, B, C
  • 李四的好友集合:B, C, D
  • 使用 SINTER (交集) 命令,瞬间算出他们的共同好友是 B, C

4.4.5 ZSet (有序集合) - 概念

ZSet 全称 Sorted Set,是 Redis 中最特殊、也最有魅力的类型之一。

比喻:带有成绩的运动会报名表

  • 它首先是一个 Set,保证了里面的成员(Member)绝对不重复。
  • 但是,它给每个成员都强制绑定了一个分数(Score)
  • Redis 会在底层根据这个分数,自动帮你把所有人从低到高排好队!

王者荣耀段位排行榜 (Key: "rank")

Member (玩家) Score (星星数)
玩家 A 80
玩家 B 65
玩家 C 12

内部永远保持按 Score 自动排序

ZSet - 基本操作

添加带分数的数据

  • ZADD key score member
// 语法注意:分数在前,名字在后
127.0.0.1:6379> ZADD rank 100 "Tom"
(integer) 1
127.0.0.1:6379> ZADD rank 90 "Jerry"

按排名范围查询

  • ZRANGE key start stop (从小到大排)
  • ZREVRANGE key start stop (从大到小排,Reverse)

例如:获取前三名,使用 ZREVRANGE rank 0 2 即可。

ZSet - 无敌的应用场景:排行榜

凡是遇到“榜单”,首选 ZSet!

微博热搜榜:将热度值作为 Score,话题作为 Member。
直播间送礼榜:将刷礼物的金额作为 Score,用户ID作为 Member。
学生成绩排名:将考试分数作为 Score,学号作为 Member。

本课理论大总结

  • Redis 身份:基于内存的 Key-Value 数据库,单线程、极速、原子性。
  • 四大场景:会话统一管理、全页缓存抗压、队列异步排队、ZSet轻松排序。
  • 键的操作:掌握 DEL, EXISTS, TYPE 以及最重要的 EXPIRE (设置过期)
  • 五大类型:String(纸盒), Hash(文件夹), List(管子), Set(去重桶), ZSet(排名表)。

理论课到此结束!

感谢大家的聆听

🚀 下节实验课预告:我们将进入机房,在电脑上实战敲击今天学过的所有命令!