9.3 KiB
tags, create time
| tags | create time | ||||
|---|---|---|---|---|---|
|
2026-05-15 18:10 |
Redis 安装与部署
概述
本节介绍 Redis 的安装方式、关键配置和安全加固。无论使用官方二进制还是容器化方案,核心目标一致:安全启动、合理分配内存、设置持久化策略。
[!QUESTION] 为什么安装步骤简单,生产部署却容易出问题?
Redis 本质是一个单进程内存服务,安装只需几行命令。但一旦上线,内存超限导致 OOM Killer 介入、未设密码被外网扫描器写入大量脏数据、或 AOF/RDB 同时触发 fork 导致内存翻倍——这些才是真正需要关注的问题。
选择安装方式
先根据场景确定合适的部署路径:
flowchart LR
A[开始:选择安装方式] --> B{运行环境?}
B -->|macOS 本地开发| C[brew install redis]
B -->|Ubuntu/Debian 服务器| D[apt install redis-server]
B -->|需要指定特定版本| E[源码编译]
B -->|本地开发 / 微服务| F[Docker Compose 推荐]
B -->|高可用集群| G[[hhs/Redis/07-集群方案]]
C --> Z[进入配置阶段 →]
D --> Z
E --> Z
F --> Z
macOS — Homebrew
brew install redis # 安装最新稳定版
brew services start redis # 注册为后台服务
redis-cli ping # 验证:应返回 PONG
[!TIP] 安装后配置文件位于
/opt/homebrew/etc/redis.conf(Apple Silicon)或/usr/local/etc/redis.conf(Intel)。
Linux — 包管理器
sudo apt update && sudo apt install redis-server
sudo systemctl enable --now redis-server
发行版默认安装的 Redis 版本可能落后于上游最新版。如果需要跟进特性或安全补丁,考虑源码编译或 Docker。
源码编译(指定版本)
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar xzf redis-7.2.4.tar.gz
cd redis-7.2.4
make -j$(nproc) # 利用多核并行编译
sudo make install # 安装到 /usr/local/bin
redis-server --version # 确认版本
[!NOTE] Redis 基于 C 开发,编译时无外部依赖(新版内置 jemalloc)。如果你的系统缺少 gcc/make,需提前安装构建工具链。
Docker(推荐本地开发)
version: "3.9"
services:
redis:
image: redis:7-alpine # Alpine 镜像仅 ~30MB,适合开发环境
container_name: redis-dev
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: >
redis-server
--requirepass ${REDIS_PASSWORD:-changeme}
--appendonly yes
--maxmemory 512mb
--maxmemory-policy allkeys-lru
restart: unless-stopped
volumes:
redis-data:
Tip
- 通过
${REDIS_PASSWORD:-changeme}引用环境变量,避免在仓库中硬编码真实密码。- 开发环境建议限制
maxmemory,防止占满本机内存。- 生产环境不要使用
redis:latest标签,锁定具体版本号以避免未知变更。
[!EXAMPLE] 如何快速连接带密码的 Redis?
export REDIS_PASSWORD="your-strong-pass" redis-cli -a "$REDIS_PASSWORD" ping # 输出: PONG
关键配置项
编辑 redis.conf(Docker 用命令行参数覆盖),以下是生产环境必看的核心选项:
| 配置项 | 推荐值 | 说明 |
|---|---|---|
bind 127.0.0.1 |
内网 IP 或注释 | 限制监听地址;生产环境需配合防火墙规则 |
protected-mode yes |
保持默认 | 无密码时自动拒绝外部连接 |
port 6379 |
— | 自定义端口,但不要指望这算安全措施 |
requirepass your-strong-pass |
强密码 | 必须设置,尤其对外暴露时 |
maxmemory 2gb |
物理内存的 60%~70% | 防止 OOM Killer 接管,给 OS 和子进程留余地 |
maxmemory-policy allkeys-lru |
— | 内存满时的淘汰策略,见下方说明 |
tcp-backlog 511 |
511~1024 | 三次握手已完成但未被 accept 的队列深度 |
timeout 300 |
300 | 客户端空闲超时断开(秒),释放无效连接 |
loglevel notice |
— | debug 级别会产生海量日志,影响性能 |
databases 16 |
— | 逻辑数据库数量,通常不改 |
[!IMPORTANT] maxmemory-policy 的选择直接影响业务语义
allkeys-lru:对所有键做 LRU 淘汰。通用场景首选。volatile-lru:仅对设置了过期时间的键做 LRU 淘汰。适合缓存+热数据混合的场景。noeviction:不淘汰,空间不足时直接报错。适合纯缓存,应用层自行控制生命周期。选错策略的代价是什么? 如果用
noeviction而忘了设置过期时间,Redis 会在写操作时报OOM错误,而非优雅降级。
启动并验证配置:
# 以自定义配置启动
redis-server /etc/redis/redis.conf
# 逐项检查是否生效
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli CONFIG GET requirepass
[!NOTE] 线上修改无需重启:大部分配置可以通过
CONFIG SET key value动态调整,但退出后失效。持久化需在配置文件中修改。
Systemd 服务管理(Linux)
使用 systemd 管理能确保开机自启、崩溃自动恢复:
[Unit]
Description=Redis In-Memory Data Store
After=network.target # 网络就绪后再启动 Redis
[Service]
Type=simple
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecReload=/bin/kill -USR2 $MAINPID # USR2 触发配置重载(Redis 6.2+)
Restart=on-failure # 崩溃后自动拉起
RestartSec=5 # 间隔 5 秒重试,避免频繁闪退
LimitNOFILE=65535 # 文件描述符上限,支持大量并发连接
[Install]
WantedBy=multi-user.target # 多用户模式下的标准服务
sudo systemctl daemon-reload # 读取新增/修改的服务文件
sudo systemctl enable --now redis # 启动 + 开机自启
sudo journalctl -u redis -f # 实时查看日志
[!QUESTION] 为什么
Restart=on-failure还不够?如果 Redis 因为配置错误(如 bind 地址不可达)反复崩溃,
on-failure会无限重试。配合日志告警或健康检查才能真正发现问题。
内核级调优
Redis 是 IO 密集型单进程服务,操作系统层面的参数会直接影响吞吐量上限:
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf
echo "vm.max_map_count = 262144" >> /etc/sysctl.conf
sysctl -p # 立即生效
flowchart LR
A[客户端连接请求] -->|SYN| B[TCP 半连接队列\nsomaxconn]
B -->|三次握手完成| C[TCP 全连接队列\ntcp-backlog]
C --> D[Redis accept()]
D --> E[分叉持久化\novercommit_memory]
style A fill:#e1f5fe
style C fill:#fff3e0
style E fill:#f3e5f5
| sysctl 参数 | 作用 | 为什么需要 |
|---|---|---|
vm.overcommit_memory = 1 |
允许 fork() 时内存过度分配 | RDB 和 AOF rewrite 都通过 fork 创建子进程,父子进程共享物理页;若无此设置,大内存实例 fork 可能被内核拒绝 |
net.core.somaxconn = 1024 |
TCP 全连接队列长度 | 高并发下队列满了会导致客户端 connect 超时,表现为"Redis 连不上" |
vm.max_map_count = 262144 |
mmap 区域上限 | Redis 在开启 LFU 等特性时会使用 mmap,默认值过小会被限制 |
部署架构演进
单机 → Sentinel → Cluster,不同阶段的架构差异:
flowchart TB
subgraph S1[阶段一:单机]
C1[Client] --> M1[(Master)]
end
subgraph S2[阶段二:主从 + Sentinel]
C2[Client] --> M2[(Master)]
C2 -.-> S2a[Sentinel]
M2 --> S2b[(Slave 1)]
M2 --> S2c[(Slave 2)]
end
subgraph S3[阶段三:Cluster]
C3[Client] --> P[Hash Slot 路由]
P --> N1[Node 1: Slots 0-5460]
P --> N2[Node 2: Slots 5461-10922]
P --> N3[Node 3: Slots 10923-16383]
end
S1 ===>|数据量增长,需要高可用| S2
S2 ===>|单机内存瓶颈,需要水平扩展| S3
style S1 fill:#e8f5e9
style S2 fill:#fff3e0
style S3 fill:#fce4ec
[!INFO] 本系列后续文档将深入每个阶段:
- hhs/Redis/04-RDB持久化 — RDB 快照机制
- hhs/Redis/05-AOF持久化 — 追加日志机制
- hhs/Redis/07-集群方案 — Cluster 分片原理与部署
快速检查清单
[!CHECKLIST] 部署前核对
- 已设置
requirepass(非默认或测试密码)maxmemory不超过物理内存的 70%,预留 OS 和 fork 空间- 已启用持久化(至少 AOF
appendonly yes)bind指向内网地址,或通过防火墙限制访问来源 IPvm.overcommit_memory已设为 1- 已配置合理的
timeout和tcp-keepalive,清理僵尸连接- 确认
maxmemory-policy符合业务语义(推荐allkeys-lru)- Docker 部署时密码通过环境变量注入,未硬编码在 compose 文件中
关联笔记
- hhs/Redis/02-核心数据类型 — String / Hash / List / Set / ZSet 的使用场景
- hhs/Redis/04-RDB持久化 — RDB 快照原理与配置
- hhs/Redis/05-AOF持久化 — AOF 重写机制与 fsync 策略
- hhs/Redis/07-集群方案 — Cluster 部署与迁移策略
- hhs/Redis/11-运维与性能调优 — OOM、延迟 spike、连接数爆满的诊断思路