1. 搭建前的方案选型:先想清楚再动手
先说个很现实的事:现在几乎没有任何一家做后端服务的团队能绕开 Redis。项目刚开始可能只是用个缓存,等业务复杂了,限流、分布式锁、排行榜、消息队列、布隆过滤器都会慢慢落到 Redis 上。所以看起来是“装个 Redis 服务器”,实际上是在为你接下来 MVP 小半年的业务架构打地基。地基打歪了,后面改起来相当痛苦。
在动手搭建之前,有几个关键决策必须先定下来,不然装到一半会发现进退两难。
1.1 安装方式:源码编译、包管理器还是容器
针对“服务器搭建”这个场景,最常见的三种安装路径是:源码编译、系统包管理器(yum/apt)和 Docker 容器。很多人上来就直接yum install redis,图省事,结果装出来一个老版本,而且配置文件的位置、日志风格、systemd 托管方式都跟新版本有出入,后面排查问题时容易两脸懵。
我自己在实际项目中更推荐源码编译安装,原因有三点:
- 版本可控:Redis 的迭代速度不慢,新特性大多集中在 6.x、7.x 甚至更新的版本。源码编译能准确定位到具体小版本,避免一不小心装到古董版本。
- 目录可控:编译时可以指定安装前缀,把 Redis 全部塞进约定好的
/usr/local/redis-7.x.x目录下,备份、迁移、销毁都方便。 - 能调编译参数:虽然大部分时候默认配置就够用,但真到了要调整内存分配器或开启某些编译优化时,只有源码编译这条路。
容器方案适合快速体验和本地开发,生产环境只要你对 Docker 网络模型(特别是 host 模式和 bridge 模式)理解不深,建议先别上。容器的数据卷、持久化、权限映射都是要额外花功夫的坑。
1.2 版本怎么选:别只看最新版
Redis 的版本号分奇偶:偶数版本(6.0、6.2、7.0、7.2、8.0)是稳定版,适合生产环境直接用;奇数版本(6.1、7.1)属于功能预览版,通常只在开发环境里尝鲜。
如果你刚接触 Redis,我建议直接上 7.x 的偶数稳定版。7.0 之后,ACL 权限模型、多部分 AOF 重写机制、更好用的子命令权限、wait命令的增强,都值得你在后续运维中慢慢用上。老项目如果已经在 6.2 上跑得稳稳的,也没有特别要追的新特性,完全可以继续用 6.2,不要为了升级而升级。
有一点必须敲黑板:不要在生产环境用最新刚发布的大版本。我一个同事踩过这个坑——项目急着要 Redis 的一个新命令,于是直接上了某个刚 GA 的小版本,结果用了不到一周就撞上内存碎片率异常的场景,网上还没什么资料参考,排查了两天才定位到是该版本的内存申请逻辑回归。稳定大于一切。
1.3 单机、主从还是集群
搭建前就要想清楚你的“Redis 服务器”最终要承担什么样的角色。
- 单机 Redis:适合开发环境、演示环境、以及并发量不高的内部工具系统。配置简单,但一台机器挂了就全部不可用。
- 主从复制:适合读多写少的业务,一个主节点扛写,多个从节点分流读。同时也是数据热备的一种形式。
- Redis Sentinel(哨兵):在主从基础上加自动故障转移,能实现高可用。配置复杂度上了一个台阶,但这是生产环境基本的可选项。
- Redis Cluster:数据量大、并发量高时会考虑,但搭建和排障成本都比较高,新手阶段不建议一开始就上。
我的个人建议:第一次搭建,先老老实实把单机跑通,把配置文件里每个关键参数搞明白,然后再考虑复制和高可用。单机的坑都还没踩完就急着搭集群,最后会发现 Redis 本身没出问题,问题全出在集群拓扑和网络上面。
2. 安装全程记录:从依赖到 systemd 托管
这一节直接给你一条经过验证的安装路径。我以常见 Linux 发行版(CentOS / Rocky / AlmaLinux 这类 RHEL 家族)为例。如果你用的是 Ubuntu/Debian 系,包管理命令换成 apt 即可,源码编译的核心步骤完全一致。
2.1 安装系统依赖
Redis 是 C 语言写的,编译需要 gcc、make 等工具链。一行命令装齐:
yum install -y gcc make tcltcl 是用来跑 Redis 自带单元测试的,如果你只是要编译安装,其实不装也行。但我建议还是装一下,后面想验证编译结果时直接用官方测试兜底,省心。
编译前建议把系统升级一下(yum update -y),避免因为 gcc 版本太老导致编译报错。更新完记得重启系统,让新内核生效。
2.2 下载源码并编译安装
到 Redis 官网或 GitHub 的 releases 页面找到对应版本的源码包。以下载 7.2.5 为例(版本号可替换为你选好的稳定版):
cd /opt wget https://download.redis.io/releases/redis-7.2.5.tar.gz tar xzf redis-7.2.5.tar.gz cd redis-7.2.5 make -j4 make install PREFIX=/usr/local/redis-7.2.5注意这里的make install PREFIX=的用法,它会把所有可执行文件装到/usr/local/redis-7.2.5/bin/下,包括 redis-server、redis-cli、redis-sentinel、redis-check-aof / redis-check-rdb 这些工具。
编译过程如果报错说缺少某个库,先回头检查 gcc 和 make 是否装好。编译时看到类似Hint: It's a good idea to run 'make test'的提示,说明基本上编译成功了。
很多人会忽略make test,我个人是每次都是跑到测试通过的,特别是你准备上生产,测试一下能够排除一些特定内核或者 libc 下的兼容性问题。测试指令是:
make test测试全套下来大概几分钟。如果测试全绿,再执行make install。
2.3 目录规划:让数据和配置各就各位
装完二进制只是第一步。真正专业的服务器要管理起来,目录结构必须清晰。我习惯用这样的布局:
/usr/local/redis-7.2.5/ # Redis 安装主目录 └── bin/ # 可执行文件 /etc/redis/ # 配置文件目录 /data/redis/ # 数据持久化目录(RDB/AOF 文件) /logs/redis/ # 日志目录 /var/run/redis.pid # PID 文件位置这样规划的好处是:升级 Redis 时只需要把/usr/local/redis-7.2.5替换成新版本目录、重新放一份配置,数据和日志完全不受影响。
创建目录并设置好权限,后面不要用 root 去跑 Redis,这是一个重要的底线:
mkdir -p /etc/redis /data/redis /logs/redis useradd -r -s /sbin/nologin redis chown -R redis:redis /data/redis /logs/redis2.4 初始化配置文件
Redis 源码包自带的redis.conf在源码目录下,直接拷到/etc/redis/即可作为基础配置。安装完成后生产配置不建议在默认文件上直接改,先把一个干净的副本放过去,再逐项修改:
cp /opt/redis-7.2.5/redis.conf /etc/redis/redis.conf chown redis:redis /etc/redis/redis.conf chmod 640 /etc/redis/redis.conf2.5 用 systemd 把 Redis 托管起来
Linux 服务器上跑常驻服务,推荐使用 systemd 托管,可以配置服务自动重启、开机自启,日志也更好管理。
在/etc/systemd/system/redis.service新建一个服务文件:
[Unit] Description=Redis Server After=network.target [Service] Type=forking User=redis Group=redis ExecStart=/usr/local/redis-7.2.5/bin/redis-server /etc/redis/redis.conf ExecStop=/usr/local/redis-7.2.5/bin/redis-cli -a yourpassword shutdown Restart=always RestartSec=5 PIDFile=/var/run/redis.pid LimitNOFILE=65535 [Install] WantedBy=multi-user.target结合配置文件里daemonize yes这一项来理解:Redis 以守护进程方式启动时,父进程启动后会退出,由 systemd 的Type=forking和PIDFile来跟踪实际服务进程。如果不打算用 daemonize(也可以设 daemonize no 配合前台运行),那 systemd 的 Type 要改成 simple,并且去掉 PIDFile。
启用并启动服务:
systemctl daemon-reload systemctl enable redis systemctl start redis检查状态时,看到一个显示为active (running)的服务输出就算起来了:
systemctl status redis然后尝试用客户端测试连通:
/usr/local/redis-7.2.5/bin/redis-cli -a yourpassword ping如果返回PONG,恭喜你,一套最基本的 Redis 服务器已经落地。
提示:如果你是把 Redis 给公司内部服务用,或者正在学习阶段,不要在命令行里带密码执行 redis-cli,密码会被进程列表(ps)里看到。测试没问题后,应该用
redis-cli -h 127.0.0.1 -p 6379进去后,在交互界面里执行AUTH输入密码。
3. 配置文件逐项拆解:每改一个参数都要知道为什么
Redis 默认的 redis.conf 有大量注释,阅读门槛不高。问题是很多初学者只搜关键字照葫芦画瓢,改完也不知道自己改了个啥。我给你把最关键的一批配置项逐条讲透,顺带解释这些参数在什么业务场景下要特别注意。
3.1 网络相关:绑定、端口、保护模式
bind 127.0.0.1 -::1 port 6379 protected-mode yes默认配置下,bind 只绑定了本机回环地址,外网无法直接访问。如果你在本地开发环境装完 Redis,发现其他地方连不上,不要急着把 bind 删掉或者改成0.0.0.0,那等于把 Redis 裸奔在网络上,是很危险的做法。
正确的姿势是:如果你的 Redis 只给本机应用用,保持bind 127.0.0.1完全没问题。如果必须让局域网内的其他机器访问,把 bind 改成内网 IP 地址,例如bind 192.168.1.100,然后用防火墙把 6379 端口的访问源限制在可信任网段。不要图省事绑0.0.0.0。
protected-mode yes也很关键。它在“没有设置密码 + 没有显式配置 bind 非回环地址”的双重情况下,自动禁止非回环地址的连接。所以只要你的 Redis 还在公网可达的位置,千万别把 protected-mode 改成 no。
3.2 密码和用户名:从 requirepass 到 ACL
Redis 的旧式密码认证是requirepass:
requirepass 你的复杂密码启动后用redis-cli -a 密码就能连接。这个方式简单,但是只支持一个密码、一个账号。到了 6.x 以后有了 ACL(Access Control List),可以做到“不同用户、不同权限”。
举例来说,假设你有一个业务 A 允许读写所有 key,业务 B 只允许读特定前缀的 key,你可以:
user default off user app_a on >appA密码 ~* +@all user app_b on >appB密码 ~cache:* +get +scan这在多业务共用一套 Redis 的场景下特别香。不过实操中我也见过不少团队,内部工具系统,就两个开发在用,搞 ACL 反而折腾,一个 requirepass 就够。看你的团队复杂度做取舍,没有绝对标准。
3.3 持久化策略:RDB、AOF 怎么搭配
Redis 的持久化有两个机制,先说结论再讲细节。
RDB(快照)像游戏存档:定期把内存里的全量数据生成一份二进制快照文件 dump.rdb 存到磁盘。恢复时一把梭把全量数据灌回内存,速度很快,但一旦在两次快照之间崩溃,会丢了这一段时间的增量写操作。
AOF(追加文件)像记账流水:每执行一次写命令,就把命令追加到 appendonly.aof 文件末尾。重启时挨条执行 AOF 里的命令,恢复到崩溃前的状态。数据安全性更高,但文件体积大,重放命令恢复的速度也比 RDB 慢。
生产环境的常规组合是:
save 900 1 save 300 10 save 60 10000 appendonly yes appendfsync everysec即“RDB 做定期全量兜底 + AOF 做精细增量恢复”。appendfsync everysec表示每秒刷一次盘,极端情况最多丢 1 秒的数据,同时不至于把性能拖垮。
有一个容易踩的点是:当两个机制同时开启时,Redis 重启优先用 AOF 文件做恢复,因为 AOF 的数据新鲜度高。所以如果你改了 AOF 配置,记得确认 appendonly.aof 文件真的在生成(目录里能看到文件并且不断变大),避免 AOF 开关开了但实际上没在写,那就失去了保护意义。
3.4 内存管理和淘汰策略
Redis 默认是无限使用系统内存的,这在你内存 128G 的机器上,如果拼命往里写数据而不加限制,可能会把整台机器拖到 swap 甚至触发 OOM。生产环境强烈建议设一个上限:
maxmemory 4gb有上限之后,内存不够了怎么办?这就看淘汰策略:
noeviction:内存满的时候,写命令直接报错,不淘汰任何已有 key。适合绝不能丢数据的场景。allkeys-lru:从所有 key 中按 LRU(最近最少使用)算法淘汰,适合纯缓存场景。volatile-lru:只从设置了过期时间的 key 中淘汰。适合一部分数据要留、一部分数据可丢的业务。
我见过不少人把 Redis 当缓存时还在用 noeviction,结果业务量上来之后突然就写入报错。这背后其实是业务定位没想清楚:只要允许 Redis 丢一点旧数据来换新数据的写入,就该选 allkeys-lru;如果是强一致性的业务数据,应该走数据库而不是 Redis。
3.5 执行模型与性能参数
maxclients 10000 timeout 0 tcp-keepalive 300maxclients控制最大连接数,除非你的业务会有超高并发连接,默认值改到万级基本够用。timeout 0表示连接空闲不自动关闭,避免客户端偶发空闲就被踢掉导致业务报错。tcp-keepalive 300是系统层面用来探活短连接。
还有两个系统内核参数,单独讲一下:
vm.overcommit_memory = 1 net.core.somaxconn = 511overcommit_memory控制内存分配策略。Redis 在做 RDB 快照或 AOF 重写时需要 fork 子进程,如果系统内存overcommit_memory=0(默认的启发式策略),在内存紧张时 fork 可能直接失败,表现为前台还活着但持久化完全没有进展。设成 1 表示允许进程申请超过物理内存,为 fork 时的写时复制留出余地。
somaxconn是 TCP backlog 队列大小。如果设置过小,高并发连接时客户端会报 connection refused,调大后能显著降低连接失败率。
4. 安全加固:别人怎么黑进来,你就怎么防回去
Redis 默认配置横在公网上,就是一扇没上锁的门。业内被勒索、被植入挖矿程序的案例多得数不清,而且手法极其简单——扫 6379 端口,探测到没密码的保护模式关闭实例,直接连上去写 crontab 反向下载挖矿脚本。下面这几条安全策略,每一条我都在真实环境里见过它的必要性。
4.1 改默认端口
把 6379 改成高位随机端口(比如 16379、26379),虽然防不了定向扫描,但能避开大量无差别批量扫描的脚本。和防火墙搭配组合,效果好一截。
4.2 高危命令重命名
Redis 里有几个命令,攻击者拿到权限后就是大杀器:
FLUSHALL/FLUSHDB:清空所有数据。KEYS:遍历全库 key,海量 key 时会把服务直接拖死。CONFIG:运行时读取/修改配置。
保守方案是一律 rename 成不可猜测的长字符串,例如:
rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command KEYS "s0me_c0mplex_k3y_9a1b2c3d" rename-command CONFIG "s0me_c0mplex_cfg_9a1b2c3d"设置为空字符串代表彻底禁用。考虑到有些内部运维脚本会用 KEYS 查数据,你可以保留一个长别名给自己人用。要注意的坑是:如果你未来要搭 Redis Cluster,rename-command 不能把命令重命名为空串,某些集群控制指令被禁用会导致节点管理出问题。
4.3 物理网络隔离
最靠谱的安全就是不让它出现在公网上。生产环境把 Redis 部署在公司内网,配合安全组或防火墙,只放行来自应用服务器 IP 的访问。我在一家公司见过一个操作失误:运维图省事把 Redis 绑定在公网网卡上,发现时已经被外部扫描器写入了一个名为backup2的异常 key——里面是一段脚本。这就是典型的安全事故开头。
4.4 日志与审计
loglevel notice logfile "/logs/redis/redis.log"日志级别别用 debug(单条命令都打出来,量太大),也尽量别用 warning(会漏掉连接异常等信息)。notice 级别够用且信息量合理。真遇到入侵或误操作,通过日志能看到事发时间线和命令来源 IP(前提是 Redis 的监听地址能映射出客户端来源)。
5. 性能调优和监控:服务器跑起来了,这才只是开始
Redis 装上之后看起来一切正常,但你得知道怎么判断它“是不是真的正常”。等线上出问题再翻监控指标,往往已经晚了。
5.1 内存碎片率
用INFO memory可以看到mem_fragmentation_ratio这个指标:
- 在 1 到 1.5 之间:正常。内存分配器(jemalloc)和实际内存申请之间存在合理损耗。
- 大于 1.5:内存碎片率偏高。常见原因是频繁的更新、删除操作,或者大量 key 设置了不同的过期时间。可以通过重启释放碎片,但真正的根治是代码层将数据模型改造成少删多改的类型。
- 小于 1:物理内存本身不足,触发了 swap。这个情况比碎片率过高更危险,Redis 跑在 swap 上性能会断崖式下降。此时优先看有没有内存泄漏,考虑加内存或迁移。
5.2 慢查询
Redis 是单线程模型的(现在 6.0+ 有 IO 多线程,但执行命令还是主线程为主),一个慢命令会拖慢后面所有命令。配置:
slowlog-log-slower-than 10000 slowlog-max-len 128单位是微秒,10000表示执行耗时超过 10 毫秒的命令会被记录。通过SLOWLOG GET查看慢命令日志,能看到是哪种命令(比如KEYS *、大LRANGE、HGETALL)在拖后腿,然后针对性地优化数据结构或在业务层加缓存。
5.3 连接数和 hit/miss 比例
INFO stats里的keyspace_hits和keyspace_misses能算出缓存命中率。如果你的业务把 Redis 当缓存用,命中率长期低于 80%,要么是热点 key 的过期时间设计不合理,要么是明明可以缓存的数据每次都穿透到了后端存储。这两个指标比 CPU 使用率更能反映 Redis 是否在“干正事”。
5.4 搭建完成后的自检清单
给你一个我每次部署完都会对照检查的清单:
| 检查项 | 期望结果 |
|---|---|
| 绑定地址是否只留信任网段 | bind 不为 0.0.0.0 |
| 是否设了访问密码 | requirepass 或 ACL 已配置 |
| 是否启用持久化 | appendonly yes + save 规则存在 |
| 日志目录是否有写权限 | 启动后 /logs/redis 有日志产出 |
| maxmemory 是否设置 | 不高于物理内存 60%-70% |
| systemd 是否配置开机自启 | systemctl is-enabled redis 返回 enabled |
| vm.overcommit_memory 是否为 1 | sysctl vm.overcommit_memory 输出 1 |
| 端口是否被防火墙放行 | 仅有应用服务器 IP 可访问 |
6. 常见故障与排查思路:你大概率会遇到的四个问题
就算配置正确,有些问题在特定场景下还是会出现。我按真实环境里遇到的高频问题整理一下。
6.1 启动时报错Can't open the log file
日志文件路径的权限不对。Redis 以 redis 用户运行,但/logs/redis目录可能还是 root 拥有。解决办法是chown -R redis:redis /logs/redis,然后重新启动。这一条新手十有八九踩一次。
6.2 连接时提示Redis is running in protected mode
要么没设密码,要么 bind 配了非回环地址,而且 protected-mode 为 yes。按上面说的,设上 requirepass 并且把 bind 明确为内网可信 IP,这个错误就消失了。
6.3 内存没满但写入报OOM command not allowed when used memory > 'maxmemory'
内存确实到了上限。查看INFO memory里的used_memory和maxmemory对比,用redis-cli --bigkeys扫一下大 key(注意这在生产环境要谨慎,可能造成短暂阻塞),把没必要留的数据清理掉。
6.4 AOF 文件越来越大甚至拖慢启动
7.x 版本支持 AOF 自动重写,配置:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb当 AOF 文件相比上次重写时增长超过 100% 且文件大于 64MB 时,会自动触发重写,把冗余命令合并掉。如果你发现 AOF 文件一直没有缩小,手动执行BGREWRITEAOF触发一次重写。
6.5 实际的莫名其妙高延迟
高延迟不一定是 Redis 本身变慢。我排查过一种场景:大量集中过期的 key 在同一秒内过期,Redis 会主动清理它们,导致这一瞬间响应变慢。解决办法是业务代码里给 key 的过期时间加上随机偏移,让过期时间分散开。
还有一种情况是应用服务器和 Redis 服务器之间有网络抖动,或者 Redis 所在机器开启了 swap。这种情况别急着调 Redis 参数,先看系统层面的vmstat和free -h。
7. 一些个人经验谈
搭建过十几次 Redis 服务之后,我的一个整体感觉是:Redis 的安装本身不难,难的是把它当成一个有状态的服务来治理。很多团队的 Redis 都是“装完就不管了”,等出了故障一拍脑袋,连自己用的版本、持久化策略、内存上限是多少都说不清。这种认知盲区,比任何技术问题都更可怕。
我在项目开工时习惯做一件小事:部署完成后立刻把版本号、配置关键项、数据目录、日志目录、备份恢复验证方式,写进团队的运维文档。平时没什么用,但真到了故障演练或某个凌晨 Redis 挂了的时候,这份文档就是救命的灯。
另外一个经验是,Redis 的数据备份恢复要定期演练,不能只依赖“磁盘自动快照”。RDB 文件是否完整、AOF 重放之后数据是否一致,这些不用真实跑一遍恢复流程,都只是理论上的“应该没问题”。我见过不止一次因为 RDB 文件损坏或 AOF 文件缺失导致恢复失败的场景,演练过的人和没演练过的人,在同一时刻的反应速度完全是两个级别。
如果你现在只是刚学会怎么启动一条redis-server,恭喜你已经迈出了第一步。接下来,在配置上多留一份心,在安全上多关一道门,在监控上多看一眼指标,这套基础设施就能稳稳地撑住你上层的业务。