
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: Its 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] DescriptionRedis Server Afternetwork.target [Service] Typeforking Userredis Groupredis 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 Restartalways RestartSec5 PIDFile/var/run/redis.pid LimitNOFILE65535 [Install] WantedBymulti-user.target结合配置文件里daemonize yes这一项来理解Redis 以守护进程方式启动时父进程启动后会退出由 systemd 的Typeforking和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 到 ACLRedis 的旧式密码认证是requirepassrequirepass 你的复杂密码启动后用redis-cli -a 密码就能连接。这个方式简单但是只支持一个密码、一个账号。到了 6.x 以后有了 ACLAccess 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_memory0默认的启发式策略在内存紧张时 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 Clusterrename-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 返回 enabledvm.overcommit_memory 是否为 1sysctl vm.overcommit_memory 输出 1端口是否被防火墙放行仅有应用服务器 IP 可访问6. 常见故障与排查思路你大概率会遇到的四个问题就算配置正确有些问题在特定场景下还是会出现。我按真实环境里遇到的高频问题整理一下。6.1 启动时报错Cant 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恭喜你已经迈出了第一步。接下来在配置上多留一份心在安全上多关一道门在监控上多看一眼指标这套基础设施就能稳稳地撑住你上层的业务。