867  
查询码:00000158
redis集群sentinel哨兵模式及java连接
作者: wyasw 于 2020年03月29日 发布在分类 / Linux / 服务安装 下,并于 2020年03月29日 编辑
redis

1 Redis哨兵模式

一、Sentinel作用:

1)Master状态检测

2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave

3)Master-Slave切换后,master_redis.confslave_redis.confsentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换

二、Sentinel工作方式:

1):每个Sentinel以每秒钟一次的频率向它所知的MasterSlave以及其他 Sentinel 实例发送一个 PING 命令

2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。

3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。

4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线

5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有MasterSlave发送 INFO 命令

6):当Master Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次

7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。

 Master 重新向 Sentinel  PING 命令返回有效回复, Master 的主观下线状态就会被移除。

主观下线和客观下线

主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。

客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.

SDOWN适合于MasterSlave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。

ODOWN只适用于Master,对于Slave Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave Sentinel 永远不会达到ODOWN.

1.1 服务器规划

192.168.137.58 node01  #主,哨兵

192.168.137.59 node02  #从,哨兵

192.168.137.60 node03  #从,哨兵

1.2  Redis安装

链接:https://pan.baidu.com/s/15Ct8MXyH1ZsGYlGVPly76Q 提取码:qbwg

1、创建目录

mkdir /home/tools

mkdir /home/deploy

mkdir /home/deploy/redis

2、上软件包redis-3.2.1.tar.gz/home/tools

3、安装redis

cd  /home/tools

tar xf redis-3.2.11.tar.gz

cd redis-3.2.11/

make PREFIX=/home/deploy/redis install

cp /home/tools/redis-3.2.11/redis.conf  /home/deploy/redis/bin/

cp /home/tools/redis-3.2.11/utils/redis_init_script /etc/init.d/redis

chmod 700 /etc/init.d/redis

echo 'PATH=$PATH:$HOME/bin:/home/deploy/redis/bin/'  >> /etc/profile

source /etc/profile

redis-server --version

4、修改redis启动脚本

Vim /etc/init.d/redis

#!/bin/sh

# chkconfig:   2345 90 10

##修改运行级别--上面添加

#redis服务器监听的端口

REDISPORT=6379

#服务端所处位置

EXEC=/home/deploy/redis/bin/redis-server

#客户端位置

CLIEXEC=/home/deploy/redis/bin/redis-cli

#redisPID文件位置,需要修改

PIDFILE=/var/run/redis_6379.pid

#redis的配置文件位置,需将${REDISPORT}修改为文件名

CONF="/home/deploy/redis/bin/redis.conf"

后面 就可以用/etc/init.d/redis stop停止redis服务了

如果是给redis设置了 密码,则需要给脚本指定密码;如下

$CLIEXEC  -p $REDISPORT shutdown 这一行改为 –a "密码"

$CLIEXEC -a "123456" -p $REDISPORT shutdown

1.3 修改redis.conf配置文件

vim /home/deploy/redis/bin/redis.conf

1、允许所有访问

bind 127.0.0.1 à bind 0.0.0.0

2、设置密码

requirepass 123456

3、允许后台启动

daemonize no à daemonize yes

4、设置日志路径

Logfile " " à logfile "/home/deploy/redis/redis_6379.log"

5、设置dump.rdb路径

dir ./ à dir /home/deploy/redis/

1.4  Redis主从配置

在从服务器上操作:

vim /home/deploy/redis/bin/redis.conf

#如果为 yes,代表为只读状态,但并不表示客户端用集群方式以从节点为入口连入集群时,不可以进行 set 操作,且 set 操作的数据不会被放在从节点的槽上,会被放到某主节点的槽上。

slave-read-only yes

# slaveof <masterip> <masterport>

slaveof 192.168.137.58 6379

# masterauth <master-password>

masterauth 123456

1.5 启动警告解决

临时解决

echo never > /sys/kernel/mm/transparent_hugepage/enabled

sysctl vm.overcommit_memory=1

永久解决方法:

将其写入/etc/rc.local文件中。

1.6 检查主从同步

在主库上设置一个键值对

redis-cli

set test 12222

OK

在从库上去读该键

redis-cli

127.0.0.1:6379> get test

"12222"

如果在从库上,能取出设置的键值对,那么就表示以上操作都是成功的。

##注意:从库上是 set不了的

1.7 哨兵配置

注意:三个节点都加上

vim /home/deploy/redis/bin/sentinel-26379.conf

port 26379

sentinel monitor mymaster 192.168.137.58 6379 2

sentinel down-after-milliseconds mymaster 3000

sentinel parallel-syncs mymaster 1

sentinel failover-timeout mymaster 10000

daemonize yes

dir "/tmp"

protected-mode no

logfile "/home/deploy/redis/sentinel-26379.log"

 配置文件仅需要这些内容,如果redis 主从 有密码需要添加授权选项

#redis主节点密码

sentinel auth-pass mymaster 123456

1.8 哨兵配置文件说明

port :当前Sentinel服务运行的端口

2. dir : Sentinel服务运行时使用的临时文件夹

3.sentinel monitor mymaster 192.168.137.58 6379 2:Sentinel去监视一个名为mymaster的主redis实例,这个主实例的IP地址为本机地址192.168.137.58,端口号为6379,而将这个主实例判断为失效至少需要2 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行

4.sentinel down-after-milliseconds mymaster 30000:指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行

5.sentinel parallel-syncs mymaster 1:指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长

6.sentinel failover-timeout mymaster 180000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败

7.sentinel notification-script <master-name> <script-path>:指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用

1.9 启动哨兵

#注意三台机器,先node01、再node02node03

redis-sentinel /home/deploy/redis/bin/sentinel-26379.conf

[root@node01 redis]# tailf -199 sentinel-26379.log

_._

_.-``__ ''-._

_.-``    `.  `_.  ''-._           Redis 3.2.11 (00000000/0) 64 bit

.-`` .-```.  ```\/    _.,_ ''-._

(    '      ,       .-`  | `,    )     Running in sentinel mode

|`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379

|    `-._   `._    /     _.-'    |     PID: 11237

`-._    `-._  `-./  _.-'    _.-'

|`-._`-._    `-.__.-'    _.-'_.-'|

|    `-._`-._        _.-'_.-'    |           http://redis.io

`-._    `-._`-.__.-'_.-'    _.-'

|`-._`-._    `-.__.-'    _.-'_.-'|

|    `-._`-._        _.-'_.-'    |

`-._    `-._`-.__.-'_.-'    _.-'

`-._    `-.__.-'    _.-'

`-._        _.-'

`-.__.-'

11237:X 10 Dec 20:27:42.853 # Sentinel ID is d6c378e820404eec650f5e234e3df18704c83554

11237:X 10 Dec 20:27:42.853 # +monitor master mymaster 192.168.137.58 6379 quorum 2

11237:X 10 Dec 20:27:42.854 * +slave slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379

11237:X 10 Dec 20:27:42.855 * +slave slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379

11237:X 10 Dec 20:28:14.250 * +sentinel sentinel fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 192.168.137.59 26379 @ mymaster 192.168.137.58 6379

11237:X 10 Dec 20:29:53.691 * +sentinel sentinel 9d2cafd155cc7fd03c17b089d7402176585533e0 192.168.137.60 26379 @ mymaster 192.168.137.58 6379

###注意:如果看到11237:X 10 Dec 20:28:14.250 * +sentinel sentinel fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 192.168.137.59 26379 @ mymaster 192.168.137.58 6379

11237:X 10 Dec 20:29:53.691 * +sentinel sentinel 9d2cafd155cc7fd03c17b089d7402176585533e0 192.168.137.60 26379 @ mymaster 192.168.137.58 6379

则说明成功+ sentinel sentinel

如果是-号 ,则不成功

1.10 测试宕机切换

l  在主node01服务器上关闭redis

/etc/init.d/redis stop

node查看日志

tailf -199 sentinel-26379.log

63552:X 10 Dec 20:34:54.435 # +sdown master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.506 # +odown master mymaster 192.168.137.58 6379 #quorum 3/2

63552:X 10 Dec 20:34:54.506 # +new-epoch 1

63552:X 10 Dec 20:34:54.506 # +try-failover master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.507 # +vote-for-leader fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 1

63552:X 10 Dec 20:34:54.508 # d6c378e820404eec650f5e234e3df18704c83554 voted for fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 1

63552:X 10 Dec 20:34:54.509 # 9d2cafd155cc7fd03c17b089d7402176585533e0 voted for fe2e7fc9a4574db8bb30fb52b7c795e660b741b1 1

63552:X 10 Dec 20:34:54.597 # +elected-leader master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.597 # +failover-state-select-slave master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.655 # +selected-slave slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.655 * +failover-state-send-slaveof-noone slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.713 * +failover-state-wait-promotion slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.814 # +promoted-slave slave 192.168.137.59:6379 192.168.137.59 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.814 # +failover-state-reconf-slaves master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:54.889 * +slave-reconf-sent slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:55.588 # -odown master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:55.862 * +slave-reconf-inprog slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:55.862 * +slave-reconf-done slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:55.945 # +failover-end master mymaster 192.168.137.58 6379

63552:X 10 Dec 20:34:55.945 # +switch-master mymaster 192.168.137.58 6379 192.168.137.59 6379

63552:X 10 Dec 20:34:55.946 * +slave slave 192.168.137.60:6379 192.168.137.60 6379 @ mymaster 192.168.137.59 6379

63552:X 10 Dec 20:34:55.946 * +slave slave 192.168.137.58:6379 192.168.137.58 6379 @ mymaster 192.168.137.59 6379

63552:X 10 Dec 20:34:58.981 # +sdown slave 192.168.137.58:6379 192.168.137.58 6379 @ mymaster 192.168.137.59 6379

###从日志可以看出,master node01宕机,master已经从node01切换为node02

l  在从库上查看状态:

[root@node03 bin]# redis-cli -p 6379 -a 123456

127.0.0.1:6379> info replication

# Replication

role:slave

master_host:192.168.137.59

master_port:6379

master_link_status:up

master_last_io_seconds_ago:0

master_sync_in_progress:0

slave_repl_offset:204885

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

127.0.0.1:6379>

可以看出node02已经从从库升级为master

l  启动node01  old mater

[root@node01 redis]# /etc/init.d/redis start

查看日志

tailf -199 sentinel-26379.log

11237:X 10 Dec 20:54:54.960 * +convert-to-slave slave 192.168.137.58:6379 192.168.137.58 6379 @ mymaster 192.168.137.59 6379

###由日志可以看出

Node01 已经加入node02(现在的master节点)变为slove节点。

[root@node01 redis]# redis-cli -p 6379 -a gichain123456

127.0.0.1:6379> info replication

# Replication

role:slave

master_host:192.168.137.59

master_port:6379

master_link_status:down

master_last_io_seconds_ago:-1

master_sync_in_progress:0

slave_repl_offset:1

master_link_down_since_seconds:1544446844

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

127.0.0.1:6379>

l  停掉node02 master升级为node03

l  开启node02node02加入node03(现在的master节点)

l  关闭node03master切换为node02,没有切换到node01;这是为什么呢?

此时在node01 redis.conf 加入

# masterauth <master-password>

masterauth 123456

不然主是切换不到node01

注意点:

1):首次启动时,必须先启动Master

2)Sentinel 只在 server 端做主从切换,app端要自己开发(例如Jedis库的SentinelJedis,能够监控Sentinel的状态)

3):若Master已经被判定为下线,Sentinel已经选择了新的Master,也已经将old Master改成Slave,但是还没有将其改成new Master。若此时重启old Master,则Redis集群将处于无Master状态,此时只能手动修改配置文件,然后重新启动集群

到此redis集群配置完毕

3 Java连接redis sentinel

Java连接redis sentinel,哨兵模式下不要直连master,要连sentinelmaster挂了才会自动故障转移

 

String masterName = "mymaster";

Set<String> sentinelSet =new HashSet<String>();

sentinelSet.add("node01:26379");

sentinelSet.add("node02:26379");

sentinelSet.add("node03:26379");

 

JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName,sentinelSet,poolConfig,timeout);

Jedis jedis = null;

try{

    jedis = sentinelPool.getResource();

}catch(Exception e){

    logger.error(e.getMessage(),e);

}finally{

    if(jedis != null){

        jedis.close();

    }

}

 



 推荐知识

 历史版本

修改日期 修改人 备注
2020-03-29 20:25:44[当前版本] wyasw 创建版本

  目录
    文艺知识分享平台 -V 4.9.5 -wcp
    京公网安备100012199188号 京ICP备2021030911号