EQVPS
控制台开始使用

如何在 VPS 上安装 Redis:内存上限、持久化和不会失效的密码

在 Ubuntu 24.04 上安装 Redis,限制它的内存以免占满整台服务器,在不删除数据的前提下开启 AOF,并设置一个重启后依然有效的密码。其中两步藏着陷阱,我们在自己的测试服务器上踩过。

Redis 把数据放在内存里,响应时间约一毫秒,所以它作为缓存、队列或会话存储,藏在许许多多应用的背后。安装只要一条命令。真正的工作在默认设置上:没有内存上限,快照可能丢掉最近的写入,还有两个很容易犯的错误,会悄无声息地删掉你的数据或让密码失效。本文在 Ubuntu 24.04 上把这些都讲清楚。每一步我们都在自家镜像上跑过,数字来自一台 Micro 服务器(2 vCPU、2 GB)。

你需要一个有 sudo 权限的用户。Ubuntu 配置指南会创建一个。

1. 安装

sudo apt update
sudo apt install -y redis-server
redis-server --version
redis-cli ping

安装用了 13 秒,装上的是 Redis 7.0.15。它立刻启动,之后每次开机自动运行,返回 PONG,并且只在服务器本机监听:127.0.0.1:6379 和 [::1]:6379,开启了 protected-mode yes。没有数据时占用 13.5 MB 内存。

日志里已经有一条警告:

WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition.

Redis 用 fork 出来的副本把数据写到磁盘,而在内核的默认设置下,内存紧张时这个 fork 可能失败。改一次就好:

echo 'vm.overcommit_memory = 1' | sudo tee /etc/sysctl.d/90-redis.conf
sudo sysctl -p /etc/sysctl.d/90-redis.conf
sudo systemctl restart redis-server

重启之后警告消失了。

2. 限制内存

默认的 maxmemory 是 0,也就是没有上限,策略是 noeviction。Redis 会一直占用内存,直到服务器耗尽。设一个上限,并决定达到上限时怎么处理:

redis-cli CONFIG SET maxmemory 256mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE

我们在 64 MB 上限下写入 40 万次,测试了两种策略:

  • noeviction(默认):内存停在 63 MB,新的写入报错 OOM command not allowed when used memory > 'maxmemory'。适合队列,或者任何不能丢的数据。
  • allkeys-lru:Redis 淘汰了最久未使用的键,共 48,606 个,所有写入都成功。适合缓存。

CONFIG REWRITE 会把当前设置写入 /etc/redis/redis.conf,重启后依然有效。它还会加上一行,第 4 步之前你需要知道它。

3. 选择持久化方式

默认情况下,Redis 在 1 小时内有 1 次、5 分钟内有 100 次或 1 分钟内有 1 万次变更时写一次快照(/var/lib/redis/dump.rdb)。我们用三种方式让它停下:

Redis 如何停止仅快照(默认)开启 AOF
systemctl restart没丢:关闭时会保存没丢
用 kill -9 强杀最后一次快照之后写入的键没了强杀前 2 秒写入的键还在

两种情况下,systemd 都在几秒内自动把 Redis 拉了起来。

如果 Redis 里存着丢了会心疼的数据,就开启 AOF(append-only file)。它记录每一次写入,并每秒刷一次盘。要在运行中的服务器上开启,不要去改配置文件:

redis-cli CONFIG SET appendonly yes
redis-cli CONFIG REWRITE
redis-cli INFO persistence | grep aof_

我们一开始走了另一条路,结果丢了数据。我们把 redis.conf 里的 appendonly no 改成 appendonly yes 然后重启。Redis 带着一个空的 AOF 启动,没有从快照加载任何东西,原有的键全没了。之后它关闭时,又把不含旧键的新内容覆盖写进了 dump.rdb。CONFIG SET 能避免这个问题:Redis 会先用内存中的数据生成 AOF。重启后,我们所有的键都还在。

如果 Redis 只是一个可以从空开始的纯缓存,那就反过来,用 redis-cli CONFIG SET save "" 关掉持久化。

4. 设置密码

这是第二个陷阱。只要执行过一次 CONFIG REWRITE,Redis 7 就会在 redis.conf 末尾加上这一行:

user default on nopass ~* &* +@all

它的意思是“默认用户不需要密码”。之后我们在文件靠上的位置加了 requirepass 并重启,Redis 仍然不要密码就返回 PONG,因为 user 这一行的优先级更高。请改为通过 Redis 设置密码:

REDIS_PASS=$(openssl rand -hex 24)
echo "$REDIS_PASS"
redis-cli CONFIG SET requirepass "$REDIS_PASS"
REDISCLI_AUTH="$REDIS_PASS" redis-cli CONFIG REWRITE

把密码存到安全的地方。现在 Redis 会把它以 SHA-256 哈希的形式保存在同一行 user default 里。重启后,redis-cli ping 返回 NOAUTH Authentication required.,只有带上密码才能用。给 redis-cli 传密码时用 REDISCLI_AUTH 环境变量;用 -a 的话,密码会出现在进程列表里,redis-cli 也会警告。在应用里,把密码写进 Redis 地址:redis://:PASSWORD@127.0.0.1:6379/0。

5. 从自己的电脑访问

让 Redis 继续只监听 127.0.0.1,用 SSH 隧道访问。填写服务器的 SSH 端口,NAT 套餐上就是你的专属端口:

ssh -N -L 6380:127.0.0.1:6379 deploy@YOUR_SERVER_IP -p 22

隧道开着的时候,你电脑上的 redis-cli -p 6380 和桌面工具就能和服务器上的 Redis 通信,而公网上没有新开放任何端口。按照 SSH 密钥指南配置后,隧道登录无需密码。

速度如何

在 Micro 测试服务器上,用 50 个客户端运行 redis-benchmark 的结果:

测试每秒请求数延迟中位数
SET30,3031.0 ms
GET35,1490.9 ms
SET,每次往返 16 条命令272,1092.4 ms
GET,每次往返 16 条命令414,9381.3 ms

对 Web 应用的缓存或任务队列来说,这远远超出需要。多出来的速度来自批量发送命令(pipelining)。

选哪个套餐

Redis 需要的是存放数据的内存,其他几乎不需要。Nano(2 vCPU、1 GB、每月 $3)在 maxmemory 256mb 下可以和一个小应用一起运行 Redis。Micro(2 GB、每月 $5)能给更大的缓存和应用留足空间。如果有其他机器需要直接连接 Redis,就用独立 IPv4(Nano-IP 起,每月 $8),并在防火墙中只放行那一个地址。所有套餐都在 VPS 页面,支付方式为 Base、Ethereum 或 Polygon 网络上的 USDT、USDC 或 ETH。

常见问题

Redis 需要多少内存?

Redis 本身很小:在我们的服务器上刚装好时只占 13.5 MB。它真正需要的是存放数据的空间,因为数据都在内存里。把 maxmemory 设为服务器能腾出的量,比如 1 GB 的服务器设 256 MB,并选好内存满了之后怎么办。

选 Redis 还是 Valkey?

Valkey 是从 Redis 7.2 分出来的 Redis 分支,协议相同,所以大多数客户端两者都能用。Ubuntu 24.04 只提供 Redis 7.0.15。Debian 13 同时有 Redis 8.0 和 Valkey 8.1,Debian 12 可以从 backports 安装 Valkey 8.0。本文的步骤对两者都适用。

为什么 Redis 崩溃后会丢数据?

默认情况下,Redis 根据变更的键数量,每隔几分钟往磁盘保存一次快照。我们强行杀掉进程后,最后一次快照之后写入的键不见了。开启每秒写入一次的 AOF,崩溃时最多只会丢大约一秒的写入。

我在 redis.conf 里加了 requirepass,为什么 Redis 仍然不用密码就接受命令?

很可能是之前某个时候执行过 CONFIG REWRITE。在 Redis 7 中,它会在 redis.conf 末尾加上一行 user default on nopass ~* &* +@all,这一行会让写在上面的 requirepass 失效。先用 CONFIG SET requirepass 设置密码,再执行 CONFIG REWRITE,Redis 就会把密码保存到这一行。

可以把 6379 端口开放到公网吗?

不要。开放的 Redis 端口时刻被扫描,是入侵服务器的常见途径。从自己电脑通过 SSH 隧道连接 Redis,或者把它和使用它的应用放在同一台服务器上。

评论

暂无评论。来做第一个吧。

发表评论

评论在显示前会经过审核。