一文带你掌握 Redis

数据库 MySQL
从官方的定义看,Redis 是一款开源的,遵守 BSD 协议,使用 C 语言开发的 key-value 存储系统。简单的说,它是一款跨平台的非关系型数据库,支持优先内存存储,并提供多种语言的 API 客户端。

一、摘要

谈起 Redis,相信大家都不会陌生,做过云平台开发的程序员多多少少会接触到它,Redis 英文全称:​Remote Dictionary Server,也被称之为远程字典服务。

从官方的定义看,Redis 是一款开源的,遵守 BSD 协议,使用 C 语言开发的 key-value 存储系统。简单的说,它是一款跨平台的非关系型数据库,支持优先内存存储,并提供多种语言的 API 客户端。

Redis 由一个叫 Salvatore Sanfilippo 的人开发而闻名世界,此人来自意大利的西西里岛,网名叫 antirez,如果你有兴趣,可以去他的博客逛逛,地址是 antirez.com。

不过从 2010 年起,Redis 的开发工作由 VMware 主持,到了 2013 年后,Redis 的开发由 Pivotal 赞助。

Redis 是当下互联网技术中使用最为广泛的缓存中间件之一,随着它在新浪微博中的使用而逐渐风靡国内。

虽然开源软件市场上也有很多优秀的缓存服务中间件,比如 memcache,但是和 redis 对比起来,redis 还是显得格外的突出,优势如下:

  • 性能极高:Redis 能读的速度是 110000 次/s,写的速度是 81000次/s
  • 数据类型丰富:支持 String,Hash,List,Set,Sorted Set 等数据类型的操作
  • 支持原子性操作:Redis 的每条命令操作都是原子性的,Redis 的操作之所以是原子性的,是因为每条命令的执行都是单线程的,不存在线程竞争问题
  • 存储方式多样化:memecache 把数据全部存在内存之中,断电后会挂掉;redis 支持数据的持久化,同时也支持数据的备份,即 master-slave 模式的数据备份
  • 功能丰富:Redis 还支持 publish/subscribe,通知,key 过期等等特性

在分布式的架构环境下,Redis 基本上是缺一不可的缓存中间件,它能很好的解决服务与服务之间数据共享的问题,并且性能不受影响。

说了这么多,如何使用呢?我们一起来看看!

二、服务安装

2.1、Windows 环境

因为 redis 目前官方只支持 LINUX 系统,因此没有 Windows 版本的软件包,但是好在微软团队维护了开源的 windows 版本,虽然更新不算及时,但是对于普通测试使用足够了。

2.1.1、服务器安装

如果当前操作系统是 Windows 系统,访问如下的地址,获取对应的下载链接。

https://github.com/tporadowski/redis/releases

根据系统平台的实际情况选择,这里我们下载Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为redis。

图片

打开文件夹,内容如下:

图片

然后,打开一个 cmd 窗口,使用 cd 命令切换目录到C:\redis,并且输入如下命令:

redis-server.exe redis.windows.conf

图片

出现以上界面,表示​​redis​​服务器已经成功启动了。

2.1.2、客户端测试

如果想用安装包里面的客户端脚本测试一下服务,可以这样操作。

另启一个 cmd 窗口,原来的窗口不要关闭,不然就无法访问服务端了。

使用 cd 命令切换目录到C:\redis,并且输入如下命令:

redis-cli.exe -h 127.0.0.1 -p 6379

连接到服务器之后,输入写命令和取命令,相关命令如下:

#写数据测试
set myKey abc

#取数据测试
get myKey

图片

2.2、Linux 环境

如果当前操作系统是 Linux 系统,访问如下的官方地址,获取最新的下载链接。

http://redis.io/download
2.2.1、服务器安装

本教程使用的最新文档版本为 6.2.6,下载并安装:

# wget https://download.redis.io/releases/redis-6.2.6.tar.gz
# tar xzf redis-6.2.6.tar.gz
# cd redis-6.2.6
# make

执行完make命令后,redis-6.2.6目录下会出现编译后的 redis 服务程序 redis-server,还有用于测试的客户端程序 redis-cli,两个程序位于安装目录 src 目录下。

执行下面的脚本,启动 redis 服务器。

# cd src
# ./redis-server

需要注意的地方是,这种方式启动 redis 使用的是默认配置,也可以通过参数告诉 redis 使用指定配置文件来启动服务,其中​​redis.conf​​是一个默认的配置文件,我们可以根据需要使用自己的自定义配置文件。

# cd src
# ./redis-server ../redis.conf

图片

当出现Ready to accept connections时,表示服务已经启动成功。

2.2.2、客户端测试

同样的,如果想用安装包里面的客户端脚本测试一下服务,新创建一个命令窗口,这样操作。

# cd src
# ./redis-cli
redis> set foo bar
OK
redis> get foo
"bar"

图片

2.2.3、参数配置

可能有的同学会发出一个疑问,如何将 Redis 改成后台服务?

也就是将窗体关闭也能正常提供服务,答案就藏在redis.conf这个配置文件里。

打开redis.conf文件,常用配置如下:

#绑定ip
bind 0.0.0.0

#启动端口
port 6379

# 是否运行远程访问
protected-mode yes

# 是否允许后台运行,默认no,将其改成yes
daemonize yes

# redis访问密码,根据需要设置,如果要打开,将#去掉
# requirepass foobared

# 数据库的数量
databases 16

修改配置,然后重启服务即可生效,操作如下:

# 寻找redis相关进程
ps -ef|grep redis

# 杀掉进程
kill -9 <pid>

# 重新启动redis
./redis-server ../redis.conf
2.2.3、配置详解

redis.conf详细配置项说明如下:

配置参数

说明

bind 127.0.0.1

如果是内网可以直接绑定 127.0.0.1, 或者忽略, 0.0.0.0是外网

port 6379

指定 Redis 监听端口,默认端口为 6379

protected-mode yes

是否运行远程访问,默认是yes

daemonize no

Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程

databases 16

设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id

requirepass foobared

设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH password 命令提供密码,默认关闭

timeout 300

当客户端闲置多长秒后关闭连接,如果指定为 0 ,表示关闭该功能

maxclients 128

设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息

maxmemory ​​<bytes>​

指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区

pidfile /var/run/redis.pid

当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定

loglevel notice

指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 notice

logfile stdout

日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null

save ​​<seconds>​​​ ​​<changes>​

指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合,比如​​save 900 1​​,表示 900 秒内有 1 个更改

rdbcompression yes

指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大

dbfilename dump.rdb

指定本地数据库文件名,默认值为 dump.rdb

dir ./

指定本地数据库存放目录

slaveof ​​<masterip>​​​ ​​<masterport>​

设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步

masterauth ​​<master-password>​

当 master 服务设置了密码保护时,slave 服务连接 master 的密码

appendonly no

指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为 no

appendfilename appendonly.aof

指定更新日志文件名,默认为 appendonly.aof

appendfsync everysec

指定更新日志条件,共有 3 个可选值:no:表示等操作系统进行数据缓存同步到磁盘(快);always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全);everysec:表示每秒同步一次(折中,默认值)

vm-enabled no

指定是否启用虚拟内存机制,默认值为 no,简单的介绍一下,VM 机制将数据分页存放,由 Redis 将访问量较少的页即冷数据 swap 到磁盘上,访问多的页面由磁盘自动换出到内存中

vm-swap-file /tmp/redis.swap

虚拟内存文件路径,默认值为 /tmp/redis.swap,不可多个 Redis 实例共享

vm-max-memory 0

将所有大于 vm-max-memory 的数据存入虚拟内存,无论 vm-max-memory 设置多小,所有索引数据都是内存存储的(Redis 的索引数据 就是 keys),也就是说,当 vm-max-memory 设置为 0 的时候,其实是所有 value 都存在于磁盘。默认值为 0

vm-page-size 32

Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size 是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page 大小最好设置为 32 或者 64bytes;如果存储很大大对象,则可以使用更大的 page,如果不确定,就使用默认值

vm-pages 134217728

设置 swap 文件中的 page 数量,由于页表(一种表示页面空闲或使用的 bitmap)是在放在内存中的,,在磁盘上每 8 个 pages 将消耗 1byte 的内存

vm-max-threads 4

设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4

glueoutputbuf yes

设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启

activerehashing yes

指定是否激活重置哈希,默认为开启(后面在介绍 Redis 的哈希算法时具体介绍)

include /path/to/local.conf

指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件

2.3、Mac 环境

如果当前操作系统是 Mac 系统,同样的访问官方地址http://redis.io/download,下载最新的安装包。

图片

然后本地解压,后续的操作跟​​linux​​一样,在此就不过多的介绍了!

图片

三、命令行客户端

如果想要在 redis 服务上执行命令,需要一个 redis 客户端,而 Redis 客户端在我们下载的的 redis 的安装包里面,其实已经有了。

3.1、连接 redis

Redis 客户端的基本语法为

$ ./redis-cli

比如,连接本地的 redis 服务器(前提是已经启动成功)。

$ ./redis-cli
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING

PONG

如果 redis 设置了密码,通过AUTH命令输入密码即可进入,方式如下:

$ ./redis-cli
redis 127.0.0.1:6379> AUTH "password"
redis 127.0.0.1:6379> PING

PONG

如果我们想连接远程  redis 服务器,可以通过如下语法方式实现。

$ ./redis-cli -h host -p port -a password

比如连接192.168.121.1,命令如下:

$redis-cli -h 192.168.121.1 -p 6379 -a "mypass"
redis 192.168.121.1:6379>
redis 192.168.121.1:6379> PING

PONG

默认连接的数据库是0,如果我们想切换数据库,可以通过如下方式实现切换!

# 使用 1 号数据库
redis 192.168.121.1:6379>SELECT 1

如果想要关闭当前连接,通过如下方式即可实现!

redis 192.168.121.1:6379>QUIT

3.2、常用的 crud 操作

以字符串为例,增删改查操作如下!

1、设置指定 key 的值, SET 在设置操作成功完成时,返回 OK。

redis 127.0.0.1:6379>SET mykey redis
OK

2、查询指定 key 的值,操作完成时,如果 key 不存在时,返回 (nil)

redis 127.0.0.1:6379>GET mykey
"redis"

3、检查指定 key 的值是否存在,操作完成时,若 key 存在返回 1 ,否则返回 0

redis 127.0.0.1:6379>EXISTS  mykey
(integer) 1

4、删除指定 key 的值,操作完成时,返回被删除 key 的数量。

redis 127.0.0.1:6379>DEL mykey
(integer) 1

5、设置 key 的过期时间,以为单位,操作完成时,若成功返回 1 ,否则返回 0。

# 设置 mykey,60秒过期
redis 127.0.0.1:6379>EXPIRE mykey 60
(integer) 1

6、获取 key 的剩余过期时间,以为单位,操作完成时,当 key 不存在时,返回 -2;当 key 存在但没有设置剩余生存时间时,返回 -1;否则,以秒为单位,返回 key 的剩余生存时间。

redis 127.0.0.1:6379>TTL mykey
(integer) 60

7、通过 Incr 命令,实现指定的 key 原子性自增操作,每执行一次 Incr 命令,key 中储存的数字值增一,操作完成时,如果 key 不存在,那么 key 的值会先被初始化为 0,然后加 1,返回最后的结果。

redis 127.0.0.1:6379>INCR mykey
(integer) 1

当然,也可以在设置阶段,指定某个初始值数字,比如将​​mykey​​的自增初始值设置为​​10​​。

redis 127.0.0.1:6379>INCR mykey 10
(integer) 11

3.3、事务操作

Redis 也支持事务操作,Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 1.批量操作在发送 EXEC 命令前被放入队列缓存
  • 2.收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
  • 3.在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中

一个事务从开始到执行会经历以下三个阶段:

  • 1.开始事务
  • 2.命令入队
  • 3.执行事务

以某个事务操作为例, 我们先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令,过程如下:

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set a aaa
QUEUED
redis 127.0.0.1:6379> set b bbb
QUEUED
redis 127.0.0.1:6379> set c ccc
QUEUED
redis 127.0.0.1:6379> exec
1) OK
2) OK
3) OK

特别注意的地方是:单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

也就是说,如果在set b bbb处失败,set a aaa已成功不会回滚,set c ccc还会继续执行,当set b bbb处执行失败,这个事务是不会回滚的。

但是如果执行过程中,命令不存在或者是命令参数不对,这个时候 redis 的事务执行会失败,并返回错误信息给客户端;如果是命令逻辑上的执行失败,redis 的事务无法感知,会继续执行下去。

3.4、Lua 脚本操作

在上面我们也介绍到了,Redis 事务的执行并不能完全保证原子性,那么如何将一批命令操作做到原子性操作呢

Redis 支持通过 Lua 脚本来实现一批命令原子性操作,执行脚本的常用命令为  EVAL。

Eval 命令的基本语法如下:

redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]

比如简单的赋值操作如下:

redis 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

1) "key1"
2) "key2"
3) "first"
4) "second"

比如我们给指定的key设置指定值value,并且设置过期时间60秒,实现原子性操作,如果操作成功就返回 1,否则返回 0,内容如下:

redis 127.0.0.1:6379>EVAL "if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then return redis.call('expire', KEYS[1], ARGV[2]) else return 0 end" 1 key1 hello 60

(integer) 1

获取指定key的值,如果存在就删除key,实现原子性操作,如果操作成功就返回 1,否则返回 0,内容如下:

redis 127.0.0.1:6379>EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end" 1 key1 hello

(integer) 1

以上就是实现常用的分布式加锁、解锁原子性操作的 lua 脚本。

四、可视化客户端

对于开发者来说,使用客户端命令来操作 redis 非常不便捷,因此诞生了很多的基于 redis 的可视化客户端,今天我们就一起来看看有哪些免费又好用的客户端工具。

4.1、Redis Desktop Manager

Redis Desktop Manager 应该是现在使用率最广的可视化工具了,存在时间很久,经过了数次迭代,基于 Qt 5 开发,支持跨平台支持。

以前是免费的,不过现在改成收费工具,试用期可以有半个月的时间,最新版的访问地址如下!

https://github.com/uglide/RedisDesktopManager/releases

图片

测评:界面看着比较简洁,该有的功能都有,功能很全,key 的显示可以支持按冒号分割的键名空间。

免费版本的下载地址如下

百度网盘:https://pan.baidu.com/s/1rMWR-OQnfsxJ3_HSqEE8xw

提取码:tebu

4.2、medis2

medis2 是 mac 系统中使用率最高的 redis 可视化工具,布局简洁,界面美观,关键还免费,最新版的访问地址如下!

https://getmedis.com/

图片

测评:软件颜值挺高,功能符合日常使用要求,对 key 有颜色鲜明的图标标识,在key的搜索上挺方便的,可以模糊搜索出匹配的 key,渐进式的 scan,无明显卡顿,在搜索的体验上还是比较出色的,不过对操作系统要求很高,要求 MacOS 11.0 以上才能安装,如果当前你的操作系统低于以上,只有升级或者换别的软件!

4.3、AnotherRedisDesktopManager

AnotherRedisDesktopManager 是一款比较稳定简洁的 redis UI工具,国人开发,支持跨平台,完全免费,最新版的访问地址如下!

https://github.com/qishibo/AnotherRedisDesktopManager

图片

测评:基本的功能都有,有监控统计,支持暗黑主题,还支持集群的添加,是一款非常不错的可视化客户端。

4.4、Redis Insight

Redis Insight 是目前官方推荐的一款 redis 可视化工具,功能非常丰富,支持跨平台,完全免费,最新版的访问地址如下!

https://redis.com/redis-enterprise/redis-insight/

图片

测评:相比于其他可视化工具,RedisInsight 实现的功能更强大、执行效率更改,通用性更好,出了 CRUD 基本功能的支持,还支持内存分析、指标监控、发布/订阅、慢命令日志查询等等。

五、小结

本文主要围绕redis的一些基本知识,做了一次简单的总结,包括软件安装、基本命令操作、可视化客户端介绍。

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2023-12-21 17:11:21

Containerd管理工具命令行

2023-12-15 09:45:21

阻塞接口

2021-02-22 09:05:59

Linux字符设备架构

2021-06-04 09:35:05

Linux字符设备架构

2020-12-18 11:54:22

Linux系统架构

2023-05-15 08:44:15

Redis数据库

2023-09-11 06:32:30

VPAHPA容量

2021-04-28 08:05:30

SpringCloudEureka服务注册

2022-10-21 17:24:34

契约测试定位

2023-11-20 08:18:49

Netty服务器

2023-07-31 08:18:50

Docker参数容器

2021-05-29 10:11:00

Kafa数据业务

2023-11-06 08:16:19

APM系统运维

2022-11-11 19:09:13

架构

2024-10-10 09:12:10

Spring接口初始化

2021-05-12 18:22:36

Linux 内存管理

2023-10-27 08:15:45

2022-02-24 07:34:10

SSL协议加密

2023-11-08 08:15:48

服务监控Zipkin

2020-11-27 09:40:53

Rollup前端代码
点赞
收藏

51CTO技术栈公众号