1、环境及版本
系统版本: Centos 7.9.2009
Redis: 5.0.14
2、源码安装
tar -zxvf redis-5.0.14.tar.gz
cd redis-5.0.14
make
# 指定 安装目录 PREFIX
make PREFIX=/usr/local/redis install
3、复制、修改 [ redis.conf ] 配置
# 创建 redis 下的配置目录
mkdir -p /usr/local/redis/conf
mkdir -p /usr/local/redis/data
mkdir -p /usr/local/redis/logs
# 创建完成后,目录结构
[root@centos7 redis]# tree /usr/local/redis/
/usr/local/redis/
├── bin
│ ├── redis-benchmark
│ ├── redis-check-aof
│ ├── redis-check-rdb
│ ├── redis-cli
│ ├── redis-sentinel -> redis-server
│ └── redis-server
├── conf # 配置文件存放目录
| └── redis.conf # 从 源码包 复制过来的默认配置文件
├── data # rdb 数据文件存放目录
├── logs # 日志文件存放目录
修改 [ redis.conf ] 配置
[root@centos7 redis]# vim conf/redis.conf
# bind IP配置
bind 0.0.0.0
# 守护进程方式运行
daemonize yes
# 日志文件路径(配置到上方创建的日志目录)
logfile "/usr/local/redis/log/redis_6379.log"
# 数据文件存放目录
dir "/usr/local/redis/data"
4、创建启动脚本方便操作
脚本支持效果如下:
在目录 [ /usr/local/redis/ ] 下创建脚本文件 [ redis.sh ] 内容:
#!/bin/sh
# Redis 启动脚本
#
# @author: hal@xhal.net 2022-11-16
# 脚本当前目录
SH_DIR=$(cd $( dirname ${BASH_SOURCE[0] } ) && pwd)
APP_NAME="redis-server"
# 根路径
#APP_PATH=/usr/local/redis
APP_PATH=$SH_DIR
BIN_PATH=$APP_PATH/bin
# 配置文件路径
CONF_PATH=$APP_PATH/conf
CONF_FILE_PATH=$CONF_PATH/redis.conf
MASTER_CONF_FILE_PATH=$CONF_PATH/master.conf
SLAVE_CONF_FILE_PATH=$CONF_PATH/slave.conf
# 运行端口 - 默认 6379
APP_PORT=6379
# Redis 密码 - 默认为空
APP_PASS=""
## 从配置文件,读取端口、密码
CONFIG_STR=$(cat $CONF_FILE_PATH | grep -E '^port|^requirepass')
#echo "CONFIG_STR: $CONFIG_STR"
PORT_STR=$(echo -e $CONFIG_STR | sed 's/port \([0-9]*\).*/\1/g' )
PASS_STR=$(echo -e $CONFIG_STR | sed 's/.*requirepass \(.*\)/\1/g' | sed 's/"//g')
#echo "PORT_STR: $PORT_STR"
#echo "PASS_STR: $PASS_STR"
if [ -n "$PORT_STR" ]; then
APP_PORT=$PORT_STR;
fi
if [ -n "$PASS_STR" ]; then
APP_PASS=$PASS_STR;
fi
# 处理密码连接字符串
PASS_KEY=""
if [ -n "$APP_PASS" ]; then
PASS_KEY="-a $APP_PASS"
fi
echo -e "\e[35m======================================================================\e[0m"
#使用说明 用来提示参数
usage(){
echo -e "\e[33mAPP_PATH:\e[0m \e[36m $APP_PATH \e[0m"
echo -e "\e[33mUsage:\e[0m \e[36m $0 [start|stop|restart] \e[0m"
echo -e "\e[33mUsage:\e[0m \e[36m $0 [status|running|role|slaveup] \e[0m"
echo -e "\e[33mUsage:\e[0m \e[36m $0 [tomaster|toslave|startmaster|startslave|startauto] \e[0m"
echo -e "\e[35m----------------------------------------------------------------------\e[0m"
echo -e " -\e[32m start \e[0m: 正常启动 Redis,$BIN_PATH/redis-server $CONF_FILE_PATH"
echo -e " -\e[32m stop \e[0m: 停止 Redis, $BIN_PATH/redis-cli shutdown"
echo -e " -\e[32m restart \e[0m: 重启 Redis, stop && start"
echo -e "\e[35m----------------------------------------------------------------------\e[0m"
echo -e " -\e[32m status \e[0m: 当前运行状态、对应角色类型"
echo -e " -\e[32m running \e[0m: 当前运行状态,运行中返回 0,否则返回 1"
echo -e " -\e[32m role \e[0m: 当前运行对应角色类型,master 返回 0, slave 返回 1, 其它 返回2, redis 未运行 返回9"
echo -e " -\e[32m slaveup \e[0m: 当前运行状态为slave时,master_link_status是否为up (是则返回0,否则为1)"
echo -e "\e[35m----------------------------------------------------------------------\e[0m"
echo -e " -\e[32m tomaster \e[0m: 运行状态转换角色类型为【master】"
echo -e " -\e[32m toslave \e[0m: 运行状态转换角色类型为【slave】"
echo -e " -\e[32m startmaster\e[0m: 未运行时,以【master】角色类型运行"
echo -e " -\e[32m startslave \e[0m: 未运行时,以【slave】角色类型运行"
echo -e " -\e[32m startauto \e[0m: 未运行时,根据slave.conf的master节点状态,自动判断当前节点以【master/slave】角色类型运行"
echo ""
exit 1
}
#检查程序是否已运行
is_running(){
# 根据应用名称,获取进程pid (当存在多个时不适用)
#pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
# 根据端口号获取对应 pid
#pid=$(lsof -t -i:$APP_PORT)
pid=$(lsof -i:$APP_PORT | grep *: | awk '{print $2}')
#如果不存在返回1 存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
# 启动方法
start(){
is_running
if [ $? -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] is already running . pid=${pid}"
else
$BIN_PATH/redis-server $CONF_FILE_PATH
sleep 1
status
if [ $? -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] start success . pid=${pid}"
else
echo "$APP_NAME - [PORT: $APP_PORT] start fail ."
fi
fi
}
# 用 master.conf 的配置文件替换 redis.conf 后启动
startmaster(){
echo "准备以【 master 】模式启动,复制替换 redis.conf 文件..."
cp -f $MASTER_CONF_FILE_PATH $CONF_FILE_PATH
sleep 1
start
}
# 用 slave.conf 的配置文件替换 redis.conf 后启动
startslave(){
echo "准备以【 slave 】模式启动,复制替换 redis.conf 文件..."
cp -f $SLAVE_CONF_FILE_PATH $CONF_FILE_PATH
sleep 1
start
}
# 自动判断当前启用 master 还是 slave 模式
startauto(){
is_running
if [ $? -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] is already running . pid=${pid}"
exit 1
fi
# 读取 slave.conf 配置,获取对应 master 配置
arr=(`cat $SLAVE_CONF_FILE_PATH | grep ^replicaof`)
master_host=${arr[1]}
master_port=${arr[2]}
authcmd=$(cat $SLAVE_CONF_FILE_PATH | grep ^masterauth | sed 's/masterauth //g' | sed 's/"//g')
auth_key=""
if [ -n "$authcmd" ]; then
auth_key="-a $authcmd"
fi
echo "设置 master -h $master_host -p $master_port $auth_key "
# 判断 master 配置中的服务,对应角色类型
roleName=$($BIN_PATH/redis-cli -h $master_host -p $master_port $auth_key info | grep role: | sed 's/.$//g')
echo "slave 配置的 master 当前类型: $roleName"
if [ "$roleName" = "role:master" ]; then
startslave
else
startmaster
fi
}
# 停止方法
stop(){
is_running
if [ $? -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] is running . pid=${pid} ; stoping..."
# 执行 shutdown
$BIN_PATH/redis-cli $PASS_KEY shutdown
sleep 1
is_running
if [ $? -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] stop fail . pid=${pid}"
else
echo "$APP_NAME - [PORT: $APP_PORT] stop success ."
fi
else
echo "$APP_NAME - [PORT: $APP_PORT] is not running ."
fi
}
#重启
restart(){
stop
start
}
# 判断运行的角色[ master, slave ]
# master 返回 0, slave 返回 1, 其它 返回2, redis 未运行 返回9
role(){
is_running
if [ $? -eq "0" ]; then
roleName=$($BIN_PATH/redis-cli $PASS_KEY info | grep role: | sed 's/.$//g')
if [ "$roleName" = "role:master" ]; then
return 0
elif [ "$roleName" = "role:slave" ]; then
return 1
else
#echo "ERROR: unknow role: [$roleName] !!!"
return 2
fi
else
#echo "$APP_NAME - [PORT: $APP_PORT] is not running ."
return 9
fi
}
# 判断当前运行的 是否为 slave 且 正常连接上 master
# 为简化逻辑,此处实现仅 在 info 信息中匹配 master_link_status:up (运行正常返回0,否则为1)
# 即正常调用前,应该要知道此节点正常运行 且 为 slave
slaveup(){
linkStatus=$($BIN_PATH/redis-cli $PASS_KEY info | grep master_link_status:up)
if [ -z "$linkStatus" ]; then
#echo "redis master link is down"
return 1
else
#echo "redis master link is up"
return 0
fi
}
# Change Redis to master; Use Command: replicaof no one
tomaster(){
role
mode=$?
if [ $mode -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] 已经是[ master ] 不必要切换 ."
elif [ $mode -eq "1" ]; then
# 切换配置文件 - 避免下次重启后变化
cp -f $MASTER_CONF_FILE_PATH $CONF_FILE_PATH
# 执行切换为 主服务
$BIN_PATH/redis-cli $PASS_KEY replicaof no one
sleep 1
status
else
echo "$APP_NAME - [PORT: $APP_PORT] 不支持操作状态 [$mode]."
fi
}
# Change Redis to slave; Use Command: replicaof masterip masterport
toslave(){
role
mode=$?
if [ $mode -eq "1" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] 已经是[ slave ] 不必要切换 ."
elif [ $mode -eq "0" ]; then
# 切换配置文件 - 避免下次重启后变化
cp -f $SLAVE_CONF_FILE_PATH $CONF_FILE_PATH
authcmd=$(cat $CONF_FILE_PATH | grep ^masterauth | sed 's/"//g')
echo "设置 master 连接密码. $authcmd"
# 执行更新密码
$BIN_PATH/redis-cli $PASS_KEY config set $authcmd
repcmd=$(cat $CONF_FILE_PATH | grep ^replicaof)
echo "准备切换为[ slave ], $repcmd"
# 执行切换为 从服务
$BIN_PATH/redis-cli $PASS_KEY $repcmd
sleep 1
status
else
echo "$APP_NAME - [PORT: $APP_PORT] 不支持操作状态 [$mode]."
fi
}
# 判断状态
status(){
is_running
if [ $? -eq "0" ]; then
echo "$APP_NAME - [PORT: $APP_PORT] is running . pid=${pid}"
role
if [ $? -eq "0" ]; then
echo "Redis is master role"
elif [ $? -eq "1" ]; then
echo "Redis is slave role"
else
echo "Redis is unknow role"
fi
else
echo "$APP_NAME - [PORT: $APP_PORT] is not running ."
fi
}
# 根据输入的参数执行对应的方法
case "$1" in
"start")
start
;;
"stop")
stop
;;
"running")
is_running
;;
"status")
status
;;
"role")
role
;;
"restart")
restart
;;
"tomaster")
tomaster
;;
"toslave")
toslave
;;
"startmaster")
startmaster
;;
"startslave")
startslave
;;
"startauto")
startauto
;;
"slaveup")
slaveup
;;
*)
usage
;;
esac
5、配置开机启动服务
在系统服务目录` /usr/lib/systemd/system/`下,创建 ` redis.service ` 文件
内容如下:
[Unit]
# 服务描述
Description=Redis-Server
# 在 XX 服务后启动
After=network.target
# 服务运行参数; 注意本节点内命令要用绝对路径
[Service]
# 后台运行方式
Type=forking
# 启动命令
ExecStart=/usr/local/redis/redis.sh start
# 是否给服务分配独立的临时空间
PrivateTmp=true
# 运行级别下服务安装的相关设置, 可设置为多用户,即系统运行级别为3
[Install]
WantedBy=multi-user.target
systemctl daemon-reload # 重载 systemd
systemctl enable redis.service # 设置开机启动
systemctl disable redis.service # 停止开机启动
systemctl start redis.service # 启动服务
systemctl stop redis.service # 停止服务
systemctl status redis.service # 查看服务状态
systemctl restart redis.service # 重启服务
systemctl list-units --type=service # 查看所有已启动的服务