Redis 安装部署和基本数据结构介绍


安装部署

Redis 是由意大利开发者 Salvatore Sanfilippo(antirez)通过 C 语言开发的、基于内存的、可持久化的开源键值对存储数据库(英文全称是 REmote DIctionary Server,中文译作远程字典服务器),由于其简单易用、高性能、支持丰富的数据结构和原子操作,已逐渐成为目前互联网最流行的存储中间件解决方案,被广泛应用于缓存、NoSQL、消息队列等技术领域。

网上关于 Redis 的简介和安装教程很多,这里不过多介绍了。如果是在 Mac 本地安装的话,可以使用 Homebrew 包管理器进行快速安装:

brew install redis

然后通过 redis-server 即可启动 Redis 服务器。

不过,不管是服务器还是本地,学院君更推荐使用 Docker 进行快速安装和部署,相关的教程网上也很多,我本地使用的是 Laradock 这个 PHP Docker 集成开发环境,通过如下命令即可启动 Redis 容器:

docker-compose up -d redis

客户端连接

启动成功后,就可以通过 Redis Docker 容器提供的客户端命令连接到在该容器中启动的 Redis 服务器了:

docker-compose exec redis redis-cli

-w780

你可以通过如下基准测试命令简单测试下部署在本地 Docker 容器中的 Redis 服务器同时处理 10 万个并发请求的性能:

docker-compose exec redis redis-benchmark -n 100000 -q

-w896

由于本地 Docker 容器默认的内存使用上限是 2G,CPU 是 4 核,即便如此,并发量也达到了 1.6w/s 左右,整体性能已经非常好了。

当然,你也可以像 MySQL 那样使用交互界面更加友好的图形化客户端软件连接到 Redis 服务器,比如 RDM

-w1138

或者支持 Redis 的 TablePlus

-w1177

如果你也使用的是 Laradock 开发环境的话,还可以使用其集成的 Redis Web 管理后台 —— redis-webui(封装了 phpMyRedis,你也可以自行搭建):

docker-compose up -d redis-webui

然后通过 http://127.0.0.1:9987 即可访问这个 Web 管理后台(用户名/密码是 laradock/laradock):

-w899

支持的数据结构

了解了 Redis 服务器的安装部署和客户端连接后,接下来我们来看下 Redis 支持的所有数据结构和基本使用(以命令行客户端为演示界面)。

当然了,网上相关的教程也多如牛毛,学院君这里会侧重结合实际项目应用场景进行介绍,同时也为接下来的各个业务场景 Redis 使用教程开一个头,做一个提纲挈领。

Redis 目前支持的数据结构包含以下五种:

  • String:字符串
  • List:列表
  • Set:集合
  • SortedSet:有序集合
  • Hash:哈希字典

字符串

首先来看最简单的字符串。

我们可以通过 SET 指令设置指定字符串的值:

-w733

然后通过 GET 指令获取该字符串的值:

-w722

非常简单,我们比较熟知的应用缓存功能通常都是基于这种字符串键值对实现的,当然了,很多缓存键存在有效期的概念,我们在设置缓存键值的时候,可以通过额外的 EX 参数指定有效期(单位:秒):

-w619

这里我们设置 username 有效期是 3 秒,过了 3 秒后就取不到对应的键值了,因为过期后该键值对会自动销毁,免除了我们自己去维护的麻烦,非常方便。

除了字符串格式的值外,还支持数字格式的值,我们可以利用这个特性实现计数器功能,比如浏览数、购买数、点赞数等,这个时候,我们可以使用 INCR 命令来初始化对应的键值:

-w576

获取还是通过 GET 指令,默认步长是 1,即每次调用 INCR 指令会将对应的键值 +1,此外,还可以通过 INCRBY 显式设置步长,比如我们在前面的基础上将步长设置为 5,可以这么做:

-w663

INCR/INCRBY 相对的是 DECR/DECRBY 指令,即对给定键值做 -1 操作或者做给定步长的减少操作(对应取消点赞之类的操作)。

当然,字符串键值还支持很多其他指令,这里就不一一列出了,你可以在 Redis 官网 Commands 页面进行查阅(在 Filter by group 下拉框选择对应的数据格式即可查看该数据格式支持的所有指令):

-w908

列表

接下来,我们来看另一个常见的数据结构 —— 列表。

列表类似于我们前面数据结构中介绍的链表,我们可以将元素添加到列表(支持从头部添加也支持从尾部添加),也可以从列表中移除并获取某个元素(支持从头部移除也支持从尾部移除),还可以读取整个列表的元素。

显然,我们可以基于 Redis 的列表实现类似栈和队列的数据结构,基于 Redis 的消息队列也正是基于这个数据结构实现的(后面介绍消息队列实现时我们会详细介绍)。

以队列为例,我们从尾部添加数据,从头部读取数据。

先通过 RPUSH 指令推送数据到队列末尾(通过键名 skills 命名):

-w639

推送成功后,你可以通过 LRANGE 指令获取列表中的所有元素(0 表示起始位置索引、-1 表示结束位置索引,你也可以通过其他索引值获取给定区间元素):

-w666

然后通过 LPOP 指令从队列头部移除并获取元素:

-w599

上述数据添加和获取符合「先入先出」规则,所以是一个标准的队列结构。

当然了,还有与之相对的 RPOPLPUSH 指令,你可以基于 LPUSHLPOP 实现栈这种数据结构,这里就不单独演示了。

更多 Redis 列表支持的指令可以在 Redis 官网 Commands 页面查阅:

-w909

集合

学过高中数学的同学对集合这个数学概念都不陌生,集合拥有确定性、互异性和无序性,对应到 Redis 里面的集合数据结构也是一样。

注:与集合不同,列表可以包含重复元素,列表内的元素顺序也和添加时的顺序一致。

确定性很好理解,你必须将一个确定的元素值添加到 Redis 集合,而不能把一个不确定的变量添加进去。

Redis 集合中所有元素都是互异的,即任意一个元素都是唯一的,当我们尝试向集合中添加相同元素时,会忽略后续添加的值,比如我们通过 SADD 指令尝试向 skills 集合添加两个相同的 PHP 元素:

-w689

第二次添加返回值是 0,表示添加失败,通过 SMEMBERS 列举集合时,也只有一个元素,表明 Redis 集合确实会自动帮我们做去重处理:

-w582

另外,Redis 集合具备无序性,所以当你向 skills 集合添加多个元素时,返回的结果和添加时的排序并不一致:

-w638

这当然是为了降低底层数据维护成本从而提升性能考虑。因此,我们如果尝试从 Redis 集合获取元素时,返回的结果值也是随机的,并不能确保给定位置的值是添加序列时的值,你可以看到 Redis Set 指令集中的 SPOP 返回值也确实是随机的:

-w897

当业务场景需要对集合数据做去重处理而又不需要确保数据顺序时,Redis 集合是个不错的选择。

有序集合

但有些时候我们的业务场景既要去重,又要确保排序,比如一些热门数据排行榜的实现,因此,Redis 还支持另一种数据结构 —— 有序集合。

顾名思义,有序集合就是在集合的基础上让内部元素有确定的排序,不过这个排序不是按照添加时的顺序,而是通过额外的排序字段值指定,还是以上面的例子为例。

我们将有序集合命名为 sorted_skills,然后通过 ZADD 指令向这个有序集合添加元素:

-w723

SADD 指令不同,在元素值之前插入了一个数值(score),在返回有序集合时,默认会根据这个数值进行升序排序:

-w669

LRANGE 指令一样,最后面的两个数字表示集合区间,前面是起始位置,后面是结束位置,-1 表示集合末尾索引值。

当然,你也可以通过 ZREVRANGE 指令返回基于排序字段的倒序排序结果:

-w627

还可以通过 WITHSCORES 选项在返回结果中包含排序字段值:

-w647

显然,有序集合非常适用于 Web 应用的一些排行榜功能,比如热门阅读、热门讨论等。

更多有序集合指令,请在 Redis Commands 界面查阅,这里就不一一展开了。

哈希字典

最后,我们来看哈希字典。

这种数据结构在很多语言中就是字典,但在 Redis 中英文名是 Hash,因为这些键值对字典中的键是基于 Hash 算法计算后存储的,从而确保唯一性。

对于 PHP 初级程序员而言,可能对列表、集合、字典这些数据结构不太熟悉,因为所有的数据结构都被 PHP 数组包圆了,不过 PHP 数组底层也是基于哈希表实现的,感兴趣的同学可以去看看其底层的实现原理。在 PHP 中,可以通过关联数组来类比哈希字典。

你可以通过 HSET 指令逐个添加字典元素:

-w628

在红框里,我们设定的字典名称是 student.1,字段名是 name,字段值是 lilei,其他两条指令类似,最终构建的是如下所示的字典结构:

{
    name: "lilei",
    class: 7,
    grade: "A"
}

你也可以通过 HMSET 指令一次性设置多个字典字段:

-w749

设置完成后,可以通过 HKEYS 指令获取所有键,通过 HVALS 指令获取所有值:

-w632

可以通过 HGET 指令获取单个字典字段值,也可以通过 HMGET 指令获取多个字典字段值,还可以通过 HGETALL 指令获取所有字典字段值:

-w653

关于 Redis 字典的应用场景自然就是 NoSQL 数据库了。

更多字典指令集请查阅 Redis Commands 页面 Hashes 指令

关于 Redis 支持的基本数据结构和使用我们就简单介绍到这里,从下篇教程开始,学院君将给大家演示如何通过这些数据结构实现各种不同的业务功能。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: 课程介绍 & 目录索引

>> 下一篇: 基于 Redis 实现 Laravel 全站访问 PV 统计中间件功能