Redis在生产环境中,很少使用单机模式,原因很明显:存在单点故障,无法保证高可用性。所以,在生产环境中可以选择主备模式或者集群模式,这里介绍一下主备模式的自动化部署脚本,后续文章会介绍集群模式的部署。
部署脚本 #!/bin/bash #-------------------------------------------------------------------------------------------# #---------------------------------------配置信息--------------------------------------------# #-------------------------------------------------------------------------------------------# #请准确配置以下信息 #redis所在(绝对)路径 redis_path="/usr/redis-3.2.1" #保存配置文件的目录 --可不修改 save_file_catalog="config" #部署模式 #模式1: 将所有主从节点以及sentinel节点部署在同一台机器上 #模式2: 将一个数据节点和一个sentinel节点部署在一台机器上,如master+sentinel1,slave1+sentinel2 #模式3: 将所有节点分开部署 deploy_mode="1" #主节点配置信息 master_ip="192.168.5.33" master_port="6379" #从节点配置信息 redis_slave_num="1" slave_1_port="6380" #sentinel配置信息 sentinel_num="2" sentinel_port_1="26379" sentinel_port_2="26380" master_alias="mymaster" #需要node_fail_votes个sentinel认为该节点下线时,该节点才会被判定为下线 node_fail_votes="1" #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX# #-------------------------------------------------------------------------------------------# #-------------------------------!!!下方内容请勿修改!!!--------------------------------# #-------------------------------------------------------------------------------------------# #创建目录 cd ${redis_path} if [ -e "${save_file_catalog}" ] then rm -rf ${save_file_catalog} fi mkdir ${save_file_catalog} #编译redis function compileRedis(){ cd ${redis_path} if [ ! -f "src/redis-sentinel" -o ! -f "src/redis-server" -o ! -f "src/redis-cli" ] then echo "The redis may not be compiled. Compile it first! Please wait a moment!" echo -e "\n\nComplie redis : $(date)\n" >> ${save_file_catalog}/compile.log make >> ${save_file_catalog}/compile.log 2>&1 make install >> ${save_file_catalog}/compile.log 2>&1 echo -e "Compile success!\n" fi } #修改redis数据节点配置文件 function modifyAndCreateRedisConfigFile(){ echo "Beging to Create and Mmodify redis config file..." cd ${redis_path} #将原有redis.conf拷贝(slave_num+1)份 if [ ! -e "redis.conf" ] then echo "redis.conf is not exist!" exit 1 fi #修改公共配置 lineNum=$(egrep "^bind" redis.conf | wc -l) if [ ${lineNum} -gt 0 ] then sed -i 's/^bind\( \|.\|[0-9]\)\+/bind 0.0.0.0/g' redis.conf else echo "${lineNum}, into else" echo "bind 0.0.0.0" >> redis.conf fi sed -i 's/^protected-mode yes/protected-mode no/g' redis.conf #创建并配置主节点 cp redis.conf ${save_file_catalog}/redis_master.conf sed -i "s/^port\( \|[0-9]\)\+/port ${master_port}/g" ${save_file_catalog}/redis_master.conf #创建并配置从节点 for((i=1;i<=${redis_slave_num};i++)) do cp redis.conf ${save_file_catalog}/redis_slave_$i.conf slave_port=`eval echo '$'slave_"$i"_port` sed -i "s/^port\( \|[0-9]\)\+/port ${slave_port}/g" ${save_file_catalog}/redis_slave_$i.conf echo "slaveof ${master_ip} ${master_port}" >> ${save_file_catalog}/redis_slave_$i.conf done echo -e "Config redis success!\n" } #创建sentinel配置文件 function createSentinelConfigFile(){ echo "Begin to create sentinel config file..." cd ${redis_path} for((i=1;i<=${sentinel_num};i++)) do sentinel_port=`eval echo '$'sentinel_port_"$i"` sentinel_config_filename="${save_file_catalog}/sentinel_$i.conf" echo -e "bind 0.0.0.0" >> ${sentinel_config_filename} echo -e "port ${sentinel_port}" >> ${sentinel_config_filename} echo -e "daemonize yes" >> ${sentinel_config_filename} echo -e "logfile \"${sentinel_port}.log\"" >> ${sentinel_config_filename} echo -e "sentinel monitor ${master_alias} ${master_ip} ${master_port} ${node_fail_votes}" >> ${sentinel_config_filename} echo -e "sentinel down-after-milliseconds ${master_alias} 30000" >> ${sentinel_config_filename} echo -e "sentinel parallel-syncs ${master_alias} 1" >> ${sentinel_config_filename} echo -e "sentinel failover-timeout ${master_alias} 180000" >> ${sentinel_config_filename} echo -e "protected-mode no" >> ${sentinel_config_filename} done echo -e "Config sentinel success!\n" } #创建启动文件 function createStartScrit(){ echo "Begin to create start script..." cd ${redis_path} cd ${save_file_catalog} echo "echo \"Begin to start Redis and Sentinel!\"" >> startRedis.sh echo "nohup redis-server redis_master.conf > redis_master.log 2>&1 &" >> startRedis.sh for((i=1;i<=${redis_slave_num};i++)) do echo "nohup redis-server redis_slave_${i}.conf > redis_slave_${i}.log 2>&1 &" >> startRedis.sh done for((i=1;i<=${sentinel_num};i++)) do echo "nohup redis-sentinel sentinel_$i.conf > sentinel_$i.log 2>&1 &" >> startRedis.sh done echo "echo \"Start Redis and Sentinel Success!\"" >> startRedis.sh chmod 777 startRedis.sh echo -e "Create start script success!\n" } #创建停止文件 function createStopScrit(){ echo "Begin to create stop script..." cd ${redis_path} cd ${save_file_catalog} echo "echo \"Begin to stop Redis and Sentinel!\"" >> stopRedis.sh echo 'pids=$(ps -ef | grep redis | cut -c 10-16)' >> stopRedis.sh echo 'pidArr=$(echo ${pids}|tr "\n", "\n")' >> stopRedis.sh echo 'for pid in ${pidArr}' >> stopRedis.sh echo 'do' >> stopRedis.sh echo ' ps -p ${pid} > /dev/null' >> stopRedis.sh echo ' if [ $? -eq 0 ]' >> stopRedis.sh echo ' then' >> stopRedis.sh echo ' kill -9 ${pid}' >> stopRedis.sh echo ' fi' >> stopRedis.sh echo 'done' >> stopRedis.sh echo "echo \"Stop Redis and Sentinel Success!\"" >> stopRedis.sh chmod 777 stopRedis.sh echo -e "Create stop script success!\n" } #调用以上函数,完成redis的编译和全量脚本及配置文件 compileRedis modifyAndCreateRedisConfigFile createSentinelConfigFile createStartScrit createStopScrit originFolderName=${redis_path##*/} #-----------------------适用于模式3:主、从、sentinel都分开部署-----------------------# #创建单独的主节点文件夹 function createMasterFolder() { echo "Begin to create master folder..." cd ${redis_path} cd .. cp -r ${originFolderName} "${originFolderName}_master" cd "${originFolderName}_master/${save_file_catalog}" rm -f ./redis_slave_* rm -f ./sentinel_* sed -i 's/Redis and Sentinel/Redis/g' startRedis.sh sed -i 's/Redis and Sentinel/Redis/g' stopRedis.sh #删除包含redis_slave的行 sed -i '/redis_slave/d' startRedis.sh #删除包含sentinel_的行 sed -i '/sentinel_/d' startRedis.sh echo -e "Create master folder success!\n" } #创建单独的从节点文件夹 function createSlaveFolderForMode3() { echo "Begin to create slave_$1 folder..." cd ${redis_path} cd .. cp -r ${originFolderName} "${originFolderName}_slave$1" cd "${originFolderName}_slave$1/${save_file_catalog}" rm -f ./redis_master* rm -f ./redis_slave_[^$1].conf rm -f ./sentinel_* sed -i 's/Redis and Sentinel/Redis/g' startRedis.sh sed -i 's/Redis and Sentinel/Redis/g' stopRedis.sh #删除包含redis_master的行 sed -i '/redis_master/d' startRedis.sh #删除其他slave的启动命令行 sed -i "/redis_slave_[^$1]/d" startRedis.sh #删除包含sentinel_的行 sed -i '/sentinel_/d' startRedis.sh echo -e "Create slave_$1 folder success!\n" } #创建单独的sentinel节点文件夹 function createSentinelFolder() { echo "Begin to create sentinel_$1 folder..." cd ${redis_path} cd .. cp -r ${originFolderName} "${originFolderName}_sentinel$1" cd "${originFolderName}_sentinel$1/${save_file_catalog}" rm -f ./redis_master* rm -f ./redis_slave_* rm -f ./sentinel_[^$1].conf sed -i 's/Redis and Sentinel/Sentinel/g' startRedis.sh sed -i 's/Redis and Sentinel/Sentinel/g' stopRedis.sh #删除包含redis_master的行 sed -i '/redis_master/d' startRedis.sh #删除其他slave的启动命令行 sed -i "/redis_slave_*/d" startRedis.sh #删除包含sentinel_的行 sed -i "/sentinel_[^$1]/d" startRedis.sh echo -e "Create sentinel_$1 folder success!\n" } #-----------------------适用于模式2:主+sentinel、从+sentinel部署模式-----------------------# #创建主节点与sentinel的文件夹 function createMasterAndSentinelFolder() { echo "Begin to create master and sentinel$1 folder..." cd ${redis_path} cd .. cp -r ${originFolderName} "${originFolderName}_master_sentinel$1" cd "${originFolderName}_master_sentinel$1/${save_file_catalog}" rm -f ./redis_slave_* rm -f ./sentinel_[^$1].conf #删除包含redis_slave的行 sed -i '/redis_slave/d' startRedis.sh #删除包含sentinel_的行 sed -i "/sentinel_[^$1]/d" startRedis.sh echo -e "Create master and sentinel$1 folder success!\n" } #创建从节点与sentinel的文件夹 function createSlaveAndSentinelFolder() { echoStr="" folderSubstr="" flag=0 #判断当前slave或者sentinel的序号是否超过实际个数 if [ $1 -gt ${redis_slave_num} ]; then echoStr="sentinel$2" folderSubstr="sentinel$2" flag=1 elif [ $2 -gt ${sentinel_num} ]; then echoStr="slave$1" folderSubstr="slave$1" flag=2 else echoStr="slave$1 and sentinel$2" folderSubstr="slave$1_sentinel$2" flag=3 fi echo "Begin to create ${echoStr} folder..." cd ${redis_path} cd .. cp -r ${originFolderName} "${originFolderName}_${folderSubstr}" cd "${originFolderName}_${folderSubstr}/${save_file_catalog}" rm -f ./redis_master* rm -f ./redis_slave_[^$1].conf rm -f ./sentinel_[^$2].conf if [ ${flag} -eq 1 ]; then sed -i 's/Redis and Sentinel/Sentinel/g' startRedis.sh sed -i 's/Redis and Sentinel/Sentinel/g' stopRedis.sh elif [ ${flag} -eq 2 ]; then sed -i 's/Redis and Sentinel/Redis/g' startRedis.sh sed -i 's/Redis and Sentinel/Redis/g' stopRedis.sh fi #删除包含redis_master的行 sed -i '/redis_master/d' startRedis.sh #删除其他slave的启动命令行 sed -i "/redis_slave_[^$1]/d" startRedis.sh #删除包含sentinel_的行 sed -i "/sentinel_[^$2]/d" startRedis.sh echo -e "Create ${echoStr} folder success!\n" } #******----------------------------****根据不同模式生成编译后的文件夹***------------------------------******# function createDeployedFolderByModel() { echo "Start to create deployed folders by model..." if [ $1 -eq 1 ]; then echo -e "You input mode is 1, namely all the node deployed in one!\n" elif [ $1 -eq 2 ]; then echo -e "You input mode is 2, namely master+sentinel1, slaveX+sentinelX+1!\n" createMasterAndSentinelFolder 1 num=0 if [ ${redis_slave_num} -gt $[${sentinel_num}-1] ]; then num=${redis_slave_num} else num=$[${sentinel_num}-1] fi for((i=1;i<=${num};i++)) do createSlaveAndSentinelFolder ${i} $[${i}+1] done elif [ $1 -eq 3 ]; then echo -e "You input mode is 3, namely every node deployed in different machines!\n" createMasterFolder for((i=1;i<=${redis_slave_num};i++)) do createSlaveFolderForMode3 ${i} done for((i=1;i<=${sentinel_num};i++)) do createSentinelFolder ${i} done fi echo -e "Create deployed folders by model success!\n" } #根据不同模式生成编译后的文件夹 createDeployedFolderByModel ${deploy_mode} exit 0 使用说明 执行前需要已经安装GCC等基础环境;只需要修改配置信息部分的内容,redis_path为解压后redis的根目录路径,deploy_mode为部署模式,这里提供三种可选项: 模式1: 将所有主从节点以及sentinel节点部署在同一台机器上,即将生成的所有配置文件保存在一个Redis目录的config目录中; 模式2: 将一个数据节点和一个sentinel节点部署在一台机器上,如master+sentinel1,slave1+sentinel2,即将这两组的配置文件分别保存在一个Redis目录的config目录下。最终会生成两个Redis目录,可将其中一个拷贝至其他机器; 模式3: 将所有节点分开部署,即将所有节点的配置文件分别保存在一个Redis目录的config目录下。最终会生成多个Redis目录,在本机保存一个节点后,可将其他目录拷贝至其他机器。成功执行该脚本后,在redis_path目录下会生成config目录,里面有配置文件、Redis启动脚本和停止脚本。 结语以上脚本可能还有很多不足之处,望各位指正,如果能对你有一点帮助,那深感荣幸。