夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Node基础

  • 《MySQL》学习笔记

  • Midway

  • Nest

    • 开篇词
    • 学习理由
    • nest概念扫盲
    • 快速掌握 nestcli
    • 5种http数据传输方式
    • IoC 解决了什么痛点问题?
    • 如何调试 Nest 项目
    • Provider注入对象
    • 全局模块和生命周期
    • AOP 架构有什么好处?
    • 一网打尽 Nest 全部装饰器
    • Nest如何自定义装饰器
    • Metadata和Reflector
    • ExecutionContext切换上下文
    • Module和Provider的循环依赖处理
    • 如何创建动态模块
    • Nest和Express,fastify
    • Nest的Middleware
    • RxJS和Interceptor
    • 内置Pipe和自定义Pipe
    • ValidationPipe验证post请求参数
    • 如何自定义 Exception Filter
    • 图解串一串 Nest 核心概念
    • 接口如何实现多版本共存
    • Express如何使用multer实现文件上传
    • Nest使用multer实现文件上传
    • 图书管理系统
    • 大文件分片上传
    • 最完美的 OSS 上传方案
    • Nest里如何打印日志
    • 为什么Node里要用Winston打印日志
    • Nest 集成日志框架 Winston
    • 通过Desktop学Docker也太简单了
    • 你的第一个 Dockerfile
    • Nest 项目如何编写 Dockerfile
    • 提升 Dockerfile 水平的 5 个技巧
    • Docker 是怎么实现的
    • 为什么 Node 应用要用 PM2 来跑?
    • 快速入门 MySQL
    • SQL 查询语句的所有语法和函数
    • 一对一、join 查询、级联方式
    • 一对多、多对多关系的表设计
    • 子查询和 EXISTS
    • SQL 综合练习
    • MySQL 的事务和隔离级别
    • MySQL 的视图、存储过程和函数
    • Node 操作 MySQL 的两种方式
    • 快速掌握 TypeORM
    • TypeORM 一对一的映射和关联 CRUD
    • TypeORM 一对多的映射和关联 CRUD
    • TypeORM 多对多的映射和关联 CRUD
    • 在 Nest 里集成 TypeORM
    • TypeORM保存任意层级的关系
    • 生产环境为什么用TypeORM的migration迁移功能
    • Nest 项目里如何使用 TypeORM 迁移
    • 如何动态读取不同环境的配置?
    • 快速入门 Redis
      • 首先我们把 redis 服务跑起来。
      • 它会让你填一些容器的信息:
      • 指定数据卷,用本机的任意一个目录挂载到容器内的 /data 目录,这样数据就会保存在本机。
      • redis 服务跑起来之后,我们用 redis-cli 操作下。
        • 在 terminal 输入 redis-cli,进入交互模式:
        • 文档里的命令有这么几个:
        • set、get 都挺简单:
        • incr 是用于递增的:
        • 当我存了几个 key 后,可以通过 keys 来查询有哪些 key:
        • 然后再来看看 list。
      • 我用的是官方的 RedisInsight,它号称是最好的 Redis GUI 工具:
        • 然后我们继续看 list 类型的数据结构:
        • 接下来我们再来看看 set:
        • 如果排序、去重的需求,比如排行榜,可以用 sorted set,也就是 zset,:
        • 接下来是 hash:
        • 再就是 geo 的数据结构,就是经纬度信息,根据距离计算周围的人用的。
        • 一般 redis 的 key 我们会设置过期时间,通过 expire 命令。
      • 总结
    • 在 Nest 里操作 Redis
    • 为什么不用 cache-manager 操作 Redis
    • 两种登录状态保存方式:JWT、Session
    • Nest 里实现 Session 和 JWT
    • MySQL + TypeORM + JWT 实现登录注册
    • 基于 ACL 实现权限控制
    • 基于 RBAC 实现权限控制
    • access_token和refresh_token实现无感登录
    • 单token无限续期实现登录无感刷新
    • 使用 passport 做身份认证
    • passport 实现 GitHub 三方账号登录
    • passport 实现 Google 三方账号登录
    • 为什么要使用 Docker Compose ?
    • Docker 容器通信的最简单方式:桥接网络
    • Docker 支持重启策略,是否还需要 PM2
    • 快速掌握 Nginx 的 2 大核心用法
    • 基于 Nginx 实现灰度系统
    • 基于 Redis 实现分布式 session
    • Redis + 高德地图,实现附近的充电宝
    • 用 Swagger 自动生成 api 文档
    • 如何灵活创建 DTO
    • class- validator 的内置装饰器,如何自定义装饰器
    • 序列化 Entity,你不需要 VO 对象
    • 手写序列化 Entity 的拦截器
    • 使用 compodoc 生成文档
    • Node 如何发邮件?
    • 实现基于邮箱验证码的登录
    • 基于 sharp 实现 gif 压缩工具
    • 大文件如何实现流式下载?
    • Puppeteer 实现爬虫,爬取 BOSS 直聘全部前端岗位
    • 实现扫二维码登录
    • Nest 的 REPL 模式
    • 实现 Excel 导入导出
    • 如何用代码动态生成 PPT
    • 如何拿到服务器 CPU、内存、磁盘状态
    • Nest 如何实现国际化?
    • 会议室预订系统:需求分析和原型图
    • 会议室预订系统:技术方案和数据库设计
    • 会议室预订系统:用户管理模块--用户注册
    • 会议室预订系统:用户管理模块--配置抽离、登录认证鉴权
    • 会议室预订系统:用户管理模块-- interceptor、修改信息接口
    • 会议室预订系统:用户管理模块--用户列表和分页查询
    • 会议室预订系统:用户管理模块-- swagger 接口文档
    • 会议室预订系统:用户管理模块-- 用户端登录注册页面
    • 会议室预订系统:用户管理模块-- 用户端信息修改页面
    • 会议室预订系统:用户管理模块-- 头像上传
    • 会议室预订系统:用户管理模块-- 管理端用户列表页面
    • 会议室预订系统:用户管理模块-- 管理端信息修改页面
    • 会议室预订系统:会议室管理模块-后端开发
    • 会议室预订系统:会议室管理模块-管理端前端开发
    • 会议室预订系统:会议室管理模块-用户端前端开发
    • 会议室预订系统:预定管理模块-后端开发
    • 会议室预订系统:预定管理模块-管理端前端开发
    • 会议室预订系统:预定管理模块-用户端前端开发
    • 会议室预订系统:统计管理模块-后端开发
    • 会议室预订系统:统计管理模块-前端开发
    • 会议室预订系统:后端项目部署到阿里云
    • 会议室预订系统:前端项目部署到阿里云
    • 会议室预定系统:用 migration 初始化表和数据
    • 会议室预定系统:文件上传 OSS
    • 会议室预定系统:Google 账号登录后端开发
    • 会议室预定系统:Google 账号登录前端开发
    • 会议室预定系统:后端代码优化
    • 会议室预定系统:集成日志框架 winston
    • 会议室预定系统:前端代码优化
    • 会议室预定系统:全部功能测试
    • 会议室预定系统:项目总结
    • Nest 如何创建微服务?
    • Nest 的 Monorepo 和 Library
    • 用 Etcd 实现微服务配置中心和注册中心
    • Nest 集成 Etcd 做注册中心、配置中心
    • 用 Nacos 实现微服务配置中心和注册中心
    • 基于 gRPC 实现跨语言的微服务通信
    • 快速入门 ORM 框架 Prisma
    • Prisma 的全部命令
    • Prisma 的全部 schema 语法
    • Primsa Client 单表 CRUD 的全部 api
    • Prisma Client 多表 CRUD 的全部 api
    • 在 Nest 里集成 Prisma
    • 为什么前端监控系统要用 RabbitMQ?
    • 基于 Redis 实现关注关系
    • 基于 Redis 实现各种排行榜(周榜、月榜、年榜)
    • 考试系统:需求分析
    • 考试系统:技术方案和数据库设计
    • 考试系统:微服务、Lib 拆分
    • 考试系统;用户注册
    • 考试系统:用户登录、修改密码
    • 考试系统:考试微服务
    • 考试系统:登录、注册页面
    • 考试系统:修改密码、试卷列表页面
    • 考试系统:新增试卷、回收站
    • 考试系统:试卷编辑器
    • 考试系统:试卷回显、预览、保存
    • 考试系统:答卷微服务
    • 考试系统:答题页面
    • 考试系统:自动判卷
    • 考试系统:分析微服务、排行榜页面
    • 考试系统:整体测试
    • 考试系统:项目总结
    • 用 Node.js 手写 WebSocket 协议
    • Nest 开发 WebSocket 服务
    • 基于 Socket.io 的 room 实现群聊
    • 聊天室:需求分析和原型图
    • 聊天室:技术选型和数据库设计
    • 聊天室:用户注册
    • 聊天室:用户登录
    • 聊天室:修改密码、修改信息
    • 聊天室:好友列表、发送好友申请
    • 聊天室:创建聊天室、加入群聊
    • 聊天室:登录、注册页面开发
    • 聊天室:修改密码、信息页面开发
    • 聊天室:头像上传
    • 聊天室:好友∕群聊列表页面
    • 聊天室:添加好友弹窗、通知页面
    • 聊天室:聊天功能后端开发
    • 聊天室:聊天功能前端开发
    • 聊天室:一对一聊天
    • 聊天室:创建群聊、进入群聊
    • 聊天室:发送表情、图片、文件
    • 聊天室:收藏
    • 聊天室:全部功能测试
    • 聊天室:项目总结
    • MongoDB 快速入门
    • 使用 mongoose 操作 MongoDB 数据库
    • GraphQL 快速入门
    • Nest 开发 GraphQL 服务:实现 CRUD
    • GraphQL + Primsa + React 实现 TodoList
    • 如何调试 Nest 源码?
  • 其他

  • 服务端
  • Nest
神说要有光
2025-03-10
目录

快速入门 Redis

前面我们学了 mysql,它是通过表和字段来存储信息的,表和表之间通过 id 关联,叫做关系型数据库。

它提供了 sql 语言,可以通过这种语言来描述对数据的增删改查。

mysql 是通过硬盘来存储信息的,并且还要解析并执行 sql 语句,这些决定了它会成为性能瓶颈。

也就是说服务端执行计算会很快,但是等待数据库查询结果就很慢了。

那怎么办呢?

计算机领域最经常考虑到的性能优化手段就是缓存了。

能不能把结果缓存在内存中,下次只查内存就好了呢?

内存和硬盘的速度差距还是很大的:

所以做后端服务的时候,我们不会只用 mysql,一般会结合内存数据库来做缓存,最常用的是 redis。

因为需求就是缓存不同类型的数据,所以 redis 的设计是 key、value 的键值对的形式。

并且值的类型有很多:字符串(string)、列表(list)、集合(set)、有序集合(sorted set)、哈希表(hash)、地理信息(geospatial)、位图(bitmap)等。

我们分别来试一下。

redis 是分为服务端和客户端的,它提供了一个 redis-cli 的命令行客户端。

# 首先我们把 redis 服务跑起来。

在 docker desktop 搜索框搜索 redis,点击 run,把 redis 官方镜像下载并跑起来。

# 它会让你填一些容器的信息:

端口映射就是把主机的 6379 端口映射到容器内的 6379 端口,这样就能直接通过本机端口访问容器内的服务了。

# 指定数据卷,用本机的任意一个目录挂载到容器内的 /data 目录,这样数据就会保存在本机。

跑起来之后是这样的:

容器内打印的日志说明 redis 服务跑起来了。

files 里可以看到所有的容器内的文件:

看到这个 mounted 的标志了没?

就代表这个目录是挂载的本地的一个目录。

我们在本地目录添加一个文件。

在容器内的 data 目录就能访问到这个文件了:

同样,在容器内修改了 data 目录,那本机目录下也会修改。

# redis 服务跑起来之后,我们用 redis-cli 操作下。

# 在 terminal 输入 redis-cli,进入交互模式:

我们在这里做下 string 相关的操作:

# 文档 (opens new window)里的命令有这么几个:

# set、get 都挺简单:

# incr 是用于递增的:

平时我们用的阅读量、点赞量等都是通过这个来计数的。

# 当我存了几个 key 后,可以通过 keys 来查询有哪些 key:

keys 后加一个模式串来过滤,常用的是 '*' 来查询所有 key。

# 然后再来看看 list。

这里我们切换成 GUI 工具吧,那个更直观一些。

这个就像 git 有人喜欢用命令行,有人喜欢用 GUI 工具一样。只是习惯问题,都可以。

# 我用的是官方的 RedisInsight (opens new window),它号称是最好的 Redis GUI 工具:

输入操作系统信息,还有邮箱、姓名、职业、手机号等信息,就可以下载安装包了。

安装后就是这个东西:

点击 add database:

连接信息用默认的就行:

然后就可以看到新建的这个链接:

点击它就可以可视化看到所有的 key 和值:

同样也可以执行命令:

# 然后我们继续看 list 类型的数据结构:

文档中有这么几个命令:

我们试一下:

lpush list1 111
lpush list1 222
lpush list1 333

输入上面的命令,点击执行:

然后回到浏览页面,点击刷新,就可以看到新的 key 和它的值:

这就是一个列表的结构。

lpush 是 left push 的意思,执行后会从左到右添加到列表中。

rpush 是 right push 的意思,执行后会从右往左添加到列表中:

rpush list1 444
rpush list1 555

lpop 和 rpop 自然是从左边和从右边删除数据。

lpop list1

rpop list1

如果想查看 list 数据呢?

在 GUI 里直接点开看就行,但在命令行里呢?

有同学说,不就是 get 么?

是不行的,get 只适用于 string 类型的数据,list 类型的数据要用 lrange。

lrange list1 0 -1

输入一段 range,结尾下标为 -1 代表到最后。lrange list1 0 -1 就是查询 list1 的全部数据。

# 接下来我们再来看看 set:

set 的特点是无序并且元素不重复。

当我添加重复数据的时候:

sadd set1 111
sadd set1 111
sadd set1 111
sadd set1 222
sadd set1 222
sadd set1 333

刷新之后可以看到它只保留去重后的数据:

可以通过 sismember 判断是否是集合中的元素:

sismember set1 111

sismember set1 444

set 只能去重、判断包含,不能对元素排序。

# 如果排序、去重的需求,比如排行榜,可以用 sorted set,也就是 zset,:

它每个元素是有一个分数的:

zadd zset1 5 guang
zadd zset1 4 dong
zadd zset1 3 xxx
zadd zset1 6 yyyy

会按照分数来排序:

通过 zrange 命令取数据,比如取排名前三的数据:

zrange zset1 0 2

# 接下来是 hash:

和我们用的 map 一样,比较容易理解:

hset hash1 key1 1
hset hash1 key2 2
hset hash1 key3 3
hset hash1 key4 4
hset hash1 key5 5

hget hash1 key3

# 再就是 geo 的数据结构,就是经纬度信息,根据距离计算周围的人用的。

我们试一下:

geoadd loc 13.361389 38.115556 "guangguang" 15.087269 37.502669 "dongdong"

用 loc 作为 key,分别添加 guangguang 和 dongdong 的经纬度

你会发现 redis 实际使用 zset 存储的,把经纬度转化为了二维平面的坐标:

你可以用 geodist 计算两个坐标点的距离:

geodist loc guangguang dogndong

用 georadius 搜索某个半径内的其他点,传入经纬度、半径和单位:

georadius loc 15 37 100 km
georadius loc 15 37 200 km

平时我们查找周围的人、周围的 xxx 都可以通过 redis 的 geo 数据结构实现。

# 一般 redis 的 key 我们会设置过期时间,通过 expire 命令。

比如我设置 dong1 的 key 为 30 秒过期:

expire dogn1 30

等到了过期时间就会自动删除:

想查剩余过期时间使用 ttl:

一些有时效的数据可以设置个过期时间。

redis 的数据结构就先介绍到这里。

所有的命令都可以在官方文档查: https://redis.io/commands/ (opens new window)

是不是感觉还挺简单的。

确实,redis 学习成本挺低的,过一遍就会了。

回到最开始的问题,我们完全可以查出数据来之后放到 redis 中缓存,下次如果 redis 有数据就直接用,没有的话就查数据库然后更新 redis 缓存。

这是 redis 的第一种用途,作为数据库的缓存,也是主要的用途。

第二种用途就是直接作为存储数据的地方了,因为 redis 本身是会做持久化的,也可以把数据直接保存在 redis 里,不存到 mysql。

当然,因为 redis 在内存存储数据,这样成本还是比较高的,需要经常扩容。

最后,还记得我们跑 redis 的 docker 镜像时指定了数据卷么:

可以看到它确实把数据保存到了宿主机,这样就不怕再跑一个容器数据会丢了:

# 总结

这节我们学习了 redis。

因为 mysql 存在硬盘,并且会执行 sql 的解析,会成为系统的性能瓶颈,所以我们要做一些优化。

常见的就是在内存中缓存数据,使用 redis 这种内存数据库。

它是 key、value 的格式存储的,value 有很多种类型,比如 string、list、set、sorted set(zset)、hash、geo 等。

灵活运用这些数据结构,可以完成各种需求,比如排行榜用 zset、阅读数点赞数用 string、附近的人用 geo 等。

而且这些 key 都可以设置过期时间,可以完成一些时效性相关的业务。

用官方 GUI 工具 RedisInsight 可以可视化的操作它,很方便。

redis 几乎和 mysql 一样是后端系统的必用中间件了,它除了用来做数据库的缓存外,还可以直接作为数据存储的地方。

学会灵活使用 redis,是后端开发很重要的一步。

编辑 (opens new window)
上次更新: 2025/9/2 10:26:16
如何动态读取不同环境的配置?
在 Nest 里操作 Redis

← 如何动态读取不同环境的配置? 在 Nest 里操作 Redis→

最近更新
01
H5调用微信jssdk
09-28
02
VueVirtualScroller
09-19
03
IoC 解决了什么痛点问题?
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式