从安装到安全配置
本章目标是在 Linux 或 Docker 中得到一个“可连接、不会暴露公网、有内存上限、可恢复”的实例。先部署单机练习;高可用在后续章节再搭建。
完成后你将能够:
- 规划 Redis 的配置、数据、日志和备份目录;
- 使用 Docker Compose 启动一个持久化实例;
- 看懂网络、AOF、内存和客户端相关配置;
- 创建应用用户和运维用户并验证权限;
- 重启实例后确认数据仍存在。
1. 先检查机器
Redis 的数据主要在内存中。maxmemory 不能等于物理内存,因为操作系统、复制缓冲区、RDB fork 的写时复制和内存碎片都需要空间。
free -h
df -h /var/lib/redis
sysctl vm.overcommit_memory
cat /sys/kernel/mm/transparent_hugepage/enabled
生产环境应预留内存、关闭 THP、设置 vm.overcommit_memory=1,数据目录使用可靠磁盘。不要把 Redis 与其他高内存服务随意混部。
1.1 一个简单的内存预算例子
一台 16 GiB 主机不应直接配置 maxmemory 16gb。初始可按下列思路评估:
| 用途 | 示例预算 |
|---|---|
| Redis 数据集上限 | 10 GiB |
| fork 写时复制、复制缓冲与碎片 | 3 GiB |
| 操作系统、页缓存和守护进程 | 3 GiB |
这不是通用公式。写入越频繁、value 越大、持久化越频繁,fork 期间的额外内存越高,最终必须通过压测和监控校准。
2. 用 Docker Compose 完成可重复部署
建立独立目录:
mkdir -p ~/redis-tutorial/config
cd ~/redis-tutorial
创建 config/redis.conf:
bind 0.0.0.0
protected-mode yes
port 6379
dir /data
appendonly yes
appendfsync everysec
maxmemory 256mb
maxmemory-policy allkeys-lru
loglevel notice
创建 compose.yaml:
services:
redis:
image: redis:7.4-alpine
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis-data:/data
- ./config:/usr/local/etc/redis:ro
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
volumes:
redis-data:
docker compose config
docker compose up --detach --wait
docker compose ps
redis-cli -h 127.0.0.1 ping
预期 PING 返回 PONG,docker compose ps 显示容器为 healthy。127.0.0.1:6379:6379 只允许本机访问;生产不要直接发布到公网。
2.1 验证数据卷真的有效
redis-cli SET tutorial:persist 'before-restart'
docker compose restart redis
redis-cli GET tutorial:persist
重启后仍应返回 before-restart。如果执行 docker compose down --volumes,命名卷会被删除,实验数据也会消失。
3. 看懂关键配置
# 网络与日志
bind 127.0.0.1 10.0.10.15
protected-mode yes
port 6379
tcp-keepalive 300
dir /var/lib/redis
logfile /var/log/redis/redis-server.log
# 持久化与内存
save 900 1
appendonly yes
appendfsync everysec
maxmemory 12gb
maxmemory-policy allkeys-lfu
activedefrag yes
maxclients 10000
everysec 通常是性能和可靠性的折中:主机异常时仍可能丢失约一秒写入。缓存常用 LRU/LFU 淘汰;不能淘汰的数据使用 noeviction,并让应用处理写入失败。
3.1 网络参数
bind决定监听哪些本机地址;应填写环回或私网地址;protected-mode yes会在缺少明确安全配置时限制访问,但不能代替防火墙;tcp-keepalive用于发现失效连接;tcp-backlog需要与内核somaxconn一起看。
3.2 内存上限和淘汰策略
| 策略 | 行为 | 常见用途 |
|---|---|---|
noeviction | 内存满后写命令报错 | 不能静默丢数据的场景 |
allkeys-lru | 从所有 key 中近似淘汰最近少用者 | 通用缓存 |
allkeys-lfu | 从所有 key 中近似淘汰低频 key | 热点稳定的缓存 |
volatile-lru | 只从设置 TTL 的 key 中淘汰 | 同实例混合缓存和不可淘汰数据时使用,但风险较高 |
不要等线上内存满了才第一次验证策略。可以在小容量实验实例写入数据,观察 INFO stats 中 evicted_keys 是否增加。
4. 用 ACL 替代“一个万能密码”
在 config/redis.conf 中增加 ACL 文件路径:
aclfile /usr/local/etc/redis/users.acl
创建 config/users.acl:
# users.acl,文件权限应为 0600
user default off
user app on >替换为随机密码 ~app:* +@read +@write -@dangerous
user ops on >替换为随机密码 ~* +@all
chmod 0600 config/users.acl
docker compose restart redis
ACL 启用后,原先无需认证的健康检查也要调整。在 compose.yaml 的 Redis 服务中增加与 ACL 文件一致的实验密码:
environment:
REDISCLI_AUTH: ${REDIS_OPS_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "redis-cli --user ops ping | grep -q PONG"]
将密码写入不提交 Git 的 .env,再执行 docker compose up --detach --wait。生产环境应使用 Secret 管理,环境变量方式仅用于本地实验。
应用用户只能访问自身前缀;运维用户才有管理权限。密码、ACL 和证书不要提交 Git。完成后使用专用用户验证:
export REDISCLI_AUTH='<ops 密码>'
redis-cli --user ops -h 127.0.0.1 ping
redis-cli --user ops CONFIG GET maxmemory
4.1 验证最小权限
配置 ACL 后重启 Redis,再分别验证:
# 应用用户可以访问 app:* key
REDISCLI_AUTH='<app 密码>' redis-cli --user app SET app:test ok
REDISCLI_AUTH='<app 密码>' redis-cli --user app GET app:test
# 应用用户访问其他前缀应返回 NOPERM
REDISCLI_AUTH='<app 密码>' redis-cli --user app GET secret:test
# 应用用户执行危险命令应返回 NOPERM
REDISCLI_AUTH='<app 密码>' redis-cli --user app FLUSHALL
4.2 ACL 配置不生效时怎么查
docker compose logs --tail 100 redis
REDISCLI_AUTH='<ops 密码>' redis-cli --user ops ACL LIST
REDISCLI_AUTH='<ops 密码>' redis-cli --user ops ACL WHOAMI
常见原因是 aclfile 路径未挂载、文件权限不允许 Redis 读取、配置文件未加载或用户规则语法错误。
5. Linux systemd 部署时的目录规范
生产服务器通常将配置、数据、日志和备份分开:
/etc/redis/redis.conf 配置
/etc/redis/users.acl ACL
/var/lib/redis/ RDB/AOF 数据
/var/log/redis/ 日志
/backup/redis/ 本机临时备份,不替代异地备份
sudo install -d -o redis -g redis -m 0750 /var/lib/redis /var/log/redis
sudo install -d -o root -g redis -m 0750 /etc/redis
sudo chmod 0600 /etc/redis/users.acl
sudo systemctl enable --now redis
sudo systemctl status redis --no-pager
sudo journalctl -u redis -n 100 --no-pager
不同发行版的软件包路径可能不同,先通过 systemctl cat redis 和 redis-cli CONFIG GET dir 确认实际配置,不要照抄路径覆盖已有部署。
6. 本章验收与清理
确认以下结果:
docker compose ps显示 healthy;- Redis 仅绑定本机或私网;
CONFIG GET maxmemory返回预期值;- 应用 ACL 用户无法执行
FLUSHALL; - 容器重启后测试 key 仍存在。
保留环境继续后续章节,或清理:
docker compose down
# 确认不再需要实验数据时才删除卷
docker compose down --volumes