一、概述
Redis是一个开源的,使用C语言编写,支持网络,可基于内存工作亦可持久化(AOF、RDB)的日志型,key-values(键值对)数据库,一个速度极快的非关系型数据库,也就是我们所说的NoSQL数据库,他可以存储(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展性能,并且它还提供了多种语言的API。
Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这个称为半持久化RDB);也可以把每一次数据变化都写入到一个append onlyfile(AOF)里面(这称为“全持久化”)。
二、工作原理
Redis服务器程序是一个单进程模型,也就是说在一台服务器上可以开启多个redis进程(多实例),而redis的实际处理速度则完全依靠于主进程的执行速率,若在服务器上只运行一个redis进程,当多个客户端同时访问时,服务器处理能力会有一定程度的下降,若在一个服务器上开启多个redis进程,redis在提高并发处理能力的同时也会给CPU造成很大的压力,所以在实际生产环境中,结合实际服务器环境来决定如何使用。
三、优点
1、具有极高的数据读写速度:数据读写速度最高可达11万次/s,数据写入速度最高可达8万1千次/s
2、支持丰富的数据类型,支持丰富的数据类型不仅支持key-values数据类型,还支持Strings,Lists,Hashes,Sets,及Ordered Sets等数据类型操作
3、支持数据的持久化,在这一点上redis远远强于memcached,redis可以将数据保存到磁盘中,重启后还可以继续加载使用
4、原子性redis的所有操作都是原子性的
5、支持数据备份及master-slave模式的数据备份
四、redis 命令工具
1、redis-server: 用于启动redis的工具
2、redis-benchmark: 用于检测redis在本机的运行效率
3、redis-check-aof: 修复apf持久化文件
4、redis-check-rdb: 修复rdb持久化文件
5、redis-cli: redis client命令工具
6、redis-setinel: redis-server文件的软连接
五、redis-cli语法
redis-cli -h 远程连接主机 -p 指定端口 -a 指定密码 #注:若未设置数据库密码 -a 选项可以忽略 退出数据库操作环境可以执行quit或exit就可以返回到原来的shell文件
六、redis-benchmark测试工具
redis-benchmark [option] [option value]
常用选项:
-h:指定服务器名
-p:指定服务器端口
-s:指定服务器socket
-c:指定并发连接数
-n:指定请求连接数
-d:以字节(B)的形式指定SET/GET值的数据大小
-k:1=keep alive 0=reconnect
-r:SET/GET/INCR使用随机key,SADD使用的随机值
-P:通过管道传输<numreq>请求
-q:强制退出redis。仅显示query/sec值
--csv:以CSV格式输出
-l:生成循环,永久执行测试
-t:仅运行以逗号分隔的测试命令列表
-I:idle模式。仅打开/v个idle连接并等待
Redis-benchmark应用实例
1、测试并发数为10请求连接数为100000个请求的性能
[root@localhost ~]# redis-benchmark -h 192.168.200.111 -p 6379 -c 10 -n 100000
2、测试存取大小为100B的数据包时redis性能
[root@localhost ~]# redis-benchmark -h 192.168.200.111 -p 6379 -q -d 100
3、测试执行set,lpush操作时的性能
[root@localhost ~]# redis-benchmark -h 192.168.200.111 -p 6379 -t set,lpush -n 100000 -q
七、Redis数据库常用命令
set:用于redis数据库中存放数据 命令格式为 set key value
get:用于redis数据库中获取数据 命令格式为 get key
exists命令:用来判断键值是否存在
del命令:用来删除当前数据库中指定的key
type命令:使用type命令可以获取key对应的value值的类型
rename命令:对已有的key进行重命名
格式:rename 源key 目标key #注意:使用rename命令进行重命名时,无论目标key是否存在都会进行重命名,在实际使用过程中建议先使用exists查看目标key是否存在,再决定是否执行rename命令,以免覆盖重要的数据。
renamenx命令:对已有的key进行重命名,并检测新名是否存在
格式:renamenx 源key 目标key #注意:使用renamenx进行重命名时renamenx会检测新名是否存在,如目标key存在则不进行重命名
dbsize命令:查看当前数据库中key的数目
八、redis集群简介
我们日常在对于redis的使用中,经常会遇到一些问题:
1、高可用问题,如何保证redis的持续高可用性
2、容量问题,单实例redis内存无法无限扩充,达到32G后进入了64位世界,性能下降
3、并发性能问题,redis号称单实例10万并发,但也是有尽头的
九、redis哨兵介绍
Redis cluster是redis的分布式解决方案,在redis3.0版本中正式推出的采用的是hash slot(hash槽),可以将多个redis实例整合在一起,形成一个集群,也就是将数据分散到集群的多台机器上。有效的解决了redis分布式方面的需求,当遇到单机内存、开发、流量等瓶颈时,可以采用cluster架构达到负载均衡的目的。
Redis-cluster的优势
1. 官方推荐,毋庸置疑
2. 去中心化,集群最大可增加1000个节点,性能随节点增加而线性扩展
3. 管理方便,后续可自行增加或摘除节点,移动分槽等等。
4. 简单,易上手
十、redis数据分布
分布式数据库主要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。常见的分区规则有哈希分区和顺序分区。Redis cluster采用哈希分区规则,因此接下来会讨论哈希规则,常见的哈希分区有以下几种:
1. 节点取余
2. 一致性哈希分区
3. 虚拟槽分区
Redis cluster采用虚拟槽分区
十一、虚拟槽分区
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好地哈希函数把所有地数据映射到一个固定地范围内地整数集合。
Redis cluster槽的范围是0-16383。槽是集群数据管理和迁移地基本地单位。采用大范围槽地主要目的是为了方便数据地拆分和集群地扩展(同时这也是redis地优点),使每个节点负责一定数量地值。
十二、Redis集群原理
Redis cluster是一个无中心地结构,其每一个节点都会保存着数据和整个集群地状态。每个节点都会保存其他节点地信息,知道其它节点所负责地槽,并且会与其他节点定时发送心跳信息能够及时感知整个集群中异常地节点
Redis群集原理图
1、当client向群集中任一节点发送与数据库有关命令时
2、接受命令地redis节点会计算出命令属于哪个槽,并检查这个槽是否指派了给自己
1)如果键所在地槽正好指派给当前节点,那么节点直接执行这个命令
2)如果键所在地槽没有指派给当前节点,那么节点会向客户端返回一个moved错误,并指引客户端转向(redirect)正确地节点,在发送希望执行的命令。
群集角色工作原理介绍
集群角色有Master和Slave。群集中master之间分配slots(槽)[范围:0-16383],一共16384个slot。Slave向它指定的master同步数据,实现备份,当其中的一个master无法提供服务时,该master的slave将提升为master,以保证群集键slot的完整性,当其中的某一个master和他的slave都失效,导致slot不完整,群集将会失效,这时就需要人工处理了。
Redis架构细节信息
1. 所有redis彼此互联的机制(ping-pong机制),内部使用二进制协议优化传输速度和带宽
2. 节点的失效(fail)在群集中超过半数的主(master)节点检测失效时才会失效。
3. 客户端与redis节点直连,不需要中间代理(proxy)层,客户端不需要连接群集所有节点,连接群集中任何几个节点都可以。
4. redis-cluster把所有的物理及节点映射到[0-16383]slot上,cluster负责维护node<->slot<->key。
Redis-cluster选举
选举过程是群集所有master参与,如果半数以上的master节点与当前master节点通信时(cluster-node-timeout),认为当前的master节点挂掉,
出现以下两种情况将认为群集不可用
1. 当群集不可用时,所有对进群的操作都将不可用
2. 收到((error)CLUSTERDBWN the cluster di down)错误
1)如果群集中任意的master宕机,没有slave直接进入fail状态,此时之前分配到master上的槽[0-16383范围]在整个群集中将会出现slot不完整进入fail状态
2)如果群集中超过半数的master挂掉,无论是否有slave群集都会进入fail状态
Redis cluster中服务器节点都使用两个tcp端口号:
1. 6379端口号:用于服务于client连接
2. 16379端口号:用于群集总线,即二进制协议的节点到节点通信通道。节点使用群集总线进行故障检测,配置更新,故障转移授权等,如果开启了防火墙需要注意开放两个端口
十三、集群部署
环境(用两台主机模拟六台服务器)
主机名 IP地址 端口 描述
redis-master 192.168.200.111 7000 redis-master01
7001 redis-master02
7002 redis-master03
redis-slave 192.168.200.112 8000 redis-slave01
8001 redis-slave02
8002 redis-slave03
环境初始化(两台主机配置主机名,关闭防火墙和selinux)
[root@localhost ~]# hostname redis-master #主机名不同
[root@localhost ~]# bash
[root@redis-master ~]# iptables -F
[root@redis-master ~]# setenforce 0
[root@redis-master ~]# systemctl stop firewalld #关闭防火墙
[root@redis-master ~]# sestatus #查看系统状态
环境部署
redis编译部署及基础优化
redis-4.0源码包提取链接
链接:https://pan.baidu.com/s/1Xw0uD3Cj63zT4pmVAPLufQ?pwd=3l93
提取码:3l93
[root@redis-master ~]# yum -y install wget gcc gcc-c++ make tar openssl openssl-devel cmake #下载依赖包
[root@redis-master ~]# tar xf redis-4.0.10.tar.gz -C /usr/src/ #解压安装包
[root@redis-master ~]# cd /usr/src/redis-4.0.10/ #到解压完的目录下
[root@redis-master redis-4.0.10]# make #编译
[root@redis-master redis-4.0.10]# make MALLOC=jemalloc #避免碎片和可伸缩的并发支持
[root@redis-master redis-4.0.10]# make PREFIX=/usr/local/redis install
[root@redis-master redis-4.0.10]# mkdir -p /usr/local/redis/conf
优化redis程序命令
[root@redis-master redis-4.0.10]# cp sentinel.conf /usr/local/redis/conf/ #redis哨兵配置文件
[root@redis-master redis-4.0.10]# cp src/redis-trib.rb /usr/local/redis/bin/ #redis-cluster的集群创建工具
[root@redis-master redis-4.0.10]# ln -s /usr/local/redis/bin/* /usr/local/bin/ #创建命令连接
redis配置文件精简
[root@redis-master redis-4.0.10]# cp redis.conf /usr/local/redis/conf/
[root@redis-master redis-4.0.10]# cd /usr/local/redis/
[root@redis-master redis]# cp conf/redis.conf{,.bak}
[root@redis-master redis]# egrep -v "^$|^#" conf/redis.conf.bak > conf/redis.conf
系统调优配置
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.local
echo "* - nofile 10240" >> /etc/security/limits.conf --文件并发数
echo "net.core.somaxconn = 10240" >> /etc/sysctl.conf --监听队列
echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf -- 0内存不够,就会拒绝申请
1物理内存都允许分配给你,只要有内存就给你用,这样可以避免申请内存失败的问题。
sysctl -p #刷新
十四、redis多实例配置
在redis-master上操作
[root@redis-master ~]# mkdir -p /data/redis-cluster
[root@redis-master ~]# cd /data/redis-cluster
[root@redis-master redis-cluster]# mkdir 7000 7001 7002 创建各个节点的目录
[root@redis-master redis-cluster]# cp /usr/local/redis/conf/redis.conf /data/redis-cluster/7000/ #复制配置文件到7000端口目录下
[root@redis-master redis-cluster]# cp /usr/local/redis/conf/redis.conf /data/redis-cluster/7001/
[root@redis-master redis-cluster]# cp /usr/local/redis/conf/redis.conf /data/redis-cluster/7002/
[root@redis-master redis-cluster]# tree /data/
/data/
└── redis-cluster
├── 7000
│ └── redis.conf
├── 7001
│ └── redis.conf
└── 7002
└── redis.conf
4 directories, 3 files
在redis-slave上操作
[root@redis-slave ~]# mkdir -p /data/redis-cluster
[root@redis-slave ~]# cd /data/redis-cluster
[root@redis-slave redis-cluster]# mkdir 8000 8001 8002
修改redis-master和redis-slave的redis.conf配置文件(在redis-master上操作)
[root@redis-master redis-cluster]# vim 7000/redis.conf
cluster-enabled yes #添加
bind 0.0.0.0 #监听的主机地址
port 7000 #端口
pidfile /data/redis-cluster/7000/redis.pid #指定pid文件
logfile "/data/redis-cluster/7000/redis.log" #日志文件路径
dir /data/redis-cluster/7000/ #数据目录
tcp-backlog 1024 #调整访问池大小
timeout 0 #当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
tcp-keepalive 0
daemonize yes #启用守护进程
loglevel notice #日志级别
databases 16 # 设置数据库的数量,默认数据库为0
stop-writes-on-bgsave-error yes
rdbcompression yes #指定本地数据库文件名,默认值为dump.rdb
rdbchecksum yes
dbfilename "dump.rdb"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
slave-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
启动redis-master多实例
[root@redis-master ~]# redis-server /data/redis-cluster/7001/redis.conf #启动7001端口
[root@redis-master ~]# redis-server /data/redis-cluster/7002/redis.conf #启动7002端口
[root@redis-master ~]# redis-server /data/redis-cluster/7000/redis.conf #启动7000端口
[root@redis-master ~]# netstat -antup | grep redis #查看端口
tcp 0 0 0.0.0.0:7000 0.0.0.0:* LISTEN 5412/redis-server 0
tcp 0 0 0.0.0.0:7001 0.0.0.0:* LISTEN 5400/redis-server 0
tcp 0 0 0.0.0.0:7002 0.0.0.0:* LISTEN 5405/redis-server 0
tcp 0 0 0.0.0.0:17000 0.0.0.0:* LISTEN 5412/redis-server 0
tcp 0 0 0.0.0.0:17001 0.0.0.0:* LISTEN 5400/redis-server 0
tcp 0 0 0.0.0.0:17002 0.0.0.0:* LISTEN 5405/redis-server 0
十五、构建redis cluster集群
编译安装高ruby版本,Ruby版本需要大于等于2.2.2(yum安装的不符合)
ruby-2.5源码包提取链接
链接:https://pan.baidu.com/s/1fglHEe1rCfj3cFAttCq8jA?pwd=jf3g
提取码:jf3g
[root@redis-master ~]# tar xf ruby-2.5.1.tar.gz -C /usr/src/
[root@redis-master ~]# cd /usr/src/ruby-2.5.1/
[root@redis-master ruby-2.5.1]# ./configure && make && make install
[root@redis-master ruby-2.5.1]# ruby --version
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
在线安装ruby的redis扩展
[root@redis-master ruby-2.5.1]# /usr/local/bin/gem install redis
Fetching: redis-4.1.4.gem (100%)
Successfully installed redis-4.1.4
Parsing documentation for redis-4.1.4
Installing ri documentation for redis-4.1.4
Done installing documentation for redis after 1 seconds
1 gem installed
在redis-master上操作
[root@redis-master ~]# redis-trib.rb create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 #创建节点
>>> Creating cluster
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
127.0.0.1:7000
127.0.0.1:7001
127.0.0.1:7002
M: 4e729d539ceb6b5b6bce86f4d6f3dbb6de1cb5ca 127.0.0.1:7000
slots:0-5460 (5461 slots) master
M: 6e3809c102d7cb3013ef8a89bc17f4d6ca1fc93a 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
M: 61b60ec318606a1c86770cee4da74e5b6962076b 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes #输入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 127.0.0.1:7000)
M: 4e729d539ceb6b5b6bce86f4d6f3dbb6de1cb5ca 127.0.0.1:7000
slots:0-5460 (5461 slots) master
0 additional replica(s)
M: 61b60ec318606a1c86770cee4da74e5b6962076b 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
0 additional replica(s)
M: 6e3809c102d7cb3013ef8a89bc17f4d6ca1fc93a 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
查看cluster集群的构建节点信息
[root@redis-master ~]# redis-cli -p 7000 cluster nodes #查看集群节点关系
61b60ec318606a1c86770cee4da74e5b6962076b 127.0.0.1:7002@17002 master - 0 1589298445481 3 connected 10923-16383
4e729d539ceb6b5b6bce86f4d6f3dbb6de1cb5ca 127.0.0.1:7000@17000 myself,master - 0 1589298444000 1 connected 0-5460
6e3809c102d7cb3013ef8a89bc17f4d6ca1fc93a 127.0.0.1:7001@17001 master - 0 1589298446490 2 connected 5461-10922
[root@redis-master ~]# ls /data/redis-cluster/7000/ #查看7000节点目录下所生成的配置文件
nodes.conf redis.conf redis.log redis.pid
[root@redis-master ~]# cat /data/redis-cluster/7000/nodes.conf #查看集群配置文件各个节点的关系
61b60ec318606a1c86770cee4da74e5b6962076b 127.0.0.1:7002@17002 master - 0 1589298205185 3 connected 10923-16383
4e729d539ceb6b5b6bce86f4d6f3dbb6de1cb5ca 127.0.0.1:7000@17000 myself,master - 0 0 1 connected 0-5460
6e3809c102d7cb3013ef8a89bc17f4d6ca1fc93a 127.0.0.1:7001@17001 master - 0 1589298205085 2 connected 5461-10922
vars currentEpoch 3 lastVoteEpoch 0
使用redis-cli去操作集群,需要加入-c参数
redis-cli -c:启用集群模式(跟随-ASK和-MOVED重定向)
-c 将Redis客户端配置为集群模式,当启用集群模式后,Redis客户端将能够正确处理分片的数据访问
-ASK和-MOVED是Redis集群中的重定向指令:
当客户端访问的键被迁移到其他节点时,Redis会返回ASK重定向,告知客户端将请求发送到新的节点上。
当客户端访问的节点不是合适的主节点时,Redis会返回MOVED重定向,告知客户端应该将请求发送到正确的主节点上。
通过使用redis-cli命令的"-c"选项,可以在集群模式下顺利处理这些重定向,并正确路由到相应的节点。这样可以使客户端能够透明地与Redis集群进行交互,而不需要手动处理重定向。
在redis-master上操作
[root@redis-master ~]# redis-cli -c -p 7000 #登录7000端口
127.0.0.1:7000> set name crushlinux #添加数据
-> Redirected to slot [5798] located at 127.0.0.1:7001 #被分配到了7001端口
OK
127.0.0.1:7001> set age 18 #添加数据
-> Redirected to slot [741] located at 127.0.0.1:7000 #被分配到了7000端口
OK
127.0.0.1:7000> exit
去中心化,随意一个入口
[root@redis-master ~]# redis-cli -c -p 7000 get name #用7000端口查看数据
"crushlinux"
[root@redis-master ~]# redis-cli -c -p 7001 get name
"crushlinux"
[root@redis-master ~]# redis-cli -c -p 7002 get name
"crushlinux"
在redis-slave上操作
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7000 get name
Could not connect to Redis at 127.0.0.1:7001: Connection refused #被拒绝了
Could not connect to Redis at 127.0.0.1:7001: Connection refused
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7001 get name
"crushlinux" #只有7001成功了
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7002 get name
Could not connect to Redis at 127.0.0.1:7001: Connection refused #被拒绝了
Could not connect to Redis a t 127.0.0.1:7001: Connection refused
以远程的方式访问redis-cluster时,被拒绝是因为我们创建集群的时候,是以127.0.0.1的本地IP方式创建的,因此只有本地访问时cluster集群才能发挥作用。
远程访问7001端口时,之所以能成功,是因为数据本来就是存在了监听7001端口的redis上,所以我们不加-c也能访问成功。
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -p 7001 get name
"crushlinux"
十六、cluster生产集群部署
在redis-master上操作
[root@redis-master ~]# ls /data/redis-cluster/7000
nodes.conf redis.conf redis.log redis.pid
[root@redis-master ~]# ls /data/redis-cluster/7001
nodes.conf redis.conf redis.log redis.pid
[root@redis-master ~]# ls /data/redis-cluster/7002
nodes.conf redis.conf redis.log redis.pid
删除cluster集群配置文件
[root@redis-master ~]# rm -rf /data/redis-cluster/7000/nodes.conf
[root@redis-master ~]# rm -rf /data/redis-cluster/7001/nodes.conf
[root@redis-master ~]# rm -rf /data/redis-cluster/7002/nodes.conf
[root@redis-master ~]# redis-cli -p 7000 shutdown #关闭服务
[root@redis-master ~]# redis-cli -p 7001 shutdown
[root@redis-master ~]# redis-cli -p 7002 shutdown
关闭服务后继续删除各个节点文件内的文件只留redis.conf和redis.log文件(不删除的话会报错)
启动redis-server
[root@redis-master ~]# redis-server /data/redis-cluster/7000/redis.conf #启动服务
[root@redis-master ~]# redis-server /data/redis-cluster/7001/redis.conf
[root@redis-master ~]# redis-server /data/redis-cluster/7002/redis.conf
重新创建redis-cluster集群
[root@redis-master ~]# redis-trib.rb create 192.168.200.111:7000 192.168.200.111:7001 192.168.200.111:7002 #创建集群
>>> Creating cluster
>>> Performing hash slots allocation on 3 nodes...
Using 3 masters:
192.168.200.111:7000
192.168.200.111:7001
192.168.200.111:7002
M: a4f23ae3a3fbbfab8c9fcd22f499d96badff9434 192.168.200.111:7000
slots:0-5460 (5461 slots) master
M: d41141bbb9559a0d1a7df036ed0bca190603d786 192.168.200.111:7001
slots:5461-10922 (5462 slots) master
M: e6421050008242d4e98090c0d45df98edcd66d5b 192.168.200.111:7002
slots:10923-16383 (5461 slots) master
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.200.111:7000)
M: a4f23ae3a3fbbfab8c9fcd22f499d96badff9434 192.168.200.111:7000
slots:0-5460 (5461 slots) master
0 additional replica(s)
M: d41141bbb9559a0d1a7df036ed0bca190603d786 127.0.0.1:7001
slots:5461-10922 (5462 slots) master
0 additional replica(s)
M: e6421050008242d4e98090c0d45df98edcd66d5b 127.0.0.1:7002
slots:10923-16383 (5461 slots) master
0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@redis-master ~]# ps -ef | grep cluster | grep -v grep #查看服务的pid及启动情况
root 20005 1 0 23:54 ? 00:00:00 redis-server 0.0.0.0:7000 [cluster]
root 20010 1 0 23:54 ? 00:00:00 redis-server 0.0.0.0:7001 [cluster]
root 20015 1 0 23:54 ? 00:00:00 redis-server 0.0.0.0:7002 [cluster]
在redis-slave上进行远程连接cluster集群测试
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7000 set name crushlinux #远程写入数据
OK
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7001 get name #远程查看写入数据
"crushlinux"
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7002 get name
"crushlinux"
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7001 #远程登录7001端口
192.168.200.111:7001> get name
"crushlinux"
192.168.200.111:7001> set age 18
-> Redirected to slot [741] located at 192.168.200.111:7000
OK
192.168.200.111:7000> get age
"18"
192.168.200.111:7000> exit
批量导入数据观察key的集群分布情况
[root@redis-slave ~]# for line in `seq -w 10000`;do redis-cli -h 192.168.200.111 -p 7000 -c set key3_${line} value_${line};done
分析cluster集群key的节点分布情况
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -p 7000 info Keyspace
# Keyspace
db0:keys=3338,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -p 7001 info Keyspace
# Keyspace
db0:keys=3354,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -p 7002 info Keyspace
# Keyspace
db0:keys=3310,expires=0,avg_ttl=0
三个节点个数大概平均
十七、cluster集群故障切换
启动redis-slave上所有的从库
[root@redis-slave ~]# redis-server /data/redis-cluster/8000/redis.conf #启动从服务
[root@redis-slave ~]# redis-server /data/redis-cluster/8001/redis.conf
[root@redis-slave ~]# redis-server /data/redis-cluster/8002/redis.conf
[root@redis-slave ~]# netstat -lnpt | grep redis #查看端口
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 30034/redis-server
tcp 0 0 0.0.0.0:8001 0.0.0.0:* LISTEN 30039/redis-server
tcp 0 0 0.0.0.0:8002 0.0.0.0:* LISTEN 30044/redis-server
tcp 0 0 0.0.0.0:18000 0.0.0.0:* LISTEN 30034/redis-server
tcp 0 0 0.0.0.0:18001 0.0.0.0:* LISTEN 30039/redis-server
tcp 0 0 0.0.0.0:18002 0.0.0.0:* LISTEN 30044/redis-server
redis-cluster集群从库的添加,在redis-master上操作
添加第一组从服务器
[root@redis-master ~]# redis-trib.rb add-node --slave 192.168.200.112:8000 192.168.200.111:7000 #指定8000端口为7000端口的从
>>> Adding node 192.168.200.112:8000 to cluster 192.168.200.111:7000
>>> Performing Cluster Check (using node 192.168.200.111:7000)
M: 2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000
slots:0-5460 (5461 slots) master
0 additional replica(s)
M: 8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001
slots:5461-10922 (5462 slots) master
0 additional replica(s)
M: ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002
slots:10923-16383 (5461 slots) master
0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 192.168.200.111:7000
>>> Send CLUSTER MEET to node 192.168.200.112:8000 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 192.168.200.111:7000.
[OK] New node added correctly.
添加第二组从服务器
[root@redis-master ~]# redis-trib.rb add-node --slave 192.168.200.112:8001 192.168.200.111:7001
>>> Adding node 192.168.200.112:8001 to cluster 192.168.200.111:7001
>>> Performing Cluster Check (using node 192.168.200.111:7001)
M: 8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001
slots:5461-10922 (5462 slots) master
0 additional replica(s)
S: 174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000
slots: (0 slots) slave
replicates 2bae369154e135d5ad031440b09de2643d061afd
M: ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002
slots:10923-16383 (5461 slots) master
0 additional replica(s)
M: 2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 192.168.200.111:7001
>>> Send CLUSTER MEET to node 192.168.200.112:8001 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 192.168.200.111:7001.
[OK] New node added correctly.
添加第三组从服务器
[root@redis-master ~]# redis-trib.rb add-node --slave 192.168.200.112:8002 192.168.200.111:7002
>>> Adding node 192.168.200.112:8002 to cluster 192.168.200.111:7002
>>> Performing Cluster Check (using node 192.168.200.111:7002)
M: ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002
slots:10923-16383 (5461 slots) master
0 additional replica(s)
M: 8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001
slots:5461-10922 (5462 slots) master
1 additional replica(s)
M: 2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000
slots: (0 slots) slave
replicates 2bae369154e135d5ad031440b09de2643d061afd
S: b71ac8244275903d84f186995be122c1098db40c 192.168.200.112:8001
slots: (0 slots) slave
replicates 8fe3563c65bb2539066bbacc4d202a9debcb33f7
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 192.168.200.111:7002
>>> Send CLUSTER MEET to node 192.168.200.112:8002 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 192.168.200.111:7002.
[OK] New node added correctly.
查看集群所有节点的信息
[root@redis-master ~]# redis-cli -p 7000 cluster nodes
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589299534687 3 connected
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589299535000 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 slave 2bae369154e135d5ad031440b09de2643d061afd 0 1589299536704 1 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 myself,master - 0 1589299534000 1 connected 0-5460
b71ac8244275903d84f186995be122c1098db40c 192.168.200.112:8001@18001 slave 8fe3563c65bb2539066bbacc4d202a9debcb33f7 0 1589299535696 2 connected
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589299534000 3 connected 10923-16383
slave从库的读写测试
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8000
192.168.200.112:8000> set address beijing
-> Redirected to slot [3680] located at 192.168.200.111:7000
OK
192.168.200.111:7000> exit
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8000 get address
"beijing"
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8001 get address
"beijing"
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8002 get address
"beijing"
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7000 get address
"beijing"
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7001 get address
"beijing"
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7002 get address
"beijing"
通过测试,我们发现redis的cluster集群不论是主库还是从库都可以进行set和get。因此,在使用中我们就没必要都去主库了
查看主从cluster集群key的分布情况
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8000 info Keyspace
# Keyspace
db0:keys=3339,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8001 info Keyspace
# Keyspace
db0:keys=3354,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -c -p 8002 info Keyspace
# Keyspace
db0:keys=3310,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7000 info Keyspace
# Keyspace
db0:keys=3339,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7001 info Keyspace
# Keyspace
db0:keys=3354,expires=0,avg_ttl=0
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7002 info Keyspace
# Keyspace
db0:keys=3310,expires=0,avg_ttl=0
redis集群的主从自动切换,主库挂掉后,从自动变为主
手动切换主从命令cluster failover
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -p 7000 shutdown #停掉主库
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -p 8000 cluster nodes #查看从库变化
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589299715540 3 connected 10923-16383
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589299716000 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 myself,slave 2bae369154e135d5ad031440b09de2643d061afd 0 1589299710000 0 connected
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589299716547 3 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 master - 1589299711406 1589299708479 1 disconnected 0-5460
b71ac8244275903d84f186995be122c1098db40c 192.168.200.112:8001@18001 slave 8fe3563c65bb2539066bbacc4d202a9debcb33f7 0 1589299715000 2 connected
手动down掉了7000端口的redis-server。从信息得知,7000挂了,8000被切换成了master
重新启动7000端口的server,再次查看
[root@redis-master ~]# redis-server /data/redis-cluster/7000/redis.conf
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -p 8000 cluster nodes
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589299786257 3 connected 10923-16383
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589299784240 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 myself,master - 0 1589299783000 4 connected 0-5460
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589299785248 3 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 slave 174e1a9ce3c75d521788a43ebf9d22279645331b 0 1589299783230 4 connected
b71ac8244275903d84f186995be122c1098db40c 192.168.200.112:8001@18001 slave 8fe3563c65bb2539066bbacc4d202a9debcb33f7 0 1589299784000 2 connected
从信息得知:7000的redis启动以后,变成了slave。
手动将redis-server 7000端口重新切换成主库
[root@redis-slave ~]# redis-cli -h 192.168.200.111 -c -p 7000 cluster failover #手动切换主
OK
[root@redis-slave ~]# redis-cli -h 192.168.200.112 -p 8000 cluster nodes #查看主从关系
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589299834000 3 connected 10923-16383
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589299831677 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 myself,slave 2bae369154e135d5ad031440b09de2643d061afd 0 1589299832000 4 connected
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589299834709 3 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 master - 0 1589299831000 5 connected 0-5460
b71ac8244275903d84f186995be122c1098db40c 192.168.200.112:8001@18001 slave 8fe3563c65bb2539066bbacc4d202a9debcb33f7 0 1589299833000 2 connected
从信息得知:7000的redis启动以后,变成了master
删除节点
[root@redis-master ~]# redis-cli -h 192.168.200.112 -p 8000 cluster nodes #查看节点身份标识
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589302327000 3 connected 10923-16383
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589302328000 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 myself,slave 2bae369154e135d5ad031440b09de2643d061afd 0 1589302327000 7 connected
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589302329494 3 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 master - 0 1589302328790 8 connected 0-5460
b71ac8244275903d84f186995be122c1098db40c 192.168.200.112:8001@18001 slave 8fe3563c65bb2539066bbacc4d202a9debcb33f7 0 1589302328484 2 connected
[root@redis-master ~]# redis-trib.rb del-node 192.168.200.112:8001 'b71ac8244275903d84f186995be122c1098db40c' #删除8001节点
>>> Removing node b71ac8244275903d84f186995be122c1098db40c from cluster 192.168.200.112:8001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
[root@redis-master ~]# redis-cli -h 192.168.200.112 -p 8000 cluster nodes
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589302365000 3 connected 10923-16383
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589302366849 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 myself,slave 2bae369154e135d5ad031440b09de2643d061afd 0 1589302365000 7 connected
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589302367859 3 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 master - 0 1589302366000 8 connected 0-5460
最后跟着的是这个节点的ID,可在redis-cli终端中使用cluster nodes查看
修复节点
[root@redis-master ~]# redis-trib.rb add-node --slave 192.168.200.112:8001 192.168.200.111:7001
>>> Adding node 192.168.200.112:8001 to cluster 192.168.200.111:7001
>>> Performing Cluster Check (using node 192.168.200.111:7001)
M: 8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001
slots:5461-10922 (5462 slots) master
0 additional replica(s)
M: ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000
slots: (0 slots) slave
replicates 2bae369154e135d5ad031440b09de2643d061afd
S: 54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002
slots: (0 slots) slave
replicates ee18fa3426c2216f026ddea07db4c603a89afac8
M: 2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 192.168.200.111:7001
[ERR] Node 192.168.200.112:8001 is not empty. Either the node already knows other no #可以了看见这里会报错,是因为之前节点的数据没有删干净所致
des (check with CLUSTER NODES) or contains some key in database 0.
清空8001节点现有数据
[root@redis-slave ~]#kill -9 67708 #杀死8001服务
[root@redis-slave ~]# rm -rf /data/redis-cluster/8001/dump.rdb #删除8001节点文件内的数据文件
[root@redis-slave ~]# rm -rf /data/redis-cluster/8001/nodes.conf #删除配置内容
[root@redis-slave ~]# rm -rf /data/redis-cluster/8001/redis.pid #删除节点pid文件
[root@redis-slave ~]# redis-server /data/redis-cluster/8001/redis.conf #启动8001服务
[root@redis-master ~]# redis-trib.rb add-node --slave 192.168.200.112:8001 192.168.200.111:7001 #重新修复节点数据
>>> Adding node 192.168.200.112:8001 to cluster 192.168.200.111:7001
>>> Performing Cluster Check (using node 192.168.200.111:7001)
M: 8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001
slots:5461-10922 (5462 slots) master
0 additional replica(s)
M: ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000
slots: (0 slots) slave
replicates 2bae369154e135d5ad031440b09de2643d061afd
S: 54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002
slots: (0 slots) slave
replicates ee18fa3426c2216f026ddea07db4c603a89afac8
M: 2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000
slots:0-5460 (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 192.168.200.111:7001
>>> Send CLUSTER MEET to node 192.168.200.112:8001 to make it join the cluster.
Waiting for the cluster to join....
>>> Configure node as replica of 192.168.200.111:7001.
[OK] New node added correctly.
[root@redis-master ~]# redis-cli -h 192.168.200.112 -p 8000 cluster nodes #查看服务是否正常启动
ee18fa3426c2216f026ddea07db4c603a89afac8 192.168.200.111:7002@17002 master - 0 1589302761564 3 connected 10923-16383
8fe3563c65bb2539066bbacc4d202a9debcb33f7 192.168.200.111:7001@17001 master - 0 1589302759000 2 connected 5461-10922
174e1a9ce3c75d521788a43ebf9d22279645331b 192.168.200.112:8000@18000 myself,slave 2bae369154e135d5ad031440b09de2643d061afd 0 1589302758000 7 connected
def222dea64e5a6b16cf977c9f90c23f372b7e3a 192.168.200.112:8001@18001 slave 8fe3563c65bb2539066bbacc4d202a9debcb33f7 0 1589302760554 2 connected
54faa8b2ce0035eac8e0a850372d637de731e854 192.168.200.112:8002@18002 slave ee18fa3426c2216f026ddea07db4c603a89afac8 0 1589302759544 3 connected
2bae369154e135d5ad031440b09de2643d061afd 192.168.200.111:7000@17000 master - 0 1589302759000 8 connected 0-5460
这样节点修复完成,服务正常运行。