文章目录

  • 一、Redis安装部署
  • 1、编译安装Redis
  • 2、配置conf文件
  • 二、命令工具
  • 1、redis-cli命令行工具
  • 2、redis-benchmark 测试工具
  • 三、Redis数据库常用命令
  • 1、全局命令
  • 2、字符串类型:string
  • 3、列表:list
  • 4、哈希:hash
  • 5、集合:set
  • 6、多数据库常用命令
  • 四、redis主从复制
  • 五、手动搭建部署集群
  • 1、安装redis集群节点
  • 2、手动配置节点发现
  • 3、Redis Cluster手动分配槽位
  • 4、Redis Cluster ASK路由测试
  • 5、模拟故障转移
  • 六、使用工具自动搭建部署Redis Cluster
  • 1、创建集群
  • 2、工具扩容节点

一、Redis安装部署

1、编译安装Redis

[root@redis-1 ~]# mkdir -p /data/soft
[root@redis-1 ~]# mkdir -p /opt/redis_cluster/redis_6379/{conf,logs,pid}
[root@redis-1 ~]# cd /data/soft
[root@redis-1 soft]# wget http://download.redis.io/releases/redis-5.0.7.tar.gz
[root@redis-1 soft]# tar xf redis-5.0.7.tar.gz -C /opt/redis_cluster/
[root@redis-1 soft]# ln -s /opt/redis_cluster/redis-5.0.7  /opt/redis_cluster/redis
[root@redis-1 soft]# cd /opt/redis_cluster/redis
[root@redis-1 redis]# make && make install

2、配置conf文件

[root@redis-1 ~]# vim /opt/redis_cluster/redis_6379/conf/6379.conf
bind 127.0.0.1 192.168.1.10       #监听的主机地址
port 6379       #端口
daemonize yes       #启用守护进程
pidfile /opt/redis_cluster/redis_6379/pid/redis_6379.pid       #指定PID文件
logfile /opt/redis_cluster/redis_6379/logs/redis_6379.log       #指定日志文件
databases 16       #设置redis启动时创建内存数据库的数量
dbfilename redis.rdb       #指定本地数据库文件名
dir /opt/redis_cluster/redis_6379       #指定本地数据库存放目录
save 900 1       #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 300 10       #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
save 60 10000       #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照
appendonly yes       #启用AOF持久化
appendfilename "redis.aof"       #指定AOF文件名
appendfsync everysec       #每秒同步一次
[root@redis-1 ~]# redis-server /opt/redis_cluster/redis_6379/conf/6379.conf
[root@redis-1 ~]# redis-cli shutdown
[root@redis-1 ~]# netstat -anput | grep redis
tcp        0      0 192.168.1.10:6379       0.0.0.0:*               LISTEN      16003/redis-server  
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN

二、命令工具

1、redis-cli命令行工具

[root@localhost ~]# redis-cli
127.0.0.1:6379> ping             //连接本机上的 Redis 数据库,检测 Redis 服务是否启动
PONG
127.0.0.1:6379> info             //查看 Redis 服务的统计信息
127.0.0.1:6379> help @list             //查看所有与List数据类型相关的命令
127.0.0.1:6379> help set             //查看set命令的命令帮助
127.0.0.1:6379> exit             //退出数据库,或者quit

通讯消息类型

说明

meet

用于通知新节点加入,消息发送者通知接受者加入到当前集群,meet 消息通信正常完成后,接收节点会加入到集群中并进行ping、 pong 消息交换

ping

集群内交换最频繁的消息,集群内每个节点每秒想多个其他节点发送 ping 消息,用于检测节点是否在线和交换彼此信息

Pong

当接收到 ping,meet 消息时,作为相应消息回复给发送方确认消息正常通信,节点也可以向集群内广播自身的 pong 消息来通知整个集群对自身状态进行更新

fail

当节点判定集群内另一个节点下线时,回向集群内广播一个fail 消息,其他节点收到 fail 消息之后把对应节点更新为下线状态

连接指定远程主机的 Redis 数据库

[root@redis-1 ~]# redis-cli -h 127.0.0.1 -p 6379             //-h指定远程主机,-p指定Redis服务的端口号,-a指定密码(无密码可省略)

2、redis-benchmark 测试工具

参数

说明

参数

说明

-h

指定服务器主机名

-p

指定服务器端口

-s

指定服务器 socketo

-c

指定并发连接数

-n

指定请求数

-d

以字节(B)的形式指定SET/GET值的数据大小

-k

1 =keep alive 0=reconnecto

-r

SET/GET/INCR使用随机key, SADD使用随机值

-P

通过管道传输< numreq>请求

-q

强制退出redis。仅显示query/sec值

–csv

以CSV格式输出

-I

生成循环,永久执行测试

-t

仅运行以逗号分隔的测试命令列表

-I

Idle模式。仅打开N个idle连接并等待

1、向IP地址为192.168.1.20,端口为 6379 的Redis服务器发送100个并发连接与10000个请求测试性能

[root@redis-1 ~]# redis-benchmark -h 192.168.1.20 -p 6379 -c 100 -n 100000
====== PING_INLINE ======
  100000 requests completed in 3.00 seconds
  100 parallel clients
  3 bytes payload
  keep alive: 1

0.01% <= 1 milliseconds
94.63% <= 2 milliseconds
99.63% <= 3 milliseconds
99.93% <= 4 milliseconds
99.97% <= 5 milliseconds
99.99% <= 6 milliseconds
100.00% <= 6 milliseconds
33311.12 requests per second
......

2、测试存取大小为100B的数据包的性能

[root@redis-1 ~]# redis-benchmark -h 192.168.1.20 -p 6379 -q -d 100
PING_INLINE: 34071.55 requests per second
PING_BULK: 33990.48 requests per second
SET: 34059.95 requests per second
GET: 34083.16 requests per second
INCR: 34013.61 requests per second
LPUSH: 34364.26 requests per second
RPUSH: 35473.57 requests per second
LPOP: 35523.98 requests per second
RPOP: 35625.22 requests per second
SADD: 34094.78 requests per second
HSET: 33288.95 requests per second
SPOP: 33760.97 requests per second
LPUSH (needed to benchmark LRANGE): 33355.57 requests per second
LRANGE_100 (first 100 elements): 33932.81 requests per second
LRANGE_300 (first 300 elements): 34293.55 requests per second
LRANGE_500 (first 450 elements): 33658.70 requests per second
LRANGE_600 (first 600 elements): 33534.54 requests per second
MSET (10 keys): 32819.17 requests per second

3、测试本机上Redis服务在进行set与Ipush操作时的性能

[root@redis-1 ~]# redis-benchmark -t set,lpush -n 100000 -q
SET: 71787.51 requests per second
LPUSH: 73637.70 requests per second

三、Redis数据库常用命令

1、全局命令

[root@redis-1 ~]# redis-cli
127.0.0.1:6379> keys *             //列出所有键值名,但在企业环境禁止使用
1) "mylist"
2) "v5"
3) "k2"
4) "k3"
5) "k1"
6) "v1"
7) "key:__rand_int__"
127.0.0.1:6379> keys v*             //查看当前数据库中以v开头的数据
1) "v5"
2) "v22"
3) "v1"
127.0.0.1:6379> keys v?             //查看当前数据库中以v开头后面包含任意一位的数据
1) "v5"
2) "v1"
127.0.0.1:6379> keys v??             //查看当前数据库中以v开头后面包含任意两位的数据
1) "v22"
127.0.0.1:6379> DBSIZE             //查看有多少键值数
(integer) 8
127.0.0.1:6379> EXISTS k1             //查看键值是否存在
(integer) 1
127.0.0.1:6379> EXPIRE k2 20             //设置K2过期时间为20秒,20秒后k2自动取消
(integer) 1
127.0.0.1:6379> PERSIST k2             //取消k2的过期时间
(integer) 1
127.0.0.1:6379> TTL k2             //查看k2的生命周期
(integer) 15
127.0.0.1:6379> TYPE k1             //查看数据类型
string

2、字符串类型:string

[root@redis-1 ~]# redis-cli
127.0.0.1:6379> set k1 1             //创建键值
OK
127.0.0.1:6379> get k1             //查看键值
"1"
127.0.0.1:6379> del k1             //删除键值 
(integer) 1
127.0.0.1:6379> get k1             //查看键值
(nil)
127.0.0.1:6379> exists v22             //判断v22键是否存在
(integer) 1             //表示v22键存在
127.0.0.1:6379> exists v2             //判断v2键是否存在
(integer) 0             //表示v2键不存在
127.0.0.1:6379> keys v*             //查看当前数据库中以v开头的数据
1) "v5"
2) "v22"
3) "v1"
127.0.0.1:6379> rename v22 v2             //将v22重命名为v2
OK
127.0.0.1:6379> keys v*             //查看当前数据库中以v开头的数据
1) "v2"
2) "v5"
3) "v1"
127.0.0.1:6379> get v1             //查看键值
"4"
127.0.0.1:6379> get v2             //查看键值
"5"
127.0.0.1:6379> rename v1 v2             //将v1重命名为v2
OK
127.0.0.1:6379> get v1             //查看键值
(nil)
127.0.0.1:6379> get v2             //查看键值
"4"             //源key的值会覆盖目标key的值
127.0.0.1:6379> get v2
"4"
127.0.0.1:6379> get k2
"2"
127.0.0.1:6379> renamenx v2 k2
(integer) 0             //目标key存在则不进行重命名
127.0.0.1:6379> INCR k3             //键值k3为整数,递增加1
(integer) 4
127.0.0.1:6379> INCRBY k3 10             //递增k3的量值10 
(integer) 14
127.0.0.1:6379> MSET k4 v4 k5 v5 k6 v6 k7 v7             //批量创建键值
OK
127.0.0.1:6379> MGET k4 k5 k6 k7             //批量查看键值
1) "v4"
2) "v5"
3) "v6"
4) "v7"

3、列表:list

127.0.0.1:6379> RPUSH list1 1 2 3 4             //创建列表list1,值为1 2 3 4
(integer) 4
127.0.0.1:6379> RPUSH list1 5 6 7 8             //在list1右侧添加5 6 7 8
(integer) 8
127.0.0.1:6379> LPUSH list1 0             //在list1左侧添加0
(integer) 9
127.0.0.1:6379> LRANGE list1 0  -1             //查看list1所有值
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"
7) "6"
8) "7"
9) "8"
127.0.0.1:6379> RPOP list1             //删除右侧最后一个值
"8"
127.0.0.1:6379> LPOP list1             //删除左侧第一个值
"0"
127.0.0.1:6379> LTRIM list1 0 2             //仅保留前3位,其他值删除
OK
127.0.0.1:6379> LRANGE list1 0  -1
1) "1"
2) "2"
3) "3"

4、哈希:hash

127.0.0.1:6379> HMSET user:1000 username zhangsan age 17 job it             //创建hash键值user:1000 
OK
127.0.0.1:6379> HGET user:1000 username             //查看键值中username参数
"zhangsan"
127.0.0.1:6379> HGET user:1000 age             //查看键值中age参数
"17"
127.0.0.1:6379> HGET user:1000 job             //查看键值中job参数
"it"
127.0.0.1:6379> HMSET user:1000 tel 18866668888             //添加值tel
OK

5、集合:set

127.0.0.1:6379> SADD set1 1 2 3             //创建集合set1
(integer) 3
127.0.0.1:6379> SMEMBERS set1             //查看集合set1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> SADD set1 1 4             //为集合set1添加值1 4 ,但集合特性是去除重复,所以1无法再添加
(integer) 1
127.0.0.1:6379> SREM set1 1 4             //删除集合的值1 4
(integer) 2
127.0.0.1:6379> sadd set2 1 4 5             //创建第二个集合set2
(integer) 3
127.0.0.1:6379> SDIFF set1 set2             //求差集
1) "2"
2) "3"
127.0.0.1:6379> SINTER set1 set2             //求合集(交集)
(empty list or set)
127.0.0.1:6379> SUNION set1 set2             //求并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"

6、多数据库常用命令

1、多数据库间切换:使用select命令切换数据库

127.0.0.1:6379> select 10
OK
127.0.0.1:6379[10]> select 15
OK
127.0.0.1:6379[15]> select 0
OK

2、多数据库间移动数据
Redis的多数据库在一定程度上是相对独立的。例如,在数据库0上面存放的K1的数据,在其他的1-15的数据库上是无法查看到的。

127.0.0.1:6379> set k1 100
OK
127.0.0.1:6379> get k1
"100"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get k1
(nil)

Redis数据库提供了一个move命令,其可以进行多数据库的数据移动。命令的基本语法格式为 “move key dbindex” 。其中,key表示当前数据库的目标键,dbindex表示目标数据库的序号

127.0.0.1:6379> get k1
"100"
127.0.0.1:6379> move k1 1
(integer) 1
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get k1
"100"
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> get k1
(nil)

3、清除数据库内数据
清空当前数据库的数据,使用FLUSHDB命令
清空所有数据库的数据,使用FLUSHALL命令

四、redis主从复制

[root@redis-1 ~]# scp -rp /opt/redis_cluster/ root@192.168.1.20:/opt             //把第一台服务器的redis安装目录,scp到第二台服务器上
[root@redis-2 ~]# cd /opt/redis_cluster/redis
[root@redis-2 redis]# make install             //安装redis
[root@redis-2 redis]# vim /opt/redis_cluster/redis_6379/conf/6379.conf 
bind 127.0.0.1 192.168.1.20
#将当前服务器转变为指定服务器的从属服务器
slaveof 192.168.1.10 6379
......
[root@redis-2 redis]# redis-server /opt/redis_cluster/redis_6379/conf/6379.conf

五、手动搭建部署集群

1、安装redis集群节点

redis1操作

[root@redis-1 ~]# mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}             //redis安装目录
[root@redis-1 ~]# mkdir -p /data/redis_cluster/redis_{6380,6381}             //redis数据目录
[root@redis-1 ~]# vim /opt/redis_cluster/redis_6380/conf/redis_6380.conf
bind 192.168.1.10
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_cluster/redis_6380/"
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
[root@redis-1 ~]# cd /opt/redis_cluster/
[root@redis-1 redis_cluster]# cp redis_6380/conf/redis_6380.conf redis_6381/conf/redis_6381.conf
[root@redis-1 redis_cluster]# sed -i 's#6380#6381#g' redis_6381/conf/redis_6381.conf 
[root@redis-1 redis_cluster]# redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-1 redis_cluster]# redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
[root@redis-1 redis_cluster]# cd
[root@redis-1 ~]# scp -rp /opt/redis_cluster/ root@192.168.1.20:/opt/             //复制redis1的安装和数据目录到redis2、redis3
[root@redis-1 ~]# scp -rp /opt/redis_cluster/ root@192.168.1.30:/opt/

redis2操作

[root@redis-2 ~]# cd /opt/redis_cluster/redis
[root@redis-2 redis]# make install
[root@redis-2 redis]# find /opt/redis_cluster/redis_638* -type f -name "*.conf" | xargs sed -i "s#10#20#g"
[root@redis-2 ~]# mkdir -p /data/redis_cluster/redis_{6380,6381}
[root@redis-2 ~]# redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-2 ~]# redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf

redis3操作

[root@redis-3 ~]# cd /opt/redis_cluster/redis
[root@redis-3 redis]# make install
[root@redis-3 redis]# find /opt/redis_cluster/redis_638* -type f -name "*.conf"|xargs sed -i "s#10#30#g"
[root@redis-3 ~]# mkdir -p /data/redis_cluster/redis_{6380,6381}
[root@redis-3 ~]# redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-3 ~]# redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
[root@redis-3 ~]# ps aux | grep redis
root      35574  0.0  0.4 153836  7712 ?        Ssl  15:45   0:00 redis-server 192.168.1.30:6380 [cluster]
root      35663  0.0  0.4 153836  7716 ?        Ssl  15:45   0:00 redis-server 192.168.1.30:6381 [cluster]
root      36258  0.0  0.0 112664  1008 pts/0    S+   15:47   0:00 grep --color=auto redis

2、手动配置节点发现

[root@redis-1 ~]# vim redis_shell.sh             //redis运维脚本
#!/bin/bash

USAG(){
    echo "sh $0 {start|stop|restart|login|ps|tail} PORT"
}
if [ "$#" = 1 ]
then
    REDIS_PORT='6379'
elif 
    [ "$#" = 2 -a -z "$(echo "$2"|sed 's#[0-9]##g')" ]
then
    REDIS_PORT="$2"
else
    USAG
    exit 0
fi

REDIS_IP=$(hostname -I|awk '{print $1}')
PATH_DIR=/opt/redis_cluster/redis_${REDIS_PORT}/
PATH_CONF=/opt/redis_cluster/redis_${REDIS_PORT}/conf/redis_${REDIS_PORT}.conf
PATH_LOG=/opt/redis_cluster/redis_${REDIS_PORT}/logs/redis_${REDIS_PORT}.log

CMD_START(){
    redis-server ${PATH_CONF}
}

CMD_SHUTDOWN(){
    redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT} shutdown
}

CMD_LOGIN(){
    redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT}
}

CMD_PS(){
    ps -ef|grep redis
}

CMD_TAIL(){
    tail -f ${PATH_LOG}
}

case $1 in
    start)
        CMD_START
        CMD_PS
        ;;
    stop)
        CMD_SHUTDOWN
        CMD_PS
        ;;
    restart)
        CMD_START
        CMD_SHUTDOWN
        CMD_PS
        ;;
    login)
        CMD_LOGIN
        ;;
    ps)
        CMD_PS
        ;;
    tail)
        CMD_TAIL
        ;;
    *)
        USAG
esac
[root@redis-1 ~]# sh redis_shell.sh login 6380
192.168.1.10:6380> CLUSTER MEET 192.168.1.10 6381             //将192.168.1.10:6381添加到集群当中
OK
192.168.1.10:6380>  CLUSTER MEET 192.168.1.20 6380
OK
192.168.1.10:6380> CLUSTER MEET 192.168.1.30 6380
OK
192.168.1.10:6380> CLUSTER MEET 192.168.1.20 6381
OK
192.168.1.10:6380> CLUSTER MEET 192.168.1.30 6381
OK
192.168.1.10:6380> CLUSTER NODES             //列出集群当前已知的所有节点
8c57f9393090404c0ada0d258a964dec3583f191 192.168.1.10:6381@16381 master - 0 1596032980568 1 connected
f0672e893f80b751abe49862aafb7740dfa34506 192.168.1.30:6381@16381 master - 0 1596032981000 5 connected
c92419d7d715447a422df4e954d31d924a85b39c 192.168.1.20:6380@16380 master - 0 1596032978000 4 connected
f57ff74970ef3c24d450e1b141ee911e91bc6350 192.168.1.20:6381@16381 master - 0 1596032981585 0 connected
b25723025c04492fac759645d75477efc01d7dbd 192.168.1.10:6380@16380 myself,master - 0 1596032979000 2 connected
0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 192.168.1.30:6380@16380 master - 0 1596032979544 3 connected

Redis集群常用命令

说明

CLUSTER INFO

打印集群的信息

CLUSTER NODES

列出集群当前已知的所有节点(node),以及这些节点的相关信息

CLUSTER MEET ip port

将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子

CLUSTER FORGET node_id

从集群中移除 node_id 指定的节点

CLUSTER REPLICATE node_id

将当前节点设置为 node_id 指定的节点的从节点

CLUSTER SAVECONFIG

将节点的配置文件保存到硬盘里面

CLUSTER ADDSLOTS slot [slot …]

将一个或多个槽(slot)指派(assign)给当前节点

CLUSTER DELSLOTS slot [slot …]

移除一个或多个槽对当前节点的指派

CLUSTER FLUSHSLOTS

移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点

CLUSTER SETSLOT slot NODE node_id

将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派

CLUSTER SETSLOT slot MIGRATING node_id

将本节点的槽 slot 迁移到 node_id 指定的节点中

CLUSTER SETSLOT slot IMPORTING node_id

从 node_id 指定的节点中导入槽 slot 到本节点

CLUSTER SETSLOT slot STABLE

取消对槽 slot 的导入(import)或者迁移(migrate)

CLUSTER KEYSLOT key

计算键 key 应该被放置在哪个槽上

CLUSTER COUNTKEYSINSLOT slot

返回槽 slot 目前包含的键值对数量

CLUSTER GETKEYSINSLOT slot count

返回 count 个 slot 槽中的键

3、Redis Cluster手动分配槽位

[root@redis-1 ~]# redis-cli -h 192.168.1.10 -p 6380 cluster addslots {0..5461}             //分配槽位
OK
[root@redis-1 ~]# redis-cli -h 192.168.1.20 -p 6380 cluster addslots {5462..10922}
OK
[root@redis-1 ~]# redis-cli -h 192.168.1.30 -p 6380 cluster addslots {10923..16383}
OK
[root@redis-1 ~]# sh redis_shell.sh login 6380 
192.168.1.10:6380> CLUSTER NODES
8c57f9393090404c0ada0d258a964dec3583f191 192.168.1.10:6381@16381 slave c92419d7d715447a422df4e954d31d924a85b39c 0 1596033441077 4 connected
f0672e893f80b751abe49862aafb7740dfa34506 192.168.1.30:6381@16381 slave b25723025c04492fac759645d75477efc01d7dbd 0 1596033438029 5 connected
c92419d7d715447a422df4e954d31d924a85b39c 192.168.1.20:6380@16380 master - 0 1596033442088 4 connected 5462-10922             //已分配(主节点)
f57ff74970ef3c24d450e1b141ee911e91bc6350 192.168.1.20:6381@16381 slave 0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 0 1596033439041 3 connected
b25723025c04492fac759645d75477efc01d7dbd 192.168.1.10:6380@16380 myself,master - 0 1596033441000 2 connected 0-5461             //已分配(主节点)
0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 192.168.1.30:6380@16380 master - 0 1596033440062 3 connected 10923-16383             //已分配(主节点)
[root@redis-1 ~]# redis-cli -h 192.168.1.10 -p 6381 CLUSTER REPLICATE c92419d7d715447a422df4e954d31d924a85b39c             //将当前节点设置为192.168.1.20:6380的从节点
OK
[root@redis-1 ~]# redis-cli -h 192.168.1.20 -p 6381 CLUSTER REPLICATE 0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5             //将当前节点设置为192.168.1.30:6380的从节点
OK
[root@redis-1 ~]# redis-cli -h 192.168.1.30 -p 6381 CLUSTER REPLICATE b25723025c04492fac759645d75477efc01d7dbd             //将当前节点设置为192.168.1.10:6380的从节点
OK
[root@redis-1 ~]# sh redis_shell.sh login 6380 
192.168.1.10:6380> CLUSTER INFO             //打印集群的信息
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:2
cluster_stats_messages_ping_sent:482
cluster_stats_messages_pong_sent:505
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:992
cluster_stats_messages_ping_received:505
cluster_stats_messages_pong_received:487
cluster_stats_messages_received:992
192.168.1.10:6380> CLUSTER NODES
8c57f9393090404c0ada0d258a964dec3583f191 192.168.1.10:6381@16381 slave c92419d7d715447a422df4e954d31d924a85b39c 0 1596033441077 4 connected
f0672e893f80b751abe49862aafb7740dfa34506 192.168.1.30:6381@16381 slave b25723025c04492fac759645d75477efc01d7dbd 0 1596033438029 5 connected
c92419d7d715447a422df4e954d31d924a85b39c 192.168.1.20:6380@16380 master - 0 1596033442088 4 connected 5462-10922
f57ff74970ef3c24d450e1b141ee911e91bc6350 192.168.1.20:6381@16381 slave 0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 0 1596033439041 3 connected
b25723025c04492fac759645d75477efc01d7dbd 192.168.1.10:6380@16380 myself,master - 0 1596033441000 2 connected 0-5461
0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 192.168.1.30:6380@16380 master - 0 1596033440062 3 connected 10923-16383

4、Redis Cluster ASK路由测试

[root@redis-1 ~]# vim input_key.sh
#!/bin/bash
for i in $(seq 1 1000)
do
    redis-cli -c -h 192.168.1.10 -p 6380 set k_${i} v_${i} && echo "set k_${i} is ok"
done
[root@redis-1 ~]# sh input_key.sh 
[root@redis-1 ~]# redis-cli -c -h 192.168.1.10 -p 6380
192.168.1.10:6380> get k_1
"v_1"
192.168.1.10:6380> get k_100
-> Redirected to slot [5541] located at 192.168.1.20:6380             //定位到192.168.1.20:6380
"v_100"
192.168.1.20:6380> get k_1000
-> Redirected to slot [79] located at 192.168.1.10:6380             //定位到192.168.1.10:6380
"v_1000"
192.168.1.10:6380> exit

5、模拟故障转移

[root@redis-2 ~]# pkill redis-server             //中止redis2的服务
[root@redis-1 ~]# sh redis_shell.sh tail 6380             //查看日志
73050:M 29 Jul 2020 22:29:10.145 # IP address for this node updated to 192.168.1.10
73050:M 29 Jul 2020 22:36:08.157 # Cluster state changed: ok
73050:M 29 Jul 2020 22:37:03.562 * Replica 192.168.1.30:6381 asks for synchronization
73050:M 29 Jul 2020 22:37:03.562 * Partial resynchronization not accepted: Replication ID mismatch (Replica asked for '448427f9eaf3c5872f0ee92431a3ff457ee09f4a', my replication IDs are '457f10755e59ab129adfdab9af3af316bb54ece1' and '0000000000000000000000000000000000000000')
73050:M 29 Jul 2020 22:37:03.562 * Starting BGSAVE for SYNC with target: disk
73050:M 29 Jul 2020 22:37:03.565 * Background saving started by pid 73274
73274:C 29 Jul 2020 22:37:03.569 * DB saved on disk
73274:C 29 Jul 2020 22:37:03.569 * RDB: 4 MB of memory used by copy-on-write
73050:M 29 Jul 2020 22:37:03.657 * Background saving terminated with success
73050:M 29 Jul 2020 22:37:03.657 * Synchronization with replica 192.168.1.30:6381 succeeded
73050:M 29 Jul 2020 22:52:03.297 * Marking node c92419d7d715447a422df4e954d31d924a85b39c as failing (quorum reached).             //192.168.1.20:6380连接失败
73050:M 29 Jul 2020 22:52:03.297 * Marking node f57ff74970ef3c24d450e1b141ee911e91bc6350 as failing (quorum reached).             //192.168.1.20:6381连接失败
73050:M 29 Jul 2020 22:52:03.298 # Cluster state changed: fail             //集群状态更改:失败
73050:M 29 Jul 2020 22:52:04.060 # Failover auth granted to 8c57f9393090404c0ada0d258a964dec3583f191 for epoch 6             //故障转移授权
73050:M 29 Jul 2020 22:52:04.101 # Cluster state changed: ok             //集群状态更改
[root@redis-2 ~]# redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf
[root@redis-2 ~]# redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
[root@redis-1 ~]# sh redis_shell.sh login 6380 
192.168.1.10:6380> CLUSTER NODES
8c57f9393090404c0ada0d258a964dec3583f191 192.168.1.10:6381@16381 master - 0 1596034622000 6 connected 5462-10922
f0672e893f80b751abe49862aafb7740dfa34506 192.168.1.30:6381@16381 slave b25723025c04492fac759645d75477efc01d7dbd 0 1596034624939 5 connected
c92419d7d715447a422df4e954d31d924a85b39c 192.168.1.20:6380@16380 slave 8c57f9393090404c0ada0d258a964dec3583f191 0 1596034624000 6 connected
f57ff74970ef3c24d450e1b141ee911e91bc6350 192.168.1.20:6381@16381 slave 0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 0 1596034623925 3 connected
b25723025c04492fac759645d75477efc01d7dbd 192.168.1.10:6380@16380 myself,master - 0 1596034622000 2 connected 0-5461
0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 192.168.1.30:6380@16380 master - 0 1596034622918 3 connected 10923-16383
192.168.1.10:6380> exit
[root@redis-2 ~]# redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf             //重新启动redis2的服务
[root@redis-2 ~]# redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf
[root@redis-1 ~]# redis-cli  -h 192.168.1.20 -p  6380 CLUSTER FAILOVER
OK             //redis2重回master
[root@redis-1 ~]# sh redis_shell.sh login 6380 
192.168.1.10:6380> CLUSTER NODES
8c57f9393090404c0ada0d258a964dec3583f191 192.168.1.10:6381@16381 slave c92419d7d715447a422df4e954d31d924a85b39c 0 1596034670671 7 connected
f0672e893f80b751abe49862aafb7740dfa34506 192.168.1.30:6381@16381 slave b25723025c04492fac759645d75477efc01d7dbd 0 1596034667605 5 connected
c92419d7d715447a422df4e954d31d924a85b39c 192.168.1.20:6380@16380 master - 0 1596034669651 7 connected 5462-10922             //已恢复
f57ff74970ef3c24d450e1b141ee911e91bc6350 192.168.1.20:6381@16381 slave 0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 0 1596034670000 3 connected
b25723025c04492fac759645d75477efc01d7dbd 192.168.1.10:6380@16380 myself,master - 0 1596034669000 2 connected 0-5461
0a2778d9265a83bf4708fc496c7ea6d9a3f6b9e5 192.168.1.30:6380@16380 master - 0 1596034671691 3 connected 10923-16383
192.168.1.10:6380> exit

六、使用工具自动搭建部署Redis Cluster

1、创建集群

[root@redis-1 ~]# redis-cli --cluster create --cluster-replicas 1 192.168.1.10:6380 192.168.1.10:6381 192.168.1.20:6380 192.168.1.20:6381 192.168.1.30:6380 192.168.1.30:6381
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.20:6381 to 192.168.1.10:6380
Adding replica 192.168.1.30:6381 to 192.168.1.20:6380
Adding replica 192.168.1.10:6381 to 192.168.1.30:6380
M: 250c5fe40651229a69c8ba3ca15ca0fab390a645 192.168.1.10:6380
   slots:[0-5460] (5461 slots) master
S: 5b350813df4fd301d909872796840996eff4faa4 192.168.1.10:6381
   replicates 16afd3566f680254c395af0079d8c0e9f55140ea
M: d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 192.168.1.20:6380
   slots:[5461-10922] (5462 slots) master
S: 4c4bb55ced287945d0394de8cbccd10839f51a48 192.168.1.20:6381
   replicates 250c5fe40651229a69c8ba3ca15ca0fab390a645
M: 16afd3566f680254c395af0079d8c0e9f55140ea 192.168.1.30:6380
   slots:[10923-16383] (5461 slots) master
S: 23a24197ff1f3472629dbb967fea642bd6fb7975 192.168.1.30:6381
   replicates d46ec19a9d4d5cae7bf1585d47ccb2690f60658d
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 192.168.1.10:6380)
M: 250c5fe40651229a69c8ba3ca15ca0fab390a645 192.168.1.10:6380
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 16afd3566f680254c395af0079d8c0e9f55140ea 192.168.1.30:6380
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 192.168.1.20:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 23a24197ff1f3472629dbb967fea642bd6fb7975 192.168.1.30:6381
   slots: (0 slots) slave
   replicates d46ec19a9d4d5cae7bf1585d47ccb2690f60658d
S: 5b350813df4fd301d909872796840996eff4faa4 192.168.1.10:6381
   slots: (0 slots) slave
   replicates 16afd3566f680254c395af0079d8c0e9f55140ea
S: 4c4bb55ced287945d0394de8cbccd10839f51a48 192.168.1.20:6381
   slots: (0 slots) slave
   replicates 250c5fe40651229a69c8ba3ca15ca0fab390a645
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@redis-1 ~]# redis-cli --cluster check 192.168.1.10:6380
192.168.1.10:6380 (250c5fe4...) -> 0 keys | 5461 slots | 1 slaves.
192.168.1.30:6380 (16afd356...) -> 0 keys | 5461 slots | 1 slaves.
192.168.1.20:6380 (d46ec19a...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.1.10:6380)
M: 250c5fe40651229a69c8ba3ca15ca0fab390a645 192.168.1.10:6380
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 16afd3566f680254c395af0079d8c0e9f55140ea 192.168.1.30:6380
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 192.168.1.20:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 23a24197ff1f3472629dbb967fea642bd6fb7975 192.168.1.30:6381
   slots: (0 slots) slave
   replicates d46ec19a9d4d5cae7bf1585d47ccb2690f60658d
S: 5b350813df4fd301d909872796840996eff4faa4 192.168.1.10:6381
   slots: (0 slots) slave
   replicates 16afd3566f680254c395af0079d8c0e9f55140ea
S: 4c4bb55ced287945d0394de8cbccd10839f51a48 192.168.1.20:6381
   slots: (0 slots) slave
   replicates 250c5fe40651229a69c8ba3ca15ca0fab390a645
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

2、工具扩容节点

[root@redis-1 ~]# mkdir -p /opt/redis_cluster/redis_{6390,6391}/{conf,logs,pid}             //创建2个新节点
[root@redis-1 ~]# mkdir -p /data/redis_cluster/redis_{6390,6391}
[root@redis-1 ~]# cd /opt/redis_cluster/
[root@redis-1 redis_cluster]# cp redis_6380/conf/redis_6380.conf redis_6390/conf/redis_6390.conf
[root@redis-1 redis_cluster]# cp redis_6380/conf/redis_6380.conf redis_6391/conf/redis_6391.conf
[root@redis-1 redis_cluster]# sed -i 's#6380#6390#g' redis_6390/conf/redis_6390.conf
[root@redis-1 redis_cluster]# sed -i 's#6380#6391#g' redis_6391/conf/redis_6391.conf
[root@redis-1 redis_cluster]# cd
[root@redis-1 ~]# bash redis_shell.sh start 6390             //启动节点
root      74661      1  0 7月29 ?       00:00:00 redis-server 192.168.1.10:6380 [cluster]
root      74672      1  0 7月29 ?       00:00:00 redis-server 192.168.1.10:6381 [cluster]
root      75289  11092  0 00:03 pts/0    00:00:00 bash redis_shell.sh start 6390
root      75297      1  0 00:03 ?        00:00:00 redis-server 192.168.1.10:6390 [cluster]
root      75299  75289  0 00:03 pts/0    00:00:00 grep redis
[root@redis-1 ~]# bash redis_shell.sh start 6391
root      74661      1  0 7月29 ?       00:00:00 redis-server 192.168.1.10:6380 [cluster]
root      74672      1  0 7月29 ?       00:00:00 redis-server 192.168.1.10:6381 [cluster]
root      75297      1  0 00:03 ?        00:00:00 redis-server 192.168.1.10:6390 [cluster]
root      75309  11092  0 00:03 pts/0    00:00:00 bash redis_shell.sh start 6391
root      75317      1  0 00:03 ?        00:00:00 redis-server 192.168.1.10:6391 [cluster]
root      75319  75309  0 00:03 pts/0    00:00:00 grep redis
[root@redis-1 ~]# redis-cli --cluster add-node 192.168.1.10:6390 192.168.1.10:6380             //发现节点
>>> Adding node 192.168.1.10:6390 to cluster 192.168.1.10:6380
>>> Performing Cluster Check (using node 192.168.1.10:6380)
M: 250c5fe40651229a69c8ba3ca15ca0fab390a645 192.168.1.10:6380
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 16afd3566f680254c395af0079d8c0e9f55140ea 192.168.1.30:6380
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 192.168.1.20:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 5b350813df4fd301d909872796840996eff4faa4 192.168.1.10:6381
   slots: (0 slots) slave
   replicates 16afd3566f680254c395af0079d8c0e9f55140ea
S: 23a24197ff1f3472629dbb967fea642bd6fb7975 192.168.1.30:6381
   slots: (0 slots) slave
   replicates d46ec19a9d4d5cae7bf1585d47ccb2690f60658d
S: 4c4bb55ced287945d0394de8cbccd10839f51a48 192.168.1.20:6381
   slots: (0 slots) slave
   replicates 250c5fe40651229a69c8ba3ca15ca0fab390a645
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.1.10:6390 to make it join the cluster.
[OK] New node added correctly.
[root@redis-1 ~]# redis-cli --cluster add-node 192.168.1.10:6391 192.168.1.10:6380
>>> Adding node 192.168.1.10:6391 to cluster 192.168.1.10:6380
>>> Performing Cluster Check (using node 192.168.1.10:6380)
M: 250c5fe40651229a69c8ba3ca15ca0fab390a645 192.168.1.10:6380
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 16afd3566f680254c395af0079d8c0e9f55140ea 192.168.1.30:6380
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 10c89190ebac6dfb98d84b9335c6a573bc11663e 192.168.1.10:6390
   slots: (0 slots) master
M: d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 192.168.1.20:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 5b350813df4fd301d909872796840996eff4faa4 192.168.1.10:6381
   slots: (0 slots) slave
   replicates 16afd3566f680254c395af0079d8c0e9f55140ea
S: 23a24197ff1f3472629dbb967fea642bd6fb7975 192.168.1.30:6381
   slots: (0 slots) slave
   replicates d46ec19a9d4d5cae7bf1585d47ccb2690f60658d
S: 4c4bb55ced287945d0394de8cbccd10839f51a48 192.168.1.20:6381
   slots: (0 slots) slave
   replicates 250c5fe40651229a69c8ba3ca15ca0fab390a645
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 192.168.1.10:6391 to make it join the cluster.
[OK] New node added correctly.
[root@redis-1 ~]# redis-cli --cluster rebalance 192.168.1.10:6380
>>> Performing Cluster Check (using node 192.168.1.10:6380)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.
[root@redis-1 ~]# sh redis_shell.sh login 6380 
192.168.1.10:6380> CLUSTER NODES
16afd3566f680254c395af0079d8c0e9f55140ea 192.168.1.30:6380@16380 master - 0 1596038944213 5 connected 10923-16383
10c89190ebac6dfb98d84b9335c6a573bc11663e 192.168.1.10:6390@16390 master - 0 1596038945236 7 connected
d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 192.168.1.20:6380@16380 master - 0 1596038943000 3 connected 5461-10922
5b350813df4fd301d909872796840996eff4faa4 192.168.1.10:6381@16381 slave 16afd3566f680254c395af0079d8c0e9f55140ea 0 1596038944000 5 connected
23a24197ff1f3472629dbb967fea642bd6fb7975 192.168.1.30:6381@16381 slave d46ec19a9d4d5cae7bf1585d47ccb2690f60658d 0 1596038942000 6 connected
250c5fe40651229a69c8ba3ca15ca0fab390a645 192.168.1.10:6380@16380 myself,master - 0 1596038940000 1 connected 0-5460
4f0d09dfd520125ba659f13c072bcc4c25ef5e99 192.168.1.10:6391@16391 master - 0 1596038944000 0 connected
4c4bb55ced287945d0394de8cbccd10839f51a48 192.168.1.20:6381@16381 slave 250c5fe40651229a69c8ba3ca15ca0fab390a645 0 1596038943000 4 connected