yokila
yokila
Published on 2025-03-31 / 13 Visits
0
0

Redis

一、前言

本文编写基于:

  • 部署 Redis 的服务器操作系统:Ubuntu 24.04

  • 远程连接 Redis 的设备的操作系统:Windows 11

  • Redis 社区版 V7.4.2

二、简介

官网:

全称:REmote DIctionary Server

Redis 始于2009年,最初的开发者是 Salvatore Sanfilippo。2020年6月,Sanfilippo 辞去 Redis 维护者职务,退居二线担任“谋士”。Redis 转为社区自治模式。

Redis 是一个使用 ANSI C 编写的支持网络、基于内存、分布式、可选持久性的键值对存储数据库。根据月度排行网站 DB-Engines.com 的数据,Redis是最流行的键值对存储数据库。

Redis 通常被称为 数据结构服务器(data structures server)。这意味着 Redis 通过一组命令提供对可变数据结构的访问,这些命令使用具有 TCP 套接字和简单协议的 服务器-客户端(C/S) 模型发送。因此,不同的进程可以以共享的方式查询和修改相同的数据结构。

Redis 是一款内存数据存储系统,数百万开发人员将其用作缓存(cache)、向量数据库(vector database)、文档数据库(document database)、流式引擎(streaming engine)和消息代理(message broker)。Redis 内置数据复制(用于支持高可用和故障转移)和多级磁盘持久化机制。它支持复杂的数据类型(例如,字符串、哈希、列表、集合、有序集合和 JSON),并对这些数据类型定义了原子操作。

三、安装

参考:在 Linux 上安装 Redis

3.1 安装相关软件包

sudo apt-get install lsb-release curl gpg

可以放心大胆执行以上命令,若已安装软件包,则只是会更新版本,不会覆盖安装。

这些组件主要是安装过程中会需要:

  • lsb-release:Linux 标准基础(LSB,Linux Standard Base) 的一部分,它的核心作用是提供系统发行版的标准化信息(如发行版名称、版本号、代号等)。许多第三方软件源(如 Redis 官方仓库)需要根据系统的 发行版代号(如 noble、jammy)动态生成正确的仓库地址。

  • curl:用来获取官方的软件包签名密钥。

  • gpg:GNU Privacy Guard,是PGP的一个开源替代品。PGP,即 Pretty Good Privacy,一个专有的加密程序,用于对文件和目录进行签名、加密和解密。用于验证下载的 Redis 软件包有无被篡改。

3.2 获取官方的签名密钥

curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg

命令解析(扩展了解):

  • -fsSL:安静地下载密钥文件(无冗余输出)。如果 URL 发生重定向(如 HTTPS 强制跳转),自动跟进。如果下载失败(如 404),直接报错并退出,避免脚本继续执行错误操作。

  • gpg --dearmor:将下载到的pgp内容转换成gpg内容。

  • -o /usr/share/keyrings/redis-archive-keyring.gpg:将内容输入到指定的文件中。

3.3 修改文件权限

sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg

3.4 配置 apt

echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list

其实就是将 Redis 的官方软件仓库添加到系统的 APT 软件源列表中,写上去哪里下 Redis(以及自动获取系统发行版代号填入),以及用什么密钥去校验。

3.5 更新软件包列表

sudo apt-get update

3.6 执行安装最新版 redis

sudo apt-get install redis

查看安装的 Redis 服务的版本,执行命令:

redis-server -v

redis 在安装以后,会自动由 systemctl 进行管理并启动。

可以通过 systemctl 命令进行查看运行状态:

systemctl status redis-server

QQ20250329-224908.png

从输出信息可以看出:默认情况下,Redis 服务不会开机自启动。

(若有需要)设置 Redis 服务开机自启动:

sudo systemctl enable redis-server

四、CLI 使用

从前文 systemctl 查看 Redis 的运行状态可以看出,Redis 默认的监听端口是:6379

为什么是 6379?

因为 6379 在手机按键上 MERZ 对应的号码,而 MERZ 取自意大利歌女 Alessia Merz 的名字。

—— Salvatore Sanfilippo《Redis 作为 LRU 缓存

4.1 本地访问(无密码)

默认情况下,Redis 访问无需密码。

启动 Redis 安装时自带的命令行客户端工具,执行命令:

redis-cli

测试连接:

ping

QQ20250329-225756.png

退出:

exit

4.2 本地访问(有密码)

若 Redis 有设置密码,则应该在建立连接后,在连接中使用 auth password 的方式进行身份验证,然后执行操作。

QQ20250407-222609.png

4.3 设置值

set key_name key_value

set pai_key1 abcdefg

4.3 查询值

get key_name

get pai_key1

4.4 防火墙开放端口

(非必须,看是否有外部访问的需求)

(推荐)仅允许特定的 IP 范围(如:192.168.0.1 ~ 192.168.0.254)访问 6379 端口。

sudo ufw allow from 192.168.0.0/24 to any port 6379 

(不推荐)若不想限制来源 IP 范围:

sudo ufw allow 6379

五、修改 Redis 的配置(可选)

官网提供默认的 Redis 配置文件内容:Redis configuration file example

查看启动服务的配置信息,执行命令:

cat /usr/lib/systemd/system/redis-server.service 

可以看到,执行 redis-server 时加载的配置文件位于:/etc/redis/redis.conf

由于默认 /etc/redis 目录禁止 redis 以外的用户读取,所以需要用管理员权限操作。

备份默认的配置文件(可选,但推荐)

sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.backup

开始编辑:

sudo vi /etc/redis/redis.conf

输入 : (英文冒号),然后输入 set nu 让内容出现行号。

注意:修改完 redis.conf 文件后,需要重启 Redis 服务才能让配置生效。

如执行 Systemctl 的重启服务命令:

sudo systemctl restart redis-server

5.1 允许外部访问

默认情况下,Redis 仅允许本机访问。

修改配置,允许所有 IP 访问(但是实际上还受到防火墙限制)

bind 0.0.0.0

修改后如下图:

QQ20250331-214537.png

5.2 修改监听端口

修改监听的端口的配置(需要配合防火墙的开放,这里作为示例,改成了:16379

QQ20250331-215354.png

5.3 配置访问密码

默认情况下,没有访问密码,任何人都能访问,很不安全。

设置默认用户(Username = default,或者不配置)访问密码(这里作为示例,密码是:redisPwd123

requirepass redisPwd123

QQ20250331-220058.png

5.4 设置最大内存占用

默认情况下,Redis 会无限制地占用内存。所以生产环境必须设置最大内存占用。

一般情况下,按实际需求评估来配置 Redis 的最大物理内存占用大小。

如果是有单独的 Redis 服务器,则一般建议最大值为物理内存的 70%~80%,因为需要预留一些物理内存用于持久化、系统等用途。

设置内存即在配置文件中配置值:

 maxmemory 1gb

Redis 在数据存储到达内存上限后,默认策略下,会在插入新数据时报错(不自动清理数据)。

一般会设置一个到达内存上限后执行的清理数据策略,配置文件中已有对支持的所有策略进行介绍。

例如可以选择自动清理使用频率最低的键值对(针对所有 key-value):

maxmemory-policy allkeys-lfu

下图为配置示例:

QQ20250407-230223.png

5.5 持久化

Redis 是内存型数据库,意味着一旦宕机或者服务停止,则存储的数据会丢失。

为了数据不丢失,即需要对 Redis 存储的数据进行持久化。

参考文档:Redis persistence

目前 Redis 的持久化策略有三种:

  1. RDB:Redis DataBase。

    • 本质是达到指定条件后生成一份当前时刻的数据快照。

    • 适合灾备。

    • 毕竟不是实时备份,会丢失最近一段时间的数据(因为还未发生下一次 RDB)。

    • Redis 默认使用此策略,通常情况下对数据的丢失要求不是特别严格的话就足够了。

  2. AOF:Append Only File。

    • 存储 Redis 对内存中数据修改的指令序列,后续重启 Redis 服务时再次重放这些操作。

    • 为了防止时间比较长以后AOF文件体积太大,Redis 会自动 fork 子进程执行 AOF Rewrite,即遍历当前内存中的数据,转换成指令并序列化到新的 AOF 文件中,然后把这期间新的操作指令也追加到新的 AOF文件中,再用新的 AOF 文件替换旧的 AOF 文件,完成 AOF 文件的瘦身。

    • 官方推荐(默认)配置:appendfsync everysec

  3. RDB + AOF

    • V4.0 开始支持,即混合模式。

    • 该方式实际是在 AOF 里配置,让 AOF rewrite 时,把当前数据用 RDB 快照的形式记录,然后 AOF 里就只需要记录此次快照之后的指令执行序列。

    • 官方推荐。

  4. 无持久化:禁用持久化,即不需要对数据进行持久化保存

5.5.1 RDB

QQ20250408-222717.png

通过配置文件的描述可知,默认情况下,Redis 使用 RDB 策略进行持久化。

默认触发持久化的条件(满足其一则立即执行持久化):

  • 3600秒(一小时)内若至少发生1次修改

  • 300秒(5分钟)内若至少发生100次修改

  • 60秒内若至少发生10,000次修改

若不想使用,则还需要手动关闭,配置 save ""

QQ20250408-223128.png

默认存储目录为:/var/lib/redis,文件名是 dump.rdb

若有需要可以自行修改。(Redis 在启动时默认会自动加载此 RDB 文件的数据,即恢复数据)

5.5.2 AOF

QQ20250408-225522.png

默认情况下,AOF 是关闭的,若有需要则可以如图改成:appendonly yes

默认情况下,将在 appendonlydir 配置的目录(若没有显式指定,则为 /var/lib/redis 目录)中生成 appendonly.aof 文件(V7.0 开始是生成一个 appendonlydir 文件夹)。

从 Redis 7.0.0 开始,Redis 使用多部分 AOF 机制。 也就是说,原始的单个 AOF 文件被拆分为基本文件(最多一个)和增量文件(可能有多个)。 基本文件表示重写 AOF 时存在的数据的初始(RDB 或 AOF 格式)快照。 增量文件包含自上次创建基本 AOF 文件以来的增量更改。所有这些文件都放在一个单独的目录中,并由一个清单文件进行跟踪。

V7.0.0 生成文件示例:

  • appendonly.aof.1.base.rdb

  • appendonly.aof.1.incr.aof

  • appendonly.aof.manifest

QQ20250408-225604.png

默认策略是每秒进行一次操作记录的追加到 aof 文件中,若发生宕机,则丢失1s 的数据。

QQ20250408-225647.png

这两个配置是用于控制 Redis 依据什么条件来决定 AOF 文件过大,从而执行 AOF rewrite 操作。

触发 AOF rewrite 需要同时满足这两个条件才执行:

  • auto-aof-rewrite-percentage:当 AOF 文件的当前大小 比上一次重写后的体积大 百分之多少 时触发 rewrite。(初始为启动时加载的 AOF 文件的大小)

  • auto-aof-rewrite-min-size:AOF 文件至少多大才会触发 rewrite。

QQ20250408-225704.png

此配置 yes 表示开启 RDB + AOF 的混合模式,此时其实可以关闭 RDB 了。

V4.0 开始支持。

  • < V7.0.0 时,每次触发 AOF rewrite,Redis 会生成一份 RDB,RDB的内容写在新的 aof 文件中。

  • >= V7.0.0 时,每次触发 AOF rewrite,Redis 会生成一份新的 RDB文件。

5.5.3 AOF 和 RDB 同时启用

Redis 允许同时启用 AOF 和 RDB,两者互不冲突。重启时默认优先使用 AOF 文件恢复数据(因为 AOF 的完整性通常更高)。

5.6 SSL/TLS 连接

需要 Redis V6 开始支持。

默认:关闭。

若 Redis 允许外网访问(且不限制访问来源IP)或者 内部存有敏感信息(如 Token),则建议启用 SSL。

注意:使用 TLS 会导致每个 Redis 实例可实现的吞吐量降低。

此时需要先自建CA(参考:OpenSSL命令行:自建CA&操作CRL)或者从权威机构获取证书。

本文基于 OpenSSL,相关指令可参考:OpenSSL命令行实例

本节考虑的是 Redis 作为服务端的情况,若是 Redis 作为客户端,则方法类似,但不太一样,不在本文考虑范围内,请格外注意。

5.6.1 新建目录

进入 redis.conf 所在目录(仅为了方便管理):

cd /etc/redis

新建文件夹(命名任意,后续配置要用)

mkdir tls

进入新文件夹:

cd tls

5.6.2 生成服务端密钥对

生成 2048 长度的密钥(附带口令保护),文件命名为 redis.key:

openssl genrsa -aes128 -out redis.key 2048

请记住设置的口令,后续将配置到配置文件中。

若不想附带口令保护,则移除命令中的 -aes128 即可。

5.6.3 生成服务端 CSR

基于上一步的密钥,生成 CSR:

openssl req -new -key redis.key -out redis.csr

需要注意的是,Common Name 字段,应该为外部访问此服务时基于的 域名 或者 IP地址。

其他值填错或者为空问题都不大。

QQ20250409-222621.png

将 CSR 文件复制一份到 /tmp 目录:

cp redis.csr /tmp

从 tmp 目录下载 CSR 文件到本地。(避免因为 root 用户不允许远程登录导致无权限下载文件)

5.6.4 其他步骤

参考:OpenSSL 生成双向认证使用的证书

参考以上文章,最终将获得所有下文会使用到的证书文件。

参考文档中:

  • server = redis 服务器

  • client = 我们要远程连接 redis 的客户端,比如自己的PC机。

5.6.5 证书文件上传

将 redis.crt(由 redis.csr 签发出来的证书文件)、serverTrustChain.pem 文件上传到 tls 文件夹中。

(若因权限问题无法直接上传到 tls 文件夹,则可以先上传到 tmp 文件夹,然后移动到 tls 文件夹中)

此时,tls 文件夹内,应该可以看到以下文件:

QQ20250413-221024.png

注意:因为很有可能是通过 root 用户操作上传文件的,所以我们需要把整个 tls 文件夹及其子文件,都转给 redis 用户,这样 Redis 就可以正常读取使用 tls 里的文件了。

执行命令:

chown -R redis:redis /etc/redis/tls/

5.6.6 修改 redis.conf

执行命令:

vi /etc/redis/redis.conf

编辑后如图所示:

QQ20250413-224648.png

注意保存编辑后的内容,然后重启 Redis。

  • port:无需 TLS/SSL 连接的端口,一般给本机访问/内网访问时提供(注意防火墙配置)。否则,配置为 0,意味着没有。(这里的配置实测会覆盖 139 行左右的同名 port 配置,但还是建议仅保留一处配置)

  • tls-port:需要 TLS/SSL 连接的端口(注意防火墙配置)。(若和 port 配置的端口是同一个,则以这个优先)

  • tls-cert-file:Redis 证明自身身份的证书文件路径(这里指的是作为服务端时的证书)。(要求 PEM 格式)

  • tls-key-file:Redis 证明自身身份证书 对应的私钥文件路径。(要求 PEM 格式)

  • tls-key-file-pass:Redis 证明自身身份证书 对应的私钥 的保护口令(可能没有,没有保护口令就无需配置,注释掉这一行)。

  • tls-ca-cert-file:(要求验证客户端证书时配置,即双向认证时需要)表示信任证书链文件路径。(要求 PEM 格式)

    • 其实这里也可以不合成证书链文件为一个文件,使用 tls-ca-cert-dir 指定一个证书链文件夹。但是这样的话,不是简单地把证书放入文件夹中就行了,还得把证书链安装到系统中才行,否则连接时会报错:Error accepting a client connection: error:0A000086:SSL routines::certificate verify failed。解决办法参考:tls-ca-cert-dir directive not working

  • tls-auth-clients:(要求验证客户端证书时配置,即双向认证时需要)yes 表示开启验证客户端。

    • 如果验证客户端是可选的,则可以使用 tls-auth-clients optional

  • 纵览其他 TLS/SSL 配置(如:TLS protocol、 TLS ciphersuite),默认配置已经足够,个人认为若非必要无需修改。

5.6.7 客户端配置连接

见下文安装的 Redis Insight 里的操作步骤。

5.7 日志

默认情况下,Redis 日志输出位置:/var/log/redis/redis-server.log

默认输出日志的等级:notice

详细可见 redis.conf 的配置。

5.8 Memory overcommit

WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

Redis 启动时,可能会有这个警告信息。

相关的原因、修改操作都已经在提示信息中指出。

其实就是为了保障 RDB、AOF、主从同步 时可以成功 fork() 子进程(不会因为内存不足而失败), Redis 建议启用内存过度提交(vm.overcommit_memory = 1),否则在内存不足的情况下,后台保存或复制可能会失败。(实测 Ubuntu 24 默认情况下,vm.overcommit_memory = 0

若有信心内存始终充足,或者不关心 RDB、AOF、主从同步 成功或失败(比如不用),则可以无视此警告。

如果设置 vm.overcommit_memory = 1,则要保障内存充裕,避免出现 OOM killer,因为此时内核不再严格检查物理内存是否足够,极限情况下有可能导致系统内存(物理内存 + 交换空间)耗尽,内核开始随机终止进程以释放内存。

六、使用 Redis Insight

Redis Insight 是 Redis 官方推出的免费图形界面,用于对 Redis 进行可视化、优化和故障排除。

官网学习课程:Redis Insight

以下 Redis Insight 的安装和操作,基于 Window11。

下载地址:Redis Insignt

在页面里,点击 Download now,然后会被要求填写一个表单,表单内容的个人信息可以是杜撰的(实测没有校验真实性),提交表单后,即可开始下载安装包。

QQ20250330-153931.png

找到安装包文件,双击开始安装(若有需要则调整安装目录位置)。

打开 Redis Insight,首先显示的是“隐私设置”,笔者看下来无需调整里面的默认设置,只需要点击已阅读,然后提交确认即可。

QQ20250330-154512.png

点击主页的 Add Redis database

QQ20250330-155329.png

弹窗中点击 Connection Settings

QQ20250330-155648.png

填写 Redis 的连接配置(图中内容仅作为示例),然后点击 Test Connection,测试连接成功,则点击 Add Redis Database。(无 TLS/SSL 时)

(若要以 TLS/SSL 连接)打开 security 标签页,开启 TLS 连接配置,并设置验证服务器的信任链、客户端自身的证书、私钥。(若 Redis 服务器配置无需验证客户端,则可以不配置客户端证书、私钥)

  • Name 此处是设置成证书的 Common Name,实际上可以随便命名,只是 Redis Insight 内部用来记录这个配置的名字,以后其他连接可以直接复用这里的证书配置(直接变成一个选项)。

QQ20250413-225813.png

QQ20250413-225840.png

QQ20250413-225853-pskk.png

此时,点击主页里,刚刚添加的 Redis数据库,则可以打开其操作页面。

QQ20250331-221551.png

QQ20250331-221621.png

当 Redis 中有数据时:

QQ20250407-223540.png


Comment