linux系统redis集群

一、redis主从

1.redis主从原理

1.从库配置主从同步
2.从库像主库发起sync命令
3.主库接收sync命令,执行bgsave,生成持久化rdb文件
4.主库将新的数据临时写入缓冲区
5.主库将rdb文件推送至从库
6.从库接收到rdb文件,会清空自己的数据
7.从库读取并导入rdb文件
8.主库将缓冲区的数据也传给从库
9.实现数据同步

2.redis主从实践

1)环境准备

角色 主机 IP 端口
主库 db01 172.16.1.51 6379
从库 db02 172.16.1.52 6379
从库 db03 172.16.1.53 6379

2)配置主从

#1.登陆三台redis
[root@db01 redis]# redis-cli -h 172.16.1.51
172.16.1.51:6379>
[root@db02 redis]# redis-cli -h 172.16.1.52
172.16.1.52:6379>
[root@db03 redis]# redis-cli -h 172.16.1.53
172.16.1.53:6379>

#2.查看主从状态
172.16.1.51:6379> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

#3.配置主从
172.16.1.52:6379> SLAVEOF 172.16.1.51 6379
OK
172.16.1.53:6379> SLAVEOF 172.16.1.51 6379
OK

#4.再次查看主从状态
#主库
172.16.1.51:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.52,port=6379,state=online,offset=29,lag=0
slave1:ip=172.16.1.53,port=6379,state=online,offset=29,lag=0
master_repl_offset:29
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:28

#从库
172.16.1.52:6379> info replication
# Replication
role:slave
master_host:172.16.1.51
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:71
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

#5.如果主库有密码
在从库的配置文件中加上
masterauth 123

3.如果主库出现故障

1)模拟主库故障

[root@db01 redis]# redis-cli shutdown

2)查看从库状态

172.16.1.52:6379> info replication
# Replication
role:slave
master_host:172.16.1.51
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:393
master_link_down_since_seconds:63
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
172.16.1.52:6379> set k1 v2
(error) READONLY You can‘t write against a read only slave.

#从库仍然还是从库,还是只读权限,没有办法提供写服务

3)选择一台机器,取消主从

#取消主从
172.16.1.52:6379> SLAVEOF no one
OK

#再次查看状态
172.16.1.52:6379> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

4)将其他从库指向新的主库

#重新做主从
172.16.1.53:6379> SLAVEOF 172.16.1.52 6379
OK

172.16.1.53:6379> info replication
# Replication
role:slave
master_host:172.16.1.52
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:1
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

二、redis高可用--sentinel哨兵

linux系统redis集群

linux系统redis集群

1.sentinel介绍

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

#必须在redis主从已经做好的前提下

2.sentinel的构造

Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。

linux系统redis集群

3.sentinel的功能

1.监控(Monitoring):
Sentinel会不断地检查你的主服务器和从服务器是否运作正常。

2.提醒(Notification):
当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。

3.自动故障迁移(Automatic failover):
当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器。

4.sentinel的具体工作

1.Sentinel通过用户给定的配置文件来发现主服务器
2.Sentinel会与被监视的主服务器创建两个网络连接:
    命令连接用于向主服务器发送命令。
    订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他Sentinel。
3.Sentinel通过向主服务器发送INFO命令来自动获得所有从服务器的地址。
4.发现其他sentinel
	Sentinel 会通过命令连接向被监视的主从服务器发送 “HELLO” 信息,该消息包含 Sentinel 的 IP、端口号、ID 等内容,以此来向其他 Sentinel 宣告自己的存在。与此同时Sentinel 会通过订阅连接接收其他 Sentinel 的“HELLO” 信息,以此来发现监视同一个主服务器的其他 Sentinel 。
5.多个Sentinel之间只会互相创建命令连接,用于进行通信。因为已经有主从服务器作为发送和接收HELLO信息的中介,所以Sentinel之间不会创建订阅连接。
6.检测实例的状态:
	Sentinel使用PING命令来检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被 Sentinel 判断为下线。
	Redis的Sentinel中关于下线(down)有两个不同的概念:
	1)主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。
	2)客观下线(Objectively Down,简称 ODOWN)指的是多个Sentinel实例在对同一个服务器做出SDOWN判断,并且通过SENTINEL is-master-down-by-addr命令互相交流之后,得出的服务器下线判断。(一个 Sentinel可以通过向另一个Sentinel发送SENTINEL is-master-down-by-addr命令来询问对方是否认为给定的服务器已下线。)

5.故障转移流程

一次故障转移操作由以下步骤组成:
1.发现主服务器已经进入客观下线状态。
2.基于Raft leader election协议,进行投票选举
3.如果当选失败,那么在设定的故障迁移超时时间的两倍之后,重新尝试当选。如果当选成功,那么执行以下步骤。
	1)选出一个从服务器,并将它升级为主服务器。
	2)向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
	3)通过发布与订阅功能,将更新后的配置传播给所有其他Sentinel,其他Sentinel对它们自己的配置进行更新。
	4)向已下线主服务器的从服务器发送SLAVEOF命令,让它们去复制新的主服务器。
	5)当所有从服务器都已经开始复制新的主服务器时, leader Sentinel 终止这次故障迁移操作。

6.sentinel选择主库的规则

1.在失效主服务器属下的从服务器当中,那些被标记为主观下线、已断线、或者最后一次回复PING命令的时间大于五秒钟的从服务器都会被淘汰。
2.在失效主服务器属下的从服务器当中,那些与失效主服务器连接断开的时长超过down-after选项指定的时长十倍的从服务器都会被淘汰。
3.在经历了以上两轮淘汰之后剩下来的从服务器中,我们选出复制偏移量(replication offset)最大的那个从服务器作为新的主服务器;如果复制偏移量不可用,或者从服务器的复制偏移量相同,那么带有最小运行ID的那个从服务器成为新的主服务器。

7.sentinel特性

1.Sentinel自动故障迁移使用Raft算法来选举领头(leader)Sentinel ,从而确保在一个给定的周期(epoch)里,只有一个领头产生。
2.这表示在同一个周期中,不会有两个 Sentinel 同时被选中为领头,并且各个 Sentinel 在同一个节点中只会对一个领头进行投票。
3.更高的配置节点总是优于较低的节点,因此每个 Sentinel 都会主动使用更新的节点来代替自己的配置。

#简单来说,我们可以将Sentinel配置看作是一个带有版本号的状态。一个状态会以最后写入者胜出(last-write-wins)的方式(也即是,最新的配置总是胜出)传播至所有其他Sentinel。

三、sentinel实战

1.环境准备

角色 主机 IP 端口
主库 db01 172.16.1.51 6379
从库 db02 172.16.1.52 6379
从库 db03 172.16.1.53 6379

2.恢复主从状态

#修复坏掉的主库
[root@db01 ~]# redis-server /service/redis/6379/redis.conf 
[root@db01 ~]# redis-cli -h 172.16.1.51
172.16.1.51:6379> info replication
172.16.1.51:6379> SLAVEOF 172.16.1.52 6379
OK
172.16.1.51:6379> info replication

#主库查看
172.16.1.52:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.53,port=6379,state=online,offset=4229,lag=1
slave1:ip=172.16.1.51,port=6379,state=online,offset=4229,lag=1
master_repl_offset:4229
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:4228

3.配置sentinel哨兵

#创建目录(随便创建)
[root@db01 ~]# mkdir /service/redis/26379

#编辑sentinel配置文件
[root@db01 ~]# vim /service/redis/26379/sentinel.conf
port 26379
daemonize yes
pidfile /service/redis/26379/sentinel.pid
logfile /service/redis/26379/sentinel.log
dir /service/redis/26379
bind 172.16.1.51 127.0.0.1
sentinel monitor mymaster 172.16.1.52 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

4.启动sentinel

[root@db01 ~]# redis-sentinel /service/redis/26379/sentinel.conf

#启动之后配置文件会发生改变
[root@db01 ~]# vim /service/redis/26379/sentinel.conf
port 26379
daemonize yes
pidfile "/service/redis/26379/sentinel.pid"
logfile "/service/redis/26379/sentinel.log"
dir "/service/redis/26379"
bind 172.16.1.51 127.0.0.1
sentinel myid 7d430385a1269307819e5300ecf09dfbf92b46f5
sentinel monitor mymaster 172.16.1.52 6379 1
sentinel down-after-milliseconds mymaster 5000
sentinel config-epoch mymaster 0
# Generated by CONFIG REWRITE
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 172.16.1.51 6379
sentinel known-slave mymaster 172.16.1.53 6379
sentinel current-epoch 0

5.停止sentinel

[root@db01 ~]# redis-cli -p 26379 shutdown

6.测试sentinel

#关闭主库的redis
[root@db02 ~]# redis-cli shutdown

#查看其它从库主从状态
172.16.1.51:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.53,port=6379,state=online,offset=586,lag=1
master_repl_offset:723
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:722

7.恢复故障节点

#修复故障节点
[root@db02 ~]# redis-server /service/redis/6379/redis.conf 

#查看主库状态
172.16.1.51:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.53,port=6379,state=online,offset=5077,lag=1
slave1:ip=172.16.1.52,port=6379,state=online,offset=5077,lag=1
master_repl_offset:5077
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:5076

8.sentinel管理命令(不常用)

#连接sentinel管理端口
[root@db01 ~]# redis-cli -p 26379

#检测状态,返回PONG
127.0.0.1:26379> ping
PONG

#列出所有被监视的主服务器
127.0.0.1:26380> SENTINEL masters

#列出所有被监视的从服务器
127.0.0.1:26380> SENTINEL slaves mymaster

#返回给定名字的主服务器的IP地址和端口号
127.0.0.1:26380> SENTINEL get-master-addr-by-name mymaster
1) "172.16.1.51"
2) "6379

#重置所有名字和给定模式
127.0.0.1:26380> SENTINEL reset mymaster

#当主服务器失效时,在不询问其他Sentinel意见的情况下,强制开始一次自动故障迁移。
127.0.0.1:26380> SENTINEL failover mymaster

9.设置权重,指定主库的优先级

#查看db02的权重
172.16.1.52:6379> CONFIG GET slave-priority
1) "slave-priority"
2) "100"

#修改db02的权重值为0
172.16.1.52:6379> CONFIG set slave-priority 0
OK

172.16.1.52:6379> CONFIG GET slave-priority
1) "slave-priority"
2) "0"

#权重值越低越不会优先切换为主库

#强制开始一次自动故障迁移
127.0.0.1:26380> SENTINEL failover mymaster

#再次查看,主库为db03
172.16.1.53:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.1.52,port=6379,state=online,offset=71377,lag=0
slave1:ip=172.16.1.51,port=6379,state=online,offset=71377,lag=0
master_repl_offset:71514
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:70496
repl_backlog_histlen:1019

四、Redis Cluster 分布式集群

1.什么是Redis Cluster

1.Redis集群是一个可以在多个Redis节点之间进行数据共享的设施(installation)
2.Redis集群不支持那些需要同时处理多个键的Redis命令,因为执行这些命令需要在多个Redis节点之间移动数据,并且在高负载的情况下,这些命令将降低Redis集群的性能,并导致不可预测的行为。(使用ack协议)
3.Redis集群通过分区(partition)来提供一定程度的可用性(availability):即使集群中有一部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。
4.Redis集群有将数据自动切分(split)到多个节点的能力。

2.Redis Cluster的特点

#高性能:
1.在多分片节点中,将16384个槽位,均匀分布到多个分片节点中
2.存数据时,将key做crc16(key),然后和16384进行取模,得出槽位值(0-16384之间)
3.根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
4.如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储
5.客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
6.Redis Cluster解决了redis资源利用率的问题

#高可用
7.在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof功能,同时当主节点down,实现类似于sentinel的自动failover的功能。

3.槽的概念

1.在集群中,会把所有节点分为16384个槽位
2.槽位的序号是 0 - 16383,序号不重要,数量才重要
3.每一个槽位分配到数据的概率是一样

4.redis故障转移

1.在集群里面,节点会对其他节点进行下线检测。
2.当一个主节点下线时,集群里面的其他主节点负责对下线主节点进行故障移。
3.换句话说,集群的节点集成了下线检测和故障转移等类似 Sentinel 的功能。

五、redis集群搭建

1.环境准备

节点 IP 端口
节点1 172.16.1.51 6379,6380
节点2 172.16.1.52 6379,6380
节点3 172.16.1.53 6379,6380

2.搭建redis

#删除以前的redis数据
[root@db01 ~]# rm -rf /service/redis/*

#创建多实例目录
[root@db01 ~]# mkdir /service/redis/{6379,6380}
[root@db02 ~]# mkdir /service/redis/{6379,6380}
[root@db03 ~]# mkdir /service/redis/{6379,6380}

#配置所有redis
[root@db01 ~]# vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis.pid
loglevel notice
logfile /service/redis/6379/redis.log
dbfilename dump.rdb
dir /service/redis/6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

[root@db01 ~]# vim /service/redis/6380/redis.conf
bind 172.16.1.51 127.0.0.1
port 6380
daemonize yes
pidfile /service/redis/6380/redis.pid
loglevel notice
logfile /service/redis/6380/redis.log
dbfilename dump.rdb
dir /service/redis/6380
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

3.启动所有redis

[root@db01 ~]# redis-server /service/redis/6379/redis.conf 
[root@db01 ~]# redis-server /service/redis/6380/redis.conf
[root@db02 ~]# redis-server /service/redis/6379/redis.conf 
[root@db02 ~]# redis-server /service/redis/6380/redis.conf
[root@db03 ~]# redis-server /service/redis/6379/redis.conf 
[root@db03 ~]# redis-server /service/redis/6380/redis.conf

4.关联所有redis节点

1)登录所有节点

[root@db01 ~]# redis-cli -h 172.16.1.51 -p 6379
[root@db01 ~]# redis-cli -h 172.16.1.51 -p 6380
[root@db02 ~]# redis-cli -h 172.16.1.52 -p 6379
[root@db02 ~]# redis-cli -h 172.16.1.52 -p 6380
[root@db03 ~]# redis-cli -h 172.16.1.53 -p 6379
[root@db03 ~]# redis-cli -h 172.16.1.53 -p 6380

2)查看集群节点

#查看集群节点,每一各节点只能看到自己
172.16.1.51:6379> CLUSTER NODES
28faba09f4c0ec8cdb90d92e09636796427b7143 :6379 myself,master - 0 0 0 connected


3)关联所有节点

172.16.1.51:6379> CLUSTER MEET 172.16.1.51 6380
OK
172.16.1.51:6379> CLUSTER MEET 172.16.1.52 6379
OK
172.16.1.51:6379> CLUSTER MEET 172.16.1.52 6380
OK
172.16.1.51:6379> CLUSTER MEET 172.16.1.53 6379
OK
172.16.1.51:6379> CLUSTER MEET 172.16.1.53 6380
OK

#查看集群状态,所有节点
172.16.1.51:6379> CLUSTER NODES
aee9f4e6e09a452fd44bca7639be442b5138f141 172.16.1.52:6380 master - 0 1596687131655 4 connected
777412c8d6554e3390e1083bf1f55002be08cf62 172.16.1.51:6380 master - 0 1596687131352 2 connected
ef18ab5bab6d8bc06917a0cf2dc9bffa8b431087 172.16.1.52:6379 master - 0 1596687132362 3 connected
f2747c92813ea06b25c3e9c8d5232b46b3cf9d3d 172.16.1.53:6379 master - 0 1596687131856 0 connected
25f735f08ac62b2f758c1e2c21e178cc46279087 172.16.1.53:6380 master - 0 1596687131251 5 connected
28faba09f4c0ec8cdb90d92e09636796427b7143 172.16.1.51:6379 myself,master - 0 0 1 connected

5.分配槽位

#查看集群状态
172.16.1.51:6379> CLUSTER INFO
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_sent:1168
cluster_stats_messages_received:1168

#槽位规划
db01:     5462 个槽位  (0-5461)
db02:     5461 个槽位  (5462-10922)
db03:	  5461 个槽位  (10923-16383)

#分配槽位
[root@db01 ~]# redis-cli -p 6379 -h 172.16.1.51 CLUSTER ADDSLOTS {0..5461}
OK
[root@db02 ~]# redis-cli -p 6379 -h 172.16.1.52 CLUSTER ADDSLOTS {5462..10922}
OK
[root@db02 ~]# redis-cli -p 6379 -h 172.16.1.53 CLUSTER ADDSLOTS {10923..16383}

linux系统redis集群

上一篇:在Ubuntu版本中如何更改下载源


下一篇:04_Linux搭建Jdk和tomcat环境