去年年底帮朋友排查一个线上Redis频繁抖动的问题,最后发现根因居然是当初图省事用包管理器装的Redis 6.0,版本旧、内存分配策略也不对,折腾了一整晚。从那以后我自己装Redis,都坚持一个原则:要么源码编译装官方稳定版,要么用Docker镜像固定版本,绝不给线上留下版本黑洞。这次就把一套完整的Linux系统安装Redis 7的流程写出来,从环境检查到编译、配置、systemd托管、客户端连接,一步不落。文章面向两类人:第一次在Linux上装Redis的新手,以及装过Redis但总在细节上翻车的运维同学。跟着走一遍,至少能少踩一半坑。
1. 装Redis 7之前,先把环境和方案想清楚
1.1 确认你的Linux发行版和系统架构
很多人拿到服务器就直接开装,结果第一步就栽了。不同发行版的包管理器、目录结构、默认防火墙策略都不一样。拿Redis来说,CentOS/RHEL系默认用yum/dnf,Ubuntu/Debian系用apt,openEuler、统信这类国产发行版又是另一套体系。装之前先看系统底细:
cat /etc/os-release uname -m/etc/os-release能告诉你发行版名称和版本号,uname -m看架构。绝大多数服务器是x86_64,但也有不少ARM架构的机器(比如鲲鹏、飞腾),这时候编译参数和依赖包会略有差别。另外nproc看一下CPU核数,free -h看一下内存,后面编译和运行都要心里有数。
1.2 Redis 7对编译器和系统资源的要求
Redis虽然是一个轻量级内存数据库,但源码编译对编译器有硬性要求。Redis 7.x引入了不少现代C语言特性,编译器太老会直接编译失败。最典型的例子是CentOS 7自带的gcc 4.8.5,拿它去编译Redis 6以上版本,大概率报一堆错。所以环境准备阶段要先解决编译器问题:
# Ubuntu / Debian apt update && apt install -y build-essential # CentOS / RHEL / Rocky / openEuler yum install -y gcc make如果CentOS 7的gcc版本太低,建议用devtoolset-9或者干脆升级到CentOS 7的软件集:
yum install -y centos-release-scl yum install -y devtoolset-9 scl enable devtoolset-9 bash这个“先开编译器,再编译”的顺序,是我踩过几次坑后才养成的习惯。后面5.1节会专门讲报错长什么样。
内存方面,编译Redis时make不暴躁,但建议至少保留1GB空闲内存,磁盘留出2GB以上空间。后面运行时,Redis占多大内存取决于你的maxmemory配置,这个后面细说。
1.3 到底选编译安装、yum/apt安装还是Docker安装
我见过不少教程只推编译安装,这不客观。给你一份对比,方便按场景选:
| 安装方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 源码编译 | 版本最可控、可定制编译参数、能装任意版本 | 步骤多、编译耗时长、对编译器版本有要求 | 生产环境、对版本有强制要求的场景 |
| yum/apt安装 | 快、依赖自动解决 | 版本往往偏旧、定制能力差、升级麻烦 | 本地测试、快速搭建 |
| Docker安装 | 环境隔离、部署快、版本固定、主从集群方便 | 对宿主内核特性有依赖、网络和持久化要额外配置 | 微服务环境、容器化平台 |
这次文章重点用源码编译,因为标题就叫“详细版”,源码编译能把底层原理讲透,而且装完Redis长什么样、文件在哪、进程怎么管,你全都一目了然。但Docker方式我也会在第6节专门提,因为现在很多新项目直接用容器了。
2. 下载源码、编译、安装,一步步来
2.1 从官网拿Redis,别下载到不三不四的“野包”
Redis官方下载地址是https://download.redis.io/releases/,页面里能看到所有历史版本。截至当前稳定版本号已经到7.2.x,你可以选自己需要的7.x小版本。建议不要用浏览器去“百度一下下载”,那种第三方站点上给的包,轻则版本和描述不符,重则被人动过手脚。生产环境对来源一定要较真。
命令行下载最稳:
cd /usr/local/src wget https://download.redis.io/releases/redis-7.2.4.tar.gz下载完先校验一下SHA-256,官网每个版本旁边都有checksum。别看这一步繁琐,真遇到二进制被篡改的情况,校验就是最后一道防线。
sha256sum redis-7.2.4.tar.gz对比官方给出的哈希值,一致再继续。
2.2 解压编译,三步走完基本流程
解压、编译、安装是传统老三样:
tar -zxvf redis-7.2.4.tar.gz cd redis-7.2.4 make -j$(nproc)第一条命令解压,第二条进目录,第三条make -j$(nproc)用所有CPU核并行编译,速度会快很多。中间如果报错,绝大部分情况是编译器版本问题或者缺依赖,回到1.2节解决。
编译完成之后,官方强烈建议先跑一遍测试再安装:
make test这个测试会跑个几百项用例,耗时几分钟。它的意义在于提前发现你的系统环境和Redis源码之间可能存在的兼容性问题。测试通过后再执行安装:
make install PREFIX=/usr/local/redisPREFIX指定安装根目录,最后Redis的可执行文件会落在/usr/local/redis/bin下面,包括redis-server、redis-cli、redis-benchmark、redis-check-aof等。不写PREFIX的话,默认装到/usr/local/bin,也能用,但目录会很散,我习惯指定一个独立目录,后面做软链或者做systemd配置都清晰。
2.3 顺便说下为什么不直接make install就完事
很多人编译完直接make install,也不指定PREFIX,最后二进制散落在系统PATH里。这本身不算错,但对运维来说,后面升级、卸载、做多实例部署都很痛苦。你想,如果机器上同时跑Redis 6和Redis 7,两个版本的可执行文件都叫redis-server,都在/usr/local/bin里,你怎么分清楚哪个是哪个?
所以我的习惯是:一个版本对应一个独立目录,例如/usr/local/redis-7.2.4,再把当前要用的版本做个软链:
ln -s /usr/local/redis-7.2.4 /usr/local/redis这样以后切版本只换软链,配置文件、服务脚本不用乱动。这个习惯帮我少头疼很多次。
3. Redis 7的配置、目录规划和systemd托管
3.1 给Redis建一个独立用户,别拿root裸奔
装完二进制后,下一步不是急着启动,而是搞目录规划和账号隔离。运维的常识是:一个服务一个用户,权限最小化。Redis被攻击利用后,如果以root身份运行,攻击者直接拿到最高权限;如果是个普通用户,至少还能拦一道。
我一般在生产环境这样建:
useradd -s /sbin/nologin redis mkdir -p /usr/local/redis/conf mkdir -p /data/redis mkdir -p /var/log/redis chown -R redis:redis /data/redis /var/log/redis/usr/local/redis/conf放配置文件,/data/redis放持久化数据,/var/log/redis放日志。这套“配置、数据、日志分目录”的习惯,来自多年被日志塞满磁盘的惨痛教训。
3.2 手把手改核心配置项
Redis的配置模板在源码目录里,叫redis.conf。直接拷贝到上面建的配置目录:
cp /usr/local/src/redis-7.2.4/redis.conf /usr/local/redis/conf/redis.conf然后编辑它。这里我只强调几个必须改的项,其余的先用默认值,跑通了再慢慢调。
bind 127.0.0.1 内网IP port 6379 protected-mode yes daemonize no supervised systemd pidfile /var/run/redis_6379.pid loglevel notice logfile /var/log/redis/redis.log dir /data/redis appendonly yes requirepass 你的高强度密码一项一项说:
bind:指定监听地址。如果只本机用就写127.0.0.1,如果允许内网其他机器访问就把内网IP加上去。千万不要直接填0.0.0.0再配合弱密码,不然全世界都在扫你的6379端口。protected-mode yes:这个保护模式在“没有密码 + 只绑定回环地址”的时候才安全。一旦你绑定了非本机IP但没设置密码,Redis会直接拒绝外部访问。所以密码和绑定地址要一起配好。daemonize no:这里是个大坑。如果你后面打算用systemd管理Redis进程,这里必须设成no,让Redis以前台进程方式运行,由systemd负责守护。如果你设daemonize yes,systemd反而会认为服务没起来或者管理混乱。supervised systemd:配合systemd使用的关键配置,它告诉Redis“我在systemd环境里”,这样Redis会使用systemd的通知机制上报“我已经就绪”。这一步不配,systemctl start redis之后看起来启动了,但其实systemd并不知道服务状态到底好不好。dir:持久化RDB/AOF文件存放目录,必须是Redis可写权限。appendonly yes:开启AOF持久化。Redis默认是开RDB的,但生产环境我强烈建议同时开启AOF,降低数据丢失窗口。AOF刷盘策略默认everysec,意思是每秒刷一次磁盘,性能和数据安全平衡得不锠。requirepass:设置认证密码。注意密码别写在命令行里,避免被ps看到。配置文件本身也要设置好权限,只让redis用户和管理员能读。
3.3 配置systemd,让它开机自启且自动拉起
配置文件改好后,写一个systemd服务单元。在/etc/systemd/system/redis.service里:
[Unit] Description=Redis 7.2.4 Server After=network.target [Service] Type=notify User=redis Group=redis ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf ExecReload=/bin/kill -s HUP $MAINPID TimeoutStopSec=0 LimitNOFILE=10240 NoNewPrivileges=yes ProtectSystem=full ReadWritePaths=/data/redis /var/log/redis [Install] WantedBy=multi-user.target几个点解释一下:
Type=notify要和supervised systemd配对,这是Redis 7官方推荐的方式,能准确判断服务是否完成启动。User=redis和Group=redis指定进程身份,收尾在3.1步创建的目录权限。LimitNOFILE提高文件描述符上限,高并发场景下默认的1024肯定不够。ProtectSystem=full和ReadWritePaths是安全加固,限制服务只能写数据目录和日志目录。
写完后:
systemctl daemon-reload systemctl enable --now redis systemctl status redis看到active (running),说明服务已经托管成功。再重启一下机器试试是否开机自启,这一步千万别省,不然下次机房断电重启,Redis不会自己回来的。
4. 验证安装效果,并解决远程连接问题
4.1 本机先做一轮冒烟测试
服务起来后,先在本机验证最基础的功能:
/usr/local/redis/bin/redis-cli -a '你的密码' ping返回PONG说明Redis进程正常。接下来做个简单的读写测试:
redis-cli -a '你的密码' set hello world redis-cli -a '你的密码' get hello redis-cli -a '你的密码' -h 127.0.0.1 -p 6379 info serverinfo server能看Redis版本、进程ID、运行模式等信息。同时看一眼日志:
tail -f /var/log/redis/redis.log正常会看到类似Ready to accept connections tcp的日志行,说明服务真正对外可用了。
4.2 远程连接失败的三大元凶
本机玩得好好的,换个机器就连不上了,这是所有Redis新手都会撞上的问题。基本就三件事:
第一,Redis监听地址不对。确认redis.conf里bind是否包含了客户端能访问到的IP,别只写127.0.0.1。如果机器有多个网卡,要明确监听哪张网卡。改完配置后重启Redis:systemctl restart redis。
第二,防火墙拦住了。CentOS/RHEL系用firewalld:
firewall-cmd --zone=public --add-port=6379/tcp --permanent firewall-cmd --reloadUbuntu用ufw:
ufw allow 6379/tcp有些云服务器还要在控制台的安全组里额外放行6379端口,这两个层面都通过才能真正连进来。
第三,保护模式和密码冲突。如果Redis同时设置了bind 0.0.0.0但没设requirepass,protected-mode yes仍会拒绝远程访问。所以远程连接时,确保requirepass已经配置,并且客户端带着密码访问。
验证远程连接,可以在另一台机器上:
redis-cli -h 服务器IP -p 6379 -a '密码' ping4.3 可视化客户端和连接配置参考
命令行能连通了,剩下的事就是选一个趁手的客户端。Windows/Mac上最常用的是Redis Desktop Manager,后来不开源免费版了,更多人选用了Another Redis Desktop Manager。这两个工具连接配置都很直白:填主机、端口、密码,点Connect就完事。工具本身没有太多坑,真正会出问题的往往是服务器端的安全配置不正确。如果你连客户端都连不上,先回到4.2节,把bind、防火墙、密码这三样挨个排查一遍,多半当场解决。
4.4 用redis-benchmark快速压一把
安装完Redis,我习惯跑一遍基准测试,确认硬件性能没有异常:
/usr/local/redis/bin/redis-benchmark -h 127.0.0.1 -p 6379 -a '密码' -c 50 -n 100000 -t get,set-c 50模拟50个并发连接,-n 100000总共发10万个请求。结果里能看到每秒请求数(如req/sec)。这套数据可以作为后续调优的基线。如果这里出来的吞吐量差得离谱,多半是系统参数需要调,比如vm.overcommit_memory、transparent_hugepage,后面第5节会专门讲。
5. 高频报错和排查技巧,全是实战记录
5.1 编译阶段的经典报错
Redis编译阶段最经典的报错是:
cc: error: unrecognized command line option "-std=gnu11"这就是编译器太老的典型表现。gcc 4.8.5根本不认识gnu11。解决办法是升级编译器,CentOS 7装一个高版本的devtoolset:
yum install -y centos-release-scl yum install -y devtoolset-9 scl enable devtoolset-9 bash切完之后再重新make clean && make -j$(nproc)。Ubuntu的老系统可以考虑换用gcc-9:
apt install -y gcc-9 g++-9 CC=gcc-9 make -j$(nproc)还有一个容易忽略的编译报错是Memory allocation error,这种通常是编译时内存不够,gcc进程被杀掉了。解决方法是关掉部分并行任务,把-j$(nproc)改成-j2甚至-j1,或者临时加swap。
5.2 启动阶段的权限与日志坑
用systemd启动Redis,看着像起来了,一查状态却是failed,journalctl -u redis里报:
Can't open the log file: Permission denied这就是典型的目录权限问题。日志目录和数据目录的owner必须是redis用户,用chown -R redis:redis修复。还有一种情况是pidfile指定的路径redis用户没权限写。我建议把pidfile设到/run或者/var/run,并且确认目录可写。
启动阶段的另一个高频坑是:daemonize yes和systemd混用。你明明配置了supervised systemd,但忘了把daemonize改成no,结果服务起来后systemd立刻认为服务“退出”,然后反复重启。排查方式就是看systemctl status redis里是不是有频繁重启的日志,然后回到3.2节把daemonize no改好。
5.3 运行时内存和持久化相关的坑
Redis跑到半夜,突然大量请求超时。这种问题十有八九和系统的内存策略有关。Linux默认的vm.overcommit_memory可能是0或1,而Redis在启用RDB后台保存时,需要fork一个子进程,写时复制(COW)机制下,如果系统不允许内存过量分配,fork就会失败。典型日志是:
Can't save in background: fork: Cannot allocate memory解决办法是调整系统参数:
sysctl vm.overcommit_memory=1 echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf另一个影响Redis性能的系统参数是transparent_hugepage,这个开启后Redis fork子进程时页面复制开销变大,延迟会明显上升。建议关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local chmod +x /etc/rc.local5.4 一个排查问题的“笨方法”,其实最有效
很多同学一遇到Redis起不来就慌,到处问人。我分享一个万能排查方案:直接在前台启动Redis,不要用systemd,不要用daemonize。命令很简单:
sudo -u redis /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf因为在前台运行时,所有错误日志会直接刷到终端上。这个输出比任何systemd log都直观,是判断配置错误、目录权限问题最快的方法。等你在终端里把服务正常跑起来了,再退出,回到systemd托管,绝大多数启动问题就已经解决了。这个方法我用了快十年,简单粗暴但几乎从不失手。
6. 装完Redis 7之后,还能顺便做这几件事
6.1 把Redis 7的新特性用起来
Redis 7不是简单的版本数字变化,它引入的不少能力在生产里很有用。比如ACL(访问控制列表)让你能按用户精确授权,不再只有一个全局密码;Redis Functions提供了一种服务端脚本方案,比传统Lua脚本更适合做业务封装;Sharded Pub/Sub让集群模式下的消息通知更顺畅。
装好之后,我最先建议你用ACL替换裸的requirepass。创建一个只读账号:
redis-cli -a '管理员密码' ACL SETUSER readonlyuser on '>只读密码' ~* +@read这样分配出去的账号只能读数据,写不了也删不了,对业务方的权限控制比较友好。
6.2 顺手聊聊Docker安装Redis主从的思路
如果你们公司已经全面容器化,那10分钟用Docker装Redis的方式也得会。Docker安装最大的好处是版本干净、删除不留痕、多实例方便。简单演示单个节点:
docker run -d --name redis7 \ -p 6379:6379 \ -v /data/redis:/data \ -v /usr/local/redis/conf/redis.conf:/etc/redis/redis.conf \ redis:7.2.4 redis-server /etc/redis/redis.confDocker里做主从也很直接:在从节点的配置里指定replicaof 主节点IP 6379,或者启动时用--replicaof参数。不过容器里要注意网络模式,如果宿主机之间用端口映射,主从复制的地址要根据实际网络环境调整。
我个人的建议是:能用Docker的就别纠结源码编译;但如果是传统物理机/虚拟机环境、特别是要和系统监控深度集成的场景,源码编译+systemd依然是更稳的选择。
6.3 安装后立刻做一次“盘逻辑”:数据类型、缓存治理、面试相关
很多人在Redis装好之后,不知道下一步学什么。我建议从这几个方向展开:
一是搞清Redis的五种基本数据类型:String、Hash、List、Set、ZSet。每个类型适合存什么数据、常用命令是什么、底层结构大致怎样。这是基础,也是面试必问。
二是了解过期淘汰策略和缓存治理。比如maxmemory-policy可以设allkeys-lru、volatile-ttl等,生产环境要根据缓存命中率和业务容忍度来选择。我一般建议热点数据单独评估,而不是一个策略通吃。
三是分布式锁。Redis分布式锁是面试高频题,也是很多系统实际会用到的东西。Redis 7里可以基于SET key value NX EX来实现一把相对安全的锁,配合Lua脚本释放锁避免误删。这篇安装文的篇幅不允许我展开,但至少你可以先把环境跑起来,然后自己动手写一段加锁解锁的代码试试。
7. 最后分享一点我的个人经验
这篇文章写到这里,没有讲太多花哨的东西,全是这几年来我在真实环境里摸爬滚打的经验。如果只留一句话,那就是:安装Redis不是把redis-server跑起来就完了,配置、权限、systemd、防火墙、内存参数,这五样一样都不能少。
我个人建议,刚装完Redis的时候别急着丢到一边,花半小时把Redis的数据类型、ACL、持久化策略各试一遍。你的实验环境越“脏”,后来生产环境踩的坑就越少。另外,多熟悉一下redis-cli的--bigkeys、--stat这些实用参数,它们在你日后排查问题时能救你无数次。
最后一个小技巧:生产环境的Redis进程一定要加--rename-command禁用掉FLUSHALL和CONFIG这类危险命令,就算配置被人看到了,破坏面也会小很多。好了,这篇就写到这,动手装一台Redis 7试试吧。