Redis 快速入门

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

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

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

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

访问内存的速度跟访问硬盘的速度差距:

img

在后端服务中,一般会结合数据库来做缓存,最常用的是 redis。

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

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

使用 docker 开启 redis 容器

创建保存 redis 数据的 volume

docker volume create local-redis-volume

开启 redis 容器

bash
1docker run -d --name local-redis -p 6379:6379 -v local-redis-volume:/data redis

上面的命令做的事情:

  1. 会通过 git pull redis拉取 redis image
  2. redis image run 一个名为local-redis 的 container
  3. 容器与宿主机的映射为端口号为 6379:6379
  4. 将 redis 容器的/data挂载到local-redis-volume

下载 Redisinsight

这是 Redis 的 GUI 工具,非常好看。免费下载地址:https://redis.com/redis-enterprise/redis-insight/

image-20231021120112141

打开后可以看到已经有连接了,如果没有,则通过 ADD REDIS DATABASE 按钮添加

image-20231021120553804

命令

Strings

set 和 get 示例:

image-20231021123947141

incr 示例:

每执行一次,都会让 like +1。incr 常用于点赞、阅读等功能。

image-20231021124257603

Lists

这是一种列表的数据结构,有这些基本方法:

image-20231021124727262

添加:

bash
1LPUSH list1 "1"
2LPUSH list1 [2,3]

image-20231021125011052

LPUSH 是 left push 的意思,执行后会从左到右添加到列表中,类似array.unshift方法。

当然还有 RPUSH,类似于array.push方法:

bash
1RPUSH list1 "4"

现在查看一下 list1 的内容:

image-20231021130156644

LPOP 和 RPOP 自然是从左边和从右边删除数据,分别类似于array.shiftarray.pop方法。

image-20231021130529964

想要查看 Lists 数据结构的内容,需要用到 LRANGE ,语法是这样的:

bash
1LRANGE key start stop

示例一下

bash
1LRANGE list1 0 -1

结尾的-1 代表到最后,这样就可以查到 list1 全部的数据了。

image-20231021131004639

Sets

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

添加 Sets 数据:

bash
1SADD set1 1
2SADD set1 1
3SADD set1 2
4SADD set1 2
5SADD set1 3
6SADD set1 3

刷新后查看 set1 里都有哪些东西

image-20231021131327284

它已经将重复的给删除了。

判断是否是 Sets 里的数据:

bash
1SISMEMBER set1 1
2SISMEMBER set1 2
3SISMEMBER set1 5

Sorted sets

Sets 的仅用于去重而不能排序,如果想要去重加排序,则需要用到 Sorted sets。

它的基础命令有这些:

image-20231021132626553

它主要是使用 score 来排序:

bash
1ZADD racer_scores 10 "Norem"
2ZADD racer_scores 12 "Castilla"
3ZADD racer_scores 8 "Sam-Bodden" 10 "Royce" 6 "Ford" 14 "Prickett"

image-20231021132958357

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

bash
1ZRANGE racer_scores 0 2
bash
11) "Ford"
22) "Sam-Bodden"
33) "Norem"

Hashes

Hashes 跟我们使用的 map 差不多。它有这些基本命令:

image-20231021133338858

添加:

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

image-20231021133734670

获取:

bash
1HGET hash1 key1

geospatial

这是用来存储经纬度信息的,根据距离来计算周围的人。

文档里只显示两个 API,需要点开查看所有的 commands。

image-20231021134746237

bash
1GEOADD bikes:rentable -122.27652 37.805186 station:1
2GEOADD bikes:rentable -122.2674626 37.8062344 station:2

我们分别在 key 为bikes:rentable下给成员station:1station:2添加了经纬度信息。

image-20231021134550293

通过 GEODIST 计算两个坐标点的距离:

bash
1GEODIST bikes:rentable station:1 station:2

image-20231021135046011

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

bash
1GEORADIUS bikes:rentable -122.27652 37.805186 1000 km

image-20231021135427978

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

expire

一些有时效的数据可以设置个过期时间,通过 expire 命令。

bash
1EXPIRE hello 10

这个数据 10s 后就会删除。

Oct-21-2023 14-03-22

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

bash
1TTL <key>

数据库与 Redis 结合

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

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

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

一开始创建 redis 时我们就指定了 volume,也不怕 redis 容器丢失后数据会丢失。

bash
1docker run -d --name local-redis -p 6379:6379 -v local-redis-volume:/data redis

总结

由于数据库里的数据都存在硬盘里,直接读取的话可能会很慢,所以后端服务中常用的方式是将查询出来的数据缓存到 redis 里,下次直接读取 redis 里的数据,查询效率会高很多。

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

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

redis 还可以直接作为数据存储使用,不仅限于缓存的场景。由于是将数据存放在内存上读取,所以遇到非常多的数据时,需要做内存扩容。