- Redis入门指南(第3版)
- 李子骅
- 4988字
- 2021-10-27 17:10:12
第2章 准备
“纸上得来终觉浅,绝知此事要躬行。”
——陆游《冬夜读书示子聿》
学习Redis最好的办法就是动手尝试它。在介绍Redis的核心内容之前,本章先来介绍一下如何安装和运行Redis,以及Redis的基础知识,使读者可以在之后的章节中一边学习一边实践。
2.1 安装Redis
安装Redis是开始Redis学习之旅的第一步。在安装Redis前需要了解Redis的版本规则,以选择最适合自己的版本,Redis约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版(如5.0版、6.2版),为奇数的版本是非稳定版(如5.3版、6.1版),生产环境下一般需要使用稳定版本。本书的内容基于 6.0 版编写,同时绝大部分内容也适用于以前的版本。对于部分只在最新版才有的特性,本书会做特别说明。
2.1.1 在POSIX中安装
Redis兼容大部分POSIX操作系统,包括Linux、macOS和BSD等,在这些操作系统中,可以直接下载Redis源代码并进行编译安装,以获得最新的稳定版本。Redis最新稳定版本的源代码可以从Redis官方网站下载。
下载安装包后解压即可使用make命令完成编译,完整的命令如下:
wget http://download.redis.io/redis-stable.tar.gz tar xzf redis-stable.tar.gz cd redis-stable make
Redis没有其他外部依赖,安装过程很简单。编译后在Redis源代码目录的src文件夹中可以找到若干可执行程序,最好在编译后直接执行make install命令来将这些可执行程序复制到/usr/local/bin目录中,以便以后执行程序时可以不用输入完整的路径。
在实际运行Redis前,推荐使用make test命令测试Redis是否编译正确,尤其是在编译一个不稳定版本的Redis时。
提示
除了手动编译,还可以使用操作系统中的软件包管理器来安装Redis,但目前大多数软件包管理器中的Redis的版本都比较古老。考虑到 Redis 的每次升级都提供了对以往版本的问题修复和性能提升,使用最新版本的 Redis 往往可以提供更加稳定的体验。如果希望享受包管理器带来的便利,在安装前请确认您使用的软件包管理器中Redis的版本并了解该版本与最新版之间的差异。Redis官网的“Problems with Redis? This is a good starting point.”中列举了一些在以往版本中存在的已知问题。
另外,Ubuntu用户可以使用官方提供的仓库 redislabs/redis 来方便地安装最新的稳定版本:
sudo add-apt-repository ppa:redislabs/redis sudo apt-get update sudo apt-get install redis
2.1.2 在macOS中安装
macOS下的软件包管理工具Homebrew提供了较新版本的Redis包,所以我们可以直接使用它们来安装Redis,省去了像其他POSIX操作系统那样需要手动编译的麻烦。下面以使用Homebrew安装Redis为例。
1.安装Homebrew
在终端输入如下命令即可安装Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/ install.sh)"
也可以参照Homebrew的官方网站获取其他的安装方式。如果之前安装过Homebrew,请执行brew update来更新Homebrew,以便安装较新版的Redis。
2.通过Homebrew安装Redis
使用brew install软件包名可以安装相应的包,此处执行brew install redis来安装Redis:
$ brew install redis ==> Downloading https:// *****redis-6.0.9.big_sur.bottle.tar.gz ==> Downloading from https:// *****redis-6.0.9.big_sur.bottle.tar ######################################################################## 100.0% ==> Reinstalling redis ==> Pouring redis-6.0.9.big_sur.bottle.tar.gz ==> Caveats To have launchd start redis now and restart at login: brew services start redis Or, if you don't want/need a background service you can just run: redis-server /usr/local/etc/redis.conf ==> Summary /usr/local/Cellar/redis/6.0.9: 13 files, 3.9MB
在安装结果中,Homebrew贴心地提示了如何启动Redis并让其随操作系统自动运行:
brew services start redis
以此方式运行的Redis会加载位于/usr/local/etc/redis.conf的配置文件,关于配置文件的内容会在2.4节中介绍。
2.1.3 在Windows中安装
Redis官方不支持Windows。有趣的是,微软[1]早在2011年向Redis提交了一个补丁,以使Redis可以在Windows下编译运行,但被Salvatore Sanfilippo拒绝了,原因是Linux在服务器领域中已经得到了广泛的使用,这让Redis能在Windows下运行相比而言显得不那么重要。并且Redis使用了如写时复制等很多操作系统相关的特性,要使这些特性兼容Windows会耗费太多的精力而影响Redis其他功能的开发。尽管如此,微软还是发布了一个可以在Windows运行的Redis分支[2],不过目前已经停止维护。
如果想使用Windows学习或测试,目前有如下一些方法。
(1)在 Windows 中安装虚拟机(如VirtualBox),并在其中的 Linux 操作系统安装Redis。
(2)类似于方法(1),可以直接使用Docker来安装和运行Redis。
(3)Windows 10提供了适用于Linux的Windows子系统(Windows Subsystem for Linux,WSL),可以在其上安装Redis。
(4)使用Memurai。Memurai是一个第三方开发商维护的专门运行于Windows的Redis版本。这个开发商在2013年时就开始参与前文提到的微软维护的分支的开发,后来独立出Memurai。Memurai是商业软件,以开发为目的使用是免费的,但是如果用于生产环境则需要付费。
这里以方法(3)为例,简要介绍一下安装方法。
(1)参照微软官方文档[3],启用WSL。
(2)在Microsoft Store中安装一个支持的Linux发行版,考虑到前文提到的Redis官方提供了Ubuntu的官方仓库,Ubuntu是一个比较好的选择。
(3)接下来的步骤可以参照2.1.1节,这里不再赘述。
注意
Redis官方并没有针对Windows提供第一方的支持,所以本节提到的前3种方法只适合在开发环境中运行和使用Redis。运行Redis的最佳操作系统仍然是Linux和macOS,官方推荐的生产操作系统是Linux。
2.2 启动和停止Redis
安装完Redis后的下一步就是启动它,本节将分别介绍在开发环境和生产环境中启动Redis的方法以及正确停止Redis的步骤。
在这之前首先需要了解Redis包含哪些可执行文件,表2-1中列出了这些文件名以及对应的说明。如果在编译后执行了make install命令,这些文件会被复制到/usr/local/bin目录下,所以在命令行中直接输入文件名即可执行。
表2-1 Redis可执行文件及说明
我们最常使用的两个文件是redis-server和redis-cli,其中redis-server是Redis的服务器,启动Redis即执行redis-server;而redis-cli是Redis自带的Redis命令行客户端,是学习Redis的重要工具,在2.3节中会详细介绍它。
2.2.1 启动Redis
启动Redis有直接启动和通过初始化脚本启动两种方式,分别适用于开发环境和生产环境。
1.直接启动
直接执行redis-server即可启动Redis,十分简单:
$ redis-server 823:C # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 823:C # Redis version=6.2.1, bits=64, commit=00000000, modified=0, pid=823, just started 823:M * Increased maximum number of open files to 10032 (it was originally set to 256). 823:M * monotonic clock: POSIX clock_gettime ... 823:M # Server initialized 823:M * Ready to accept connections
Redis服务器默认使用6379号端口,通过--port参数可以自定义端口号:
$ redis-server --port 6380
2.通过初始化脚本启动
在Linux操作系统中可以通过初始化脚本启动Redis,使Redis能随操作系统自动运行,在生产环境中推荐使用此方法启动 Redis,这里以Ubuntu和Debian发行版为例进行介绍。在Redis源代码目录的utils文件夹中有一个名为redis_init_script的初始化脚本文件,其内容如下:
#!/bin/sh # # Simple Redis init.d script conceived to work on Linux systems # as it does use of the /proc filesystem. REDISPORT=6379 EXEC=/usr/local/bin/redis-server CLIEXEC=/usr/local/bin/redis-cli PIDFILE=/var/run/redis_${REDISPORT}.pid CONF="/etc/redis/${REDISPORT}.conf" case "$1" in start) if [ -f $PIDFILE ] then echo "$PIDFILE exists, process is already running or crashed" else echo "Starting Redis server..." $EXEC $CONF fi ;; stop) if [ ! -f $PIDFILE ] then echo "$PIDFILE does not exist, process is not running" else PID=$(cat $PIDFILE) echo "Stopping ..." $CLIEXEC -p $REDISPORT shutdown while [ -x /proc/${PID} ] do echo "Waiting for Redis to shutdown ..." sleep 1 done echo "Redis stopped" fi ;; *) echo "Please use start or stop as first argument" ;; esac
我们需要配置Redis的运行方式和持久化文件、日志文件的存储位置等,具体步骤如下。
(1)配置初始化脚本。首先将初始化脚本复制到/etc/init.d目录下,文件名为redis_端口号,其中端口号表示要让Redis监听的端口号,客户端通过该端口连接Redis。然后修改脚本第6行的REDISPORT变量的值为同样的端口号。
(2)建立需要的文件夹。建立表2-2中列出的目录。
表2-2 需要建立的目录及说明
(3)修改配置文件。首先将配置文件模板(见2.4节)复制到/etc/redis目录下,以端口号命名(如“6379.conf”),然后按照表2-3对其中的部分参数进行编辑。
表2-3 需要修改的配置及说明
现在就可以使用/etc/init.d/redis_端口号start来启动Redis了,而后需要执行下面的命令使Redis随操作系统自动启动:
$ sudo update-rc.d redis_端口号 defaults
2.2.2 停止Redis
考虑到Redis有可能正在将内存中的数据同步到硬盘中,强行终止Redis进程可能会导致数据丢失。正确停止Redis的方式应该是向Redis发送SHUTDOWN命令,方法为:
$ redis-cli SHUTDOWN
当Redis接收到SHUTDOWN命令后,会先断开所有客户端连接,然后根据配置执行持久化,最后完成退出。
Redis可以妥善处理SIGTERM信号,所以使用kill Redis进程的PID也可以正常停止Redis,效果与发送SHUTDOWN命令一样。
2.3 Redis命令行客户端
还记得我们刚才编译出的redis-cli文件吗?redis-cli(Redis Command Line Interface)是Redis自带的基于命令行的Redis客户端,也是我们学习和测试Redis的重要工具,本书后面会使用它来讲解Redis各种命令的用法。
本节将会介绍如何通过redis-cli向Redis发送命令,并且对Redis命令返回值的不同类型进行简单介绍。
2.3.1 发送命令
通过redis-cli向Redis发送命令有两种方式,第一种方式是将命令作为redis-cli的参数执行,例如在2.2.2节中用过的redis-cli SHUTDOWN。redis-cli执行时会自动按照默认配置(服务器IP地址为127.0.0.1,端口号为6379)连接Redis,通过参数-h和-p可以分别自定义IP地址和端口号:
$ redis-cli -h 127.0.0.1 -p 6379
Redis提供了PING命令来测试客户端与Redis的连接是否正常,如果连接正常会收到回复PONG,例如:
$ redis-cli PING PONG
第二种方式是不附带参数执行redis-cli,这样会进入交互模式,可以自由输入命令,例如:
$ redis-cli redis 127.0.0.1:6379> PING PONG redis 127.0.0.1:6379> ECHO hi "hi"
这种方式在要输入多条命令时比较方便,也是本书中主要采用的方式。为简便起见,后文中我们将用redis>表示redis 127.0.0.1:6379>。
2.3.2 命令返回值
在大多数情况下,执行一条命令后我们往往会关心命令的返回值,如1.2.4节中的HGET命令的返回值就是我们需要的指定键的title字段的值。命令的返回值有5种类型,对于每种类型,redis-cli的展现结果都不同,下面分别说明。
1.状态回复
状态回复(status reply)是最简单的一种回复,例如,向Redis发送SET命令设置某个键的值时,Redis会回复状态OK表示设置成功。另外,之前演示的对PING命令的回复PONG也是状态回复。状态回复直接显示状态信息,如:
redis> PING PONG
2.错误回复
当出现命令不存在或命令格式有错误等情况时,Redis会返回错误回复(error reply)。错误回复以(error)开头,并在后面跟上错误消息。如执行一条不存在的命令:
redis> ERRORCOMMAND (error) ERR unknown command 'ERRORCOMMAND'
在最早的版本中,所有的错误消息都是以“ERR”开头的,而在2.8版以后,部分错误消息会以具体的错误类型开头,如:
redis> LPUSH key 1 (integer) 1 redis> GET key (error) WRONGTYPE Operation against a key holding the wrong kind of value
这里错误消息开头的WRONGTYPE就表示类型错误,这个改进使得在调试时能更容易地知道遇到的是哪种类型的错误。
3.整数回复
Redis虽然没有整数类型,但是提供了一些用于整数操作的命令,如递增键值的INCR命令会以整数形式返回递增后的键值。除此之外,其他一些命令也会返回整数,如可以获取当前数据库中键的数量的DBSIZE命令等。整数回复(integer reply)以(integer)开头,并在后面跟上整数数据:
redis> INCR foo (integer) 1
4.字符串回复
字符串回复(bulk reply)是最常见的一种回复类型,当请求一个字符串类型键的键值或一个其他类型键中的某个元素时,就会得到一个字符串回复。字符串回复以双引号包裹:
redis> GET foo "1"
特殊情况是当请求的键值不存在时得到的结果为空,显示为(nil)。如:
redis> GET noexists (nil)
5.多行字符串回复
多行字符串回复(multi-bulk reply)同样很常见,如当请求一个非字符串类型键的元素列表时,就会收到多行字符串回复。多行字符串回复中的每行字符串都以一个序号开头,如:
redis> KEYS * 1) "bar" 2) "foo"
提示
KEYS命令的作用是获取数据库中符合指定规则的键名,由于读者的Redis中还没有存储数据,因此得到的返回值应该是(empty list or set)。3.1节会具体介绍KEYS命令,此处读者只需了解多行字符串回复的格式。
2.4 配置
在2.2.1节中,我们通过redis-server的启动参数port设置了Redis的端口号,除此之外,Redis还支持其他配置选项,如是否开启持久化、日志级别等。由于可以配置的选项较多,通过启动参数设置这些选项并不方便,因此Redis支持通过配置文件来设置这些选项。启用配置文件的方法是在启动时将配置文件的路径作为启动参数传递给redis-server,如:
$ redis-server /path/to/redis.conf
通过启动参数传递同名的配置选项会覆盖配置文件中相应的参数,就像这样:
$ redis-server /path/to/redis.conf --loglevel warning
Redis提供了一个配置文件的模板文件redis.conf,位于源代码目录的根目录下。
除此之外,还可以在Redis运行时通过CONFIG SET命令在不重新启动Redis的情况下动态修改部分Redis配置。就像这样:
redis> CONFIG SET loglevel warning OK
并不是所有的配置都可以使用CONFIG SET命令修改,附录B列出了哪些配置能够使用该命令修改。同样,在执行的时候也可以使用CONFIG GET命令获得Redis当前的配置情况,如:
redis> CONFIG GET loglevel 1) "loglevel" 2) "warning"
其中,第一行字符串回复表示的是选项名,第二行是选项值。
2.5 多数据库
第1章介绍过Redis是一个字典结构的存储服务器,而实际上一个Redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。这与我们熟知的在一个关系数据库实例中可以创建多个数据库类似,所以可以将其中的每个字典都理解成一个独立的数据库。
每个数据库对外都以一个从0开始的递增数字命名,Redis默认支持16个数据库,可以通过配置参数databases来修改这一数字。客户端与Redis建立连接后会自动选择0号数据库,不过可以随时使用SELECT命令更换数据库,如选择1号数据库:
redis> SELECT 1 OK redis [1]> GET foo (nil)
然而,这些以数字命名的数据库又与我们理解的数据库有所区别。首先,Redis不支持自定义数据库的名字,每个数据库都以编号命名,开发者必须自己记录哪些数据库存储了哪些数据。其次,Redis不支持为每个数据库设置不同的访问密码,所以一个客户端要么可以访问全部数据库,要么不能访问任何数据库。最后也是最重要的一点是,多个数据库之间并不是完全隔离的,例如FLUSHALL命令可以清空一个Redis实例中的所有数据库中的数据。综上所述,这些数据库更像一种命名空间,而不适宜存储不同应用的数据。例如可以使用0号数据库存储某个应用的生产环境中的数据,使用1号数据库存储该应用的测试环境中的数据,但不适宜使用0号数据库存储A应用的数据而使用1号数据库存储B应用的数据,不同的应用应该使用不同的Redis实例存储数据。由于Redis非常轻量级,一个空Redis实例占用的内存只有1 MB左右,因此不用担心多个Redis实例会占用很多内存。
[1] 微软开放技术有限公司(Microsoft Open Technologies Inc.)专注于参与开源项目、开放标准工作组以及提出倡议。
[2] 可在GitHub官网搜索“microsoftarchive/redis”获取。
[3] 适用于Windows 10的文档为Windows Subsystem for Linus Installation Guide for Windows 10。