目录
简介
通过 docker 的形式来跑:
set、get 都挺简单:
incr 是用于递增的:
keys 来查询有哪些 key:
redis insight GUI 工具。
list 类型
left push
rpush
lpop 和 rpop 自然是从左边和从右边删除数据。编辑
如果想查看数据呢?
set
sorted set(可排序)
zrange 命令取数据
hash
hget 获取key 编辑
geo
expire 过期时间
总结
简介
提到数据库,大家可能会想到 mysql,它是通过表和字段来存储信息的,表和表之间通过 id 关联,叫做关系型数据库。
它提供了 sql 语言,可以通过这种语言来描述对数据的增删改查。
mysql 是通过硬盘来存储信息的,并且还要解析并执行 sql 语句,这些决定了它会成为性能瓶颈。
也就是说服务端执行计算会很快,但是等待数据库查询结果就很慢了。
那怎么办呢?
计算机领域最经常考虑到的性能优化手段就是缓存了,能不能把结果缓存在内存中,下次只查内存就好了呢?
内存和硬盘的速度差距还是很大的:
所以做后端服务的时候,我们不会只用 mysql,一般会结合内存数据库来做缓存,最常用的是 redis。
因为需求就是缓存不同类型的数据,所以 redis 的设计是 key、value 的键值对的形式。
并且值的类型有很多:字符串(string)、列表(list)、集合(set)、有序集合(sorted set)、哈希表(hash)、地理信息(geospatial)、位图(bitmap)等。
我们分别来试一下。
redis 是分为服务端和客户端的,它提供了一个 redis-cli 的命令行客户端。
首先我们把 redis 服务跑起来。
通过 docker 的形式来跑:
下载一个 docker desktop 桌面端工具:
左边分别是镜像和镜像跑起来后的容器。
在搜索框搜索 redis,点击 run,把 redis 官方镜像下载并跑起来。
它会让你填一些容器的信息:
名字没啥好说的。
端口映射就是把主机的 6379 端口映射到容器内的 6379 端口,这样就能直接通过本机端口访问容器内的服务了。
volume 是数据卷,也就是挂载本地目录到容器的一个目录。
为什么要挂载数据卷呢?
因为镜像是不可修改的,每次运行都是全新的,但如果每次跑 redis 镜像,之前的数据都清空了可咋办?
所以要把本机的一个目录挂载上去,数据保存在本机。
跑起来之后是这样的:
容器内打印的日志说明 redis 服务跑起来了。
files 里可以看到所有的容器内的文件:
看到这个 mounted 的标志了没?
就代表这个目录是挂载的本地的一个目录。
我们在本地目录添加一个文件。
在容器内的 data 目录就能访问到这个文件了:
同样,在容器内修改了 data 目录,那本机目录下也会修改。
redis 服务跑起来之后,我们用 redis-cli 操作下。
在 terminal 输入 redis-cli,进入交互模式:
我们在这里做下 string 相关的操作:
文档里的命令有这么几个:
set、get 都挺简单:
incr 是用于递增的:
平时我们用的阅读量、点赞量等都是通过这个来计数的。
keys 来查询有哪些 key:
当我存了几个 key 后,可以通过 keys 来查询有哪些 key:
keys 后加一个模式串来过滤,常用的是 '*' 来查询所有 key。
redis insight GUI 工具。
这里我们切换成 GUI 工具吧,那个更直观一些。
这个就像 git 有人喜欢用命令行,有人喜欢用 GUI 工具一样。只是习惯问题,都可以。
我用的是 redis insight,一个 mac 上的开源 redis GUI 工具。
输入 ip 和端口之后点击连接:
就可以可视化看到所有的 key 和值:
同样也可以执行命令:
(不想装 GUI 工具的同学直接用 redis-cli 也是一样的,没啥区别)
list 类型
然后我们继续看 list 类型的数据结构:
文档中有这么几个命令:
我们试一下:
left push
lpush 是 left push 的意思,执行后会从左到右添加到列表中:
rpush
rpush 是 right push 的意思,执行后会从右往左添加到列表中:
lpop 和 rpop 自然是从左边和从右边删除数据。
如果想查看数据呢?
在 GUI 里直接点开看就行,但在命令行里呢?
有同学说,不就是 get 么?
是不行的,get 只适用于 string 类型的数据,list 类型的数据要用 lrange。
输入一段 range,结尾下标为 -1 代表到最后。lrange list1 0 -1 就是查询 list1 的全部数据。
set
接下来我们再来看看 set:
set 的特点是无序并且元素不重复。
当我添加重复数据的时候:
只保留去重后的数据:
可以通过 sismember 判断是否是集合中的元素:
set 只能去重、判断包含,不能对元素排序。
如果排序、去重的需求,比如排行榜,可以用 sorted set,也就是 zset,:
sorted set(可排序)
它每个元素是有一个分数的: 会按照分数来排序:
通过 zrange 命令取数据,比如取排名前三的数据:
zrange 命令取数据
通过 zrange 命令取数据,比如取排名前三的数据:
hash
接下来是 hash:
和我们用的 map 一样,比较容易理解:
hget 获取key
geo
再就是 geo 的数据结构,就是经纬度信息,根据距离计算周围的人用的:
平时我们查找周围的人、周围的 xxx 都可以通过 redis 的 geospatial 数据结构实现。
redis 的数据结构就先介绍到这里。
是不是感觉还挺简单的。
确实,redis 学习成本挺低的,过一遍就会了。
不过一般 redis 的 key 我们会设置过期时间,通过 expire 命令:
expire 过期时间
比如我设置guang1 的 key 为 3 秒过期:
3s 后就查不到了:
想查剩余过期时间使用 ttl:
一些有时效的数据可以设置个过期时间。
总结
因为 mysql 存在硬盘,并且会执行 sql 的解析,会成为系统的性能瓶颈,所以我们要做一些优化。
常见的就是在内存中缓存数据,使用 redis 这种内存数据库。
它是 key、value 的格式存储的,value 有很多种类型,比如 string、list、set、sorted set(zset)、hash、geopitial 等。
灵活运用这些数据结构,可以完成各种需求,比如排行榜用 zset、阅读数点赞数用 string、附近的人用 geopitial 等。
而且这些 key 都可以设置过期时间,可以完成一些时效性相关的业务。
通过 redis 的 npm 包就可以轻松的连接和操作 redis 了,如果在 nest 里,可以封装一个 provider,在里面使用 redis 的 npm 包创建连接。
redis 几乎和 mysql 一样是后端系统的必用中间件了,它除了用来做数据库的缓存外,还可以直接作为数据存储的地方。
学会灵活使用 redis,是后端开发很重要的一步。