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 的结果:
| 测试 | 每秒请求数 | 延迟中位数 |
|---|---|---|
| SET | 30,303 | 1.0 ms |
| GET | 35,149 | 0.9 ms |
| SET,每次往返 16 条命令 | 272,109 | 2.4 ms |
| GET,每次往返 16 条命令 | 414,938 | 1.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。
评论
暂无评论。来做第一个吧。