简介:面向Linux运维与开发人员的Redis部署指南,围绕源码包下载、编译安装、启动停止与服务化展开,解决每次手动进入安装目录执行./redis-server的繁琐问题;下载环节还提示了官方源可能访问受限时可改用国内镜像等渠道。文档以redis-3.0.2为例,详细演示了将redis_init_script复制为/etc/init.d/redis、添加chkconfig配置、设置CONF路径与PID文件名,再通过service命令统一启动和停止服务的过程。资源为1个PDF文件,大小仅261KB,以图文步骤承载全部操作,适合需要部署Redis服务器或将其集成进系统服务的读者,已有13618人学习下载,实用性较强。除服务化外,文档还补充了Java客户端连接不上时的典型排查思路,例如注释bind 127.0.0.1限制、识别并处理protected mode提示,以及通过requirepass设置密码后完成远程访问。读者可据此完成从源码到系统服务的完整搭建,并建立对常见连接问题的排错思路。
1. 把 Redis 装成系统服务:绕过每次手动进目录的折腾
在 Linux 下做 redis 安装、启动与停止,很多人装完就扔在源码目录里,每次要用都得先 cd 到解压目录,再 ./redis-server 起一个前台进程,SSH 一断开服务就跟着没了。这种用法做开发机调试勉强够用,放到服务器上就是给自己埋坑。这篇文章我按自己实际拆过的流程,把 redis 从源码包下载、编译、启动、停止,一直到注册成系统服务的完整链路走一遍,连 PID 文件对不上、远程连不上这种翻车点也一并列出来。适合刚接触 redis 的运维新手,也适合不想再看零零散散教程、想一次把服务化搞定的从业者。
2. 下载与编译 Redis 3.0.2:源码获取、make 与第一轮启动测试
2.1 源码包获取:外网直连不稳定,建议手动上传
我最早看到网上教程都是直接给一条wget命令,从外网源码仓库拉 Redis 压缩包。实际在服务器上敲的时候,经常出现连接超时或者下载到一半断掉的情况,尤其是某些国外源码托管平台的地址在国内网络环境下非常不稳定。所以这里我的建议是:不要在生产服务器上依赖这条直链下载,而是先在本地或者内网环境把包下载好,再通过 scp、rz 或者内部文件服务器传到 Linux 机器上。
# 如果网络条件确实好,可以尝试直连下载,但要做好失败的准备 wget http://download.redis.io/releases/redis-3.0.2.tar.gz # 更稳妥的做法:本地下载后上传到服务器指定目录 scp redis-3.0.2.tar.gz user@192.168.0.104:/usr/local/src/参数说明:wget后面跟的是 Redis 官方 release 包的下载地址;传到/usr/local/src是一个约定俗成的习惯,源码包统一放在 src 目录,编译产物不会污染系统目录。我在上传后会顺手用ls -lh看一眼文件大小,源包大概在 1.5MB 上下,如果只有几十 KB,基本是下载页面而不是包,解压必失败。
2.2 解压、编译并检查产物
上传完成后,进入存放目录,解压。这里注意文件名有可能带-也有可能是_,比如redis-3.0.2.tar.gz和redis_3.0.2.tar.gz都见过,解压命令不受影响,但解压出来的目录名要看清,后续所有 cd 都依赖这个目录名。
cd /usr/local/src tar -zxvf redis-3.0.2.tar.gz cd redis-3.0.2 make这里简单解释一下:tar -zxvf中z表示 gzip 解压,x表示解开,v会打印解压过程,f指定文件名。make会读取源码根目录下的 Makefile,依次编译依赖的各个模块,Redis 3.0.2 整体编译时间在配置一般的机器上大约 8 到 15 分钟。编译过程中如果提示缺少 gcc 或者 make 未安装,先用yum install -y gcc make补上再重新执行。
有一个编译玄学问题值得单独提醒:部分 GCC 版本下 make 会报jemalloc/jemalloc.h: No such file or directory。这不是源码缺失,而是 Redis 的分配器检测逻辑在特定环境下选了 jemalloc,但系统没装对应头文件。常见的解决办法是指定使用 libc 分配器重新编译:
make MALLOC=libc参数说明:MALLOC=libc让 Redis 放弃 jemalloc 改用 glibc 的内存分配器。功能上完全够用,后续集群、持久化都不受影响,只是性能上略有差异,开发环境一般感知不到。编译完成后再确认一下产物:
ls -lh src/redis-server src/redis-cli看到redis-server和redis-cli两个可执行文件存在,这一步才算真正结束。redis-server是服务端启动入口,redis-cli是命令行客户端,后面启动和停止都会用到这两个文件。
2.3 第一次启动:redis-server 前台运行与 redis-cli 验证
编译成功后先不要急着做服务化,先在源码目录里跑一次原生的启动流程,确认 Redis 本身没有问题,再做服务封装。这一步可以理解为把变量控制住:先验证「软件本身没坏」,再验证「服务配置没坏」。
# 前台启动,默认端口 6379 ./src/redis-server启动后终端会输出一个 ASCII 的 Redis logo,下面会列出Running in standalone mode、Port: 6379、PID: xxx等信息。这时候 Redis 进程是前台运行的,终端会被占住,Ctrl+C 即可停止。注意观察日志里的WARNING: The TCP backlog setting of 511 cannot be enforced这类提示,属于内核参数调优问题,不影响本次安装。
另开一个终端窗口,进入同一个目录,用客户端验证读写是否正常:
./src/redis-cli -p 6379 127.0.0.1:6379> ping PONG 127.0.0.1:6379> set foo bar OK 127.0.0.1:6379> get foo "bar"redis-cli -p 6379中的-p指定连接端口,Redis 默认监听 6379。ping返回PONG说明服务端存活,set/get一组命令验证最基本的键值读写链路。到这里,Redis 本体的安装和基础启动/停止已经验证完毕,接下来考虑怎么做成服务。
3. 把 Redis 注册成服务:init.d 脚本、chkconfig 与后台运行符
3.1 复制初始化脚本并改名
Redis 源码包中自带了一个utils/redis_init_script,这是官方为 SysV init 体系准备的启动脚本模板。把它复制到/etc/rc.d/init.d/目录下,并改名为redis,这样service redis start/stop就能直接找到它。
cp /usr/local/src/redis-3.0.2/utils/redis_init_script /etc/rc.d/init.d/redis chmod +x /etc/rc.d/init.d/redis这里有个细节:很多教程写的是复制到/etc/init.d/redis,而/etc/init.d通常是/etc/rc.d/init.d的软链接,两者指向同一位置。我习惯直接写全路径,避免在部分精简系统上遇到链接缺失的问题。chmod +x给脚本加执行权限,否则后续service redis start会提示权限拒绝。
3.2 脚本里必须改的三处:chkconfig 注释、CONF 路径、& 符号
复制过来之后还不能直接用,先打开脚本看一下内容:
vi /etc/rc.d/init.d/redis脚本核心逻辑并不复杂,关键就这几行:
#!/bin/sh # chkconfig: 2345 80 90 # 第二行添加,chkconfig 依赖此行进行服务管理 REDISPORT=6379 EXEC=/usr/local/redis/bin/redis-server # 可执行文件路径 CLIEXEC=/usr/local/redis/bin/redis-cli PIDFILE=/var/run/redis_${REDISPORT}.pid # PID 文件路径 CONF="/etc/redis/${REDISPORT}.conf" # 配置文件路径 case "$1" in start) if [ -f $PIDFILE ]; then echo "$PIDFILE exists, process is already running or crashed" else echo "Starting Redis server..." $EXEC $CONF & # 结尾的 & 不能去掉 fi ;; stop) if [ ! -f $PIDFILE ]; then echo "$PIDFILE does not exist, process is neither running nor crashed" else PID=$(cat $PIDFILE) echo "Stopping ..." $CLIEXEC -p $REDISPORT shutdown # 通过客户端命令优雅停止 while [ -x /proc/${PID} ]; do echo "Waiting for Redis to shutdown ..." sleep 1 done echo "Redis stopped" fi ;; esac必须动手改三个地方。第一,在#!/bin/sh下面加上# chkconfig: 2345 80 90这一行,它告诉 chkconfig 工具在运行级别 2/3/4/5 下接管这个服务,启动优先级 80,停止优先级 90。没有这行,chkconfig --add redis会直接报错说服务不支持 chkconfig。
第二,确认EXEC和CLIEXEC指向的目录里真的有 redis-server 和 redis-cli 文件。如果按前面步骤只在源码目录编译过,/usr/local/redis/bin/是不存在的,需要手动创建并把两个可执行文件复制过去:
mkdir -p /usr/local/redis/bin cp /usr/local/src/redis-3.0.2/src/redis-server /usr/local/redis/bin/ cp /usr/local/src/redis-3.0.2/src/redis-cli /usr/local/redis/bin/第三,留意$EXEC $CONF &这行结尾的&。加了它,Redis 进程在后台运行,脚本立即返回;去掉它,服务会一直占着当前终端,service redis start之后脚本无法结束,看起来就像卡住了一样。这一点很多教程会漏掉,属于「看起来是小问题、实际上必踩」的典型。
3.3 配置路径规划:/etc/redis/6379.conf
脚本里CONF="/etc/redis/${REDISPORT}.conf",展开后就是/etc/redis/6379.conf。Redis 启动时加载这个配置文件,所以我们要把源码目录里的redis.conf复制过去,文件名严格对应端口号。
mkdir /etc/redis cp /usr/local/src/redis-3.0.2/redis.conf /etc/redis/6379.conf复制过去之后,建议顺手检查两个配置项:daemonize和pidfile。脚本本身用&把进程放到后台,所以daemonize保持no即可,不会冲突。pidfile默认值在 3.0.2 版本里是/var/run/redis.pid,这跟第 4 章的 PID 文件坑直接相关,先在这里留个印象。
3.4 注册服务与启动验证
前面所有准备工作做完,接下来就是注册和启动。注册用 chkconfig,启动用 service,实际上背后调用的就是/etc/init.d/redis这个脚本。
chkconfig --add redis service redis start启动后立刻验证进程是否在跑:
ps -ef | grep redis-server正常会看到一个 redis-server 进程,启动参数里带上了/etc/redis/6379.conf。此时再用redis-cli ping测一下,能返回 PONG 就说明服务化后的 redis 已经完全可用。注意这次不需要再 cd 到源码目录,因为 redis-cli 已经在/usr/local/redis/bin/下面了,任何目录都能执行。
如果想确认开机自启是否生效,可以查看各运行级别下的服务状态:
chkconfig --list redis输出里 2、3、4、5 四个级别都是 on,说明 Redis 已经纳入系统服务管理,重启服务器后会自动拉起。
4. 服务化避坑与排查:PID 文件对不上、可执行文件缺失和远程连接失败
4.1 现象:service redis stop 报 pid 文件不存在
第一次执行service redis stop的时候,系统提示:
/var/run/redis_6379.pid does not exist, process is not running但ps -ef | grep redis-server看进程明明还在。
原因:脚本里PIDFILE=/var/run/redis_${REDISPORT}.pid,展开为/var/run/redis_6379.pid。而 Redis 3.0.2 默认配置里的pidfile /var/run/redis.pid写的是另一个文件名。进程启动时把 PID 写进了/var/run/redis.pid,脚本去读/var/run/redis_6379.pid,自然读不到,也就判断「进程不在运行」。
解决:进入/var/run目录确认实际存在的 pid 文件名,然后修改/etc/rc.d/init.d/redis中的PIDFILE变量,把redis_${REDISPORT}.pid改成redis.pid。改完重启 Redis,再执行service redis stop,就能正常走完「读取 PID → redis-cli shutdown → 等待进程退出」的流程。这个坑其实是配置文件和脚本各自维护一套 pid 文件路径导致的,核心思路只有一个:两边保持一致。
4.2 现象:服务启动时找不到 redis-server
在做完 3.2 的修改后执行service redis start,报错提示cannot execute binary file或者直接说找不到/usr/local/redis/bin/redis-server。
原因:源码编译出来的 redis-server 在src/目录下,而脚本写死的是/usr/local/redis/bin/redis-server。如果只编译没有make install,也没有手动复制,这个路径就是空的。初始化脚本不会帮你检查可执行文件是否存在,只会傻乎乎地执行。
解决:按 3.2 里说的,手动创建/usr/local/redis/bin目录,把redis-server和redis-cli复制过去。另一种做法是执行make install,它会自动安装到/usr/local/bin,但那样要同步修改脚本里的EXEC路径,反而多一步。我倾向于手动复制到指定目录,跟脚本的默认路径对齐。
4.3 现象:telnet 端口不通,其他服务却正常
如果 JAVA 客户端要连接这台 Redis 服务器,先做一个连通性测试:
telnet 192.168.0.104 6379结果发现连接超时或者直接被拒,但同一个服务器上其他端口如 22、3306 都能连通。
原因:问题不在系统防火墙,而是 Redis 自身的redis.conf里配置了bind 127.0.0.1。这个配置的意思是 Redis 只监听本机回环地址,外部 IP 的请求在 TCP 层面就被拒绝了。
解决:编辑/etc/redis/6379.conf,找到bind 127.0.0.1这一行,直接注释掉,或者改成服务器实际内网 IPbind 192.168.0.104。注释掉之后 Redis 会监听所有网卡接口,适合内网环境;如果服务器直接暴露在公网,建议还是指定具体 IP,不要裸奔。改完配置需要重启服务:service redis restart。
4.4 现象:远程连接提示 protected mode
处理好 bind 问题之后,Java 客户端再次连接,又抛了一个新错误:
DENIED Redis is running in protected mode because protected mode is enabled原因:Redis 3.2 版本之后引入了 protected mode 机制,默认开启。当 Redis 没有设置密码、也没有配置 bind 到具体非回环地址时,它会拒绝非本机 IP 的客户端连接,这个机制是为了防止没设密码的 Redis 被外界随意扫描利用。
解决:给 Redis 设置密码是最推荐的路径。在 redis-cli 里执行:
./src/redis-cli -p 6379 127.0.0.1:6379> config set requirepass 123456 OKconfig set requirepass是在运行期直接修改配置,立即生效,不需要重启。密码设置后,客户端连接命令要带上密码:
redis-cli -p 6379 -a 123456Java 客户端则要在连接配置里设置 password 属性,对应传入 123456。到这里,bind 和 protected mode 两个问题都绕过,远程连接也就通了。
5. 设置密码后的启停联动:requirepass 与 service stop 的冲突处理
很多人在第 4 章设置完密码后就以为大功告成了,实际上这里还埋着一个隐性坑:一旦设置了 requirepass,service redis stop反而会失效。
原因在初始化脚本的 stop 逻辑里写得很明确:
$CLIEXEC -p $REDISPORT shutdown这个命令是通过 redis-cli 发送 shutdown 指令来完成优雅停机的,但 redis-cli 在 Redis 开启 requirepass 之后,未携带密码的 shutdown 请求会被服务端直接拒绝。表现出来就是执行service redis stop,命令行输出却依然提示进程在运行,去看/var/run/redis.pid,PID 还在。
这时候有两个方向可以走。方向一是修改初始化脚本,在 shutdown 命令里附带密码:
$CLIEXEC -p $REDISPORT -a 123456 shutdown注意密码和-a参数之间不能有空格,-a表示 auth 密码。改完之后,service redis stop就能正常把 Redis 停掉。方向二是我更推荐的,把密码固化到配置文件里而不是只在运行期设置,因为config set requirepass只对当前进程生效,重启 Redis 后密码会丢失,到时候又是一次「明明设了密码怎么连不上」的窘境。在/etc/redis/6379.conf中搜索requirepass,把前面的#去掉并改写成自己的密码:
requirepass 123456从此之后,Redis 的启动、远程连接、停止整个链路都带上了统一的认证信息。
验证整个链路是否正常,我的习惯是一口气走三遍命令:先service redis start,再redis-cli -p 6379 -a 123456 ping,最后service redis stop,三句全部通过才算服务化真正完成。从那以后我每次在生产环境装 Redis,都会强制走一遍这个流程,确认密码已经写进配置文件、客户端连接带上了-a、服务停止不受 requirepass 影响,三个点缺一不可。踩过 PID 文件那个坑之后,我还养成了改完初始化脚本先cat /etc/rc.d/init.d/redis检查一遍路径变量的习惯,这种细节往往比主流程更决定成败。希望这篇 linux 下 redis 安装、启动与停止的实战记录能帮到你。
本文还有配套的精品资源,点击获取