├── README.md ├── calc_redis_keys.sh ├── check_redis_cluster.sh ├── clear_redis_cluster.sh ├── deploy ├── 5.0 │ ├── README.txt │ ├── redis-PORT.conf │ └── redis.conf ├── README.md ├── REDIS.crontab ├── deploy_redis_cluster.log ├── deploy_redis_cluster.sh ├── process_monitor.sh ├── redis-PORT.conf ├── redis.conf └── redis_cluster.nodes ├── move_redis_slot.sh ├── query_key_distribution.sh ├── query_redis_memory.sh ├── query_redis_queue.sh ├── query_redis_queues.sh ├── show_redis_map.sh ├── stop_redis.sh └── top_redis.sh /README.md: -------------------------------------------------------------------------------- 1 | * **deploy** 2 | 3 | Redis和Redis集群批量部署工具(deploy_redis_cluster.sh) 4 | 5 | * **check_redis_cluster.sh** 6 | 7 | 检查Redis集群工具,依赖命令SETEX 8 | 9 | * **clear_redis_cluster.sh** 10 | 11 | 清空Redis集群工具,依赖命令FLUSHALL 12 | 13 | * **show_redis_map.sh** 14 | 15 | 显示redis集群master和slave间的映射关系,如果同一IP出现两个master或者一对master和slave在同一个IP上,标星的方式提示 16 | 17 | * **query_redis_memory** 18 | 19 | 查询集群所有节点物理内存工具 20 | 21 | 22 | * **move_redis_slot.sh** 23 | 24 | 迁移slot工具 25 | 26 | * **query_key_distribution.sh** 27 | 28 | 查询key在节点中的分布工具 29 | 30 | * **stop_redis.sh** 31 | 32 | 用于停指定端口号 redis-server 进程工具 33 | 34 | * **top_redis.sh** 35 | 36 | 查看指定端口号 redis-server 进程的 top 命令信息,支持 mooon_ssh 远程批量执行 37 | -------------------------------------------------------------------------------- /calc_redis_keys.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Writed by yijian on 2021/7/21 3 | # 将一个大 key 分解成小 keys 时, 4 | # 用于计算出均衡分布的小 keys 取值。 5 | # 6 | # 带2个参数: 7 | # 第1个参数为REdis的节点字符串, 8 | # 第2个参数可选,为连接REdis的密码。 9 | # 使用前,需要先修改 KEY 的值,以及 NUM_KEYS 的值。 10 | REDIS_CLI=/usr/local/bin/redis-cli 11 | NUM_KEYS=10 # 目标 keys 的数量,可考虑为集群的主节点整数倍 12 | 13 | function usage() 14 | { 15 | echo "Usage: `basename $0` redis_node [redis-password]" 16 | echo "Example1: `basename $0` 127.0.0.1:6379" 17 | echo "Example2: `basename $0` 127.0.0.1:6379 redis-password" 18 | } 19 | 20 | # with a parameter: single redis node 21 | if test $# -ne 1 -a $# -ne 2; then 22 | usage 23 | exit 1 24 | fi 25 | 26 | # 检查参数 27 | eval $(echo "$1" | awk -F[\:] '{ printf("REDIS_IP=%s\nREDIS_PORT=%s\n",$1,$2) }') 28 | if test -z "$REDIS_IP" -o -z "$REDIS_PORT"; then 29 | echo "Parameter error" 30 | usage 31 | exit 1 32 | fi 33 | 34 | # 确保redis-cli可用 35 | which "$REDIS_CLI" > /dev/null 2>&1 36 | if test $? -ne 0; then 37 | echo -e "\`redis-cli\` not exists or not executable" 38 | exit 1 39 | fi 40 | 41 | # 根据 keys 的数量计算出 slots 的分布 42 | NUM_SLOTS=16384 43 | STEP=$(($NUM_SLOTS / $NUM_KEYS)) 44 | declare -A slots_table # 存储 slots 分布表 45 | for ((i=0;i<$NUM_SLOTS;i+=$STEP)) 46 | do 47 | slot=$(($i+99)) # 加 99 大体上跳过相邻边界值 48 | slots_table[$slot]="2021" 49 | if test ${#slots_table[@]} -eq $NUM_KEYS; then 50 | break 51 | fi 52 | done 53 | index=0 54 | for slot in ${!slots_table[*]}; do 55 | echo -e "[$index] \033[1;33m$slot\033[m" 56 | index=$(($index+1)) 57 | done 58 | echo "" 59 | 60 | index=0 61 | CURRENT_KEYS=0 # 已取得的 keys 数 62 | echo "Available keys:" 63 | for ((i=0;;++i)) 64 | do 65 | KEY="k:$i" 66 | if test $# -eq 1; then 67 | slot=`$REDIS_CLI -h $REDIS_IP -p $REDIS_PORT CLUSTER KEYSLOT "$KEY"` 68 | else 69 | slot=`$REDIS_CLI --no-auth-warning -a "$2" -h $REDIS_IP -p $REDIS_PORT CLUSTER KEYSLOT "$KEY"` 70 | fi 71 | v="${slots_table[$slot]}" 72 | if test "X$v" == "X2021"; then 73 | echo -e "[$index] \033[1;33m$KEY\033[m => $slot" 74 | 75 | slots_table[$slot]="0" 76 | CURRENT_KEYS=$(($CURRENT_KEYS+1)) 77 | index=$(($index+1)) 78 | if test $CURRENT_KEYS -eq $NUM_KEYS; then 79 | break 80 | fi 81 | fi 82 | done 83 | -------------------------------------------------------------------------------- /check_redis_cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2018/8/20 3 | # Batch to check all nodes using SCAN command 4 | # 检查redis集中是否正常工具 5 | REDIS_CLI=${REDIS_CLI:-redis-cli} 6 | REDIS_IP=${REDIS_IP:-127.0.0.1} 7 | REDIS_PORT=${REDIS_PORT:-6379} 8 | 9 | # 显示用法函数 10 | function usage() 11 | { 12 | echo "Usage: check_redis_cluster.sh a_redis_node_of_cluster redis_password" 13 | echo "Example1: check_redis_cluster.sh '127.0.0.1:6379'" 14 | echo "Example2: check_redis_cluster.sh '127.0.0.1:6379' '123456'" 15 | } 16 | 17 | # 检查参数个数 18 | if test $# -lt 1 -o $# -gt 2; then 19 | usage 20 | exit 1 21 | fi 22 | 23 | # 第一个参数为集群中的节点, 24 | REDIS_NODE="$1" 25 | # 第二个参数为密码 26 | REDIS_PASSWORD="" 27 | if test $# -ge 2; then 28 | REDIS_PASSWORD="$2" 29 | fi 30 | 31 | # 取得IP和端口 32 | eval $(echo "$1" | awk -F[\:] '{ printf("REDIS_IP=%s\nREDIS_PORT=%s\n",$1,$2) }') 33 | if test -z "$REDIS_IP" -o -z "$REDIS_PORT"; then 34 | echo "Parameter error: \`$REDIS_NODE\`." 35 | usage 36 | exit 1 37 | fi 38 | 39 | # 确保redis-cli可用 40 | echo "Checking \`redis-cli\` ..." 41 | which "$REDIS_CLI" > /dev/null 2>&1 42 | if test $? -ne 0; then 43 | echo "Command \`redis-cli\` is not exists or not executable." 44 | echo "You can set environment variable \`REDIS_CLI\` to point to the redis-cli." 45 | echo "Example: export REDIS_CLI=/usr/local/bin/redis-cli" 46 | exit 1 47 | fi 48 | 49 | if test -z "$REDIS_PASSWORD"; then 50 | redis_nodes=`redis-cli -h $REDIS_IP -p $REDIS_PORT cluster nodes | awk -F[\ \:\@] '!/ERR/{ printf("%s:%s\n",$2,$3); }'` 51 | else 52 | redis_nodes=`redis-cli --no-auth-warning -a "$REDIS_PASSWORD" -h $REDIS_IP -p $REDIS_PORT cluster nodes | awk -F[\ \:\@] '!/ERR/{ printf("%s:%s\n",$2,$3); }'` 53 | fi 54 | if test -z "$redis_nodes"; then 55 | # Standlone(非集群) 56 | if test -z "$REDIS_PASSWORD"; then 57 | $REDIS_CLI -h $REDIS_IP -p $REDIS_PORT SCAN 0 COUNT 20 58 | else 59 | $REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" -h $REDIS_IP -p $REDIS_PORT SCAN 0 COUNT 20 60 | fi 61 | else 62 | # Cluster(集群) 63 | index=0 64 | for redis_node in $redis_nodes; 65 | do 66 | if test ! -z "$redis_node"; then 67 | eval $(echo "$redis_node" | awk -F[\:] '{ printf("redis_node_ip=%s\nredis_node_port=%s\n",$1,$2) }') 68 | 69 | if test ! -z "$redis_node_ip" -a ! -z "$redis_node_port"; then 70 | echo -e "Checking \033[1;33m${redis_node_ip}:${redis_node_port}\033[m ..." 71 | if test -z "$REDIS_PASSWORD"; then 72 | $REDIS_CLI -h $redis_node_ip -p $redis_node_port -c SETEX KKKKK0123056789:$index 1 X 73 | else 74 | $REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" -h $redis_node_ip -p $redis_node_port -c SETEX KKKKK0123056789:$index 1 X 75 | fi 76 | index=$(($index+1)) 77 | fi 78 | fi 79 | done 80 | fi 81 | -------------------------------------------------------------------------------- /clear_redis_cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2018/8/20 3 | # Batch to clear all nodes using FLUSHALL command 4 | # 用来清空一个redis集群中的所有数据,要求 FLUSHALL 命令可用, 5 | # 如果在 redis.conf 中使用 rename 改名了 FLUSHALL,则不能执行本脚本。 6 | # 可带两个参数: 7 | # 1)参数1 集群中的任一可用节点(必须) 8 | # 2)连接redis的密码(设置了密码才需要) 9 | REDIS_CLI=${REDIS_CLI:-redis-cli} 10 | REDIS_IP=${REDIS_IP:-127.0.0.1} 11 | REDIS_PORT=${REDIS_PORT:-6379} 12 | 13 | # 显示用法函数 14 | function usage() 15 | { 16 | echo "Usage: clear_redis_cluster.sh a_redis_node_of_cluster redis_password" 17 | echo "Example1: clear_redis_cluster.sh '127.0.0.1:6379'" 18 | echo "Example2: clear_redis_cluster.sh '127.0.0.1:6379' '123456'" 19 | } 20 | 21 | # 检查参数个数 22 | if test $# -lt 1 -o $# -gt 2; then 23 | usage 24 | exit 1 25 | fi 26 | 27 | # 第一个参数为集群中的节点, 28 | REDIS_NODE="$1" 29 | # 第二个参数为密码 30 | REDIS_PASSWORD="" 31 | if test $# -ge 2; then 32 | REDIS_PASSWORD="$2" 33 | fi 34 | 35 | # 取得IP和端口 36 | eval $(echo "$REDIS_NODE" | awk -F[\:] '{ printf("REDIS_IP=%s\nREDIS_PORT=%s\n",$1,$2) }') 37 | if test -z "$REDIS_IP" -o -z "$REDIS_PORT"; then 38 | echo "Parameter error: \`$REDIS_NODE\`." 39 | usage 40 | exit 1 41 | fi 42 | 43 | # 确保redis-cli可用 44 | echo "Checking \`redis-cli\` ..." 45 | which "$REDIS_CLI" > /dev/null 2>&1 46 | if test $? -ne 0; then 47 | echo "Command \`redis-cli\` is not exists or not executable." 48 | echo "You can set environment variable \`REDIS_CLI\` to point to the redis-cli." 49 | echo "Example: export REDIS_CLI=/usr/local/bin/redis-cli" 50 | exit 1 51 | fi 52 | 53 | if test -z "$REDIS_PASSWORD"; then 54 | redis_nodes=`redis-cli -h $REDIS_IP -p $REDIS_PORT cluster nodes | awk -F[\ \:\@] '!/ERR/{ printf("%s:%s\n",$2,$3); }'` 55 | else 56 | redis_nodes=`redis-cli --no-auth-warning -a "$REDIS_PASSWORD" -h $REDIS_IP -p $REDIS_PORT cluster nodes | awk -F[\ \:\@] '!/ERR/{ printf("%s:%s\n",$2,$3); }'` 57 | fi 58 | if test -z "$redis_nodes"; then 59 | # Standlone(非集群) 60 | if test -z "$REDIS_PASSWORD"; then 61 | $REDIS_CLI -h $REDIS_IP -p $REDIS_PORT FLUSHALL ASYNC 62 | $REDIS_CLI -h $REDIS_IP -p $REDIS_PORT BGREWRITEAOF 63 | else 64 | $REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" -h $REDIS_IP -p $REDIS_PORT FLUSHALL ASYNC 65 | $REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" -h $REDIS_IP -p $REDIS_PORT BGREWRITEAOF 66 | fi 67 | else 68 | # Cluster(集群) 69 | for redis_node in $redis_nodes; 70 | do 71 | if test ! -z "$redis_node"; then 72 | eval $(echo "$redis_node" | awk -F[\:] '{ printf("redis_node_ip=%s\nredis_node_port=%s\n",$1,$2) }') 73 | 74 | if test ! -z "$redis_node_ip" -a ! -z "$redis_node_port"; then 75 | # clear 76 | echo -e "Clearing \033[1;33m${redis_node_ip}:${redis_node_port}\033[m ..." 77 | if test -z "$REDIS_PASSWORD"; then 78 | result=`$REDIS_CLI -h $redis_node_ip -p $redis_node_port FLUSHALL ASYNC` 79 | $REDIS_CLI -h $redis_node_ip -p $redis_node_port BGREWRITEAOF 80 | else 81 | result=`$REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" -h $redis_node_ip -p $redis_node_port FLUSHALL ASYNC` 82 | $REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" -h $redis_node_ip -p $redis_node_port BGREWRITEAOF 83 | fi 84 | 85 | if test ! -z "$result"; then 86 | # SUCCESS 87 | if test "$result" = "OK"; then 88 | echo -e "\033[0;32;32m$result\033[m" 89 | else 90 | echo -e "\033[0;32;31m$result\033[m" 91 | fi 92 | fi 93 | fi 94 | fi 95 | done 96 | fi 97 | -------------------------------------------------------------------------------- /deploy/5.0/README.txt: -------------------------------------------------------------------------------- 1 | redis-5.X.Y版本的配置文件模板 2 | 3 | 如果开启了aof,建议save参数调大一点,减少写rdb文件频率,比如可以考虑如下配置: 4 | save 900 10 5 | save 300 100 6 | save 60 100000 7 | 相比默认配置提高了10倍。 8 | -------------------------------------------------------------------------------- /deploy/README.md: -------------------------------------------------------------------------------- 1 | Redis和Redis集群部署工具 2 | 3 | 注意:最新版本仅支持5.0及以上版本。 4 | 5 | REDIS.crontab crontab监控模板 6 | deploy_redis_cluster.sh 集群部署工具 7 | redis_cluster.nodes 集群所有节点和端口配置文件 8 | 9 | 注: 10 | 本目录下的的redis.conf和redis-PORT.conf取自redis-4.0.11版本,新增了一些配置项,可能不适应于一些低版本。 11 | deploy_redis_cluster.log 为deploy_redis_cluster.sh示例的操作日志和运行日志 12 | 13 | 依赖两个批量操作工具:mooon_ssh和mooon_upload,这两个批量操作工具有C++和GO两个版本。 14 | mooon-tools-glibc2.4_i386.tar.gz:32位版本的mooon_ssh和mooon_upload,运行依赖C++运行时库 15 | mooon-tools-glibc2.17_x86_64.tar.gz:64位版本的mooon_ssh和mooon_upload,运行依赖C++运行时库 16 | 注1:GO版本的mooon_ssh和mooon_upload不依赖依赖C++运行时库 17 | 注2:只有当使用5.0版本之前的redis-cli时,才需要安装ruby和gem, 18 | 因为5.0版本开始,创建集群只能直接使用redis-cli,而不能再使用redis-trib.rb脚本。 19 | 20 | 在执行deploy_redis_cluster.sh之前, 21 | 需要先完成下列前置工作(只需要在任意一台可SSH连接Redis集群的机器上完成): 22 | 1)准备好了批量命令工具mooon_ssh 23 | 2)准备好了批量上传工具mooon_upload 24 | 3)准备好了公共的redis配置文件redis.conf 25 | 4)准备好了与端口关的redis配置文件模板redis-PORT.conf 26 | 5)配置好redis_cluster.nodes,格式请参见redis_cluster.nodes 27 | 28 | 使用批量操作工具mooon_ssh和mooon_upload完成下列工作(Redis集群每个节点均需): 29 | 1)创建好安装用户,并设置好安装用户密码 30 | 2)创建好安装目录,并且设置目录的owner为安装用户 31 | 3)系统环境的设置,主要包括(参见Redis集群安装文章): 32 | 3.1)最大可打开文件数(/etc/security/limits.conf) 33 | 3.2)TCP监听队列大小(/proc/sys/net/core/somaxconn) 34 | 3.3)OOM设置(/proc/sys/vm/overcommit_memory) 35 | 3.4)THP设置(/sys/kernel/mm/transparent_hugepage/enabled) 36 | 37 | 批量操作工具 38 | 39 | 1)C++版本mooon_ssh和mooon_upload 40 | libmooon包含了mooon_ssh和mooon_upload,这两个工具基于开源的libssh2(http://www.libssh2.org/)实现。 41 | 42 | 2)GO版本mooon_ssh和mooon_upload 43 | 44 | 3)编译libssh2 45 | Linux下编译libssh2,需要指定参数“--with-libssl-prefix”: 46 | ./configure --prefix=/usr/local/libssh2-1.6.0 --with-libssl-prefix=/usr/local/openssl 47 | make 48 | make install 49 | 因此,编译之前需要先安装好openssl 50 | 51 | 4)编译openssl 52 | ./config --prefix=/usr/local/openssl shared threads 53 | make 54 | make install 55 | 56 | 5)编译libmooon 57 | cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr/local/mooon . 58 | make 59 | make install 60 | 编译成功后,在tools目录下可以找到编译好的mooon_ssh和mooon_upload。 61 | 62 | GO版本的mooon_ssh和mooon_upload,请直接参见mooon_ssh.go和mooon_upload.go的文件头注释。 63 | 64 | Redis集群安装文章: 65 | 1)https://blog.csdn.net/Aquester/article/details/50150163 66 | 2)http://blog.chinaunix.net/uid-20682147-id-5557566.html 67 | -------------------------------------------------------------------------------- /deploy/REDIS.crontab: -------------------------------------------------------------------------------- 1 | # Added by yijian on 2018/8/27 (eyjian@qq.com) 2 | # redis 的 crontab 进程监控设置 3 | # 使用前,请先设置好REDIS_HOME、REDIS_PORT1 和 REDIS_PORT2 三者的值 4 | # 5 | # REDIS_HOME 指定 redis 的安装目录,REDIS_PORT 指定 redis 的服务端口 6 | # REDIS_LOG_SIZE 用于指定 redis 日志文件大小, 7 | # 注意 redis 并不自动滚动日志文件,也可通过 rsyslogd 实现日志文件滚动。 8 | # 9 | # 可从 https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh 下载最新的 process_monitor.sh。 10 | PMONITOR=/usr/local/bin/process_monitor.sh 11 | REDIS_HOME=/usr/local/redis 12 | REDIS_LOG_SIZE=1073741824 13 | REDIS_PORT6379=6379 14 | REDIS_PORT6380=6380 15 | 16 | # REDIS_PORT6379 17 | * * * * * $PMONITOR "$REDIS_HOME/bin/redis-server 0.0.0.0:$REDIS_PORT6379" "$REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis-$REDIS_PORT6379.conf" 18 | 0 * * * * log=$REDIS_HOME/log/redis-$REDIS_PORT6379.log;if test -f $log; then if test `ls -l $log|cut -d' ' -f5` -gt $REDIS_LOG_SIZE; then mv $log $log.old ; fi fi 19 | 20 | # REDIS_PORT6380 21 | * * * * * $PMONITOR "$REDIS_HOME/bin/redis-server 0.0.0.0:$REDIS_PORT6380" "$REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis-$REDIS_PORT6380.conf" 22 | 0 * * * * log=$REDIS_HOME/log/redis-$REDIS_PORT6380.log;if test -f $log; then if test `ls -l $log|cut -d' ' -f5` -gt $REDIS_LOG_SIZE; then mv $log $log.old ; fi fi 23 | -------------------------------------------------------------------------------- /deploy/deploy_redis_cluster.log: -------------------------------------------------------------------------------- 1 | [zhangsan@mooon ~/redis-tools/deploy]$ ls 2 | deploy_redis_cluster.sh README.txt redis-3.3.3.gem redis-check-aof redis-cli redis.conf redis-server 3 | dumpfile redis-3.0.0.gem redis-4.0.1.gem redis-check-rdb redis_cluster.nodes redis-PORT.conf redis-trib.rb 4 | 5 | [zhangsan@mooon ~/redis-tools/deploy]$ grep REDISPORT redis*.conf 6 | redis-PORT.conf:port REDISPORT 7 | redis-PORT.conf:pidfile INSTALLDIR/bin/redis_REDISPORT.pid 8 | redis-PORT.conf:logfile INSTALLDIR/log/redis-REDISPORT.log 9 | redis-PORT.conf:dbfilename dump-REDISPORT.rdb 10 | redis-PORT.conf:dir INSTALLDIR/data/REDISPORT 11 | redis-PORT.conf:appendfilename appendonly-REDISPORT.aof 12 | redis-PORT.conf:cluster-config-file nodes-REDISPORT.conf 13 | 14 | [zhangsan@mooon ~/redis-tools/deploy]$ grep INSTALLDIR redis*.conf 15 | redis-PORT.conf:include INSTALLDIR/conf/redis.conf 16 | redis-PORT.conf:pidfile INSTALLDIR/bin/redis_REDISPORT.pid 17 | redis-PORT.conf:logfile INSTALLDIR/log/redis-REDISPORT.log 18 | redis-PORT.conf:dir INSTALLDIR/data/REDISPORT 19 | 20 | [zhangsan@mooon ~/redis-tools/deploy]$ cat redis_cluster.nodes 21 | 192.168.0.101:6379 22 | 192.168.0.102:6379 23 | 192.168.0.103:6379 24 | 192.168.0.104:6379 25 | 192.168.0.105:6379 26 | 192.168.0.106:6379 27 | 192.168.0.107:6379 28 | 192.168.0.108:6379 29 | 192.168.0.109:6379 30 | 192.168.0.101:6380 31 | 192.168.0.102:6380 32 | 192.168.0.103:6380 33 | 192.168.0.104:6380 34 | 192.168.0.105:6380 35 | 192.168.0.106:6380 36 | 192.168.0.107:6380 37 | 192.168.0.108:6380 38 | 192.168.0.109:6380 39 | 40 | [zhangsan@mooon ~/redis-tools/deploy]$ ./deploy_redis_cluster.sh 22 redis 'redis^1234' /usr/local/redis-4.0.11 41 | [ssh port] 22 42 | [install user] redis 43 | [install directory] /usr/local/redis-4.0.11 44 | 45 | Checking ruby OK 46 | Checking gem OK 47 | Checking mooon_ssh OK 48 | Checking mooon_upload OK 49 | Checking /home/zhangsan/redis-tools/deploy/redis-trib.rb OK 50 | Checking /home/zhangsan/redis-tools/deploy/redis-server OK 51 | Checking /home/zhangsan/redis-tools/deploy/redis-cli OK 52 | Checking /home/zhangsan/redis-tools/deploy/redis-check-aof OK 53 | Checking /home/zhangsan/redis-tools/deploy/redis-check-rdb OK 54 | Checking /home/zhangsan/redis-tools/deploy/redis.conf OK 55 | Checking /home/zhangsan/redis-tools/deploy/redis-PORT.conf OK 56 | Checking /home/zhangsan/redis-tools/deploy/redis_cluster.nodes OK 57 | 58 | Are you sure? [yes/no] yes 59 | Starting to install ... 60 | 61 | Clear install directory? [yes/no] yes 62 | 63 | ================================ 64 | [192.168.0.106] Installing common ... 65 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 66 | [192.168.0.106] 67 | [192.168.0.106] SUCCESS 68 | 69 | 70 | ================================ 71 | [192.168.0.106 SUCCESS] 0 seconds 72 | SUCCESS: 1, FAILURE: 0 73 | 74 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 75 | [192.168.0.106] 76 | command return 1 77 | 78 | 79 | ================================ 80 | [192.168.0.106 FAILURE] 0 seconds 81 | SUCCESS: 0, FAILURE: 1 82 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 83 | [192.168.0.106] 84 | [192.168.0.106] SUCCESS 85 | 86 | 87 | ================================ 88 | [192.168.0.106 SUCCESS] 0 seconds 89 | SUCCESS: 1, FAILURE: 0 90 | 91 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 92 | [192.168.0.106] 93 | [192.168.0.106] SUCCESS 94 | 95 | 96 | ================================ 97 | [192.168.0.106 SUCCESS] 0 seconds 98 | SUCCESS: 1, FAILURE: 0 99 | 100 | mooon_upload -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 101 | [192.168.0.106] 102 | [192.168.0.106] SUCCESS: 59295 bytes (redis.conf) 103 | 104 | 105 | ================================ 106 | [192.168.0.106 SUCCESS] 0 seconds (redis.conf) 107 | SUCCESS: 1, FAILURE: 0 108 | 109 | mooon_upload -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 110 | [192.168.0.106] 111 | [192.168.0.106] SUCCESS: 5775666 bytes (redis-server) 112 | 113 | [192.168.0.106] 114 | [192.168.0.106] SUCCESS: 2617471 bytes (redis-cli) 115 | 116 | [192.168.0.106] 117 | [192.168.0.106] SUCCESS: 5775666 bytes (redis-check-aof) 118 | 119 | [192.168.0.106] 120 | [192.168.0.106] SUCCESS: 5775666 bytes (redis-check-rdb) 121 | 122 | [192.168.0.106] 123 | [192.168.0.106] SUCCESS: 65991 bytes (redis-trib.rb) 124 | 125 | 126 | ================================ 127 | [192.168.0.106 SUCCESS] 1 seconds (redis-server) 128 | [192.168.0.106 SUCCESS] 0 seconds (redis-cli) 129 | [192.168.0.106 SUCCESS] 1 seconds (redis-check-aof) 130 | [192.168.0.106 SUCCESS] 1 seconds (redis-check-rdb) 131 | [192.168.0.106 SUCCESS] 0 seconds (redis-trib.rb) 132 | SUCCESS: 5, FAILURE: 0 133 | [192.168.0.101] Installing common ... 134 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 135 | [192.168.0.101] 136 | [192.168.0.101] SUCCESS 137 | 138 | 139 | ================================ 140 | [192.168.0.101 SUCCESS] 0 seconds 141 | SUCCESS: 1, FAILURE: 0 142 | 143 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 144 | [192.168.0.101] 145 | command return 1 146 | 147 | 148 | ================================ 149 | [192.168.0.101 FAILURE] 0 seconds 150 | SUCCESS: 0, FAILURE: 1 151 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 152 | [192.168.0.101] 153 | [192.168.0.101] SUCCESS 154 | 155 | 156 | ================================ 157 | [192.168.0.101 SUCCESS] 0 seconds 158 | SUCCESS: 1, FAILURE: 0 159 | 160 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 161 | [192.168.0.101] 162 | [192.168.0.101] SUCCESS 163 | 164 | 165 | ================================ 166 | [192.168.0.101 SUCCESS] 0 seconds 167 | SUCCESS: 1, FAILURE: 0 168 | 169 | mooon_upload -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 170 | [192.168.0.101] 171 | [192.168.0.101] SUCCESS: 59295 bytes (redis.conf) 172 | 173 | 174 | ================================ 175 | [192.168.0.101 SUCCESS] 0 seconds (redis.conf) 176 | SUCCESS: 1, FAILURE: 0 177 | 178 | mooon_upload -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 179 | [192.168.0.101] 180 | [192.168.0.101] SUCCESS: 5775666 bytes (redis-server) 181 | 182 | [192.168.0.101] 183 | [192.168.0.101] SUCCESS: 2617471 bytes (redis-cli) 184 | 185 | [192.168.0.101] 186 | [192.168.0.101] SUCCESS: 5775666 bytes (redis-check-aof) 187 | 188 | [192.168.0.101] 189 | [192.168.0.101] SUCCESS: 5775666 bytes (redis-check-rdb) 190 | 191 | [192.168.0.101] 192 | [192.168.0.101] SUCCESS: 65991 bytes (redis-trib.rb) 193 | 194 | 195 | ================================ 196 | [192.168.0.101 SUCCESS] 1 seconds (redis-server) 197 | [192.168.0.101 SUCCESS] 1 seconds (redis-cli) 198 | [192.168.0.101 SUCCESS] 1 seconds (redis-check-aof) 199 | [192.168.0.101 SUCCESS] 1 seconds (redis-check-rdb) 200 | [192.168.0.101 SUCCESS] 0 seconds (redis-trib.rb) 201 | SUCCESS: 5, FAILURE: 0 202 | [192.168.0.104] Installing common ... 203 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 204 | [192.168.0.104] 205 | [192.168.0.104] SUCCESS 206 | 207 | 208 | ================================ 209 | [192.168.0.104 SUCCESS] 0 seconds 210 | SUCCESS: 1, FAILURE: 0 211 | 212 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 213 | [192.168.0.104] 214 | command return 1 215 | 216 | 217 | ================================ 218 | [192.168.0.104 FAILURE] 0 seconds 219 | SUCCESS: 0, FAILURE: 1 220 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 221 | [192.168.0.104] 222 | [192.168.0.104] SUCCESS 223 | 224 | 225 | ================================ 226 | [192.168.0.104 SUCCESS] 0 seconds 227 | SUCCESS: 1, FAILURE: 0 228 | 229 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 230 | [192.168.0.104] 231 | [192.168.0.104] SUCCESS 232 | 233 | 234 | ================================ 235 | [192.168.0.104 SUCCESS] 0 seconds 236 | SUCCESS: 1, FAILURE: 0 237 | 238 | mooon_upload -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 239 | [192.168.0.104] 240 | [192.168.0.104] SUCCESS: 59295 bytes (redis.conf) 241 | 242 | 243 | ================================ 244 | [192.168.0.104 SUCCESS] 0 seconds (redis.conf) 245 | SUCCESS: 1, FAILURE: 0 246 | 247 | mooon_upload -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 248 | [192.168.0.104] 249 | [192.168.0.104] SUCCESS: 5775666 bytes (redis-server) 250 | 251 | [192.168.0.104] 252 | [192.168.0.104] SUCCESS: 2617471 bytes (redis-cli) 253 | 254 | [192.168.0.104] 255 | [192.168.0.104] SUCCESS: 5775666 bytes (redis-check-aof) 256 | 257 | [192.168.0.104] 258 | [192.168.0.104] SUCCESS: 5775666 bytes (redis-check-rdb) 259 | 260 | [192.168.0.104] 261 | [192.168.0.104] SUCCESS: 65991 bytes (redis-trib.rb) 262 | 263 | 264 | ================================ 265 | [192.168.0.104 SUCCESS] 1 seconds (redis-server) 266 | [192.168.0.104 SUCCESS] 1 seconds (redis-cli) 267 | [192.168.0.104 SUCCESS] 1 seconds (redis-check-aof) 268 | [192.168.0.104 SUCCESS] 1 seconds (redis-check-rdb) 269 | [192.168.0.104 SUCCESS] 0 seconds (redis-trib.rb) 270 | SUCCESS: 5, FAILURE: 0 271 | [192.168.0.103] Installing common ... 272 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 273 | [192.168.0.103] 274 | [192.168.0.103] SUCCESS 275 | 276 | 277 | ================================ 278 | [192.168.0.103 SUCCESS] 0 seconds 279 | SUCCESS: 1, FAILURE: 0 280 | 281 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 282 | [192.168.0.103] 283 | command return 1 284 | 285 | 286 | ================================ 287 | [192.168.0.103 FAILURE] 0 seconds 288 | SUCCESS: 0, FAILURE: 1 289 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 290 | [192.168.0.103] 291 | [192.168.0.103] SUCCESS 292 | 293 | 294 | ================================ 295 | [192.168.0.103 SUCCESS] 0 seconds 296 | SUCCESS: 1, FAILURE: 0 297 | 298 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 299 | [192.168.0.103] 300 | [192.168.0.103] SUCCESS 301 | 302 | 303 | ================================ 304 | [192.168.0.103 SUCCESS] 0 seconds 305 | SUCCESS: 1, FAILURE: 0 306 | 307 | mooon_upload -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 308 | [192.168.0.103] 309 | [192.168.0.103] SUCCESS: 59295 bytes (redis.conf) 310 | 311 | 312 | ================================ 313 | [192.168.0.103 SUCCESS] 0 seconds (redis.conf) 314 | SUCCESS: 1, FAILURE: 0 315 | 316 | mooon_upload -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 317 | [192.168.0.103] 318 | [192.168.0.103] SUCCESS: 5775666 bytes (redis-server) 319 | 320 | [192.168.0.103] 321 | [192.168.0.103] SUCCESS: 2617471 bytes (redis-cli) 322 | 323 | [192.168.0.103] 324 | [192.168.0.103] SUCCESS: 5775666 bytes (redis-check-aof) 325 | 326 | [192.168.0.103] 327 | [192.168.0.103] SUCCESS: 5775666 bytes (redis-check-rdb) 328 | 329 | [192.168.0.103] 330 | [192.168.0.103] SUCCESS: 65991 bytes (redis-trib.rb) 331 | 332 | 333 | ================================ 334 | [192.168.0.103 SUCCESS] 1 seconds (redis-server) 335 | [192.168.0.103 SUCCESS] 1 seconds (redis-cli) 336 | [192.168.0.103 SUCCESS] 1 seconds (redis-check-aof) 337 | [192.168.0.103 SUCCESS] 1 seconds (redis-check-rdb) 338 | [192.168.0.103 SUCCESS] 0 seconds (redis-trib.rb) 339 | SUCCESS: 5, FAILURE: 0 340 | [192.168.0.102] Installing common ... 341 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 342 | [192.168.0.102] 343 | [192.168.0.102] SUCCESS 344 | 345 | 346 | ================================ 347 | [192.168.0.102 SUCCESS] 0 seconds 348 | SUCCESS: 1, FAILURE: 0 349 | 350 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 351 | [192.168.0.102] 352 | command return 1 353 | 354 | 355 | ================================ 356 | [192.168.0.102 FAILURE] 0 seconds 357 | SUCCESS: 0, FAILURE: 1 358 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 359 | [192.168.0.102] 360 | [192.168.0.102] SUCCESS 361 | 362 | 363 | ================================ 364 | [192.168.0.102 SUCCESS] 0 seconds 365 | SUCCESS: 1, FAILURE: 0 366 | 367 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 368 | [192.168.0.102] 369 | [192.168.0.102] SUCCESS 370 | 371 | 372 | ================================ 373 | [192.168.0.102 SUCCESS] 0 seconds 374 | SUCCESS: 1, FAILURE: 0 375 | 376 | mooon_upload -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 377 | [192.168.0.102] 378 | [192.168.0.102] SUCCESS: 59295 bytes (redis.conf) 379 | 380 | 381 | ================================ 382 | [192.168.0.102 SUCCESS] 0 seconds (redis.conf) 383 | SUCCESS: 1, FAILURE: 0 384 | 385 | mooon_upload -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 386 | [192.168.0.102] 387 | [192.168.0.102] SUCCESS: 5775666 bytes (redis-server) 388 | 389 | [192.168.0.102] 390 | [192.168.0.102] SUCCESS: 2617471 bytes (redis-cli) 391 | 392 | [192.168.0.102] 393 | [192.168.0.102] SUCCESS: 5775666 bytes (redis-check-aof) 394 | 395 | [192.168.0.102] 396 | [192.168.0.102] SUCCESS: 5775666 bytes (redis-check-rdb) 397 | 398 | [192.168.0.102] 399 | [192.168.0.102] SUCCESS: 65991 bytes (redis-trib.rb) 400 | 401 | 402 | ================================ 403 | [192.168.0.102 SUCCESS] 1 seconds (redis-server) 404 | [192.168.0.102 SUCCESS] 1 seconds (redis-cli) 405 | [192.168.0.102 SUCCESS] 1 seconds (redis-check-aof) 406 | [192.168.0.102 SUCCESS] 1 seconds (redis-check-rdb) 407 | [192.168.0.102 SUCCESS] 0 seconds (redis-trib.rb) 408 | SUCCESS: 5, FAILURE: 0 409 | [192.168.0.107] Installing common ... 410 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 411 | [192.168.0.107] 412 | [192.168.0.107] SUCCESS 413 | 414 | 415 | ================================ 416 | [192.168.0.107 SUCCESS] 0 seconds 417 | SUCCESS: 1, FAILURE: 0 418 | 419 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 420 | [192.168.0.107] 421 | command return 1 422 | 423 | 424 | ================================ 425 | [192.168.0.107 FAILURE] 0 seconds 426 | SUCCESS: 0, FAILURE: 1 427 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 428 | [192.168.0.107] 429 | [192.168.0.107] SUCCESS 430 | 431 | 432 | ================================ 433 | [192.168.0.107 SUCCESS] 0 seconds 434 | SUCCESS: 1, FAILURE: 0 435 | 436 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 437 | [192.168.0.107] 438 | [192.168.0.107] SUCCESS 439 | 440 | 441 | ================================ 442 | [192.168.0.107 SUCCESS] 0 seconds 443 | SUCCESS: 1, FAILURE: 0 444 | 445 | mooon_upload -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 446 | [192.168.0.107] 447 | [192.168.0.107] SUCCESS: 59295 bytes (redis.conf) 448 | 449 | 450 | ================================ 451 | [192.168.0.107 SUCCESS] 0 seconds (redis.conf) 452 | SUCCESS: 1, FAILURE: 0 453 | 454 | mooon_upload -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 455 | [192.168.0.107] 456 | [192.168.0.107] SUCCESS: 5775666 bytes (redis-server) 457 | 458 | [192.168.0.107] 459 | [192.168.0.107] SUCCESS: 2617471 bytes (redis-cli) 460 | 461 | [192.168.0.107] 462 | [192.168.0.107] SUCCESS: 5775666 bytes (redis-check-aof) 463 | 464 | [192.168.0.107] 465 | [192.168.0.107] SUCCESS: 5775666 bytes (redis-check-rdb) 466 | 467 | [192.168.0.107] 468 | [192.168.0.107] SUCCESS: 65991 bytes (redis-trib.rb) 469 | 470 | 471 | ================================ 472 | [192.168.0.107 SUCCESS] 1 seconds (redis-server) 473 | [192.168.0.107 SUCCESS] 1 seconds (redis-cli) 474 | [192.168.0.107 SUCCESS] 1 seconds (redis-check-aof) 475 | [192.168.0.107 SUCCESS] 1 seconds (redis-check-rdb) 476 | [192.168.0.107 SUCCESS] 0 seconds (redis-trib.rb) 477 | SUCCESS: 5, FAILURE: 0 478 | [192.168.0.108] Installing common ... 479 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 480 | [192.168.0.108] 481 | [192.168.0.108] SUCCESS 482 | 483 | 484 | ================================ 485 | [192.168.0.108 SUCCESS] 0 seconds 486 | SUCCESS: 1, FAILURE: 0 487 | 488 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 489 | [192.168.0.108] 490 | command return 1 491 | 492 | 493 | ================================ 494 | [192.168.0.108 FAILURE] 0 seconds 495 | SUCCESS: 0, FAILURE: 1 496 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 497 | [192.168.0.108] 498 | [192.168.0.108] SUCCESS 499 | 500 | 501 | ================================ 502 | [192.168.0.108 SUCCESS] 0 seconds 503 | SUCCESS: 1, FAILURE: 0 504 | 505 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 506 | [192.168.0.108] 507 | [192.168.0.108] SUCCESS 508 | 509 | 510 | ================================ 511 | [192.168.0.108 SUCCESS] 0 seconds 512 | SUCCESS: 1, FAILURE: 0 513 | 514 | mooon_upload -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 515 | [192.168.0.108] 516 | [192.168.0.108] SUCCESS: 59295 bytes (redis.conf) 517 | 518 | 519 | ================================ 520 | [192.168.0.108 SUCCESS] 0 seconds (redis.conf) 521 | SUCCESS: 1, FAILURE: 0 522 | 523 | mooon_upload -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 524 | [192.168.0.108] 525 | [192.168.0.108] SUCCESS: 5775666 bytes (redis-server) 526 | 527 | [192.168.0.108] 528 | [192.168.0.108] SUCCESS: 2617471 bytes (redis-cli) 529 | 530 | [192.168.0.108] 531 | [192.168.0.108] SUCCESS: 5775666 bytes (redis-check-aof) 532 | 533 | [192.168.0.108] 534 | [192.168.0.108] SUCCESS: 5775666 bytes (redis-check-rdb) 535 | 536 | [192.168.0.108] 537 | [192.168.0.108] SUCCESS: 65991 bytes (redis-trib.rb) 538 | 539 | 540 | ================================ 541 | [192.168.0.108 SUCCESS] 1 seconds (redis-server) 542 | [192.168.0.108 SUCCESS] 1 seconds (redis-cli) 543 | [192.168.0.108 SUCCESS] 1 seconds (redis-check-aof) 544 | [192.168.0.108 SUCCESS] 1 seconds (redis-check-rdb) 545 | [192.168.0.108 SUCCESS] 0 seconds (redis-trib.rb) 546 | SUCCESS: 5, FAILURE: 0 547 | [192.168.0.105] Installing common ... 548 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 549 | [192.168.0.105] 550 | [192.168.0.105] SUCCESS 551 | 552 | 553 | ================================ 554 | [192.168.0.105 SUCCESS] 0 seconds 555 | SUCCESS: 1, FAILURE: 0 556 | 557 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 558 | [192.168.0.105] 559 | command return 1 560 | 561 | 562 | ================================ 563 | [192.168.0.105 FAILURE] 0 seconds 564 | SUCCESS: 0, FAILURE: 1 565 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 566 | [192.168.0.105] 567 | [192.168.0.105] SUCCESS 568 | 569 | 570 | ================================ 571 | [192.168.0.105 SUCCESS] 0 seconds 572 | SUCCESS: 1, FAILURE: 0 573 | 574 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 575 | [192.168.0.105] 576 | [192.168.0.105] SUCCESS 577 | 578 | 579 | ================================ 580 | [192.168.0.105 SUCCESS] 0 seconds 581 | SUCCESS: 1, FAILURE: 0 582 | 583 | mooon_upload -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 584 | [192.168.0.105] 585 | [192.168.0.105] SUCCESS: 59295 bytes (redis.conf) 586 | 587 | 588 | ================================ 589 | [192.168.0.105 SUCCESS] 0 seconds (redis.conf) 590 | SUCCESS: 1, FAILURE: 0 591 | 592 | mooon_upload -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 593 | [192.168.0.105] 594 | [192.168.0.105] SUCCESS: 5775666 bytes (redis-server) 595 | 596 | [192.168.0.105] 597 | [192.168.0.105] SUCCESS: 2617471 bytes (redis-cli) 598 | 599 | [192.168.0.105] 600 | [192.168.0.105] SUCCESS: 5775666 bytes (redis-check-aof) 601 | 602 | [192.168.0.105] 603 | [192.168.0.105] SUCCESS: 5775666 bytes (redis-check-rdb) 604 | 605 | [192.168.0.105] 606 | [192.168.0.105] SUCCESS: 65991 bytes (redis-trib.rb) 607 | 608 | 609 | ================================ 610 | [192.168.0.105 SUCCESS] 1 seconds (redis-server) 611 | [192.168.0.105 SUCCESS] 1 seconds (redis-cli) 612 | [192.168.0.105 SUCCESS] 1 seconds (redis-check-aof) 613 | [192.168.0.105 SUCCESS] 1 seconds (redis-check-rdb) 614 | [192.168.0.105 SUCCESS] 0 seconds (redis-trib.rb) 615 | SUCCESS: 5, FAILURE: 0 616 | [192.168.0.109] Installing common ... 617 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="test -d /usr/local/redis-4.0.11 && test -r /usr/local/redis-4.0.11 && test -w /usr/local/redis-4.0.11 && test -x /usr/local/redis-4.0.11" 618 | [192.168.0.109] 619 | [192.168.0.109] SUCCESS 620 | 621 | 622 | ================================ 623 | [192.168.0.109 SUCCESS] 0 seconds 624 | SUCCESS: 1, FAILURE: 0 625 | 626 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="killall -q -w -u redis redis-server" 627 | [192.168.0.109] 628 | command return 1 629 | 630 | 631 | ================================ 632 | [192.168.0.109 FAILURE] 0 seconds 633 | SUCCESS: 0, FAILURE: 1 634 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="rm -fr /usr/local/redis-4.0.11/*" 635 | [192.168.0.109] 636 | [192.168.0.109] SUCCESS 637 | 638 | 639 | ================================ 640 | [192.168.0.109 SUCCESS] 0 seconds 641 | SUCCESS: 1, FAILURE: 0 642 | 643 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p bin conf log data" 644 | [192.168.0.109] 645 | [192.168.0.109] SUCCESS 646 | 647 | 648 | ================================ 649 | [192.168.0.109 SUCCESS] 0 seconds 650 | SUCCESS: 1, FAILURE: 0 651 | 652 | mooon_upload -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -s=redis.conf -d=/usr/local/redis-4.0.11/conf 653 | [192.168.0.109] 654 | [192.168.0.109] SUCCESS: 59295 bytes (redis.conf) 655 | 656 | 657 | ================================ 658 | [192.168.0.109 SUCCESS] 0 seconds (redis.conf) 659 | SUCCESS: 1, FAILURE: 0 660 | 661 | mooon_upload -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -s=redis-server,redis-cli,redis-check-aof,redis-check-rdb -d=/usr/local/redis-4.0.11/bin 662 | [192.168.0.109] 663 | [192.168.0.109] SUCCESS: 5775666 bytes (redis-server) 664 | 665 | [192.168.0.109] 666 | [192.168.0.109] SUCCESS: 2617471 bytes (redis-cli) 667 | 668 | [192.168.0.109] 669 | [192.168.0.109] SUCCESS: 5775666 bytes (redis-check-aof) 670 | 671 | [192.168.0.109] 672 | [192.168.0.109] SUCCESS: 5775666 bytes (redis-check-rdb) 673 | 674 | [192.168.0.109] 675 | [192.168.0.109] SUCCESS: 65991 bytes (redis-trib.rb) 676 | 677 | 678 | ================================ 679 | [192.168.0.109 SUCCESS] 1 seconds (redis-server) 680 | [192.168.0.109 SUCCESS] 1 seconds (redis-cli) 681 | [192.168.0.109 SUCCESS] 1 seconds (redis-check-aof) 682 | [192.168.0.109 SUCCESS] 1 seconds (redis-check-rdb) 683 | [192.168.0.109 SUCCESS] 0 seconds (redis-trib.rb) 684 | SUCCESS: 5, FAILURE: 0 685 | 686 | ================================ 687 | [192.168.0.106:6379] Installing node ... 688 | 689 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 690 | [192.168.0.106] 691 | [192.168.0.106] SUCCESS 692 | 693 | 694 | ================================ 695 | [192.168.0.106 SUCCESS] 0 seconds 696 | SUCCESS: 1, FAILURE: 0 697 | 698 | mooon_upload -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 699 | [192.168.0.106] 700 | [192.168.0.106] SUCCESS: 59018 bytes (redis-6379.conf) 701 | 702 | 703 | ================================ 704 | [192.168.0.106 SUCCESS] 0 seconds (redis-6379.conf) 705 | SUCCESS: 1, FAILURE: 0 706 | [192.168.0.106:6380] Installing node ... 707 | 708 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 709 | [192.168.0.106] 710 | [192.168.0.106] SUCCESS 711 | 712 | 713 | ================================ 714 | [192.168.0.106 SUCCESS] 0 seconds 715 | SUCCESS: 1, FAILURE: 0 716 | 717 | mooon_upload -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 718 | [192.168.0.106] 719 | [192.168.0.106] SUCCESS: 59018 bytes (redis-6380.conf) 720 | 721 | 722 | ================================ 723 | [192.168.0.106 SUCCESS] 0 seconds (redis-6380.conf) 724 | SUCCESS: 1, FAILURE: 0 725 | [192.168.0.101:6379] Installing node ... 726 | 727 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 728 | [192.168.0.101] 729 | [192.168.0.101] SUCCESS 730 | 731 | 732 | ================================ 733 | [192.168.0.101 SUCCESS] 0 seconds 734 | SUCCESS: 1, FAILURE: 0 735 | 736 | mooon_upload -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 737 | [192.168.0.101] 738 | [192.168.0.101] SUCCESS: 59018 bytes (redis-6379.conf) 739 | 740 | 741 | ================================ 742 | [192.168.0.101 SUCCESS] 0 seconds (redis-6379.conf) 743 | SUCCESS: 1, FAILURE: 0 744 | [192.168.0.101:6380] Installing node ... 745 | 746 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 747 | [192.168.0.101] 748 | [192.168.0.101] SUCCESS 749 | 750 | 751 | ================================ 752 | [192.168.0.101 SUCCESS] 0 seconds 753 | SUCCESS: 1, FAILURE: 0 754 | 755 | mooon_upload -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 756 | [192.168.0.101] 757 | [192.168.0.101] SUCCESS: 59018 bytes (redis-6380.conf) 758 | 759 | 760 | ================================ 761 | [192.168.0.101 SUCCESS] 0 seconds (redis-6380.conf) 762 | SUCCESS: 1, FAILURE: 0 763 | [192.168.0.104:6379] Installing node ... 764 | 765 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 766 | [192.168.0.104] 767 | [192.168.0.104] SUCCESS 768 | 769 | 770 | ================================ 771 | [192.168.0.104 SUCCESS] 0 seconds 772 | SUCCESS: 1, FAILURE: 0 773 | 774 | mooon_upload -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 775 | [192.168.0.104] 776 | [192.168.0.104] SUCCESS: 59018 bytes (redis-6379.conf) 777 | 778 | 779 | ================================ 780 | [192.168.0.104 SUCCESS] 0 seconds (redis-6379.conf) 781 | SUCCESS: 1, FAILURE: 0 782 | [192.168.0.104:6380] Installing node ... 783 | 784 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 785 | [192.168.0.104] 786 | [192.168.0.104] SUCCESS 787 | 788 | 789 | ================================ 790 | [192.168.0.104 SUCCESS] 0 seconds 791 | SUCCESS: 1, FAILURE: 0 792 | 793 | mooon_upload -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 794 | [192.168.0.104] 795 | [192.168.0.104] SUCCESS: 59018 bytes (redis-6380.conf) 796 | 797 | 798 | ================================ 799 | [192.168.0.104 SUCCESS] 0 seconds (redis-6380.conf) 800 | SUCCESS: 1, FAILURE: 0 801 | [192.168.0.103:6379] Installing node ... 802 | 803 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 804 | [192.168.0.103] 805 | [192.168.0.103] SUCCESS 806 | 807 | 808 | ================================ 809 | [192.168.0.103 SUCCESS] 0 seconds 810 | SUCCESS: 1, FAILURE: 0 811 | 812 | mooon_upload -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 813 | [192.168.0.103] 814 | [192.168.0.103] SUCCESS: 59018 bytes (redis-6379.conf) 815 | 816 | 817 | ================================ 818 | [192.168.0.103 SUCCESS] 0 seconds (redis-6379.conf) 819 | SUCCESS: 1, FAILURE: 0 820 | [192.168.0.103:6380] Installing node ... 821 | 822 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 823 | [192.168.0.103] 824 | [192.168.0.103] SUCCESS 825 | 826 | 827 | ================================ 828 | [192.168.0.103 SUCCESS] 0 seconds 829 | SUCCESS: 1, FAILURE: 0 830 | 831 | mooon_upload -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 832 | [192.168.0.103] 833 | [192.168.0.103] SUCCESS: 59018 bytes (redis-6380.conf) 834 | 835 | 836 | ================================ 837 | [192.168.0.103 SUCCESS] 0 seconds (redis-6380.conf) 838 | SUCCESS: 1, FAILURE: 0 839 | [192.168.0.102:6379] Installing node ... 840 | 841 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 842 | [192.168.0.102] 843 | [192.168.0.102] SUCCESS 844 | 845 | 846 | ================================ 847 | [192.168.0.102 SUCCESS] 0 seconds 848 | SUCCESS: 1, FAILURE: 0 849 | 850 | mooon_upload -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 851 | [192.168.0.102] 852 | [192.168.0.102] SUCCESS: 59018 bytes (redis-6379.conf) 853 | 854 | 855 | ================================ 856 | [192.168.0.102 SUCCESS] 0 seconds (redis-6379.conf) 857 | SUCCESS: 1, FAILURE: 0 858 | [192.168.0.102:6380] Installing node ... 859 | 860 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 861 | [192.168.0.102] 862 | [192.168.0.102] SUCCESS 863 | 864 | 865 | ================================ 866 | [192.168.0.102 SUCCESS] 0 seconds 867 | SUCCESS: 1, FAILURE: 0 868 | 869 | mooon_upload -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 870 | [192.168.0.102] 871 | [192.168.0.102] SUCCESS: 59018 bytes (redis-6380.conf) 872 | 873 | 874 | ================================ 875 | [192.168.0.102 SUCCESS] 0 seconds (redis-6380.conf) 876 | SUCCESS: 1, FAILURE: 0 877 | [192.168.0.107:6379] Installing node ... 878 | 879 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 880 | [192.168.0.107] 881 | [192.168.0.107] SUCCESS 882 | 883 | 884 | ================================ 885 | [192.168.0.107 SUCCESS] 0 seconds 886 | SUCCESS: 1, FAILURE: 0 887 | 888 | mooon_upload -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 889 | [192.168.0.107] 890 | [192.168.0.107] SUCCESS: 59018 bytes (redis-6379.conf) 891 | 892 | 893 | ================================ 894 | [192.168.0.107 SUCCESS] 0 seconds (redis-6379.conf) 895 | SUCCESS: 1, FAILURE: 0 896 | [192.168.0.107:6380] Installing node ... 897 | 898 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 899 | [192.168.0.107] 900 | [192.168.0.107] SUCCESS 901 | 902 | 903 | ================================ 904 | [192.168.0.107 SUCCESS] 0 seconds 905 | SUCCESS: 1, FAILURE: 0 906 | 907 | mooon_upload -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 908 | [192.168.0.107] 909 | [192.168.0.107] SUCCESS: 59018 bytes (redis-6380.conf) 910 | 911 | 912 | ================================ 913 | [192.168.0.107 SUCCESS] 0 seconds (redis-6380.conf) 914 | SUCCESS: 1, FAILURE: 0 915 | [192.168.0.108:6379] Installing node ... 916 | 917 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 918 | [192.168.0.108] 919 | [192.168.0.108] SUCCESS 920 | 921 | 922 | ================================ 923 | [192.168.0.108 SUCCESS] 0 seconds 924 | SUCCESS: 1, FAILURE: 0 925 | 926 | mooon_upload -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 927 | [192.168.0.108] 928 | [192.168.0.108] SUCCESS: 59018 bytes (redis-6379.conf) 929 | 930 | 931 | ================================ 932 | [192.168.0.108 SUCCESS] 0 seconds (redis-6379.conf) 933 | SUCCESS: 1, FAILURE: 0 934 | [192.168.0.108:6380] Installing node ... 935 | 936 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 937 | [192.168.0.108] 938 | [192.168.0.108] SUCCESS 939 | 940 | 941 | ================================ 942 | [192.168.0.108 SUCCESS] 0 seconds 943 | SUCCESS: 1, FAILURE: 0 944 | 945 | mooon_upload -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 946 | [192.168.0.108] 947 | [192.168.0.108] SUCCESS: 59018 bytes (redis-6380.conf) 948 | 949 | 950 | ================================ 951 | [192.168.0.108 SUCCESS] 0 seconds (redis-6380.conf) 952 | SUCCESS: 1, FAILURE: 0 953 | [192.168.0.105:6379] Installing node ... 954 | 955 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 956 | [192.168.0.105] 957 | [192.168.0.105] SUCCESS 958 | 959 | 960 | ================================ 961 | [192.168.0.105 SUCCESS] 0 seconds 962 | SUCCESS: 1, FAILURE: 0 963 | 964 | mooon_upload -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 965 | [192.168.0.105] 966 | [192.168.0.105] SUCCESS: 59018 bytes (redis-6379.conf) 967 | 968 | 969 | ================================ 970 | [192.168.0.105 SUCCESS] 0 seconds (redis-6379.conf) 971 | SUCCESS: 1, FAILURE: 0 972 | [192.168.0.105:6380] Installing node ... 973 | 974 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 975 | [192.168.0.105] 976 | [192.168.0.105] SUCCESS 977 | 978 | 979 | ================================ 980 | [192.168.0.105 SUCCESS] 0 seconds 981 | SUCCESS: 1, FAILURE: 0 982 | 983 | mooon_upload -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 984 | [192.168.0.105] 985 | [192.168.0.105] SUCCESS: 59018 bytes (redis-6380.conf) 986 | 987 | 988 | ================================ 989 | [192.168.0.105 SUCCESS] 0 seconds (redis-6380.conf) 990 | SUCCESS: 1, FAILURE: 0 991 | [192.168.0.109:6379] Installing node ... 992 | 993 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6379" 994 | [192.168.0.109] 995 | [192.168.0.109] SUCCESS 996 | 997 | 998 | ================================ 999 | [192.168.0.109 SUCCESS] 0 seconds 1000 | SUCCESS: 1, FAILURE: 0 1001 | 1002 | mooon_upload -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -s=redis-6379.conf -d=/usr/local/redis-4.0.11/conf 1003 | [192.168.0.109] 1004 | [192.168.0.109] SUCCESS: 59018 bytes (redis-6379.conf) 1005 | 1006 | 1007 | ================================ 1008 | [192.168.0.109 SUCCESS] 0 seconds (redis-6379.conf) 1009 | SUCCESS: 1, FAILURE: 0 1010 | [192.168.0.109:6380] Installing node ... 1011 | 1012 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="cd /usr/local/redis-4.0.11;mkdir -p data/6380" 1013 | [192.168.0.109] 1014 | [192.168.0.109] SUCCESS 1015 | 1016 | 1017 | ================================ 1018 | [192.168.0.109 SUCCESS] 0 seconds 1019 | SUCCESS: 1, FAILURE: 0 1020 | 1021 | mooon_upload -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -s=redis-6380.conf -d=/usr/local/redis-4.0.11/conf 1022 | [192.168.0.109] 1023 | [192.168.0.109] SUCCESS: 59018 bytes (redis-6380.conf) 1024 | 1025 | 1026 | ================================ 1027 | [192.168.0.109 SUCCESS] 0 seconds (redis-6380.conf) 1028 | SUCCESS: 1, FAILURE: 0 1029 | 1030 | ================================ 1031 | Start redis? [yes/no] yes 1032 | Starting to start redis ... 1033 | 1034 | [192.168.0.106:6379] Starting node ... 1035 | 1036 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1037 | [192.168.0.106] 1038 | [192.168.0.106] SUCCESS 1039 | 1040 | 1041 | ================================ 1042 | [192.168.0.106 SUCCESS] 0 seconds 1043 | SUCCESS: 1, FAILURE: 0 1044 | [192.168.0.106:6380] Starting node ... 1045 | 1046 | mooon_ssh -h=192.168.0.106 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1047 | [192.168.0.106] 1048 | [192.168.0.106] SUCCESS 1049 | 1050 | 1051 | ================================ 1052 | [192.168.0.106 SUCCESS] 0 seconds 1053 | SUCCESS: 1, FAILURE: 0 1054 | [192.168.0.101:6379] Starting node ... 1055 | 1056 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1057 | [192.168.0.101] 1058 | [192.168.0.101] SUCCESS 1059 | 1060 | 1061 | ================================ 1062 | [192.168.0.101 SUCCESS] 0 seconds 1063 | SUCCESS: 1, FAILURE: 0 1064 | [192.168.0.101:6380] Starting node ... 1065 | 1066 | mooon_ssh -h=192.168.0.101 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1067 | [192.168.0.101] 1068 | [192.168.0.101] SUCCESS 1069 | 1070 | 1071 | ================================ 1072 | [192.168.0.101 SUCCESS] 0 seconds 1073 | SUCCESS: 1, FAILURE: 0 1074 | [192.168.0.104:6379] Starting node ... 1075 | 1076 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1077 | [192.168.0.104] 1078 | [192.168.0.104] SUCCESS 1079 | 1080 | 1081 | ================================ 1082 | [192.168.0.104 SUCCESS] 0 seconds 1083 | SUCCESS: 1, FAILURE: 0 1084 | [192.168.0.104:6380] Starting node ... 1085 | 1086 | mooon_ssh -h=192.168.0.104 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1087 | [192.168.0.104] 1088 | [192.168.0.104] SUCCESS 1089 | 1090 | 1091 | ================================ 1092 | [192.168.0.104 SUCCESS] 0 seconds 1093 | SUCCESS: 1, FAILURE: 0 1094 | [192.168.0.103:6379] Starting node ... 1095 | 1096 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1097 | [192.168.0.103] 1098 | [192.168.0.103] SUCCESS 1099 | 1100 | 1101 | ================================ 1102 | [192.168.0.103 SUCCESS] 0 seconds 1103 | SUCCESS: 1, FAILURE: 0 1104 | [192.168.0.103:6380] Starting node ... 1105 | 1106 | mooon_ssh -h=192.168.0.103 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1107 | [192.168.0.103] 1108 | [192.168.0.103] SUCCESS 1109 | 1110 | 1111 | ================================ 1112 | [192.168.0.103 SUCCESS] 0 seconds 1113 | SUCCESS: 1, FAILURE: 0 1114 | [192.168.0.102:6379] Starting node ... 1115 | 1116 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1117 | [192.168.0.102] 1118 | [192.168.0.102] SUCCESS 1119 | 1120 | 1121 | ================================ 1122 | [192.168.0.102 SUCCESS] 0 seconds 1123 | SUCCESS: 1, FAILURE: 0 1124 | [192.168.0.102:6380] Starting node ... 1125 | 1126 | mooon_ssh -h=192.168.0.102 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1127 | [192.168.0.102] 1128 | [192.168.0.102] SUCCESS 1129 | 1130 | 1131 | ================================ 1132 | [192.168.0.102 SUCCESS] 0 seconds 1133 | SUCCESS: 1, FAILURE: 0 1134 | [192.168.0.107:6379] Starting node ... 1135 | 1136 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1137 | [192.168.0.107] 1138 | [192.168.0.107] SUCCESS 1139 | 1140 | 1141 | ================================ 1142 | [192.168.0.107 SUCCESS] 0 seconds 1143 | SUCCESS: 1, FAILURE: 0 1144 | [192.168.0.107:6380] Starting node ... 1145 | 1146 | mooon_ssh -h=192.168.0.107 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1147 | [192.168.0.107] 1148 | [192.168.0.107] SUCCESS 1149 | 1150 | 1151 | ================================ 1152 | [192.168.0.107 SUCCESS] 0 seconds 1153 | SUCCESS: 1, FAILURE: 0 1154 | [192.168.0.108:6379] Starting node ... 1155 | 1156 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1157 | [192.168.0.108] 1158 | [192.168.0.108] SUCCESS 1159 | 1160 | 1161 | ================================ 1162 | [192.168.0.108 SUCCESS] 0 seconds 1163 | SUCCESS: 1, FAILURE: 0 1164 | [192.168.0.108:6380] Starting node ... 1165 | 1166 | mooon_ssh -h=192.168.0.108 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1167 | [192.168.0.108] 1168 | [192.168.0.108] SUCCESS 1169 | 1170 | 1171 | ================================ 1172 | [192.168.0.108 SUCCESS] 0 seconds 1173 | SUCCESS: 1, FAILURE: 0 1174 | [192.168.0.105:6379] Starting node ... 1175 | 1176 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1177 | [192.168.0.105] 1178 | [192.168.0.105] SUCCESS 1179 | 1180 | 1181 | ================================ 1182 | [192.168.0.105 SUCCESS] 0 seconds 1183 | SUCCESS: 1, FAILURE: 0 1184 | [192.168.0.105:6380] Starting node ... 1185 | 1186 | mooon_ssh -h=192.168.0.105 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1187 | [192.168.0.105] 1188 | [192.168.0.105] SUCCESS 1189 | 1190 | 1191 | ================================ 1192 | [192.168.0.105 SUCCESS] 0 seconds 1193 | SUCCESS: 1, FAILURE: 0 1194 | [192.168.0.109:6379] Starting node ... 1195 | 1196 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6379.conf" 1197 | [192.168.0.109] 1198 | [192.168.0.109] SUCCESS 1199 | 1200 | 1201 | ================================ 1202 | [192.168.0.109 SUCCESS] 0 seconds 1203 | SUCCESS: 1, FAILURE: 0 1204 | [192.168.0.109:6380] Starting node ... 1205 | 1206 | mooon_ssh -h=192.168.0.109 -P=22 -u=redis -p=redis^1234 -c="/usr/local/redis-4.0.11/bin/redis-server /usr/local/redis-4.0.11/conf/redis-6380.conf" 1207 | [192.168.0.109] 1208 | [192.168.0.109] SUCCESS 1209 | 1210 | 1211 | ================================ 1212 | [192.168.0.109 SUCCESS] 0 seconds 1213 | SUCCESS: 1, FAILURE: 0 1214 | 1215 | ================================ 1216 | Number of nodes: 18 1217 | 1218 | Create redis cluster? [yes/no] yes 1219 | Starting to create redis cluster with 192.168.0.101:6379 192.168.0.102:6379 192.168.0.103:6379 192.168.0.104:6379 192.168.0.105:6379 192.168.0.106:6379 192.168.0.107:6379 192.168.0.108:6379 192.168.0.109:6379 192.168.0.101:6380 192.168.0.102:6380 192.168.0.103:6380 192.168.0.104:6380 192.168.0.105:6380 192.168.0.106:6380 192.168.0.107:6380 192.168.0.108:6380 192.168.0.109:6380 ... ... 1220 | 1221 | >>> Creating cluster 1222 | >>> Performing hash slots allocation on 18 nodes... 1223 | Using 9 masters: 1224 | 192.168.0.101:6379 1225 | 192.168.0.102:6379 1226 | 192.168.0.103:6379 1227 | 192.168.0.104:6379 1228 | 192.168.0.105:6379 1229 | 192.168.0.106:6379 1230 | 192.168.0.107:6379 1231 | 192.168.0.108:6379 1232 | 192.168.0.109:6379 1233 | Adding replica 192.168.0.102:6380 to 192.168.0.101:6379 1234 | Adding replica 192.168.0.103:6380 to 192.168.0.102:6379 1235 | Adding replica 192.168.0.104:6380 to 192.168.0.103:6379 1236 | Adding replica 192.168.0.105:6380 to 192.168.0.104:6379 1237 | Adding replica 192.168.0.106:6380 to 192.168.0.105:6379 1238 | Adding replica 192.168.0.107:6380 to 192.168.0.106:6379 1239 | Adding replica 192.168.0.108:6380 to 192.168.0.107:6379 1240 | Adding replica 192.168.0.109:6380 to 192.168.0.108:6379 1241 | Adding replica 192.168.0.101:6380 to 192.168.0.109:6379 1242 | M: 9630ea3f1ce15c8ab528ce1b25a349bba71b3f03 192.168.0.101:6379 1243 | slots:0-1819 (1820 slots) master 1244 | M: fb8a2915708d863172d434198c4ca4b76b0e66f2 192.168.0.102:6379 1245 | slots:1820-3640 (1821 slots) master 1246 | M: bbdd7f116995a7498f027de48f0757aae641e190 192.168.0.103:6379 1247 | slots:3641-5460 (1820 slots) master 1248 | M: 2e9d2e0feaaac18aa62d4e25b909c865d41b4351 192.168.0.104:6379 1249 | slots:5461-7281 (1821 slots) master 1250 | M: 8cf724204b6f83879c843070defa8781a110ba3c 192.168.0.105:6379 1251 | slots:7282-9101 (1820 slots) master 1252 | M: 573d06d15b3e88f9e225c33069ff5c8da48d3144 192.168.0.106:6379 1253 | slots:9102-10922 (1821 slots) master 1254 | M: 90d39d944d53de9d6680bc6d4c3ef18c182caa6c 192.168.0.107:6379 1255 | slots:10923-12742 (1820 slots) master 1256 | M: d4454a9a8738fc3b81c9947e397cef9c0e70fac1 192.168.0.108:6379 1257 | slots:12743-14563 (1821 slots) master 1258 | M: 7949cbf8e689a26a6701de87ddbb32be2d5c1897 192.168.0.109:6379 1259 | slots:14564-16383 (1820 slots) master 1260 | S: bc8dc9b184d95f3e156e223379d3ede5fb1d09af 192.168.0.101:6380 1261 | replicates 7949cbf8e689a26a6701de87ddbb32be2d5c1897 1262 | S: 8145dede5e0845bf9911cdf405dd93fdfd5de6a3 192.168.0.102:6380 1263 | replicates 9630ea3f1ce15c8ab528ce1b25a349bba71b3f03 1264 | S: 9b133a388bfac8b9fb6c295fc59c7f3679eaf9c9 192.168.0.103:6380 1265 | replicates fb8a2915708d863172d434198c4ca4b76b0e66f2 1266 | S: b558010a7b939dabcf161095a739cbda4f8e30e0 192.168.0.104:6380 1267 | replicates bbdd7f116995a7498f027de48f0757aae641e190 1268 | S: 4b0c6570552b4f33ba930967b8fcefbe65367a2f 192.168.0.105:6380 1269 | replicates 2e9d2e0feaaac18aa62d4e25b909c865d41b4351 1270 | S: 83cce7027022da7daa60493d3f8c761d8d403509 192.168.0.106:6380 1271 | replicates 8cf724204b6f83879c843070defa8781a110ba3c 1272 | S: 34725ba72bf0857d4b40eec4a2d2871d66d1f9b9 192.168.0.107:6380 1273 | replicates 573d06d15b3e88f9e225c33069ff5c8da48d3144 1274 | S: 11fb62ef8414a866217f38bcb439fbe1dd8f8ee5 192.168.0.108:6380 1275 | replicates 90d39d944d53de9d6680bc6d4c3ef18c182caa6c 1276 | S: 6bae1e9b4f8966d8d69b8652bbb7b35b889faa18 192.168.0.109:6380 1277 | replicates d4454a9a8738fc3b81c9947e397cef9c0e70fac1 1278 | Can I set the above configuration? (type 'yes' to accept): yes 1279 | >>> Nodes configuration updated 1280 | >>> Assign a different config epoch to each node 1281 | >>> Sending CLUSTER MEET messages to join the cluster 1282 | Waiting for the cluster to join.. 1283 | >>> Performing Cluster Check (using node 192.168.0.101:6379) 1284 | M: 9630ea3f1ce15c8ab528ce1b25a349bba71b3f03 192.168.0.101:6379 1285 | slots:0-1819 (1820 slots) master 1286 | 1 additional replica(s) 1287 | M: d4454a9a8738fc3b81c9947e397cef9c0e70fac1 192.168.0.108:6379 1288 | slots:12743-14563 (1821 slots) master 1289 | 1 additional replica(s) 1290 | S: b558010a7b939dabcf161095a739cbda4f8e30e0 192.168.0.104:6380 1291 | slots: (0 slots) slave 1292 | replicates bbdd7f116995a7498f027de48f0757aae641e190 1293 | S: 34725ba72bf0857d4b40eec4a2d2871d66d1f9b9 192.168.0.107:6380 1294 | slots: (0 slots) slave 1295 | replicates 573d06d15b3e88f9e225c33069ff5c8da48d3144 1296 | S: 8145dede5e0845bf9911cdf405dd93fdfd5de6a3 192.168.0.102:6380 1297 | slots: (0 slots) slave 1298 | replicates 9630ea3f1ce15c8ab528ce1b25a349bba71b3f03 1299 | M: 90d39d944d53de9d6680bc6d4c3ef18c182caa6c 192.168.0.107:6379 1300 | slots:10923-12742 (1820 slots) master 1301 | 1 additional replica(s) 1302 | M: 573d06d15b3e88f9e225c33069ff5c8da48d3144 192.168.0.106:6379 1303 | slots:9102-10922 (1821 slots) master 1304 | 1 additional replica(s) 1305 | M: 8cf724204b6f83879c843070defa8781a110ba3c 192.168.0.105:6379 1306 | slots:7282-9101 (1820 slots) master 1307 | 1 additional replica(s) 1308 | M: 7949cbf8e689a26a6701de87ddbb32be2d5c1897 192.168.0.109:6379 1309 | slots:14564-16383 (1820 slots) master 1310 | 1 additional replica(s) 1311 | S: 6bae1e9b4f8966d8d69b8652bbb7b35b889faa18 192.168.0.109:6380 1312 | slots: (0 slots) slave 1313 | replicates d4454a9a8738fc3b81c9947e397cef9c0e70fac1 1314 | S: 83cce7027022da7daa60493d3f8c761d8d403509 192.168.0.106:6380 1315 | slots: (0 slots) slave 1316 | replicates 8cf724204b6f83879c843070defa8781a110ba3c 1317 | S: 11fb62ef8414a866217f38bcb439fbe1dd8f8ee5 192.168.0.108:6380 1318 | slots: (0 slots) slave 1319 | replicates 90d39d944d53de9d6680bc6d4c3ef18c182caa6c 1320 | M: fb8a2915708d863172d434198c4ca4b76b0e66f2 192.168.0.102:6379 1321 | slots:1820-3640 (1821 slots) master 1322 | 1 additional replica(s) 1323 | M: bbdd7f116995a7498f027de48f0757aae641e190 192.168.0.103:6379 1324 | slots:3641-5460 (1820 slots) master 1325 | 1 additional replica(s) 1326 | S: 4b0c6570552b4f33ba930967b8fcefbe65367a2f 192.168.0.105:6380 1327 | slots: (0 slots) slave 1328 | replicates 2e9d2e0feaaac18aa62d4e25b909c865d41b4351 1329 | M: 2e9d2e0feaaac18aa62d4e25b909c865d41b4351 192.168.0.104:6379 1330 | slots:5461-7281 (1821 slots) master 1331 | 1 additional replica(s) 1332 | S: bc8dc9b184d95f3e156e223379d3ede5fb1d09af 192.168.0.101:6380 1333 | slots: (0 slots) slave 1334 | replicates 7949cbf8e689a26a6701de87ddbb32be2d5c1897 1335 | S: 9b133a388bfac8b9fb6c295fc59c7f3679eaf9c9 192.168.0.103:6380 1336 | slots: (0 slots) slave 1337 | replicates fb8a2915708d863172d434198c4ca4b76b0e66f2 1338 | [OK] All nodes agree about slots configuration. 1339 | >>> Check for open slots... 1340 | >>> Check slots coverage... 1341 | [OK] All 16384 slots covered. 1342 | 1343 | [zhangsan@mooon ~/redis-tools/deploy]$ -------------------------------------------------------------------------------- /deploy/deploy_redis_cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2018/8/21 (eyjian@qq.com) 3 | # 源代码:https://github.com/eyjian/redis-tools 4 | # a tool to deploy a redis cluster 5 | # 6 | # 自动化部署redis集群工具, 7 | # 远程操作即可,不需登录到Redis集群中的任何机器。 8 | # 9 | # 以root用户批量创建用户redis示例: 10 | # export H=192.168.0.5,192.168.0.6,192.168.0.7,192.168.0.8,192.168.0.9 11 | # export U=root 12 | # export P='root^1234' 13 | # mooon_ssh -c='groupadd redis; useradd -g redis -m redis; echo "redis:redis#1234"|chpasswd' 14 | # 15 | # 批量创建redis安装目录/data/redis-4.0.11,并设置owner为用户redis,用户组为redis示例: 16 | # mooon_ssh -c='mkdir /data/redis-4.0.11;ln -s /data/redis-4.0.11 /data/redis;chown redis:redis /data/redis*' 17 | # 18 | # 可使用process_monitor.sh监控redis-server进程重启: 19 | # https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh 20 | # 使用示例: 21 | # * * * * * /usr/local/bin/process_monitor.sh "/usr/local/redis/bin/redis-server 6379" "/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis-6379.conf" 22 | # * * * * * /usr/local/bin/process_monitor.sh "/usr/local/redis/bin/redis-server 6380" "/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis-6380.conf" 23 | # 可在/tmp目录找到process_monitor.sh的运行日志,当对应端口的进程不在时,5秒内即会重启对应端口的进程。 24 | # 25 | # 运行参数: 26 | # 1)参数1:SSH端口(必选参数) 27 | # 2)参数2:安装用户(必选参数) 28 | # 3)参数3:安装用户密码(必选参数) 29 | # 4)参数4:安装目录(必选参数,要求安装用户用读取权限) 30 | # 5)参数5:redis 密码(可选参数) 31 | # 32 | # 前置条件(可借助批量工具 mooon_ssh 和 mooon_upload 完成): 33 | # 1)安装用户已经创建好 34 | # 2)安装用户密码已经设置好 35 | # 3)安装目录已经创建好,并且目录的owner为安装用户 36 | # 37 | # 4)同目录下存在以下两个可执行文件: 38 | # 4.1)redis-server 39 | # 4.2)redis-cli 40 | # 41 | # 7)同目录下存在以下两个配置文件: 42 | # 7.1)redis.conf 43 | # 7.2)redis-PORT.conf 44 | # 其中redis.conf为公共配置文件, 45 | # redis-PORT.conf为指定端口的配置文件模板, 46 | # 同时,需要将redis-PORT.conf文件中的目录和端口分别使用INSTALLDIR和REDISPORT替代,示例: 47 | # include INSTALLDIR/conf/redis.conf 48 | # pidfile INSTALLDIR/bin/redis-REDISPORT.pid 49 | # logfile INSTALLDIR/log/redis-REDISPORT.log 50 | # port REDISPORT 51 | # dbfilename dump-REDISPORT.rdb 52 | # dir INSTALLDIR/data/REDISPORT 53 | # 54 | # 其中INSTALLDIR将使用参数4的值替换, 55 | # 而REDISPORT将使用redis_cluster.nodes中的端口号替代 56 | # 57 | # 配置文件redis_cluster.nodes,定义了安装redis的节点 58 | # 文件格式(以“#”打头的为注释): 59 | # 每行由IP和端口号组成,两者间可以:空格、逗号、分号、或TAB符分隔 60 | # 61 | # 依赖: 62 | # 1)mooon_ssh 远程操作多台机器批量命令工具 63 | # 2)mooon_upload 远程操作多台机器批量上传工具 64 | # 3)https://raw.githubusercontent.com/eyjian/libmooon 65 | # 4)libmooon又依赖libssh2(http://www.libssh2.org/) 66 | 67 | BASEDIR=$(dirname $(readlink -f $0)) 68 | REDIS_CLUSTER_NODES=$BASEDIR/redis_cluster.nodes 69 | 70 | # 批量命令工具 71 | MOOON_SSH=mooon_ssh 72 | # 批量上传工具 73 | MOOON_UPLOAD=mooon_upload 74 | # redis-server 75 | REDIS_SERVER=$BASEDIR/redis-server 76 | # redis-cli 77 | REDIS_CLI=$BASEDIR/redis-cli 78 | # redis.conf 79 | REDIS_CONF=$BASEDIR/redis.conf 80 | # redis-PORT.conf 81 | REDIS_PORT_CONF=$BASEDIR/redis-PORT.conf 82 | 83 | # 全局变量 84 | # 组成redis集群的总共节点数 85 | num_nodes=0 86 | # 组成redis集群的所有IP数组 87 | redis_node_ip_array=() 88 | # 组成redis集群的所有节点数组(IP+port构造一个redis节点) 89 | redis_node_array=() 90 | 91 | # 用法 92 | function usage() 93 | { 94 | echo -e "\033[1;33mUsage\033[m: `basename $0` \033[0;32;32mssh-port\033[m install-user \033[0;32;32minstall-user-password\033[m install-dir [redis-password]" 95 | echo -e "\033[1;33mExample1\033[m: `basename $0` \033[0;32;32m22\033[m redis \033[0;32;32mredis^1234\033[m /usr/local/redis" 96 | echo -e "\033[1;33mExample2\033[m: `basename $0` \033[0;32;32m22\033[m redis \033[0;32;32mredis^1234\033[m /usr/local/redis \033[0;32;32m'password123456'\033[m" 97 | } 98 | 99 | # 需要指定五个参数 100 | if test $# -lt 4 -o $# -gt 5; then 101 | usage 102 | echo "" 103 | exit 1 104 | fi 105 | 106 | ssh_port="$1" 107 | install_user="$2" 108 | install_user_password="$3" 109 | install_dir="$4" 110 | redis_password="$5" 111 | echo -e "[ssh port] \033[1;33m$ssh_port.\033[m" 112 | echo -e "[install user] \033[1;33m$install_user.\033[m" 113 | echo -e "[install directory] \033[1;33m$install_dir.\033[m" 114 | echo "" 115 | 116 | # 检查redis-cli是否可用 117 | which "$REDIS_CLI" > /dev/null 2>&1 118 | if test $? -eq 0; then 119 | echo -e "Checking $REDIS_CLI OK." 120 | else 121 | echo -e "$REDIS_CLI \033[0;32;31mnot exists or not executable.\033[m" 122 | echo -e "Exit now.\n" 123 | exit 1 124 | fi 125 | 126 | # 得到redis-cli主版本号 127 | # 如果低于5,则用REDIS_TRIB创建集群,否则直接用redis-cli创建集群 128 | redis_cli_ver=`$REDIS_CLI --version|awk -F[\ .] '{printf("%d\n",$2);}'` 129 | echo -e "redis-cli major version: \033[1;33m${redis_cli_ver}\033[m" 130 | 131 | # 不支持低于 5.0 版本的 redis-cli 132 | if test $redis_cli_ver -lt 5; then 133 | echo -e "Version of \033[0;32;31mredis-cli\033[m is lower than 5.0" 134 | exit 1 135 | fi 136 | 137 | # 检查mooon_ssh是否可用 138 | which "$MOOON_SSH" > /dev/null 2>&1 139 | if test $? -eq 0; then 140 | echo -e "Checking $MOOON_SSH OK." 141 | else 142 | echo -e "$MOOON_SSH \033[0;32;31mnot exists or not executable.\033[m" 143 | echo "There are two versions: C++ and GO:" 144 | echo "https://github.com/eyjian/libmooon/releases" 145 | echo "https://raw.githubusercontent.com/eyjian/libmooon/master/tools/mooon_ssh.cpp" 146 | echo "https://raw.githubusercontent.com/eyjian/libmooon/master/tools/mooon_ssh.go" 147 | echo -e "Exit now.\n" 148 | exit 1 149 | fi 150 | 151 | # 检查mooon_upload是否可用 152 | which "$MOOON_UPLOAD" > /dev/null 2>&1 153 | if test $? -eq 0; then 154 | echo -e "Checking $MOOON_UPLOAD OK." 155 | else 156 | echo -e "$MOOON_UPLOAD \033[0;32;31mnot exists or not executable.\033[m" 157 | echo "There are two versions: C++ and GO:" 158 | echo "https://github.com/eyjian/libmooon/releases" 159 | echo "https://raw.githubusercontent.com/eyjian/libmooon/master/tools/mooon_upload.cpp" 160 | echo "https://raw.githubusercontent.com/eyjian/libmooon/master/tools/mooon_upload.go" 161 | echo -e "Exit now.\n" 162 | exit 1 163 | fi 164 | 165 | # 检查redis-server是否可用 166 | which "$REDIS_SERVER" > /dev/null 2>&1 167 | if test $? -eq 0; then 168 | echo -e "Checking $REDIS_SERVER OK." 169 | else 170 | echo -e "$REDIS_SERVER \033[0;32;31mnot exists or not executable.\033[m" 171 | echo -e "Exit now.\n" 172 | exit 1 173 | fi 174 | 175 | # 检查redis.conf是否可用 176 | if test -r "$REDIS_CONF"; then 177 | echo -e "Checking $REDIS_CONF OK." 178 | else 179 | echo -e "$REDIS_CONF \033[0;32;31mnot exists or not readable.\033[m" 180 | echo -e "Exit now.\n" 181 | exit 1 182 | fi 183 | 184 | # 检查redis-PORT.conf是否可用 185 | if test -r "$REDIS_PORT_CONF"; then 186 | echo -e "Checking $REDIS_PORT_CONF OK." 187 | else 188 | echo -e "$REDIS_PORT_CONF \033[0;32;31mnot exists or not readable.\033[m" 189 | echo -e "Exit now.\n" 190 | exit 1 191 | fi 192 | 193 | # 解析redis_cluster.nodes文件, 194 | # 从而得到组成redis集群的所有节点。 195 | function parse_redis_cluster_nodes() 196 | { 197 | redis_nodes_str= 198 | redis_nodes_ip_str= 199 | while read line 200 | do 201 | # 删除前尾空格 202 | line=`echo "$line" | xargs` 203 | if test -z "$line" -o "$line" = "#"; then 204 | continue 205 | fi 206 | 207 | # 跳过注释 208 | begin_char=${line:0:1} 209 | if test "$begin_char" = "#"; then 210 | continue 211 | fi 212 | 213 | # 取得IP和端口 214 | eval $(echo "$line" | awk -F[\ \:,\;\t]+ '{ printf("ip=%s\nport=%s\n",$1,$2); }') 215 | 216 | # IP和端口都必须有 217 | if test ! -z "$ip" -a ! -z "$port"; then 218 | if test -z "$redis_nodes_ip_str"; then 219 | redis_nodes_ip_str=$ip 220 | else 221 | redis_nodes_ip_str="$redis_nodes_ip_str,$ip" 222 | fi 223 | 224 | if test -z "$redis_nodes_str"; then 225 | redis_nodes_str="$ip:$port" 226 | else 227 | redis_nodes_str="$redis_nodes_str,$ip:$port" 228 | fi 229 | fi 230 | done < $REDIS_CLUSTER_NODES 231 | 232 | if test -z "$redis_nodes_ip_str"; then 233 | num_nodes=0 234 | else 235 | # 得到IP数组redis_node_ip_array 236 | redis_node_ip_array=`echo "$redis_nodes_ip_str" | tr ',' '\n' | sort | uniq` 237 | 238 | # 得到节点数组redis_node_array 239 | redis_node_array=`echo "$redis_nodes_str" | tr ',' '\n' | sort | uniq` 240 | 241 | for redis_node in ${redis_node_array[@]}; 242 | do 243 | num_nodes=$((++num_nodes)) 244 | echo "$redis_node" 245 | done 246 | fi 247 | } 248 | 249 | # check redis_cluster.nodes 250 | if test ! -r $REDIS_CLUSTER_NODES; then 251 | echo -e "File $REDIS_CLUSTER_NODES \033[0;32;31mnot exits.\033[m" 252 | echo "" 253 | echo -e "\033[0;32;32mFile format\033[m (columns delimited by space, tab, comma, semicolon or colon):" 254 | echo "IP1 port1" 255 | echo "IP2 port2" 256 | echo "" 257 | echo -e "\033[0;32;32mExample\033[m:" 258 | echo "127.0.0.1 6381" 259 | echo "127.0.0.1 6382" 260 | echo "127.0.0.1 6383" 261 | echo "127.0.0.1 6384" 262 | echo "127.0.0.1 6385" 263 | echo "127.0.0.1 6386" 264 | echo -e "Exit now.\n" 265 | exit 1 266 | else 267 | echo -e "\033[0;32;32m" 268 | parse_redis_cluster_nodes 269 | echo -e "\033[m" 270 | 271 | if test $num_nodes -lt 1; then 272 | echo -e "Checking $REDIS_CLUSTER_NODES \033[0;32;32mfailed\033[m: no any node." 273 | echo -e "Exit now.\n" 274 | exit 1 275 | else 276 | echo -e "Checking $REDIS_CLUSTER_NODES OK, the number of nodes is \033[1;33m${num_nodes}\033[m." 277 | fi 278 | fi 279 | 280 | # 确认后再继续 281 | while true 282 | do 283 | # 组成一个redis集群至少需要六个节点 284 | if test $num_nodes -lt 6; then 285 | echo -e "\033[0;32;32mAt least 6 nodes are required to create a redis cluster.\033[m" 286 | fi 287 | 288 | # 提示是否继续 289 | echo -en "Are you sure to continue? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 290 | read -r -p " " input 291 | 292 | if test "$input" = "no"; then 293 | echo -e "Exit now.\n" 294 | exit 1 295 | elif test "$input" = "yes"; then 296 | echo "Starting to install ..." 297 | echo "" 298 | break 299 | fi 300 | done 301 | 302 | # 安装公共的,包括可执行程序文件和公共配置文件 303 | # 两个参数: 304 | # 1)参数1:目标Redis的IP 305 | # 2)参数2:是否清空安装目录(值为yes表示清空,否则不清空) 306 | function install_common() 307 | { 308 | redis_ip="$1" 309 | clear_install_directory="$2" 310 | 311 | # 自动创建安装目录 312 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="if test ! -d $install_dir; then mkdir -p $install_dir; fi" 313 | 314 | # 检查安装目录是否存在,且有读写权限 315 | echo "$MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c=\"test -d $install_dir && test -r $install_dir && test -w $install_dir && test -x $install_dir\"" 316 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="test -d $install_dir && test -r $install_dir && test -w $install_dir && test -x $install_dir" 317 | if test $? -ne 0; then 318 | echo "" 319 | echo -e "Directory $install_dir \033[1;33mnot exists or no (rwx) permission\033[m, or \033[1;33mcan not login $redis_ip:$ssh_port by $install_user.\033[m" 320 | echo -e "Exit now.\n" 321 | exit 1 322 | fi 323 | 324 | # 清空安装目录 325 | if test "$clear_install_directory" = "yes"; then 326 | echo "" 327 | echo "$MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c=\"killall -q -w -u $install_user redis-server\"" 328 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c="killall -q -w -u $install_user redis-server" 329 | 330 | echo "$MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c=\"rm -fr $install_dir/*\"" 331 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="rm -fr $install_dir/*" 332 | if test $? -ne 0; then 333 | echo -e "Exit now.\n" 334 | exit 1 335 | fi 336 | fi 337 | 338 | # 创建公共目录(create directory) 339 | echo "" 340 | echo "$MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c=\"cd $install_dir;mkdir -p bin conf log data\"" 341 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="cd $install_dir;mkdir -p bin conf log data" 342 | if test $? -ne 0; then 343 | echo -e "Exit now.\n" 344 | exit 1 345 | fi 346 | 347 | # 上传公共配置文件(upload configuration files) 348 | echo "" 349 | echo "$MOOON_UPLOAD -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -s=redis.conf -d=$install_dir/conf" 350 | $MOOON_UPLOAD -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -s=redis.conf -d=$install_dir/conf 351 | if test $? -ne 0; then 352 | echo -e "Exit now.\n" 353 | exit 1 354 | fi 355 | 356 | # 上传公共执行文件(upload executable files) 357 | echo "" 358 | echo "$MOOON_UPLOAD -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -s=redis-server,redis-cli -d=$install_dir/bin" 359 | $MOOON_UPLOAD -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -s=redis-server,redis-cli -d=$install_dir/bin 360 | if test $? -ne 0; then 361 | echo -e "Exit now.\n" 362 | exit 1 363 | fi 364 | } 365 | 366 | # 安装节点配置文件 367 | function install_node_conf() 368 | { 369 | redis_ip="$1" 370 | redis_port="$2" 371 | 372 | # 生成节点配置文件 373 | cp redis-PORT.conf redis-$redis_port.conf 374 | sed -i "s|INSTALLDIR|$install_dir|g;s|REDISPORT|$redis_port|g" redis-$redis_port.conf 375 | 376 | # 创建节点数据目录(create data directory for the given node) 377 | echo "" 378 | echo "$MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c=\"cd $install_dir;mkdir -p data/$redis_port\"" 379 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="cd $install_dir;mkdir -p data/$redis_port" 380 | if test $? -ne 0; then 381 | rm -f redis-$redis_port.conf 382 | echo -e "Exit now.\n" 383 | exit 1 384 | fi 385 | 386 | # 上传节点配置文件(upload configuration files) 387 | echo "" 388 | echo "$MOOON_UPLOAD -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -s=redis-$redis_port.conf -d=$install_dir/conf" 389 | $MOOON_UPLOAD -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -s=redis-$redis_port.conf -d=$install_dir/conf 390 | if test $? -ne 0; then 391 | rm -f redis-$redis_port.conf 392 | echo -e "Exit now.\n" 393 | exit 1 394 | fi 395 | 396 | rm -f redis-$redis_port.conf 397 | } 398 | 399 | function start_redis_node() 400 | { 401 | redis_ip="$1" 402 | redis_port="$2" 403 | 404 | # 启动redis实例(start redis instance) 405 | echo "" 406 | echo "$MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p=\"$install_user_password\" -c=\"$install_dir/bin/redis-server $install_dir/conf/redis-$redis_port.conf\"" 407 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="nohup $install_dir/bin/redis-server $install_dir/conf/redis-$redis_port.conf > /dev/null 2>&1 &" 408 | if test $? -ne 0; then 409 | echo -e "Exit now.\n" 410 | exit 1 411 | fi 412 | } 413 | 414 | # 检查所有节点是否权限正常 415 | echo -e "\033[1;33m================================\033[m" 416 | echo -e "Press \033[1;33mENTER\033[m key to check login permissions by user '$install_user'." 417 | read -r -p "" 418 | for redis_node_ip in $redis_node_ip_array; 419 | do 420 | redis_ip=$redis_node_ip 421 | $MOOON_SSH -h=$redis_ip -P=$ssh_port -u=$install_user -p="$install_user_password" -c="whoami" 422 | if test $? -ne 0; then 423 | echo -e "No permissions in \033[0;32;31m$redis_ip\033[m." 424 | echo -e "Exit now.\n" 425 | exit 1 426 | else 427 | echo -e "Checked $redis_ip \033[1;33mok\033[m." 428 | echo "" 429 | fi 430 | done 431 | 432 | # 询问是否安装公共 433 | echo "" 434 | echo -e "\033[1;33m================================\033[m" 435 | echo -en "Install common (files & directories etc.)? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 436 | read -r -p " " to_install_common 437 | if test "X$to_install_common" = "Xyes"; then 438 | # 是否先清空安装目录再安装? 439 | echo -en "Clear install directory? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 440 | read -r -p " " clear_install_directory 441 | 442 | # 安装公共的,包括可执行程序文件和公共配置文件 443 | for redis_node_ip in $redis_node_ip_array; 444 | do 445 | echo -e "[\033[1;33m$redis_node_ip\033[m] Installing common ..." 446 | install_common "$redis_node_ip" "$clear_install_directory" 447 | done 448 | fi 449 | 450 | # 安装节点配置文件 451 | echo "" 452 | echo -e "\033[1;33m================================\033[m" 453 | for redis_node in ${redis_node_array[@]}; 454 | do 455 | node_ip= 456 | node_port= 457 | 458 | eval $(echo "$redis_node" | awk -F[\ \:,\;\t]+ '{ printf("node_ip=%s\nnode_port=%s\n",$1,$2); }') 459 | if test -z "$node_ip" -o -z "$node_port"; then 460 | continue 461 | fi 462 | 463 | echo -e "[\033[1;33m$node_ip:$node_port\033[m] Installing node ..." 464 | install_node_conf $node_ip $node_port 465 | done 466 | 467 | # 确认后再继续 468 | echo "" 469 | echo -e "\033[1;33m================================\033[m" 470 | while true 471 | do 472 | echo -en "Start redis-server? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 473 | read -r -p " " input 474 | 475 | if test "$input" = "no"; then 476 | echo "" 477 | exit 1 478 | elif test "$input" = "yes"; then 479 | echo "Starting to start redis ..." 480 | echo "" 481 | break 482 | fi 483 | done 484 | 485 | # 启动 redis-server 实例(start redis-server process) 486 | for redis_node in ${redis_node_array[@]}; 487 | do 488 | eval $(echo "$redis_node" | awk -F[\ \:,\;\t]+ '{ printf("node_ip=%s\nnode_port=%s\n",$1,$2); }') 489 | if test -z "$node_ip" -o -z "$node_port"; then 490 | continue 491 | fi 492 | 493 | echo -e "[\033[1;33m$node_ip:$node_port\033[m] Starting node ..." 494 | start_redis_node $node_ip $node_port 495 | done 496 | 497 | echo "" 498 | echo -e "\033[1;33m================================\033[m" 499 | echo "Number of nodes: $num_nodes" 500 | if test $num_nodes -lt 6; then 501 | echo "Number of nodes less than 6, can not create redis cluster." 502 | echo -e "Exit now.\n" 503 | exit 1 504 | else 505 | redis_nodes_str=`echo "$redis_nodes_str" | tr ',' ' '` 506 | 507 | # 确认后再继续 508 | echo "" 509 | while true 510 | do 511 | echo -en "Create redis cluster? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 512 | read -r -p " " input 513 | 514 | if test "$input" = "no"; then 515 | echo "" 516 | exit 1 517 | elif test "$input" = "yes"; then 518 | echo "Starting to create redis cluster with $redis_nodes_str ... ..." 519 | echo "" 520 | break 521 | fi 522 | done 523 | 524 | # 创建 redis 集群(create redis cluster by redis-cli) 525 | if test -z "$redis_password"; then 526 | echo "$REDIS_CLI --cluster create $redis_nodes_str --cluster-replicas 1" 527 | $REDIS_CLI --cluster create $redis_nodes_str --cluster-replicas 1 528 | else 529 | echo "$REDIS_CLI --no-auth-warning -a \"$redis_password\" --cluster create $redis_nodes_str --cluster-replicas 1" 530 | $REDIS_CLI --no-auth-warning -a "$redis_password" --cluster create $redis_nodes_str --cluster-replicas 1 531 | fi 532 | echo -e "Exit now.\n" 533 | exit 0 534 | fi 535 | -------------------------------------------------------------------------------- /deploy/process_monitor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # https://github.com/eyjian/libmooon/blob/master/shell/process_monitor.sh 3 | # Created by yijian on 2012/7/23 4 | # 5 | # 运行日志:/tmp/process_monitor-USER.log,由于多进程同时写,不一定完整,仅供参考。 6 | # 请放到crontab中运行,如(注意要以后台方式运行,因为脚本是常驻不退出的): 7 | # * * * * * /usr/local/bin/process_monitor.sh /usr/sbin/rinetd /usr/sbin/rinetd > /dev/null 2>&1 & 8 | # 9 | # 进程监控脚本,当指定进程不存在时,执行重启脚本将它拉起 10 | # 11 | # 特色: 12 | # 1.本监控脚本可重复执行,它会自动做自互斥 13 | # 2.互斥不仅依据监控脚本文件名,而且包含了它的命令行参数,只有整体相同时互斥才生效 14 | # 3.对于被监控的进程,可以只指定进程名,也可以包含命令行参数 15 | # 4.不管是监控脚本还是被监控进程,总是只针对属于当前用户下的进程 16 | # 17 | # 如果本脚本手工运行正常,但在crontab中运行不正常, 18 | # 则可考虑检查下ps等命令是否可在crontab中正常运行。 19 | # 20 | # 假设有一程序或脚本文件/home/zhangsan/test,则有如下两个使用方式: 21 | # 1) /usr/local/bin/process_monitor.sh "/home/zhangsan/test" "/home/zhangsan/test" 22 | # 2) /usr/local/bin/process_monitor.sh "test" "/home/zhangsan/test" 23 | # 24 | # 不建议第2种使用方式,推荐总是使用第1种方式,因为第1种更为严格。 25 | # 26 | # 如果需要运行test的多个实例且分别监控, 27 | # 则要求每个实例的参数必须可区分,否则无法独立监控,如: 28 | # /usr/local/bin/process_monitor.sh "/usr/local/bin/test wangwu" "/usr/local/bin/test --name=wangwu" 29 | # /usr/local/bin/process_monitor.sh "/usr/local/bin/test zhangsan" "/usr/local/bin/test --name=zhangsan" 30 | 31 | # crontab技巧: 32 | # 1)公共的定义为变量 33 | # 2)如果包含了特殊字符,比如分号则使用单引用号,而不能用双引号,比如: 34 | # RECEIVERS="tom;mike;jay" 35 | # * * * * * * * * * * /usr/local/bin/process_monitor.sh "/tmp/test" "/tmp/test '$RECEIVERS'" 36 | 37 | # 注意事项: 38 | # 不管是监控脚本还是可执行程序, 39 | # 均要求使用绝对路径,即必须以“/”打头的路径。 40 | 41 | # 需要指定个数的命令行参数 42 | # 参数1:被监控的进程名(ps命令看到的进程名) 43 | # 参数2:重启被监控进程的脚本(进程不能以相对路径的方式启动) 44 | # 45 | # 以重启 redis 为例,假设 redis-server 所在路径为 /usr/local/redis/bin,则 crontab 可设置成如下: 46 | # PMONITOR=/usr/local/bin/process_monitor.sh 47 | # REDIS_HOME=/usr/local/redis 48 | # * * * * * $PMONITOR "$REDIS_HOME/bin/redis-server" "$REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis.conf" 49 | # 50 | # 如果同一用户下启动了多个 redis-server 进程,则需要设置成如下: 51 | # PORT1=6379 52 | # PORT2=6380 53 | # * * * * * $PMONITOR "$REDIS_HOME/bin/redis-server $PORT1" "$REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis-$PORT1.conf" 54 | # * * * * * $PMONITOR "$REDIS_HOME/bin/redis-server $PORT2" "$REDIS_HOME/bin/redis-server $REDIS_HOME/conf/redis-$PORT2.conf" 55 | # 在确定对应的 redis-server 进程是否存在时,除了严格对比 $REDIS_HOME/bin/redis-server 外, 56 | # 还会进一步对比是否有匹配(部分匹配即可) PORT1 或 PORT2 的参数。 57 | if test $# -ne 2; then 58 | printf "\033[1;33musage: $0 process_cmdline restart_script\033[m\n" 59 | printf "\033[1;33mexample: /usr/local/bin/process_monitor.sh \"/usr/sbin/rinetd\" \"/usr/sbin/rinetd\"\033[m\n" 60 | printf "\033[1;33mplease install process_monitor.sh into crontab by \"* * * * *\"\033[m\n" 61 | exit 1 62 | fi 63 | 64 | # 设置ONLY_TEST的值为非1关闭测试模式 65 | # 可设置同名的环境变量ONLY_TEST来控制 66 | ONLY_TEST=${ONLY_TEST:-0} 67 | 68 | # 实际中,遇到脚本在crontab中运行时,找不到ls和ps等命令 69 | # 原来是有些环境ls和ps位于/usr/bin目录下,而不是常规的/bin目录 70 | export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:$PATH 71 | trap "" SIGPIPE # 忽略SIGPIPE 72 | 73 | # 74 | # 前置条件判断, 75 | # 所依赖的命令必须可用 76 | # 77 | which id >/dev/null 2>&1 # 依赖命令id取得当前用户的用户ID 78 | if test $? -ne 0; then 79 | printf "\033[1;33mcommand 'id' not exists\033[m\n" 80 | exit 1 81 | fi 82 | which ps >/dev/null 2>&1 # 依赖命令ps求进程数 83 | if test $? -ne 0; then 84 | printf "\033[1;33mcommand 'ps' not exists\033[m\n" 85 | exit 1 86 | fi 87 | which awk >/dev/null 2>&1 # 依赖命令awk求进程数 88 | if test $? -ne 0; then 89 | printf "\033[1;33mcommand 'awk' not exists\033[m\n" 90 | exit 1 91 | fi 92 | which ls >/dev/null 2>&1 # 依赖命令ls计算日志文件大小 93 | if test $? -ne 0; then 94 | printf "\033[1;33mcommand 'ls' not exists\033[m\n" 95 | exit 1 96 | fi 97 | which cut >/dev/null 2>&1 # 依赖命令cut计算日志文件大小 98 | if test $? -ne 0; then 99 | printf "\033[1;33mcommand 'cut' not exists\033[m\n" 100 | exit 1 101 | fi 102 | which tee >/dev/null 2>&1 # 依赖命令tee写日志 103 | if test $? -ne 0; then 104 | printf "\033[1;33mcommand 'tee' not exists\033[m\n" 105 | exit 1 106 | fi 107 | which mv >/dev/null 2>&1 # 依赖命令mv备份日志文件 108 | if test $? -ne 0; then 109 | printf "\033[1;33mcommand 'mv' not exists\033[m\n" 110 | exit 1 111 | fi 112 | which sleep >/dev/null 2>&1 # 依赖命令sleep 113 | if test $? -ne 0; then 114 | printf "\033[1;33mcommand 'sleep' not exists\033[m\n" 115 | exit 1 116 | fi 117 | which sh >/dev/null 2>&1 # 依赖命令sh重启脚本 118 | if test $? -ne 0; then 119 | printf "\033[1;33mcommand 'sh' not exists\033[m\n" 120 | exit 1 121 | fi 122 | 123 | process_cmdline="$1" # 需要监控的进程名,或完整的命令行,也可以为部分命令行 124 | restart_script="$2" # 用来重启进程的脚本,要求具有可执行权限 125 | monitor_interval=2 # 定时检测时间间隔,单位为秒 126 | start_seconds=5 # 被监控进程启动需要花费多少秒 127 | cur_user=`whoami` # 执行本监控脚本的用户名 128 | # 取指定网卡上的IP地址 129 | #eth=1&&netstat -ie|awk -F'[: ]' 'begin{found=0;} { if (match($0,"eth'"$eth"'")) found=1; else if ((1==found) && match($0,"eth")) found=0; if ((1==found) && match($0,"inet addr:") && match($0,"Bcast:")) print $13; }' 130 | 131 | uid=`id -u $cur_user` # 当前用户ID 132 | self_name=`basename $0` # 本脚本名 133 | self_cmdline="$0 $*" 134 | self_dirpath=$(dirname "$0") # 脚本所在的目录 135 | self_full_filepath=$self_dirpath/$self_name 136 | process_raw_filepath=`echo "$process_cmdline"|cut -d" " -f1` 137 | process_name=$(basename $process_raw_filepath) 138 | process_dirpath=$(dirname "$process_cmdline") 139 | process_full_filepath=$process_dirpath/$process_name 140 | process_match="${process_cmdline#* }" # 只保留用来匹配的参数部分 141 | process_match=$(echo $process_match) # 去掉前后的空格 142 | 143 | # 用来做互斥, 144 | # 以保证只有最先启动的能运行, 145 | # 但若不同参数的彼此不相互影响, 146 | # 这样保证了可同时对不同对象进行监控。 147 | # 因为trap命令对KILL命令无效,所以不能通过创建文件的方式来互斥! 148 | active=0 149 | 150 | # 日志文件,可能多个用户都在运行, 151 | # 所以日志文件名需要加上用户名,否则其它用户可能无权限写 152 | log_filepath=/tmp/process_monitor-$cur_user.log 153 | # 日志文件大小(10M) 154 | log_filesize=10485760 155 | 156 | # 关闭所有已打开的文件描述符 157 | # 子进程不能继承,否则会导致本脚本自身的日志文件滚动时,被删除的备份不能被释放 158 | close_all_fd() 159 | { 160 | return 161 | # 0, 1, 2, 255 162 | # compgen -G "/proc/$BASHPID/fd/* 163 | for fd in $(ls /proc/$$/fd); do 164 | if test $fd -ge 0; then 165 | # 关闭文件描述符fd 166 | eval "exec $fd>&-" 167 | #eval "exec $fd<&-" 168 | fi 169 | done 170 | } 171 | # 导出close_all_fd 172 | export -f close_all_fd 173 | 174 | # 写日志函数,带1个参数: 175 | # 1) 需要写入的日志 176 | log() 177 | { 178 | # 创建日志文件,如果不存在的话 179 | if test ! -f $log_filepath; then 180 | touch $log_filepath 181 | fi 182 | 183 | record=$1 184 | # 得到日志文件大小 185 | file_size=`ls --time-style=long-iso -l $log_filepath 2>/dev/null|cut -d" " -f5` 186 | 187 | # 处理日志文件过大 188 | # 日志加上头[$process_cmdline],用来区分对不同对象的监控 189 | if test ! -z "$file_size"; then 190 | LOG_TIME="`date +'%Y-%m-%d %H:%M:%S'`" 191 | 192 | if test $file_size -lt $log_filesize; then 193 | # 不需要滚动 194 | if test $ONLY_TEST=1; then 195 | printf "[$process_cmdline][$LOG_TIME]$record" |tee -a $log_filepath 196 | else 197 | printf "[$process_cmdline][$LOG_TIME]$record" >> $log_filepath 198 | fi 199 | else 200 | # 需要滚动 201 | if test $ONLY_TEST=1; then 202 | printf "[$process_cmdline][$LOG_TIME]$record" |tee -a $log_filepath 203 | else 204 | printf "[$process_cmdline][$LOG_TIME]$record" >> $log_filepath 205 | fi 206 | 207 | # 滚动备份 208 | mv $log_filepath $log_filepath.bak 209 | 210 | if test $ONLY_TEST=1; then 211 | printf "[$process_cmdline][$LOG_TIME]truncated" |tee $log_filepath 212 | printf "[$process_cmdline][$LOG_TIME]$record" |tee -a $log_filepath 213 | else 214 | printf "[$process_cmdline][$LOG_TIME]truncated" > $log_filepath 215 | printf "[$process_cmdline][$LOG_TIME]$record" >> $log_filepath 216 | fi 217 | fi 218 | fi 219 | } 220 | 221 | # 显示调试信息 222 | if test $ONLY_TEST -eq 1; then 223 | log "self_dirpath: $self_dirpath\n" 224 | log "self_full_filepath: $self_full_filepath\n" 225 | 226 | log "process_raw_filepath: $process_raw_filepath\n" 227 | log "process_name: $process_name\n" 228 | log "process_dirpath: $process_dirpath\n" 229 | log "process_full_filepath: $process_full_filepath\n" 230 | log "process_match: $process_match\n" 231 | fi 232 | 233 | # 必须使用全路径,即必须以“/”打头 234 | s1=${self_full_filepath:0:1} 235 | p1=${process_full_filepath:0:1} 236 | if test $s1 != "/"; then 237 | log "illegal, is not an absolute path: $self_cmdline" 238 | exit 1 239 | fi 240 | #if test $p1 != "/"; then 241 | # log "illegal, is not an absolute path: $process_cmdline" 242 | # exit 1 243 | #fi 244 | 245 | # 取得文件类型 246 | # process_filetype取值0表示为可执行脚本文件 247 | # process_filetype取值1表示为可执行程序文件 248 | # process_filetype取值2表示为未知类型文件 249 | if test $p1 != "/"; then 250 | process_filetype=2 251 | else 252 | file $process_full_filepath |grep ELF >/dev/null 253 | if test $? -eq 0; then 254 | process_filetype=1 255 | else 256 | file $process_full_filepath |grep script >/dev/null 257 | if test $? -eq 0; then 258 | process_filetype=0 259 | else 260 | echo "unknown file type: process_raw_filepath\n" 261 | exit 1 262 | fi 263 | fi 264 | fi 265 | 266 | # 命令“ps -C $process_name h -o euid,args”输出示例: 267 | # 1)目标为非脚本时(process_name值为test): 268 | # 1001 /home/zhangsan/bin/test -a=1 -b=2 269 | # 2)目标为脚本时(process_name值为process_monitor.sh): 270 | # 1001 /bin/sh /home/zhangsan/process_monitor.sh /home/zhangsan/bin/test -a=1 -b=1 271 | 272 | # 以死循环方式,定时检测指定的进程是否存在 273 | # 一个重要原因是crontab最高频率为1分钟,不满足秒级的监控要求 274 | while true; do 275 | self_count=`ps -C $self_name h -o euid,args| awk 'BEGIN { num=0; } { if (($1==uid) && ($3==self_full_filepath) && match($0, self_cmdline)) {++num;}} END { printf("%d",num); }' uid=$uid self_full_filepath=$self_full_filepath self_cmdline="$self_cmdline"` 276 | if test $ONLY_TEST -eq 1; then 277 | log "process_name: $process_name, self_name: $self_name, self_count: $self_count\n" 278 | fi 279 | if test ! -z "$self_count"; then 280 | if test $self_count -gt 2; then 281 | log "$0 is running[$self_count/active:$active], current user is $cur_user\n" 282 | # 经测试,正常情况下一般为2, 283 | # 但运行一段时间后,会出现值为3,因此放在crontab中非常必要 284 | # 如果监控脚本已经运行,则退出不重复运行 285 | if test $active -eq 0; then 286 | exit 1 287 | fi 288 | fi 289 | fi 290 | 291 | # 检查被监控的进程是否存在,如果不存在则重启 292 | if test -z "$process_match"; then 293 | if test $process_filetype -eq 0; then # 可执行脚本文件 294 | process_count=`ps -C $process_name h -o euid,args| awk 'BEGIN { num=0; } { if ($1==uid) && ($3==process_full_filepath)) ++num; } END { printf("%d",num); }' uid=$uid process_full_filepath=$process_full_filepath` 295 | elif test $process_filetype -eq 1; then # 可执行程序文件 296 | process_count=`ps -C $process_name h -o euid,args| awk 'BEGIN { num=0; } { if ($1==uid) && ($2==process_full_filepath)) ++num; } END { printf("%d",num); }' uid=$uid process_full_filepath=$process_full_filepath` 297 | else # 未知类型文件 298 | process_count=`ps -C $process_name h -o euid,args| awk 'BEGIN { num=0; } { if ($1==uid) ++num; } END { printf("%d",num); }' uid=$uid` 299 | fi 300 | else 301 | if test $process_filetype -eq 0; then # 可执行脚本文件 302 | process_count=`ps -C $process_name h -o euid,args| awk 'BEGIN { num=0; } { if (($1==uid) && ($3==process_full_filepath)) { for (i=3;i<=NF;++i) if (match($i, process_match)) { ++num; break; } } } END { printf("%d",num); }' uid=$uid process_full_filepath=$process_full_filepath process_match="$process_match"` 303 | elif test $process_filetype -eq 1; then # 可执行程序文件 304 | process_count=`ps -C $process_name h -o euid,args| awk 'BEGIN { num=0; } { if (($1==uid) && ($2==process_full_filepath)) { for (i=3;i<=NF;++i) if (match($i, process_match)) { ++num; break; } } } END { printf("%d",num); }' uid=$uid process_full_filepath=$process_full_filepath process_match="$process_match"` 305 | else # 未知类型文件 306 | process_count=`ps -C $process_name h -o euid,args| awk 'BEGIN { num=0; } { if ($1==uid) { for (i=3;i<=NF;++i) if (match($i, process_match)) { ++num; break; } } } END { printf("%d",num); }' uid=$uid process_match="$process_match"` 307 | fi 308 | fi 309 | 310 | if test $ONLY_TEST -eq 1; then 311 | log "process_name: $process_name, process_count: $process_count, process_match: $process_match\n" 312 | fi 313 | if test ! -z "$process_count"; then 314 | if test $process_count -lt 1; then 315 | # 执行重启脚本,要求这个脚本能够将指定的进程拉起来 316 | log "[$process_name/$process_count][process_match:$process_match]restart \"$process_cmdline\"\n" 317 | #sh -c "$restart_script" 2>&1 >> $log_filepath 318 | msg=`sh -c "$restart_script" 2>&1` 319 | if test ! -z "${msg}"; then 320 | log "${msg}\n" 321 | fi 322 | 323 | # sleep时间得长一点,原因是启动可能没那么快,以防止启动多个进程 324 | # 在某些环境遇到sleep无效,正常sleep后“$?”值为0,则异常时变成“141”, 325 | # 这个是因为收到了信号13,可以使用“trap '' SIGPIPE”忽略SIGPIPE。 326 | sleep $start_seconds 327 | else 328 | sleep $monitor_interval 329 | fi 330 | else 331 | sleep $monitor_interval 332 | fi 333 | 334 | active=1 335 | done 336 | exit 0 337 | -------------------------------------------------------------------------------- /deploy/redis-PORT.conf: -------------------------------------------------------------------------------- 1 | # Redis configuration file example. 2 | # 3 | # Note that in order to read the configuration file, Redis must be 4 | # started with the file path as first argument: 5 | # 6 | # ./redis-server /path/to/redis.conf 7 | 8 | # Note on units: when memory size is needed, it is possible to specify 9 | # it in the usual form of 1k 5GB 4M and so forth: 10 | # 11 | # 1k => 1000 bytes 12 | # 1kb => 1024 bytes 13 | # 1m => 1000000 bytes 14 | # 1mb => 1024*1024 bytes 15 | # 1g => 1000000000 bytes 16 | # 1gb => 1024*1024*1024 bytes 17 | # 18 | # units are case insensitive so 1GB 1Gb 1gB are all the same. 19 | 20 | ################################## INCLUDES ################################### 21 | 22 | # Include one or more other config files here. This is useful if you 23 | # have a standard template that goes to all Redis servers but also need 24 | # to customize a few per-server settings. Include files can include 25 | # other files, so use this wisely. 26 | # 27 | # Notice option "include" won't be rewritten by command "CONFIG REWRITE" 28 | # from admin or Redis Sentinel. Since Redis always uses the last processed 29 | # line as value of a configuration directive, you'd better put includes 30 | # at the beginning of this file to avoid overwriting config change at runtime. 31 | # 32 | # If instead you are interested in using includes to override configuration 33 | # options, it is better to use include as the last line. 34 | # 35 | # include /path/to/local.conf 36 | # include /path/to/other.conf 37 | include INSTALLDIR/conf/redis.conf 38 | 39 | ################################## MODULES ##################################### 40 | 41 | # Load modules at startup. If the server is not able to load modules 42 | # it will abort. It is possible to use multiple loadmodule directives. 43 | # 44 | # loadmodule /path/to/my_module.so 45 | # loadmodule /path/to/other_module.so 46 | 47 | ################################## NETWORK ##################################### 48 | 49 | # By default, if no "bind" configuration directive is specified, Redis listens 50 | # for connections from all the network interfaces available on the server. 51 | # It is possible to listen to just one or multiple selected interfaces using 52 | # the "bind" configuration directive, followed by one or more IP addresses. 53 | # 54 | # Examples: 55 | # 56 | # bind 192.168.1.100 10.0.0.1 57 | # bind 127.0.0.1 ::1 58 | # 59 | # ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the 60 | # internet, binding to all the interfaces is dangerous and will expose the 61 | # instance to everybody on the internet. So by default we uncomment the 62 | # following bind directive, that will force Redis to listen only into 63 | # the IPv4 lookback interface address (this means Redis will be able to 64 | # accept connections only from clients running into the same computer it 65 | # is running). 66 | # 67 | # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES 68 | # JUST COMMENT THE FOLLOWING LINE. 69 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 | #bind 127.0.0.1 71 | 72 | # Protected mode is a layer of security protection, in order to avoid that 73 | # Redis instances left open on the internet are accessed and exploited. 74 | # 75 | # When protected mode is on and if: 76 | # 77 | # 1) The server is not binding explicitly to a set of addresses using the 78 | # "bind" directive. 79 | # 2) No password is configured. 80 | # 81 | # The server only accepts connections from clients connecting from the 82 | # IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain 83 | # sockets. 84 | # 85 | # By default protected mode is enabled. You should disable it only if 86 | # you are sure you want clients from other hosts to connect to Redis 87 | # even if no authentication is configured, nor a specific set of interfaces 88 | # are explicitly listed using the "bind" directive. 89 | #protected-mode yes 90 | 91 | # Accept connections on the specified port, default is 6379 (IANA #815344). 92 | # If port 0 is specified Redis will not listen on a TCP socket. 93 | port REDISPORT 94 | 95 | # TCP listen() backlog. 96 | # 97 | # In high requests-per-second environments you need an high backlog in order 98 | # to avoid slow clients connections issues. Note that the Linux kernel 99 | # will silently truncate it to the value of /proc/sys/net/core/somaxconn so 100 | # make sure to raise both the value of somaxconn and tcp_max_syn_backlog 101 | # in order to get the desired effect. 102 | #tcp-backlog 511 103 | 104 | # Unix socket. 105 | # 106 | # Specify the path for the Unix socket that will be used to listen for 107 | # incoming connections. There is no default, so Redis will not listen 108 | # on a unix socket when not specified. 109 | # 110 | # unixsocket /tmp/redis.sock 111 | # unixsocketperm 700 112 | 113 | # Close the connection after a client is idle for N seconds (0 to disable) 114 | #timeout 0 115 | 116 | # TCP keepalive. 117 | # 118 | # If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence 119 | # of communication. This is useful for two reasons: 120 | # 121 | # 1) Detect dead peers. 122 | # 2) Take the connection alive from the point of view of network 123 | # equipment in the middle. 124 | # 125 | # On Linux, the specified value (in seconds) is the period used to send ACKs. 126 | # Note that to close the connection the double of the time is needed. 127 | # On other kernels the period depends on the kernel configuration. 128 | # 129 | # A reasonable value for this option is 300 seconds, which is the new 130 | # Redis default starting with Redis 3.2.1. 131 | #tcp-keepalive 300 132 | 133 | ################################# GENERAL ##################################### 134 | 135 | # By default Redis does not run as a daemon. Use 'yes' if you need it. 136 | # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. 137 | #daemonize no 138 | 139 | # If you run Redis from upstart or systemd, Redis can interact with your 140 | # supervision tree. Options: 141 | # supervised no - no supervision interaction 142 | # supervised upstart - signal upstart by putting Redis into SIGSTOP mode 143 | # supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET 144 | # supervised auto - detect upstart or systemd method based on 145 | # UPSTART_JOB or NOTIFY_SOCKET environment variables 146 | # Note: these supervision methods only signal "process is ready." 147 | # They do not enable continuous liveness pings back to your supervisor. 148 | #supervised no 149 | 150 | # If a pid file is specified, Redis writes it where specified at startup 151 | # and removes it at exit. 152 | # 153 | # When the server runs non daemonized, no pid file is created if none is 154 | # specified in the configuration. When the server is daemonized, the pid file 155 | # is used even if not specified, defaulting to "/var/run/redis.pid". 156 | # 157 | # Creating a pid file is best effort: if Redis is not able to create it 158 | # nothing bad happens, the server will start and run normally. 159 | #pidfile /var/run/redis_6379.pid 160 | pidfile INSTALLDIR/bin/redis-REDISPORT.pid 161 | 162 | # Specify the server verbosity level. 163 | # This can be one of: 164 | # debug (a lot of information, useful for development/testing) 165 | # verbose (many rarely useful info, but not a mess like the debug level) 166 | # notice (moderately verbose, what you want in production probably) 167 | # warning (only very important / critical messages are logged) 168 | #loglevel notice 169 | 170 | # Specify the log file name. Also the empty string can be used to force 171 | # Redis to log on the standard output. Note that if you use standard 172 | # output for logging but daemonize, logs will be sent to /dev/null 173 | logfile INSTALLDIR/log/redis-REDISPORT.log 174 | 175 | # To enable logging to the system logger, just set 'syslog-enabled' to yes, 176 | # and optionally update the other syslog parameters to suit your needs. 177 | # syslog-enabled no 178 | 179 | # Specify the syslog identity. 180 | # syslog-ident redis 181 | 182 | # Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. 183 | # syslog-facility local0 184 | 185 | # Set the number of databases. The default database is DB 0, you can select 186 | # a different one on a per-connection basis using SELECT where 187 | # dbid is a number between 0 and 'databases'-1 188 | #databases 16 189 | 190 | # By default Redis shows an ASCII art logo only when started to log to the 191 | # standard output and if the standard output is a TTY. Basically this means 192 | # that normally a logo is displayed only in interactive sessions. 193 | # 194 | # However it is possible to force the pre-4.0 behavior and always show a 195 | # ASCII art logo in startup logs by setting the following option to yes. 196 | #always-show-logo yes 197 | 198 | ################################ SNAPSHOTTING ################################ 199 | # 200 | # Save the DB on disk: 201 | # 202 | # save 203 | # 204 | # Will save the DB if both the given number of seconds and the given 205 | # number of write operations against the DB occurred. 206 | # 207 | # In the example below the behaviour will be to save: 208 | # after 900 sec (15 min) if at least 1 key changed 209 | # after 300 sec (5 min) if at least 10 keys changed 210 | # after 60 sec if at least 10000 keys changed 211 | # 212 | # Note: you can disable saving completely by commenting out all "save" lines. 213 | # 214 | # It is also possible to remove all the previously configured save 215 | # points by adding a save directive with a single empty string argument 216 | # like in the following example: 217 | # 218 | # save "" 219 | 220 | #save 900 1 221 | #save 300 10 222 | #save 60 10000 223 | 224 | # By default Redis will stop accepting writes if RDB snapshots are enabled 225 | # (at least one save point) and the latest background save failed. 226 | # This will make the user aware (in a hard way) that data is not persisting 227 | # on disk properly, otherwise chances are that no one will notice and some 228 | # disaster will happen. 229 | # 230 | # If the background saving process will start working again Redis will 231 | # automatically allow writes again. 232 | # 233 | # However if you have setup your proper monitoring of the Redis server 234 | # and persistence, you may want to disable this feature so that Redis will 235 | # continue to work as usual even if there are problems with disk, 236 | # permissions, and so forth. 237 | #stop-writes-on-bgsave-error yes 238 | 239 | # Compress string objects using LZF when dump .rdb databases? 240 | # For default that's set to 'yes' as it's almost always a win. 241 | # If you want to save some CPU in the saving child set it to 'no' but 242 | # the dataset will likely be bigger if you have compressible values or keys. 243 | #rdbcompression yes 244 | 245 | # Since version 5 of RDB a CRC64 checksum is placed at the end of the file. 246 | # This makes the format more resistant to corruption but there is a performance 247 | # hit to pay (around 10%) when saving and loading RDB files, so you can disable it 248 | # for maximum performances. 249 | # 250 | # RDB files created with checksum disabled have a checksum of zero that will 251 | # tell the loading code to skip the check. 252 | #rdbchecksum yes 253 | 254 | # The filename where to dump the DB 255 | #dbfilename dump.rdb 256 | dbfilename dump-REDISPORT.rdb 257 | 258 | # The working directory. 259 | # 260 | # The DB will be written inside this directory, with the filename specified 261 | # above using the 'dbfilename' configuration directive. 262 | # 263 | # The Append Only File will also be created inside this directory. 264 | # 265 | # Note that you must specify a directory here, not a file name. 266 | #dir ./ 267 | dir INSTALLDIR/data/REDISPORT 268 | 269 | ################################# REPLICATION ################################# 270 | 271 | # Master-Slave replication. Use slaveof to make a Redis instance a copy of 272 | # another Redis server. A few things to understand ASAP about Redis replication. 273 | # 274 | # 1) Redis replication is asynchronous, but you can configure a master to 275 | # stop accepting writes if it appears to be not connected with at least 276 | # a given number of slaves. 277 | # 2) Redis slaves are able to perform a partial resynchronization with the 278 | # master if the replication link is lost for a relatively small amount of 279 | # time. You may want to configure the replication backlog size (see the next 280 | # sections of this file) with a sensible value depending on your needs. 281 | # 3) Replication is automatic and does not need user intervention. After a 282 | # network partition slaves automatically try to reconnect to masters 283 | # and resynchronize with them. 284 | # 285 | # slaveof 286 | 287 | # If the master is password protected (using the "requirepass" configuration 288 | # directive below) it is possible to tell the slave to authenticate before 289 | # starting the replication synchronization process, otherwise the master will 290 | # refuse the slave request. 291 | # 292 | # masterauth 293 | 294 | # When a slave loses its connection with the master, or when the replication 295 | # is still in progress, the slave can act in two different ways: 296 | # 297 | # 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will 298 | # still reply to client requests, possibly with out of date data, or the 299 | # data set may just be empty if this is the first synchronization. 300 | # 301 | # 2) if slave-serve-stale-data is set to 'no' the slave will reply with 302 | # an error "SYNC with master in progress" to all the kind of commands 303 | # but to INFO and SLAVEOF. 304 | # 305 | #slave-serve-stale-data yes 306 | 307 | # You can configure a slave instance to accept writes or not. Writing against 308 | # a slave instance may be useful to store some ephemeral data (because data 309 | # written on a slave will be easily deleted after resync with the master) but 310 | # may also cause problems if clients are writing to it because of a 311 | # misconfiguration. 312 | # 313 | # Since Redis 2.6 by default slaves are read-only. 314 | # 315 | # Note: read only slaves are not designed to be exposed to untrusted clients 316 | # on the internet. It's just a protection layer against misuse of the instance. 317 | # Still a read only slave exports by default all the administrative commands 318 | # such as CONFIG, DEBUG, and so forth. To a limited extent you can improve 319 | # security of read only slaves using 'rename-command' to shadow all the 320 | # administrative / dangerous commands. 321 | #slave-read-only yes 322 | 323 | # Replication SYNC strategy: disk or socket. 324 | # 325 | # ------------------------------------------------------- 326 | # WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY 327 | # ------------------------------------------------------- 328 | # 329 | # New slaves and reconnecting slaves that are not able to continue the replication 330 | # process just receiving differences, need to do what is called a "full 331 | # synchronization". An RDB file is transmitted from the master to the slaves. 332 | # The transmission can happen in two different ways: 333 | # 334 | # 1) Disk-backed: The Redis master creates a new process that writes the RDB 335 | # file on disk. Later the file is transferred by the parent 336 | # process to the slaves incrementally. 337 | # 2) Diskless: The Redis master creates a new process that directly writes the 338 | # RDB file to slave sockets, without touching the disk at all. 339 | # 340 | # With disk-backed replication, while the RDB file is generated, more slaves 341 | # can be queued and served with the RDB file as soon as the current child producing 342 | # the RDB file finishes its work. With diskless replication instead once 343 | # the transfer starts, new slaves arriving will be queued and a new transfer 344 | # will start when the current one terminates. 345 | # 346 | # When diskless replication is used, the master waits a configurable amount of 347 | # time (in seconds) before starting the transfer in the hope that multiple slaves 348 | # will arrive and the transfer can be parallelized. 349 | # 350 | # With slow disks and fast (large bandwidth) networks, diskless replication 351 | # works better. 352 | #repl-diskless-sync no 353 | 354 | # When diskless replication is enabled, it is possible to configure the delay 355 | # the server waits in order to spawn the child that transfers the RDB via socket 356 | # to the slaves. 357 | # 358 | # This is important since once the transfer starts, it is not possible to serve 359 | # new slaves arriving, that will be queued for the next RDB transfer, so the server 360 | # waits a delay in order to let more slaves arrive. 361 | # 362 | # The delay is specified in seconds, and by default is 5 seconds. To disable 363 | # it entirely just set it to 0 seconds and the transfer will start ASAP. 364 | #repl-diskless-sync-delay 5 365 | 366 | # Slaves send PINGs to server in a predefined interval. It's possible to change 367 | # this interval with the repl_ping_slave_period option. The default value is 10 368 | # seconds. 369 | # 370 | # repl-ping-slave-period 10 371 | 372 | # The following option sets the replication timeout for: 373 | # 374 | # 1) Bulk transfer I/O during SYNC, from the point of view of slave. 375 | # 2) Master timeout from the point of view of slaves (data, pings). 376 | # 3) Slave timeout from the point of view of masters (REPLCONF ACK pings). 377 | # 378 | # It is important to make sure that this value is greater than the value 379 | # specified for repl-ping-slave-period otherwise a timeout will be detected 380 | # every time there is low traffic between the master and the slave. 381 | # 382 | # repl-timeout 60 383 | 384 | # Disable TCP_NODELAY on the slave socket after SYNC? 385 | # 386 | # If you select "yes" Redis will use a smaller number of TCP packets and 387 | # less bandwidth to send data to slaves. But this can add a delay for 388 | # the data to appear on the slave side, up to 40 milliseconds with 389 | # Linux kernels using a default configuration. 390 | # 391 | # If you select "no" the delay for data to appear on the slave side will 392 | # be reduced but more bandwidth will be used for replication. 393 | # 394 | # By default we optimize for low latency, but in very high traffic conditions 395 | # or when the master and slaves are many hops away, turning this to "yes" may 396 | # be a good idea. 397 | #repl-disable-tcp-nodelay no 398 | 399 | # Set the replication backlog size. The backlog is a buffer that accumulates 400 | # slave data when slaves are disconnected for some time, so that when a slave 401 | # wants to reconnect again, often a full resync is not needed, but a partial 402 | # resync is enough, just passing the portion of data the slave missed while 403 | # disconnected. 404 | # 405 | # The bigger the replication backlog, the longer the time the slave can be 406 | # disconnected and later be able to perform a partial resynchronization. 407 | # 408 | # The backlog is only allocated once there is at least a slave connected. 409 | # 410 | # repl-backlog-size 1mb 411 | 412 | # After a master has no longer connected slaves for some time, the backlog 413 | # will be freed. The following option configures the amount of seconds that 414 | # need to elapse, starting from the time the last slave disconnected, for 415 | # the backlog buffer to be freed. 416 | # 417 | # Note that slaves never free the backlog for timeout, since they may be 418 | # promoted to masters later, and should be able to correctly "partially 419 | # resynchronize" with the slaves: hence they should always accumulate backlog. 420 | # 421 | # A value of 0 means to never release the backlog. 422 | # 423 | # repl-backlog-ttl 3600 424 | 425 | # The slave priority is an integer number published by Redis in the INFO output. 426 | # It is used by Redis Sentinel in order to select a slave to promote into a 427 | # master if the master is no longer working correctly. 428 | # 429 | # A slave with a low priority number is considered better for promotion, so 430 | # for instance if there are three slaves with priority 10, 100, 25 Sentinel will 431 | # pick the one with priority 10, that is the lowest. 432 | # 433 | # However a special priority of 0 marks the slave as not able to perform the 434 | # role of master, so a slave with priority of 0 will never be selected by 435 | # Redis Sentinel for promotion. 436 | # 437 | # By default the priority is 100. 438 | #slave-priority 100 439 | 440 | # It is possible for a master to stop accepting writes if there are less than 441 | # N slaves connected, having a lag less or equal than M seconds. 442 | # 443 | # The N slaves need to be in "online" state. 444 | # 445 | # The lag in seconds, that must be <= the specified value, is calculated from 446 | # the last ping received from the slave, that is usually sent every second. 447 | # 448 | # This option does not GUARANTEE that N replicas will accept the write, but 449 | # will limit the window of exposure for lost writes in case not enough slaves 450 | # are available, to the specified number of seconds. 451 | # 452 | # For example to require at least 3 slaves with a lag <= 10 seconds use: 453 | # 454 | # min-slaves-to-write 3 455 | # min-slaves-max-lag 10 456 | # 457 | # Setting one or the other to 0 disables the feature. 458 | # 459 | # By default min-slaves-to-write is set to 0 (feature disabled) and 460 | # min-slaves-max-lag is set to 10. 461 | 462 | # A Redis master is able to list the address and port of the attached 463 | # slaves in different ways. For example the "INFO replication" section 464 | # offers this information, which is used, among other tools, by 465 | # Redis Sentinel in order to discover slave instances. 466 | # Another place where this info is available is in the output of the 467 | # "ROLE" command of a master. 468 | # 469 | # The listed IP and address normally reported by a slave is obtained 470 | # in the following way: 471 | # 472 | # IP: The address is auto detected by checking the peer address 473 | # of the socket used by the slave to connect with the master. 474 | # 475 | # Port: The port is communicated by the slave during the replication 476 | # handshake, and is normally the port that the slave is using to 477 | # list for connections. 478 | # 479 | # However when port forwarding or Network Address Translation (NAT) is 480 | # used, the slave may be actually reachable via different IP and port 481 | # pairs. The following two options can be used by a slave in order to 482 | # report to its master a specific set of IP and port, so that both INFO 483 | # and ROLE will report those values. 484 | # 485 | # There is no need to use both the options if you need to override just 486 | # the port or the IP address. 487 | # 488 | # slave-announce-ip 5.5.5.5 489 | # slave-announce-port 1234 490 | 491 | ################################## SECURITY ################################### 492 | 493 | # Require clients to issue AUTH before processing any other 494 | # commands. This might be useful in environments in which you do not trust 495 | # others with access to the host running redis-server. 496 | # 497 | # This should stay commented out for backward compatibility and because most 498 | # people do not need auth (e.g. they run their own servers). 499 | # 500 | # Warning: since Redis is pretty fast an outside user can try up to 501 | # 150k passwords per second against a good box. This means that you should 502 | # use a very strong password otherwise it will be very easy to break. 503 | # 504 | # requirepass foobared 505 | 506 | # Command renaming. 507 | # 508 | # It is possible to change the name of dangerous commands in a shared 509 | # environment. For instance the CONFIG command may be renamed into something 510 | # hard to guess so that it will still be available for internal-use tools 511 | # but not available for general clients. 512 | # 513 | # Example: 514 | # 515 | # rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 516 | # 517 | # It is also possible to completely kill a command by renaming it into 518 | # an empty string: 519 | # 520 | # rename-command CONFIG "" 521 | # 522 | # Please note that changing the name of commands that are logged into the 523 | # AOF file or transmitted to slaves may cause problems. 524 | 525 | ################################### CLIENTS #################################### 526 | 527 | # Set the max number of connected clients at the same time. By default 528 | # this limit is set to 10000 clients, however if the Redis server is not 529 | # able to configure the process file limit to allow for the specified limit 530 | # the max number of allowed clients is set to the current file limit 531 | # minus 32 (as Redis reserves a few file descriptors for internal uses). 532 | # 533 | # Once the limit is reached Redis will close all the new connections sending 534 | # an error 'max number of clients reached'. 535 | # 536 | # maxclients 10000 537 | 538 | ############################## MEMORY MANAGEMENT ################################ 539 | 540 | # Set a memory usage limit to the specified amount of bytes. 541 | # When the memory limit is reached Redis will try to remove keys 542 | # according to the eviction policy selected (see maxmemory-policy). 543 | # 544 | # If Redis can't remove keys according to the policy, or if the policy is 545 | # set to 'noeviction', Redis will start to reply with errors to commands 546 | # that would use more memory, like SET, LPUSH, and so on, and will continue 547 | # to reply to read-only commands like GET. 548 | # 549 | # This option is usually useful when using Redis as an LRU or LFU cache, or to 550 | # set a hard memory limit for an instance (using the 'noeviction' policy). 551 | # 552 | # WARNING: If you have slaves attached to an instance with maxmemory on, 553 | # the size of the output buffers needed to feed the slaves are subtracted 554 | # from the used memory count, so that network problems / resyncs will 555 | # not trigger a loop where keys are evicted, and in turn the output 556 | # buffer of slaves is full with DELs of keys evicted triggering the deletion 557 | # of more keys, and so forth until the database is completely emptied. 558 | # 559 | # In short... if you have slaves attached it is suggested that you set a lower 560 | # limit for maxmemory so that there is some free RAM on the system for slave 561 | # output buffers (but this is not needed if the policy is 'noeviction'). 562 | # 563 | # maxmemory 564 | 565 | # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory 566 | # is reached. You can select among five behaviors: 567 | # 568 | # volatile-lru -> Evict using approximated LRU among the keys with an expire set. 569 | # allkeys-lru -> Evict any key using approximated LRU. 570 | # volatile-lfu -> Evict using approximated LFU among the keys with an expire set. 571 | # allkeys-lfu -> Evict any key using approximated LFU. 572 | # volatile-random -> Remove a random key among the ones with an expire set. 573 | # allkeys-random -> Remove a random key, any key. 574 | # volatile-ttl -> Remove the key with the nearest expire time (minor TTL) 575 | # noeviction -> Don't evict anything, just return an error on write operations. 576 | # 577 | # LRU means Least Recently Used 578 | # LFU means Least Frequently Used 579 | # 580 | # Both LRU, LFU and volatile-ttl are implemented using approximated 581 | # randomized algorithms. 582 | # 583 | # Note: with any of the above policies, Redis will return an error on write 584 | # operations, when there are no suitable keys for eviction. 585 | # 586 | # At the date of writing these commands are: set setnx setex append 587 | # incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd 588 | # sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby 589 | # zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby 590 | # getset mset msetnx exec sort 591 | # 592 | # The default is: 593 | # 594 | # maxmemory-policy noeviction 595 | 596 | # LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated 597 | # algorithms (in order to save memory), so you can tune it for speed or 598 | # accuracy. For default Redis will check five keys and pick the one that was 599 | # used less recently, you can change the sample size using the following 600 | # configuration directive. 601 | # 602 | # The default of 5 produces good enough results. 10 Approximates very closely 603 | # true LRU but costs more CPU. 3 is faster but not very accurate. 604 | # 605 | # maxmemory-samples 5 606 | 607 | ############################# LAZY FREEING #################################### 608 | 609 | # Redis has two primitives to delete keys. One is called DEL and is a blocking 610 | # deletion of the object. It means that the server stops processing new commands 611 | # in order to reclaim all the memory associated with an object in a synchronous 612 | # way. If the key deleted is associated with a small object, the time needed 613 | # in order to execute the DEL command is very small and comparable to most other 614 | # O(1) or O(log_N) commands in Redis. However if the key is associated with an 615 | # aggregated value containing millions of elements, the server can block for 616 | # a long time (even seconds) in order to complete the operation. 617 | # 618 | # For the above reasons Redis also offers non blocking deletion primitives 619 | # such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and 620 | # FLUSHDB commands, in order to reclaim memory in background. Those commands 621 | # are executed in constant time. Another thread will incrementally free the 622 | # object in the background as fast as possible. 623 | # 624 | # DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. 625 | # It's up to the design of the application to understand when it is a good 626 | # idea to use one or the other. However the Redis server sometimes has to 627 | # delete keys or flush the whole database as a side effect of other operations. 628 | # Specifically Redis deletes objects independently of a user call in the 629 | # following scenarios: 630 | # 631 | # 1) On eviction, because of the maxmemory and maxmemory policy configurations, 632 | # in order to make room for new data, without going over the specified 633 | # memory limit. 634 | # 2) Because of expire: when a key with an associated time to live (see the 635 | # EXPIRE command) must be deleted from memory. 636 | # 3) Because of a side effect of a command that stores data on a key that may 637 | # already exist. For example the RENAME command may delete the old key 638 | # content when it is replaced with another one. Similarly SUNIONSTORE 639 | # or SORT with STORE option may delete existing keys. The SET command 640 | # itself removes any old content of the specified key in order to replace 641 | # it with the specified string. 642 | # 4) During replication, when a slave performs a full resynchronization with 643 | # its master, the content of the whole database is removed in order to 644 | # load the RDB file just transfered. 645 | # 646 | # In all the above cases the default is to delete objects in a blocking way, 647 | # like if DEL was called. However you can configure each case specifically 648 | # in order to instead release memory in a non-blocking way like if UNLINK 649 | # was called, using the following configuration directives: 650 | 651 | #lazyfree-lazy-eviction no 652 | #lazyfree-lazy-expire no 653 | #lazyfree-lazy-server-del no 654 | #slave-lazy-flush no 655 | 656 | ############################## APPEND ONLY MODE ############################### 657 | 658 | # By default Redis asynchronously dumps the dataset on disk. This mode is 659 | # good enough in many applications, but an issue with the Redis process or 660 | # a power outage may result into a few minutes of writes lost (depending on 661 | # the configured save points). 662 | # 663 | # The Append Only File is an alternative persistence mode that provides 664 | # much better durability. For instance using the default data fsync policy 665 | # (see later in the config file) Redis can lose just one second of writes in a 666 | # dramatic event like a server power outage, or a single write if something 667 | # wrong with the Redis process itself happens, but the operating system is 668 | # still running correctly. 669 | # 670 | # AOF and RDB persistence can be enabled at the same time without problems. 671 | # If the AOF is enabled on startup Redis will load the AOF, that is the file 672 | # with the better durability guarantees. 673 | # 674 | # Please check http://redis.io/topics/persistence for more information. 675 | 676 | #appendonly no 677 | 678 | # The name of the append only file (default: "appendonly.aof") 679 | 680 | appendfilename appendonly-REDISPORT.aof 681 | 682 | # The fsync() call tells the Operating System to actually write data on disk 683 | # instead of waiting for more data in the output buffer. Some OS will really flush 684 | # data on disk, some other OS will just try to do it ASAP. 685 | # 686 | # Redis supports three different modes: 687 | # 688 | # no: don't fsync, just let the OS flush the data when it wants. Faster. 689 | # always: fsync after every write to the append only log. Slow, Safest. 690 | # everysec: fsync only one time every second. Compromise. 691 | # 692 | # The default is "everysec", as that's usually the right compromise between 693 | # speed and data safety. It's up to you to understand if you can relax this to 694 | # "no" that will let the operating system flush the output buffer when 695 | # it wants, for better performances (but if you can live with the idea of 696 | # some data loss consider the default persistence mode that's snapshotting), 697 | # or on the contrary, use "always" that's very slow but a bit safer than 698 | # everysec. 699 | # 700 | # More details please check the following article: 701 | # http://antirez.com/post/redis-persistence-demystified.html 702 | # 703 | # If unsure, use "everysec". 704 | 705 | # appendfsync always 706 | #appendfsync everysec 707 | # appendfsync no 708 | 709 | # When the AOF fsync policy is set to always or everysec, and a background 710 | # saving process (a background save or AOF log background rewriting) is 711 | # performing a lot of I/O against the disk, in some Linux configurations 712 | # Redis may block too long on the fsync() call. Note that there is no fix for 713 | # this currently, as even performing fsync in a different thread will block 714 | # our synchronous write(2) call. 715 | # 716 | # In order to mitigate this problem it's possible to use the following option 717 | # that will prevent fsync() from being called in the main process while a 718 | # BGSAVE or BGREWRITEAOF is in progress. 719 | # 720 | # This means that while another child is saving, the durability of Redis is 721 | # the same as "appendfsync none". In practical terms, this means that it is 722 | # possible to lose up to 30 seconds of log in the worst scenario (with the 723 | # default Linux settings). 724 | # 725 | # If you have latency problems turn this to "yes". Otherwise leave it as 726 | # "no" that is the safest pick from the point of view of durability. 727 | 728 | #no-appendfsync-on-rewrite no 729 | 730 | # Automatic rewrite of the append only file. 731 | # Redis is able to automatically rewrite the log file implicitly calling 732 | # BGREWRITEAOF when the AOF log size grows by the specified percentage. 733 | # 734 | # This is how it works: Redis remembers the size of the AOF file after the 735 | # latest rewrite (if no rewrite has happened since the restart, the size of 736 | # the AOF at startup is used). 737 | # 738 | # This base size is compared to the current size. If the current size is 739 | # bigger than the specified percentage, the rewrite is triggered. Also 740 | # you need to specify a minimal size for the AOF file to be rewritten, this 741 | # is useful to avoid rewriting the AOF file even if the percentage increase 742 | # is reached but it is still pretty small. 743 | # 744 | # Specify a percentage of zero in order to disable the automatic AOF 745 | # rewrite feature. 746 | 747 | #auto-aof-rewrite-percentage 100 748 | #auto-aof-rewrite-min-size 64mb 749 | 750 | # An AOF file may be found to be truncated at the end during the Redis 751 | # startup process, when the AOF data gets loaded back into memory. 752 | # This may happen when the system where Redis is running 753 | # crashes, especially when an ext4 filesystem is mounted without the 754 | # data=ordered option (however this can't happen when Redis itself 755 | # crashes or aborts but the operating system still works correctly). 756 | # 757 | # Redis can either exit with an error when this happens, or load as much 758 | # data as possible (the default now) and start if the AOF file is found 759 | # to be truncated at the end. The following option controls this behavior. 760 | # 761 | # If aof-load-truncated is set to yes, a truncated AOF file is loaded and 762 | # the Redis server starts emitting a log to inform the user of the event. 763 | # Otherwise if the option is set to no, the server aborts with an error 764 | # and refuses to start. When the option is set to no, the user requires 765 | # to fix the AOF file using the "redis-check-aof" utility before to restart 766 | # the server. 767 | # 768 | # Note that if the AOF file will be found to be corrupted in the middle 769 | # the server will still exit with an error. This option only applies when 770 | # Redis will try to read more data from the AOF file but not enough bytes 771 | # will be found. 772 | #aof-load-truncated yes 773 | 774 | # When rewriting the AOF file, Redis is able to use an RDB preamble in the 775 | # AOF file for faster rewrites and recoveries. When this option is turned 776 | # on the rewritten AOF file is composed of two different stanzas: 777 | # 778 | # [RDB file][AOF tail] 779 | # 780 | # When loading Redis recognizes that the AOF file starts with the "REDIS" 781 | # string and loads the prefixed RDB file, and continues loading the AOF 782 | # tail. 783 | # 784 | # This is currently turned off by default in order to avoid the surprise 785 | # of a format change, but will at some point be used as the default. 786 | #aof-use-rdb-preamble no 787 | 788 | ################################ LUA SCRIPTING ############################### 789 | 790 | # Max execution time of a Lua script in milliseconds. 791 | # 792 | # If the maximum execution time is reached Redis will log that a script is 793 | # still in execution after the maximum allowed time and will start to 794 | # reply to queries with an error. 795 | # 796 | # When a long running script exceeds the maximum execution time only the 797 | # SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be 798 | # used to stop a script that did not yet called write commands. The second 799 | # is the only way to shut down the server in the case a write command was 800 | # already issued by the script but the user doesn't want to wait for the natural 801 | # termination of the script. 802 | # 803 | # Set it to 0 or a negative value for unlimited execution without warnings. 804 | #lua-time-limit 5000 805 | 806 | ################################ REDIS CLUSTER ############################### 807 | # 808 | # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 809 | # WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however 810 | # in order to mark it as "mature" we need to wait for a non trivial percentage 811 | # of users to deploy it in production. 812 | # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 813 | # 814 | # Normal Redis instances can't be part of a Redis Cluster; only nodes that are 815 | # started as cluster nodes can. In order to start a Redis instance as a 816 | # cluster node enable the cluster support uncommenting the following: 817 | # 818 | # cluster-enabled yes 819 | 820 | # Every cluster node has a cluster configuration file. This file is not 821 | # intended to be edited by hand. It is created and updated by Redis nodes. 822 | # Every Redis Cluster node requires a different cluster configuration file. 823 | # Make sure that instances running in the same system do not have 824 | # overlapping cluster configuration file names. 825 | # 826 | # cluster-config-file nodes-6379.conf 827 | cluster-config-file nodes-REDISPORT.conf 828 | 829 | # Cluster node timeout is the amount of milliseconds a node must be unreachable 830 | # for it to be considered in failure state. 831 | # Most other internal time limits are multiple of the node timeout. 832 | # 833 | # cluster-node-timeout 15000 834 | 835 | # A slave of a failing master will avoid to start a failover if its data 836 | # looks too old. 837 | # 838 | # There is no simple way for a slave to actually have an exact measure of 839 | # its "data age", so the following two checks are performed: 840 | # 841 | # 1) If there are multiple slaves able to failover, they exchange messages 842 | # in order to try to give an advantage to the slave with the best 843 | # replication offset (more data from the master processed). 844 | # Slaves will try to get their rank by offset, and apply to the start 845 | # of the failover a delay proportional to their rank. 846 | # 847 | # 2) Every single slave computes the time of the last interaction with 848 | # its master. This can be the last ping or command received (if the master 849 | # is still in the "connected" state), or the time that elapsed since the 850 | # disconnection with the master (if the replication link is currently down). 851 | # If the last interaction is too old, the slave will not try to failover 852 | # at all. 853 | # 854 | # The point "2" can be tuned by user. Specifically a slave will not perform 855 | # the failover if, since the last interaction with the master, the time 856 | # elapsed is greater than: 857 | # 858 | # (node-timeout * slave-validity-factor) + repl-ping-slave-period 859 | # 860 | # So for example if node-timeout is 30 seconds, and the slave-validity-factor 861 | # is 10, and assuming a default repl-ping-slave-period of 10 seconds, the 862 | # slave will not try to failover if it was not able to talk with the master 863 | # for longer than 310 seconds. 864 | # 865 | # A large slave-validity-factor may allow slaves with too old data to failover 866 | # a master, while a too small value may prevent the cluster from being able to 867 | # elect a slave at all. 868 | # 869 | # For maximum availability, it is possible to set the slave-validity-factor 870 | # to a value of 0, which means, that slaves will always try to failover the 871 | # master regardless of the last time they interacted with the master. 872 | # (However they'll always try to apply a delay proportional to their 873 | # offset rank). 874 | # 875 | # Zero is the only value able to guarantee that when all the partitions heal 876 | # the cluster will always be able to continue. 877 | # 878 | # cluster-slave-validity-factor 10 879 | 880 | # Cluster slaves are able to migrate to orphaned masters, that are masters 881 | # that are left without working slaves. This improves the cluster ability 882 | # to resist to failures as otherwise an orphaned master can't be failed over 883 | # in case of failure if it has no working slaves. 884 | # 885 | # Slaves migrate to orphaned masters only if there are still at least a 886 | # given number of other working slaves for their old master. This number 887 | # is the "migration barrier". A migration barrier of 1 means that a slave 888 | # will migrate only if there is at least 1 other working slave for its master 889 | # and so forth. It usually reflects the number of slaves you want for every 890 | # master in your cluster. 891 | # 892 | # Default is 1 (slaves migrate only if their masters remain with at least 893 | # one slave). To disable migration just set it to a very large value. 894 | # A value of 0 can be set but is useful only for debugging and dangerous 895 | # in production. 896 | # 897 | # cluster-migration-barrier 1 898 | 899 | # By default Redis Cluster nodes stop accepting queries if they detect there 900 | # is at least an hash slot uncovered (no available node is serving it). 901 | # This way if the cluster is partially down (for example a range of hash slots 902 | # are no longer covered) all the cluster becomes, eventually, unavailable. 903 | # It automatically returns available as soon as all the slots are covered again. 904 | # 905 | # However sometimes you want the subset of the cluster which is working, 906 | # to continue to accept queries for the part of the key space that is still 907 | # covered. In order to do so, just set the cluster-require-full-coverage 908 | # option to no. 909 | # 910 | # cluster-require-full-coverage yes 911 | 912 | # This option, when set to yes, prevents slaves from trying to failover its 913 | # master during master failures. However the master can still perform a 914 | # manual failover, if forced to do so. 915 | # 916 | # This is useful in different scenarios, especially in the case of multiple 917 | # data center operations, where we want one side to never be promoted if not 918 | # in the case of a total DC failure. 919 | # 920 | # cluster-slave-no-failover no 921 | 922 | # In order to setup your cluster make sure to read the documentation 923 | # available at http://redis.io web site. 924 | 925 | ########################## CLUSTER DOCKER/NAT support ######################## 926 | 927 | # In certain deployments, Redis Cluster nodes address discovery fails, because 928 | # addresses are NAT-ted or because ports are forwarded (the typical case is 929 | # Docker and other containers). 930 | # 931 | # In order to make Redis Cluster working in such environments, a static 932 | # configuration where each node knows its public address is needed. The 933 | # following two options are used for this scope, and are: 934 | # 935 | # * cluster-announce-ip 936 | # * cluster-announce-port 937 | # * cluster-announce-bus-port 938 | # 939 | # Each instruct the node about its address, client port, and cluster message 940 | # bus port. The information is then published in the header of the bus packets 941 | # so that other nodes will be able to correctly map the address of the node 942 | # publishing the information. 943 | # 944 | # If the above options are not used, the normal Redis Cluster auto-detection 945 | # will be used instead. 946 | # 947 | # Note that when remapped, the bus port may not be at the fixed offset of 948 | # clients port + 10000, so you can specify any port and bus-port depending 949 | # on how they get remapped. If the bus-port is not set, a fixed offset of 950 | # 10000 will be used as usually. 951 | # 952 | # Example: 953 | # 954 | # cluster-announce-ip 10.1.1.5 955 | # cluster-announce-port 6379 956 | # cluster-announce-bus-port 6380 957 | 958 | ################################## SLOW LOG ################################### 959 | 960 | # The Redis Slow Log is a system to log queries that exceeded a specified 961 | # execution time. The execution time does not include the I/O operations 962 | # like talking with the client, sending the reply and so forth, 963 | # but just the time needed to actually execute the command (this is the only 964 | # stage of command execution where the thread is blocked and can not serve 965 | # other requests in the meantime). 966 | # 967 | # You can configure the slow log with two parameters: one tells Redis 968 | # what is the execution time, in microseconds, to exceed in order for the 969 | # command to get logged, and the other parameter is the length of the 970 | # slow log. When a new command is logged the oldest one is removed from the 971 | # queue of logged commands. 972 | 973 | # The following time is expressed in microseconds, so 1000000 is equivalent 974 | # to one second. Note that a negative number disables the slow log, while 975 | # a value of zero forces the logging of every command. 976 | #slowlog-log-slower-than 10000 977 | 978 | # There is no limit to this length. Just be aware that it will consume memory. 979 | # You can reclaim memory used by the slow log with SLOWLOG RESET. 980 | #slowlog-max-len 128 981 | 982 | ################################ LATENCY MONITOR ############################## 983 | 984 | # The Redis latency monitoring subsystem samples different operations 985 | # at runtime in order to collect data related to possible sources of 986 | # latency of a Redis instance. 987 | # 988 | # Via the LATENCY command this information is available to the user that can 989 | # print graphs and obtain reports. 990 | # 991 | # The system only logs operations that were performed in a time equal or 992 | # greater than the amount of milliseconds specified via the 993 | # latency-monitor-threshold configuration directive. When its value is set 994 | # to zero, the latency monitor is turned off. 995 | # 996 | # By default latency monitoring is disabled since it is mostly not needed 997 | # if you don't have latency issues, and collecting data has a performance 998 | # impact, that while very small, can be measured under big load. Latency 999 | # monitoring can easily be enabled at runtime using the command 1000 | # "CONFIG SET latency-monitor-threshold " if needed. 1001 | #latency-monitor-threshold 0 1002 | 1003 | ############################# EVENT NOTIFICATION ############################## 1004 | 1005 | # Redis can notify Pub/Sub clients about events happening in the key space. 1006 | # This feature is documented at http://redis.io/topics/notifications 1007 | # 1008 | # For instance if keyspace events notification is enabled, and a client 1009 | # performs a DEL operation on key "foo" stored in the Database 0, two 1010 | # messages will be published via Pub/Sub: 1011 | # 1012 | # PUBLISH __keyspace@0__:foo del 1013 | # PUBLISH __keyevent@0__:del foo 1014 | # 1015 | # It is possible to select the events that Redis will notify among a set 1016 | # of classes. Every class is identified by a single character: 1017 | # 1018 | # K Keyspace events, published with __keyspace@__ prefix. 1019 | # E Keyevent events, published with __keyevent@__ prefix. 1020 | # g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... 1021 | # $ String commands 1022 | # l List commands 1023 | # s Set commands 1024 | # h Hash commands 1025 | # z Sorted set commands 1026 | # x Expired events (events generated every time a key expires) 1027 | # e Evicted events (events generated when a key is evicted for maxmemory) 1028 | # A Alias for g$lshzxe, so that the "AKE" string means all the events. 1029 | # 1030 | # The "notify-keyspace-events" takes as argument a string that is composed 1031 | # of zero or multiple characters. The empty string means that notifications 1032 | # are disabled. 1033 | # 1034 | # Example: to enable list and generic events, from the point of view of the 1035 | # event name, use: 1036 | # 1037 | # notify-keyspace-events Elg 1038 | # 1039 | # Example 2: to get the stream of the expired keys subscribing to channel 1040 | # name __keyevent@0__:expired use: 1041 | # 1042 | # notify-keyspace-events Ex 1043 | # 1044 | # By default all notifications are disabled because most users don't need 1045 | # this feature and the feature has some overhead. Note that if you don't 1046 | # specify at least one of K or E, no events will be delivered. 1047 | #notify-keyspace-events "" 1048 | 1049 | ############################### ADVANCED CONFIG ############################### 1050 | 1051 | # Hashes are encoded using a memory efficient data structure when they have a 1052 | # small number of entries, and the biggest entry does not exceed a given 1053 | # threshold. These thresholds can be configured using the following directives. 1054 | #hash-max-ziplist-entries 512 1055 | #hash-max-ziplist-value 64 1056 | 1057 | # Lists are also encoded in a special way to save a lot of space. 1058 | # The number of entries allowed per internal list node can be specified 1059 | # as a fixed maximum size or a maximum number of elements. 1060 | # For a fixed maximum size, use -5 through -1, meaning: 1061 | # -5: max size: 64 Kb <-- not recommended for normal workloads 1062 | # -4: max size: 32 Kb <-- not recommended 1063 | # -3: max size: 16 Kb <-- probably not recommended 1064 | # -2: max size: 8 Kb <-- good 1065 | # -1: max size: 4 Kb <-- good 1066 | # Positive numbers mean store up to _exactly_ that number of elements 1067 | # per list node. 1068 | # The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), 1069 | # but if your use case is unique, adjust the settings as necessary. 1070 | #list-max-ziplist-size -2 1071 | 1072 | # Lists may also be compressed. 1073 | # Compress depth is the number of quicklist ziplist nodes from *each* side of 1074 | # the list to *exclude* from compression. The head and tail of the list 1075 | # are always uncompressed for fast push/pop operations. Settings are: 1076 | # 0: disable all list compression 1077 | # 1: depth 1 means "don't start compressing until after 1 node into the list, 1078 | # going from either the head or tail" 1079 | # So: [head]->node->node->...->node->[tail] 1080 | # [head], [tail] will always be uncompressed; inner nodes will compress. 1081 | # 2: [head]->[next]->node->node->...->node->[prev]->[tail] 1082 | # 2 here means: don't compress head or head->next or tail->prev or tail, 1083 | # but compress all nodes between them. 1084 | # 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] 1085 | # etc. 1086 | #list-compress-depth 0 1087 | 1088 | # Sets have a special encoding in just one case: when a set is composed 1089 | # of just strings that happen to be integers in radix 10 in the range 1090 | # of 64 bit signed integers. 1091 | # The following configuration setting sets the limit in the size of the 1092 | # set in order to use this special memory saving encoding. 1093 | #set-max-intset-entries 512 1094 | 1095 | # Similarly to hashes and lists, sorted sets are also specially encoded in 1096 | # order to save a lot of space. This encoding is only used when the length and 1097 | # elements of a sorted set are below the following limits: 1098 | #zset-max-ziplist-entries 128 1099 | #zset-max-ziplist-value 64 1100 | 1101 | # HyperLogLog sparse representation bytes limit. The limit includes the 1102 | # 16 bytes header. When an HyperLogLog using the sparse representation crosses 1103 | # this limit, it is converted into the dense representation. 1104 | # 1105 | # A value greater than 16000 is totally useless, since at that point the 1106 | # dense representation is more memory efficient. 1107 | # 1108 | # The suggested value is ~ 3000 in order to have the benefits of 1109 | # the space efficient encoding without slowing down too much PFADD, 1110 | # which is O(N) with the sparse encoding. The value can be raised to 1111 | # ~ 10000 when CPU is not a concern, but space is, and the data set is 1112 | # composed of many HyperLogLogs with cardinality in the 0 - 15000 range. 1113 | #hll-sparse-max-bytes 3000 1114 | 1115 | # Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in 1116 | # order to help rehashing the main Redis hash table (the one mapping top-level 1117 | # keys to values). The hash table implementation Redis uses (see dict.c) 1118 | # performs a lazy rehashing: the more operation you run into a hash table 1119 | # that is rehashing, the more rehashing "steps" are performed, so if the 1120 | # server is idle the rehashing is never complete and some more memory is used 1121 | # by the hash table. 1122 | # 1123 | # The default is to use this millisecond 10 times every second in order to 1124 | # actively rehash the main dictionaries, freeing memory when possible. 1125 | # 1126 | # If unsure: 1127 | # use "activerehashing no" if you have hard latency requirements and it is 1128 | # not a good thing in your environment that Redis can reply from time to time 1129 | # to queries with 2 milliseconds delay. 1130 | # 1131 | # use "activerehashing yes" if you don't have such hard requirements but 1132 | # want to free memory asap when possible. 1133 | #activerehashing yes 1134 | 1135 | # The client output buffer limits can be used to force disconnection of clients 1136 | # that are not reading data from the server fast enough for some reason (a 1137 | # common reason is that a Pub/Sub client can't consume messages as fast as the 1138 | # publisher can produce them). 1139 | # 1140 | # The limit can be set differently for the three different classes of clients: 1141 | # 1142 | # normal -> normal clients including MONITOR clients 1143 | # slave -> slave clients 1144 | # pubsub -> clients subscribed to at least one pubsub channel or pattern 1145 | # 1146 | # The syntax of every client-output-buffer-limit directive is the following: 1147 | # 1148 | # client-output-buffer-limit 1149 | # 1150 | # A client is immediately disconnected once the hard limit is reached, or if 1151 | # the soft limit is reached and remains reached for the specified number of 1152 | # seconds (continuously). 1153 | # So for instance if the hard limit is 32 megabytes and the soft limit is 1154 | # 16 megabytes / 10 seconds, the client will get disconnected immediately 1155 | # if the size of the output buffers reach 32 megabytes, but will also get 1156 | # disconnected if the client reaches 16 megabytes and continuously overcomes 1157 | # the limit for 10 seconds. 1158 | # 1159 | # By default normal clients are not limited because they don't receive data 1160 | # without asking (in a push way), but just after a request, so only 1161 | # asynchronous clients may create a scenario where data is requested faster 1162 | # than it can read. 1163 | # 1164 | # Instead there is a default limit for pubsub and slave clients, since 1165 | # subscribers and slaves receive data in a push fashion. 1166 | # 1167 | # Both the hard or the soft limit can be disabled by setting them to zero. 1168 | #client-output-buffer-limit normal 0 0 0 1169 | #client-output-buffer-limit slave 256mb 64mb 60 1170 | #client-output-buffer-limit pubsub 32mb 8mb 60 1171 | 1172 | # Client query buffers accumulate new commands. They are limited to a fixed 1173 | # amount by default in order to avoid that a protocol desynchronization (for 1174 | # instance due to a bug in the client) will lead to unbound memory usage in 1175 | # the query buffer. However you can configure it here if you have very special 1176 | # needs, such us huge multi/exec requests or alike. 1177 | # 1178 | # client-query-buffer-limit 1gb 1179 | 1180 | # In the Redis protocol, bulk requests, that are, elements representing single 1181 | # strings, are normally limited ot 512 mb. However you can change this limit 1182 | # here. 1183 | # 1184 | # proto-max-bulk-len 512mb 1185 | 1186 | # Redis calls an internal function to perform many background tasks, like 1187 | # closing connections of clients in timeout, purging expired keys that are 1188 | # never requested, and so forth. 1189 | # 1190 | # Not all tasks are performed with the same frequency, but Redis checks for 1191 | # tasks to perform according to the specified "hz" value. 1192 | # 1193 | # By default "hz" is set to 10. Raising the value will use more CPU when 1194 | # Redis is idle, but at the same time will make Redis more responsive when 1195 | # there are many keys expiring at the same time, and timeouts may be 1196 | # handled with more precision. 1197 | # 1198 | # The range is between 1 and 500, however a value over 100 is usually not 1199 | # a good idea. Most users should use the default of 10 and raise this up to 1200 | # 100 only in environments where very low latency is required. 1201 | #hz 10 1202 | 1203 | # When a child rewrites the AOF file, if the following option is enabled 1204 | # the file will be fsync-ed every 32 MB of data generated. This is useful 1205 | # in order to commit the file to the disk more incrementally and avoid 1206 | # big latency spikes. 1207 | #aof-rewrite-incremental-fsync yes 1208 | 1209 | # Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good 1210 | # idea to start with the default settings and only change them after investigating 1211 | # how to improve the performances and how the keys LFU change over time, which 1212 | # is possible to inspect via the OBJECT FREQ command. 1213 | # 1214 | # There are two tunable parameters in the Redis LFU implementation: the 1215 | # counter logarithm factor and the counter decay time. It is important to 1216 | # understand what the two parameters mean before changing them. 1217 | # 1218 | # The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis 1219 | # uses a probabilistic increment with logarithmic behavior. Given the value 1220 | # of the old counter, when a key is accessed, the counter is incremented in 1221 | # this way: 1222 | # 1223 | # 1. A random number R between 0 and 1 is extracted. 1224 | # 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). 1225 | # 3. The counter is incremented only if R < P. 1226 | # 1227 | # The default lfu-log-factor is 10. This is a table of how the frequency 1228 | # counter changes with a different number of accesses with different 1229 | # logarithmic factors: 1230 | # 1231 | # +--------+------------+------------+------------+------------+------------+ 1232 | # | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | 1233 | # +--------+------------+------------+------------+------------+------------+ 1234 | # | 0 | 104 | 255 | 255 | 255 | 255 | 1235 | # +--------+------------+------------+------------+------------+------------+ 1236 | # | 1 | 18 | 49 | 255 | 255 | 255 | 1237 | # +--------+------------+------------+------------+------------+------------+ 1238 | # | 10 | 10 | 18 | 142 | 255 | 255 | 1239 | # +--------+------------+------------+------------+------------+------------+ 1240 | # | 100 | 8 | 11 | 49 | 143 | 255 | 1241 | # +--------+------------+------------+------------+------------+------------+ 1242 | # 1243 | # NOTE: The above table was obtained by running the following commands: 1244 | # 1245 | # redis-benchmark -n 1000000 incr foo 1246 | # redis-cli object freq foo 1247 | # 1248 | # NOTE 2: The counter initial value is 5 in order to give new objects a chance 1249 | # to accumulate hits. 1250 | # 1251 | # The counter decay time is the time, in minutes, that must elapse in order 1252 | # for the key counter to be divided by two (or decremented if it has a value 1253 | # less <= 10). 1254 | # 1255 | # The default value for the lfu-decay-time is 1. A Special value of 0 means to 1256 | # decay the counter every time it happens to be scanned. 1257 | # 1258 | # lfu-log-factor 10 1259 | # lfu-decay-time 1 1260 | 1261 | ########################### ACTIVE DEFRAGMENTATION ####################### 1262 | # 1263 | # WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested 1264 | # even in production and manually tested by multiple engineers for some 1265 | # time. 1266 | # 1267 | # What is active defragmentation? 1268 | # ------------------------------- 1269 | # 1270 | # Active (online) defragmentation allows a Redis server to compact the 1271 | # spaces left between small allocations and deallocations of data in memory, 1272 | # thus allowing to reclaim back memory. 1273 | # 1274 | # Fragmentation is a natural process that happens with every allocator (but 1275 | # less so with Jemalloc, fortunately) and certain workloads. Normally a server 1276 | # restart is needed in order to lower the fragmentation, or at least to flush 1277 | # away all the data and create it again. However thanks to this feature 1278 | # implemented by Oran Agra for Redis 4.0 this process can happen at runtime 1279 | # in an "hot" way, while the server is running. 1280 | # 1281 | # Basically when the fragmentation is over a certain level (see the 1282 | # configuration options below) Redis will start to create new copies of the 1283 | # values in contiguous memory regions by exploiting certain specific Jemalloc 1284 | # features (in order to understand if an allocation is causing fragmentation 1285 | # and to allocate it in a better place), and at the same time, will release the 1286 | # old copies of the data. This process, repeated incrementally for all the keys 1287 | # will cause the fragmentation to drop back to normal values. 1288 | # 1289 | # Important things to understand: 1290 | # 1291 | # 1. This feature is disabled by default, and only works if you compiled Redis 1292 | # to use the copy of Jemalloc we ship with the source code of Redis. 1293 | # This is the default with Linux builds. 1294 | # 1295 | # 2. You never need to enable this feature if you don't have fragmentation 1296 | # issues. 1297 | # 1298 | # 3. Once you experience fragmentation, you can enable this feature when 1299 | # needed with the command "CONFIG SET activedefrag yes". 1300 | # 1301 | # The configuration parameters are able to fine tune the behavior of the 1302 | # defragmentation process. If you are not sure about what they mean it is 1303 | # a good idea to leave the defaults untouched. 1304 | 1305 | # Enabled active defragmentation 1306 | # activedefrag yes 1307 | 1308 | # Minimum amount of fragmentation waste to start active defrag 1309 | # active-defrag-ignore-bytes 100mb 1310 | 1311 | # Minimum percentage of fragmentation to start active defrag 1312 | # active-defrag-threshold-lower 10 1313 | 1314 | # Maximum percentage of fragmentation at which we use maximum effort 1315 | # active-defrag-threshold-upper 100 1316 | 1317 | # Minimal effort for defrag in CPU percentage 1318 | # active-defrag-cycle-min 25 1319 | 1320 | # Maximal effort for defrag in CPU percentage 1321 | # active-defrag-cycle-max 75 1322 | 1323 | -------------------------------------------------------------------------------- /deploy/redis_cluster.nodes: -------------------------------------------------------------------------------- 1 | # 部署redis集群的机器列表 2 | # 第一列为节点IP, 3 | # 第二列为redis端口号,两者间可以空格、TAB、逗号、分号和竖线分隔 4 | # 以下每一行对应一个redis实例 5 | 127.0.0.1 6381 6 | 127.0.0.1 6382 7 | 127.0.0.1 6383 8 | 127.0.0.1 6384 9 | 127.0.0.1 6385 10 | 127.0.0.1 6386 -------------------------------------------------------------------------------- /move_redis_slot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Writed by yijian on 2020/8/10 3 | # 迁移 slot 工具,但一次只能迁移一个 slot 4 | # 5 | # 使用时,需要指定如下几个参数: 6 | # 1)参数1:必选参数,用于指定被迁移的 slot 7 | # 2)参数2:必选参数,用于指定源节点(格式为:ip:port) 8 | # 3)参数3:必选参数,用于指定目标节点(格式为:ip:port) 9 | # 6)参数4:可选参数,用于指定访问 redis 的密码 10 | # 11 | # 使用示例(将2020从10.9.12.8:1383迁移到10.9.12.9:1386): 12 | # move_redis_slot.sh 2020 10.9.12.8:1383 10.9.12.9:1386 13 | # 14 | # 执行本脚本时,有两个“确认”, 15 | # 第一个“确认”是提示参数是否正确, 16 | # 第二个“确认”是提示是否迁移已有的keys, 17 | # 如果输入非yes则只迁移slot,不迁移已有keys。 18 | 19 | # 确保redis-cli可用 20 | REDIS_CLI=${REDIS_CLI:-redis-cli} 21 | which "$REDIS_CLI" > /dev/null 2>&1 22 | if test $? -ne 0; then 23 | echo "\`redis-cli\` not exists or not executable" 24 | exit 1 25 | fi 26 | 27 | # 参数检查 28 | if test $# -ne 3 -a $# -ne 4; then 29 | echo -e "Usage: `basename $0` \033[1;33mslot\033[m source_node destition_node redis_password" 30 | echo -e "Example1: `basename $0` \033[1;33m2020\033[m 127.0.0.1:6379 127.0.0.1:6380" 31 | echo -e "Example2: `basename $0` \033[1;33m2020\033[m 127.0.0.1:6379 127.0.0.1:6380 password123456" 32 | exit 1 33 | fi 34 | 35 | SLOT=$1 36 | SRC_NODE="$2" 37 | DEST_NODE="$3" 38 | REDIS_PASSOWRD="$4" 39 | 40 | # 得到指定节点的 nodeid 41 | function get_node_id() 42 | { 43 | node="$1" 44 | node_ip="`echo $node|cut -d':' -f1`" 45 | node_port=`echo $node|cut -d':' -f2` 46 | 47 | # 得到对应的 nodeid 48 | $REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \ 49 | -h $node_ip -p $node_port \ 50 | CLUSTER NODES | awk -v node=$node -F'[ @]' '{if ($2==node) printf("%s",$1);}' 51 | } 52 | 53 | SRC_NODE_ID="`get_node_id $SRC_NODE`" 54 | SRC_NODE_IP="`echo $SRC_NODE|cut -d':' -f1`" 55 | SRC_NODE_PORT=`echo $SRC_NODE|cut -d':' -f2` 56 | DEST_NODE_ID="`get_node_id $DEST_NODE`" 57 | DEST_NODE_IP="`echo $DEST_NODE|cut -d':' -f1`" 58 | DEST_NODE_PORT=`echo $DEST_NODE|cut -d':' -f2` 59 | 60 | echo -e "\033[1;33mSource\033[m node: $SRC_NODE_IP:$SRC_NODE_PORT($SRC_NODE_ID)" 61 | echo -e "\033[1;33mDestition\033[m node: $DEST_NODE_IP:$DEST_NODE_PORT($DEST_NODE_ID)" 62 | if test -z "$SRC_NODE_ID"; then 63 | echo -e "Can not get the source node ID of \033[1;33m$SRC_NODE\033[m" 64 | exit 1 65 | fi 66 | if test -z "$DEST_NODE_ID"; then 67 | echo -e "Can not get the destition node ID of \033[1;33m$DEST_NODE\033[m" 68 | exit 1 69 | fi 70 | 71 | echo -en "Confirm to continue? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 72 | read -r -p " " input 73 | if test "$input" != "yes"; then 74 | exit 1 75 | fi 76 | echo "........." 77 | 78 | # 目标节点上执行 IMPORTING 操作 79 | # 如果 $SLOT 已在目标节点,则执行时报错“ERR I'm already the owner of hash slot 1987” 80 | echo -e "\033[1;33mImporting\033[m $SLOT from $SRC_NODE($SRC_NODE_ID) to $DEST_NODE($DEST_NODE_ID) ..." 81 | err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \ 82 | -h $DEST_NODE_IP -p $DEST_NODE_PORT \ 83 | CLUSTER SETSLOT $SLOT IMPORTING $SRC_NODE_ID` 84 | if test "X$err" != "XOK"; then 85 | echo "[destition://$DEST_NODE_IP:$DEST_NODE_PORT] $err" 86 | exit 1 87 | fi 88 | 89 | # 源节点上执行 MIGRATING 操作 90 | # 如果 $SLOT 并不在源节点上,则执行时报错“ERR I'm not the owner of hash slot 1987” 91 | echo -e "\033[1;33mMigrating\033[m $SLOT from $SRC_NODE($SRC_NODE_ID) to $DEST_NODE($DEST_NODE_ID) ..." 92 | err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \ 93 | -h $SRC_NODE_IP -p $SRC_NODE_PORT \ 94 | CLUSTER SETSLOT $SLOT MIGRATING $DEST_NODE_ID` 95 | if test "X$err" != "XOK"; then 96 | echo "[source://$SRC_NODE_IP:$SRC_NODE_PORT] $err" 97 | exit 1 98 | fi 99 | 100 | # 是否迁移已有的keys? 101 | echo -en "Migrate keys in slot://$SLOT? [\033[1;33myes\033[m/\033[1;33mno\033[m]" 102 | read -r -p " " input 103 | if test "$input" = "yes"; then 104 | first=1 # 是否第一轮keys迁移操作 105 | batch=1000 # 一次批量迁移的keys数 106 | timeout_ms=60000 # 超时时长(单位:毫秒) 107 | destination_db=0 # 对于redis集群,取值总是为0 108 | num_keys=0 109 | 110 | echo "........." 111 | echo -e "Migrating keys in slot://$SLOT ..." 112 | while true 113 | do 114 | # 在源节点上执行: 115 | # 借助命令“CLUSTER GETKEYSINSLOT”和命令“MIGRATE”迁移已有的keys 116 | keys="`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \ 117 | -h $SRC_NODE_IP -p $SRC_NODE_PORT \ 118 | CLUSTER GETKEYSINSLOT $SLOT $batch | tr '\n' ' ' | xargs`" 119 | if test -z "$keys"; then 120 | if test $first -eq 1; then 121 | echo -e "No any keys to migrate in slot://$SLOT" 122 | else 123 | echo -e "Finished migrating all keys (\033[1;33m$num_keys\033[m) in slot://$SLOT" 124 | fi 125 | break 126 | fi 127 | first=0 128 | n=`echo "$keys" | tr -cd ' ' | wc -c` 129 | num_keys=$(($num_keys + $n)) 130 | #echo -e "(\033[1;33m$n\033[m)$keys" 131 | 132 | # 在源节点上执行命令“MIGRATE”迁移到目标节点 133 | # MIGRATE returns OK on success, 134 | # or NOKEY if no keys were found in the source instance 135 | if test -z "$REDIS_PASSOWRD"; then 136 | err=`$REDIS_CLI --raw \ 137 | -h $SRC_NODE_IP -p $SRC_NODE_PORT \ 138 | MIGRATE $DEST_NODE_IP $DEST_NODE_PORT "" $destination_db $timeout_ms \ 139 | REPLACE KEYS $keys` 140 | else 141 | err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \ 142 | -h $SRC_NODE_IP -p $SRC_NODE_PORT \ 143 | MIGRATE $DEST_NODE_IP $DEST_NODE_PORT "" $destination_db $timeout_ms \ 144 | REPLACE AUTH "$REDIS_PASSOWRD" KEYS $keys` 145 | fi 146 | if test "X$err" = "XNOKEY"; then 147 | break 148 | fi 149 | echo -e "\033[1;33m$n\033[m keys migratd" 150 | done 151 | fi 152 | 153 | 154 | # 取得所有 master 节点 155 | nodes=(`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" -h $DEST_NODE_IP -p $DEST_NODE_PORT \ 156 | CLUSTER NODES | awk '{if (match($3,"master")) printf("%s\n",$2);}'`) 157 | 158 | # 在所有 master 节点上执行 NODE 操作 159 | # 实际上,只可对源节点和目标节点执行 NODE 操作, 160 | # 新的配置会自动在集群中传播。 161 | echo "........." 162 | for node in ${nodes[*]}; do 163 | node_ip="`echo $node|cut -d':' -f1`" 164 | node_port=`echo $node|cut -d':' -f2` 165 | echo -en "NODE: $node_ip:$node_port " 166 | err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \ 167 | -h $node_ip -p $node_port \ 168 | CLUSTER SETSLOT $SLOT NODE $DEST_NODE_ID` 169 | echo -e "\033[1;33m$err\033[m" 170 | done 171 | -------------------------------------------------------------------------------- /query_key_distribution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Writed by yijian on 2020/8/8 3 | # 查询key的分布信息 4 | # 可带5个参数: 5 | # 1)被查询key的前缀 6 | # 2)被查询key的数量 7 | # 3)目标redis的ip 8 | # 4)目标redis的端口号 9 | # 5)目标redis的访问密码,可选参数 10 | 11 | # 确保redis-cli可用 12 | REDIS_CLI=${REDIS_CLI:-redis-cli} 13 | which "$REDIS_CLI" > /dev/null 2>&1 14 | if test $? -ne 0; then 15 | echo "\`redis-cli\` not exists or not executable" 16 | exit 1 17 | fi 18 | 19 | # 参数检查 20 | if test $# -ne 4 -a $# -ne 5; then 21 | echo "Usage: `basename $0` key_prefix key_number redis_ip redis_port [redis_password]" 22 | echo "Example1: `basename $0` 'k:' 10 '127.0.0.1' 6379" 23 | echo "Example2: `basename $0` 'k:' 10 '127.0.0.1' 6379 'password123456'" 24 | exit 1 25 | fi 26 | 27 | KEY_PREFIX="$1" 28 | KEY_NUMBER=$2 29 | REDIS_IP=$3 30 | REDIS_PORT=$4 31 | REDIS_PASSOWRD="$5" 32 | 33 | declare -A map1 34 | declare -A map2 35 | for ((i=0; i<$KEY_NUMBER; ++i)) 36 | do 37 | key="${KEY_PREFIX}${i}" 38 | slot=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" -h $REDIS_IP -p $REDIS_PORT CLUSTER KEYSLOT "$key"` 39 | str=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" -h $REDIS_IP -p $REDIS_PORT GET "$key"` 40 | if test ! -z "$str"; then 41 | err=`echo "$str" | awk '{printf("%s",$1)}'` 42 | fi 43 | if test -z "$str" -o "$err" != "MOVED"; then 44 | node="$REDIS_IP:$REDIS_PORT" 45 | else 46 | node=`echo "$str" | awk '{printf("%s",$3)}'` 47 | fi 48 | echo -e "[${KEY_PREFIX}\033[1;33m${i}\033[m] slot=>\033[1;33m$slot\033[m node=>\033[1;33m$node\033[m" 49 | if test -z ${map1[$node]}; then 50 | map1[$node]="$key/$slot" 51 | map2[$node]=1 52 | else 53 | map1[$node]="${map1[$node]},$key/$slot" 54 | map2[$node]=$((${map2[$node]} + 1)) 55 | fi 56 | done 57 | 58 | if test ${#map1[@]} -gt 0; then 59 | printf "\n================\n" 60 | for node in ${!map1[@]};do 61 | printf "\033[1;33m%15s\033[m => (\033[1;33m%d\033[m)%s\n" "$node" ${map2[$node]} "${map1[$node]}" 62 | done 63 | fi 64 | -------------------------------------------------------------------------------- /query_redis_memory.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2018/9/2 3 | # Query the memory of all nodes in a cluster 4 | # 5 | # Output example: 6 | # $ ./query_redis_cluster.sh 192.168.0.31.21:6379 7 | # [192.168.0.31.21:6379] Used: 788.57M Max: 15.00G System: 125.56G 8 | # [192.168.0.31.22:6380] Used: 756.98M Max: 15.00G System: 125.56G 9 | # [192.168.0.31.23:6380] Used: 743.93M Max: 15.00G System: 125.56G 10 | # [192.168.0.31.24:6380] Used: 21.73M Max: 15.00G System: 125.56G 11 | # [192.168.0.31.25:6380] Used: 819.11M Max: 15.00G System: 125.56G 12 | # [192.168.0.31.24:6379] Used: 771.70M Max: 15.00G System: 125.56G 13 | # [192.168.0.31.26:6379] Used: 920.77M Max: 15.00G System: 125.56G 14 | # [192.168.0.31.27:6380] Used: 889.09M Max: 15.00G System: 125.27G 15 | # [192.168.0.31.28:6379] Used: 741.24M Max: 15.00G System: 125.56G 16 | # [192.168.0.31.29:6380] Used: 699.55M Max: 15.00G System: 125.56G 17 | # [192.168.0.31.27:6379] Used: 752.89M Max: 15.00G System: 125.27G 18 | # [192.168.0.31.21:6380] Used: 716.05M Max: 15.00G System: 125.56G 19 | # [192.168.0.31.23:6379] Used: 784.82M Max: 15.00G System: 125.56G 20 | # [192.168.0.31.26:6380] Used: 726.40M Max: 15.00G System: 125.56G 21 | # [192.168.0.31.25:6379] Used: 726.09M Max: 15.00G System: 125.56G 22 | # [192.168.0.31.29:6379] Used: 844.59M Max: 15.00G System: 125.56G 23 | # [192.168.0.31.28:6380] Used: 14.00M Max: 15.00G System: 125.56G 24 | # [192.168.0.31.22:6379] Used: 770.13M Max: 15.00G System: 125.56G 25 | 26 | REDIS_CLI=${REDIS_CLI:-redis-cli} 27 | REDIS_IP=${REDIS_IP:-127.0.0.1} 28 | REDIS_PORT=${REDIS_PORT:-6379} 29 | 30 | function usage() 31 | { 32 | echo "Usage: `basename $0` redis_node [redis-password]" 33 | echo "Example1: `basename $0` 127.0.0.1:6379" 34 | echo "Example2: `basename $0` 127.0.0.1:6379 redis-password" 35 | } 36 | 37 | # with two parameters: 38 | # 1) single redis node 39 | # 2) redis password 40 | if test $# -eq 0 -o $# -gt 2; then 41 | usage 42 | exit 1 43 | fi 44 | 45 | # 如果有两个参数,则第2个参数为密码 46 | redis_password= 47 | if test $# -eq 2; then 48 | redis_password="$2" 49 | fi 50 | 51 | eval $(echo "$1" | awk -F[\:] '{ printf("REDIS_IP=%s\nREDIS_PORT=%s\n",$1,$2) }') 52 | if test -z "$REDIS_IP" -o -z "$REDIS_PORT"; then 53 | echo "Parameter error" 54 | usage 55 | exit 1 56 | fi 57 | 58 | # 确保redis-cli可用 59 | which "$REDIS_CLI" > /dev/null 2>&1 60 | if test $? -ne 0; then 61 | echo "\`redis-cli\` not exists or not executable" 62 | exit 1 63 | fi 64 | 65 | if test -z "$redis_password"; then 66 | redis_nodes=`redis-cli -h $REDIS_IP -p $REDIS_PORT cluster nodes \ 67 | | awk -F[\ \:\@] '!/ERR/{ printf("%s:%s\n",$2,$3); }'` 68 | else 69 | redis_nodes=`redis-cli --no-auth-warning -a "$redis_password" -h $REDIS_IP -p $REDIS_PORT cluster nodes \ 70 | | awk -F[\ \:\@] '!/ERR/{ printf("%s:%s\n",$2,$3); }'` 71 | fi 72 | if test -z "$redis_nodes"; then 73 | # standlone 74 | #$REDIS_CLI -h $REDIS_IP -p $REDIS_PORT FLUSHALL 75 | $REDIS_CLI -h $REDIS_IP -p $REDIS_PORT INFO 76 | else 77 | # cluster 78 | for redis_node in $redis_nodes; 79 | do 80 | if test ! -z "$redis_node"; then 81 | eval $(echo "$redis_node" | awk -F[\:] '{ printf("redis_node_ip=%s\nredis_node_port=%s\n",$1,$2) }') 82 | 83 | if test ! -z "$redis_node_ip" -a ! -z "$redis_node_port"; then 84 | if test -z "$redis_password"; then 85 | items=(`$REDIS_CLI -h $redis_node_ip -p $redis_node_port INFO MEMORY 2>&1 | tr '\r' ' '`) 86 | else 87 | items=(`$REDIS_CLI --no-auth-warning -a "$redis_password" -h $redis_node_ip -p $redis_node_port INFO MEMORY 2>&1 | tr '\r' ' '`) 88 | fi 89 | 90 | used_memory_human=0 91 | used_memory_rss_human=0 92 | used_memory_peak_human=0 93 | maxmemory_human=0 94 | total_system_memory_human=0 95 | for item in "${items[@]}" 96 | do 97 | eval $(echo "$item" | awk -F[\:] '{ printf("name=%s\nvalue=%s\n",$1,$2) }') 98 | 99 | if test "$name" = "used_memory_human"; then 100 | used_memory_human=$value 101 | elif test "$name" = "used_memory_rss_human"; then 102 | used_memory_rss_human=$value 103 | elif test "$name" = "used_memory_peak_human"; then 104 | used_memory_peak_human=$value 105 | elif test "$name" = "maxmemory_human"; then 106 | maxmemory_human=$value 107 | elif test "$name" = "total_system_memory_human"; then 108 | total_system_memory_human=$value 109 | fi 110 | done 111 | 112 | echo -e "[\033[1;33m${redis_node_ip}:${redis_node_port}\033[m]\tVIRT: \033[0;32;32m$used_memory_human\033[m\tRSS: \033[0;32;32m$used_memory_rss_human\033[m\tPeak: \033[0;32;32m$used_memory_peak_human\033[m\tMax: \033[0;32;32m$maxmemory_human\033[m\tSystem: \033[0;32;32m$total_system_memory_human\033[m" 113 | fi 114 | fi 115 | done 116 | fi 117 | -------------------------------------------------------------------------------- /query_redis_queue.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2019/8/29 3 | # 查看redis队列长度工具, 4 | # 支持同时查看多个redis或redis集群的多个队列。 5 | # 6 | # 在使用之前,必须设置好三个环境变量: 7 | # 1)REDIS_PASSWORD 可不设置,指定访问redis的密码,没设置或值为空时表示密码为空。 8 | # 2)REDIS_CLUSTERS 必须设置,用于指定查询的redis或redis集群,如果是多套redis则密码得相同。 9 | # 3)REDIS_QUEUES 必须设置,用于指定查询的redis队列,队列key的前缀和数量以斜杠“/”分隔。 10 | # 11 | # REDIS_CLUSTERS示例1(单套redis集群): 12 | # REDIS_CLUSTERS="127.0.0.1:6379" 13 | # 14 | # REDIS_CLUSTERS示例2(多套redis集群,注意用“空格”分开): 15 | # REDIS_CLUSTERS="127.0.0.1:2021 127.0.0.1:3021" 16 | # 17 | # REDIS_QUEUES示例1(单组队列,队列key的前缀为kprefix,队列数9个): 18 | # REDIS_QUEUES="kprefix:/9" 19 | # 20 | # REDIS_QUEUES示例2(多组队列,注意用“空格”分开) 21 | # REDIS_QUEUES="kprefix1:/9 kprefix2:/11 kprefix3:/6" 22 | 23 | # 检查 redis-cli 是否可用 24 | # 依赖redis的命令行工具redis-cli 25 | # 一般建议将redis-cli放在/usr/local/bin目录下 26 | REDIS_CLI="" 27 | if test -x /usr/local/bin/redis-cli; then 28 | REDIS_CLI=/usr/local/bin/redis-cli 29 | else 30 | REDIS_CLI=redis-cli 31 | fi 32 | which $REDIS_CLI >/dev/null 1>&1 33 | if test $? -ne 0; then 34 | echo "\`redis-cli\` is not exists or not executable." 35 | echo "You can copy \`redis-cli\` to the directory \`/usr/local/bin\`." 36 | exit 1 37 | fi 38 | 39 | # 检查是否设置了环境变量 REDIS_CLUSTERS 40 | if test -z "$REDIS_CLUSTERS"; then 41 | echo "Environment variable \`REDIS_CLUSTERS\` is not set or is empty." 42 | exit 1 43 | fi 44 | # 字符串值转成数组值 45 | REDIS_CLUSTERS=(`echo $REDIS_CLUSTERS`) 46 | if test ${#REDIS_CLUSTERS[@]} -eq 0; then 47 | # 不是数组或者是空数组 48 | echo "Environment variable \`REDIS_CLUSTERS\` have an empty value." 49 | echo "Example1:" 50 | echo "export REDIS_CLUSTERS=\"127.0.0.1:6379\"" 51 | echo "Example2:" 52 | echo "export REDIS_CLUSTERS=\"127.0.0.1:2021 127.0.0.1:3021\"" 53 | exit 1 54 | fi 55 | 56 | # 检查是否设置了环境变量 REDIS_QUEUES 57 | if test -z "$REDIS_QUEUES"; then 58 | echo "Environment variable \`REDIS_QUEUES\` is not set or is empty." 59 | exit 1 60 | fi 61 | # 字符串值转成数组值 62 | REDIS_QUEUES=(`echo $REDIS_QUEUES`) 63 | if test ${#REDIS_QUEUES[@]} -eq 0; then 64 | # 不是数组或者是空数组 65 | echo "Environment variable \`REDIS_QUEUES\` have an empty value." 66 | echo "Example1:" 67 | echo "export REDIS_QUEUES=\"kprefix:/9\"" 68 | echo "Example2:" 69 | echo "export REDIS_QUEUES=\"kprefix1:/9 kprefix2:/11 kprefix3:/6\"" 70 | exit 1 71 | fi 72 | 73 | function view_all_clusters() 74 | { 75 | # 查看所有Redis集群 76 | for REDIS_NODE in ${REDIS_CLUSTERS[@]} 77 | do 78 | # 取得IP和端口 79 | eval $(echo "$REDIS_NODE" | awk -F[\ \:,\;\t]+ '{ printf("REDIS_IP=%s\nREDIS_PORT=%s\n",$1,$2); }') 80 | echo -e "\033[1;33m====================\033[m" 81 | echo -e "[\033[1;33m$REDIS_IP:$REDIS_PORT $DATE\033[m]" 82 | 83 | for queue in ${REDIS_QUEUES[@]} 84 | do 85 | total_qlen=0 # 所有队列加起来的总长度 86 | qnum=0 # 单个队列长度 87 | 88 | # qprefix 队列前缀 89 | # qnum 队列数 90 | eval $(echo "$queue" | awk -F[/]+ '{ printf("qprefix=%s\nqnum=%s\n",$1,$2); }') 91 | if test -z "$qnum" -o $qnum -eq 0; then 92 | continue 93 | fi 94 | 95 | echo -n "[$qprefix/$qnum]" 96 | for ((i=0; i<$qnum; ++i)) 97 | do 98 | if test -z "$REDIS_PASSWORD"; then 99 | qlen=`$REDIS_CLI --raw -c -h $REDIS_IP -p $REDIS_PORT LLEN "$qprefix$i"` 100 | else 101 | qlen=`$REDIS_CLI --no-auth-warning -a "$REDIS_PASSWORD" --raw -c -h $REDIS_IP -p $REDIS_PORT LLEN "$qprefix$i"` 102 | fi 103 | if test -z "$qlen"; then 104 | qlen=0 105 | fi 106 | total_qlen=$(($total_qlen+$qlen)) 107 | echo -n " $qlen" 108 | done 109 | echo -e " \033[1;33m$total_qlen\033[m" 110 | done 111 | echo "" 112 | done 113 | } 114 | 115 | while (true) 116 | do 117 | view_all_clusters 118 | sleep 2 119 | done 120 | -------------------------------------------------------------------------------- /query_redis_queues.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2021/5/12 3 | # 查看一个或多个 redis 队列长度工具 4 | # 可选带一个参数: 5 | # redis 队列配置文件,如果不指定则默认为当前目录下的 redis.queues 文件。 6 | # 7 | # redis.queues 文件的每一行格式要求为: 8 | # IP|port|password|prefix/num 9 | # 其中 password 为访问 redis 的密码,值可以为空, 10 | # prefix 为队列前缀,num 为队列个数。 11 | # 12 | # 输出结果: 13 | # 最后一个值为队列中元素个数,前面的值为各子队列中的元素个数。 14 | FILEPATH="$(readlink -f $0)" 15 | BASEDIR="$(dirname $FILEPATH)" # 本脚本文件所在目录 16 | interval_seconds=2 # 统计间隔(单位:秒) 17 | 18 | # 检查 redis-cli 是否可用 19 | # 依赖redis的命令行工具redis-cli 20 | # 一般建议将redis-cli放在/usr/local/bin目录下 21 | REDIS_CLI="" 22 | if test -x /usr/local/bin/redis-cli; then 23 | REDIS_CLI=/usr/local/bin/redis-cli 24 | else 25 | REDIS_CLI=redis-cli 26 | fi 27 | which $REDIS_CLI >/dev/null 1>&1 28 | if test $? -ne 0; then 29 | echo "\`redis-cli\` is not exists or not executable." 30 | echo "You can copy \`redis-cli\` to the directory \`/usr/local/bin\`." 31 | exit 1 32 | fi 33 | 34 | # 检查队列文件是否存在 35 | queues_file=redis.queues 36 | if test ! -f $queues_file; then 37 | echo "\`$queues_file\` is not exists" 38 | exit 1 39 | fi 40 | 41 | while true 42 | do 43 | sleep $interval_seconds 44 | 45 | # line 的格式: 46 | # IP:PORT|password|prefix/num 47 | while read line 48 | do 49 | if test -z $line; then 50 | break 51 | fi 52 | 53 | queue_load=0 54 | eval $(echo "$line"|awk -F[\|/] '{printf("ip=%s\nport=%s\npassword=%s\nprefix=%s\nnum=%s\n",$1,$2,$3,$4,$5);}') 55 | echo -en "[`date +'%Y-%m-%d %H:%M:%S'`][\033[1;33m$prefix\033[m/$num]" 56 | for ((i=0;i<$num;++i)) 57 | do 58 | if test -z "$password"; then 59 | sub_queue_load=`$REDIS_CLI -h $ip -p $port LLEN "$prefix:$i"` 60 | else 61 | sub_queue_load=`$REDIS_CLI --no-auth-warning -a "$password" -h $ip -p $port LLEN "$prefix:$i"` 62 | fi 63 | queue_load=$(($queue_load + $sub_queue_load)) 64 | echo -n " $sub_queue_load" 65 | done 66 | echo -e " \033[1;33m$queue_load\033[m" 67 | done < $queues_file 68 | echo "" 69 | done 70 | -------------------------------------------------------------------------------- /show_redis_map.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Writed by yijian on 2018/8/24 3 | # 源码位置:https://github.com/eyjian/redis-tools 4 | # 5 | # Redis集群部署注意事项: 6 | # 在一个物理IP上部署多个redis实例时,要避免: 7 | # 1) 一对master和slave出现在同一物理IP上(影响:物理机挂掉,部分keys彻底不可用) 8 | # 2) 同一物理IP上出现多个master(影响:物理机挂掉,将导致两对切换) 9 | # 10 | # 带2个参数, 11 | # 第1个参数为REdis的节点字符串, 12 | # 第2个参数可选,为连接REdis的密码。 13 | # 使用示例1)show_redis_map.sh 192.168.0.21:6380 14 | # 使用示例2)show_redis_map.sh 192.168.0.21:6380 password 15 | # 16 | # 检查Redis集群master和slave映射关系的命令行工具: 17 | # 1) 查看是否多master出现在同一IP; 18 | # 2) 查看一对master和slave出现在同一IP。 19 | # 20 | # 当同一IP出现二个或多个master,则相应的行标星显示, 21 | # 如果一对master和slave出现在同一IP上,则相应的行标星显示。 22 | # 23 | # 输出效果: 24 | # [01][MASTER] 192.168.0.21:6379 00cc3f37d938ee8ba672bc77b71d8e0a3881a98b 25 | # [02][MASTER] 192.168.0.22:6379 1115713e3c311166207f3a9f1445b4e32a9202d7 26 | # [03][MASTER] 192.168.0.23:6379 5cb6946f46ccdf543e5a1efada6806f3df72b727 27 | # [04][MASTER] 192.168.0.24:6379 b91b1309b05f0dcc1e3a2a9521b8c00702999744 28 | # [05][MASTER] 192.168.0.25:6379 00a1ba8e5cb940ba4171e0f4415b91cea96977bc 29 | # [06][MASTER] 192.168.0.26:6379 64facb201cc5c7d8cdccb5fa211af5e1a04a9786 30 | # [07][MASTER] 192.168.0.27:6379 f119780359c0e43d19592db01675df2f776181b1 31 | # [08][MASTER] 192.168.0.28:6379 d374e28578967f96dcb75041e30a5a1e23693e56 32 | # [09][MASTER] 192.168.0.29:6380 a153d2071251657004dbe77abd10e2de7f0a209a 33 | # 34 | # [01][SLAVE=>MASTER] 192.168.0.21:6380 => 192.168.0.28:6379 35 | # [02][SLAVE=>MASTER] 192.168.0.22:6380 => 192.168.0.25:6379 36 | # [03][SLAVE=>MASTER] 192.168.0.23:6380 => 192.168.0.24:6379 37 | # [04][SLAVE=>MASTER] 192.168.0.24:6380 => 192.168.0.23:6379 38 | # [05][SLAVE=>MASTER] 192.168.0.25:6380 => 192.168.0.22:6379 39 | # [06][SLAVE=>MASTER] 192.168.0.26:6380 => 192.168.0.27:6379 40 | # [07][SLAVE=>MASTER] 192.168.0.27:6380 => 192.168.0.29:6380 41 | # [08][SLAVE=>MASTER] 192.168.0.28:6380 => 192.168.0.21:6379 42 | # [09][SLAVE=>MASTER] 192.168.0.29:6379 => 192.168.0.26:6379 43 | 44 | REDIS_CLI=${REDIS_CLI:-redis-cli} 45 | REDIS_IP=${REDIS_IP:-127.0.0.1} 46 | REDIS_PORT=${REDIS_PORT:-6379} 47 | 48 | function usage() 49 | { 50 | echo "Usage: `basename $0` redis_node [redis-password]" 51 | echo "Example1: `basename $0` 127.0.0.1:6379" 52 | echo "Example2: `basename $0` 127.0.0.1:6379 redis-password" 53 | } 54 | 55 | # with a parameter: single redis node 56 | if test $# -ne 1 -a $# -ne 2; then 57 | usage 58 | exit 1 59 | fi 60 | 61 | # 检查参数 62 | eval $(echo "$1" | awk -F[\:] '{ printf("REDIS_IP=%s\nREDIS_PORT=%s\n",$1,$2) }') 63 | if test -z "$REDIS_IP" -o -z "$REDIS_PORT"; then 64 | echo "Parameter error" 65 | usage 66 | exit 1 67 | fi 68 | 69 | # 确保redis-cli可用 70 | which "$REDIS_CLI" > /dev/null 2>&1 71 | if test $? -ne 0; then 72 | echo -e "\`redis-cli\` not exists or not executable" 73 | exit 1 74 | fi 75 | 76 | # master映射表,key为master的id,value为master的“ip:port” 77 | declare -A master_map=() 78 | # slave映表,key为master的id,value为slave的“ip:port” 79 | declare -A slave_map=() 80 | master_nodes_str= 81 | master_slave_maps_str= 82 | 83 | # 如果出错,不用继续 84 | set -e 85 | 86 | # 找出所有master 87 | # 因为前面的“set -e”,所以如果第1步出错,则后面的awk将不会执行 88 | if test $# -eq 1; then 89 | masters=`$REDIS_CLI -h $REDIS_IP -p $REDIS_PORT CLUSTER NODES | awk -F[\ \@] '/master/{ printf("%s,%s\n",$1,$2); }' | sort` 90 | else 91 | masters=`$REDIS_CLI --no-auth-warning -a "$2" -h $REDIS_IP -p $REDIS_PORT CLUSTER NODES | awk -F[\ \@] '/master/{ printf("%s,%s\n",$1,$2); }' | sort` 92 | fi 93 | if test -z "$masters"; then 94 | # 可能是因为密码错误 95 | # (error) NOAUTH Authentication required. 96 | $REDIS_CLI --no-auth-warning -a "$2" -h $REDIS_IP -p $REDIS_PORT PING "hello" 97 | exit 1 98 | fi 99 | for master in $masters; 100 | do 101 | eval $(echo $master | awk -F[,] '{ printf("master_id=%s\nmaster_node=%s\n",$1,$2); }') 102 | 103 | master_map[$master_id]=$master_node 104 | if test -z "$master_nodes_str"; then 105 | master_nodes_str="$master_node|$master_id" 106 | else 107 | master_nodes_str="$master_node|$master_id,$master_nodes_str" 108 | fi 109 | done 110 | 111 | # 找出所有slave 112 | # “CLUSTER NODES”命令的输出格式当前有两个版本,需要awk需要根据NF的值做区分 113 | if test $# -eq 1; then 114 | slaves=`$REDIS_CLI -h $REDIS_IP -p $REDIS_PORT CLUSTER NODES | awk -F[\ \@] '/slave/{ if (NF==9) printf("%s,%s\n",$5,$2); else printf("%s,%s\n",$4,$2); }' | sort` 115 | else 116 | slaves=`$REDIS_CLI --no-auth-warning -a "$2" -h $REDIS_IP -p $REDIS_PORT CLUSTER NODES | awk -F[\ \@] '/slave/{ if (NF==9) printf("%s,%s\n",$5,$2); else printf("%s,%s\n",$4,$2); }' | sort` 117 | fi 118 | for slave in $slaves; 119 | do 120 | eval $(echo $slave | awk -F[,] '{ printf("master_id=%s\nslave_node=%s\n",$1,$2); }') 121 | slave_map[$master_id]=$slave_node 122 | done 123 | 124 | for key in ${!master_map[@]} 125 | do 126 | master_node=${master_map[$key]} 127 | slave_node=${slave_map[$key]} 128 | 129 | if test -z "$master_slave_maps_str"; then 130 | master_slave_maps_str="$slave_node|$master_node" 131 | else 132 | master_slave_maps_str="$slave_node|$master_node,$master_slave_maps_str" 133 | fi 134 | done 135 | 136 | # 显示所有master 137 | index=1 138 | old_master_node_ip= 139 | master_nodes_str=`echo "$master_nodes_str" | tr ',' '\n' | sort` 140 | for master_node_str in $master_nodes_str; 141 | do 142 | eval $(echo "$master_node_str" | awk -F[\|] '{ printf("master_node=%s\nmaster_id=%s\n", $1, $2); }') 143 | eval $(echo "$master_node" | awk -F[\:] '{ printf("master_node_ip=%s\nmaster_node_port=%s\n", $1, $2); }') 144 | 145 | tag= 146 | # 同一IP上出现多个master,标星 147 | if test "$master_node_ip" = "$old_master_node_ip"; then 148 | tag=" (*)" 149 | fi 150 | 151 | printf "[%02d][MASTER] %-20s \033[0;32;31m%s\033[m%s\n" $index "$master_node" "$master_id" "$tag" 152 | old_master_node_ip=$master_node_ip 153 | index=$((++index)) 154 | done 155 | 156 | # 显示所有slave到master的映射 157 | index=1 158 | echo "" 159 | master_slave_maps_str=`echo "$master_slave_maps_str" | tr ',' '\n' | sort` 160 | for master_slave_map_str in $master_slave_maps_str; 161 | do 162 | eval $(echo "$master_slave_map_str" | awk -F[\|] '{ printf("slave_node=%s\nmaster_node=%s\n", $1, $2); }') 163 | eval $(echo "$slave_node" | awk -F[\:] '{ printf("slave_node_ip=%s\nslave_node_port=%s\n", $1, $2); }') 164 | eval $(echo "$master_node" | awk -F[\:] '{ printf("master_node_ip=%s\nmaster_node_port=%s\n", $1, $2); }') 165 | 166 | tag= 167 | # 一对master和slave出现在同一IP,标星 168 | if test ! -z "$slave_node_ip" -a "$slave_node_ip" = "$master_node_ip"; then 169 | tag=" (*)" 170 | fi 171 | 172 | n=$(($index % 2)) 173 | if test $n -eq 0; then 174 | printf "[%02d][SLAVE=>MASTER] \033[1;33m%21s\033[m => \033[1;33m%s\033[m%s\n" $index $slave_node $master_node "$tag" 175 | else 176 | printf "[%02d][SLAVE=>MASTER] %21s => %s%s\n" $index $slave_node $master_node "$tag" 177 | fi 178 | 179 | index=$((++index)) 180 | done 181 | 182 | echo "" 183 | exit 0 184 | -------------------------------------------------------------------------------- /stop_redis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Writed by yijian on 2020/8/26 3 | # 停止监控在指定端口的 redis-server 进程 4 | # 执行依赖 netstat 和 awk 两个命令 5 | # 6 | # 带一个参数: 7 | # 1)参数1:redis-server 的监听端口号 8 | 9 | # 使用帮助函数 10 | function usage() 11 | { 12 | echo "Stop redis-server process listen on the given port." 13 | echo "Usage: `basename $0` redis-port" 14 | echo "Example: `basename $0` 6379" 15 | } 16 | 17 | # 参数检查 18 | if test $# -ne 1; then 19 | usage 20 | exit 1 21 | fi 22 | 23 | # 参数指定的 redis-server 监听端口 24 | REDIS_PORT=$1 25 | 26 | # 取得 redis-server 进程ID 27 | # 命令 ps 输出的时间格式有两种:“7月17”和“20:42”,所以端口所在字段有区别: 28 | pid=`ps -f -C redis-server | awk -v port=$REDIS_PORT -F'[ :]*' '{ if ($12==port || $13==port) print $2 }'` 29 | if test -z "$pid"; then 30 | echo "redis-server[$REDIS_PORT] is not running" 31 | else 32 | # 检查 $pid 是否为数字值, 33 | # 它可能是“12 34”这样的值,即包含了两个 pid。 34 | $(expr $pid + 0 > /dev/null 2>&1) 35 | if test $? -ne 0; then 36 | echo "Can not kill: \"$pid\"" 37 | else 38 | if test "$pid" -eq 0; then 39 | echo "redis-server[$REDIS_PORT]'s pid is 0" 40 | else 41 | echo "kill $pid (redis-server[$REDIS_PORT])" 42 | #kill -0 $pid 43 | kill $pid 44 | fi 45 | fi 46 | fi 47 | -------------------------------------------------------------------------------- /top_redis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Writed by yijian on 2020/9/5 3 | # 查看指定端口的 redis-server 进程的内存和CPU 4 | # 执行依赖 top 和 awk 两个命令, 5 | # 支持 mooon_ssh 远程批量执行。 6 | # 7 | # 带一个参数: 8 | # 1)参数1:redis-server 的监听端口号 9 | 10 | # 使用帮助函数 11 | function usage() 12 | { 13 | echo "Top redis-server process listen on the given port." 14 | echo "Usage: `basename $0` redis-port" 15 | echo "Example: `basename $0` 6379" 16 | } 17 | 18 | # 参数检查 19 | if test $# -ne 1; then 20 | usage 21 | exit 1 22 | fi 23 | 24 | # 参数指定的 redis-server 监听端口 25 | REDIS_PORT=$1 26 | 27 | # top 命令可能位于不同目录下 28 | TOP=/usr/bin/top 29 | which $TOP > /dev/null 2>&1 30 | if test $? -ne 0; then 31 | TOP=/bin/top 32 | which $TOP > /dev/null 2>&1 33 | if test $? -ne 0; then 34 | echo "\`top\` is not exists or is not executable." 35 | exit 1 36 | fi 37 | fi 38 | 39 | # 取得 redis-server 进程ID 40 | # 命令 ps 输出的时间格式有两种:“7月17”和“20:42”,所以端口所在字段有区别: 41 | pid=`ps -f -C redis-server | awk -v port=$REDIS_PORT -F'[ :]*' '{ if ($12==port || $13==port) print $2 }'` 42 | if test -z "$pid"; then 43 | echo "Can not get PID of redis-server:$REDIS_PORT" 44 | exit 1 45 | fi 46 | 47 | # 执行 top 之前需要设置好环境变量“TERM”,否则执行将报如下错: 48 | # TERM environment variable not set. 49 | export TERM=xterm 50 | 51 | # 后台方式执行命令 top 时, 52 | # 需要加上参数“-b”(非交互模式),不然报错“top: failed tty get” 53 | #$TOP -b -p $pid -n 1 | grep redis-serv+ 54 | eval $($TOP -b -p $pid -n 1 | awk '{ if (match($12,"redis-serv+")) printf("PID=%s\nUSER=%s\nPR=%s\nNI=%s\nVIRT=%s\nRES=%s\nSHR=%s\nS=%s\nCPU=%s\nMEM=%s\n",$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12); }') 55 | # PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 56 | echo -e "PID:\033[1;33m$PID\033[m USER:$USER PR:$PR NI:$NI VIRT:\033[1;33m$VIRT\033[m RES:\033[1;33m$RES\033[m SHR:$SHR S:$S %CPU:\033[1;33m$CPU\033[m %MEM:\033[1;33m$MEM\033[m" 57 | --------------------------------------------------------------------------------