redis哨兵モード-sentinel,javaクライアント動的切替master
4955 ワード
redisの構築モードスタンドアロンモード:スタンドアロンサービス マスタスレーブモード:バックアップを提供するバックアップ、および読み書きを分離する機能 哨兵モード:masterダウン後、哨兵会選挙予備機がmaster に置き換えられるクラスタモード:クラスタは分布式を行うことができ、masterはダウンタイムし、準備機会はmaster にアップグレードされる.
redis哨兵モードの使用
単機モードと主備モードは実は差が少なく、哨兵モードのサービスアーキテクチャ:master 1つ、複数のslave、複数の哨兵.
redisを配備したら、master./redis-4.0/src/redis-server.../conf/redis-master-6379.confをオンにします.
slave./redis-4.0/src/redis-server.../conf/redis-slave-6380.conf
歩哨を開く./redis-4.0/src/redis-sentinel.../conf/redis-sentinel-26379.conf
JAvaクライアント
ネット上でいくつかの歩哨モードのJAVAクライアントを探して、適当なことを探し当てていません.自分で1つのサンプルを書いて、基本的に走ることができて、マスターを切り替える時、やはり一定量の要求があって間違いを報告します
哨兵モードでは、取得した接続クライアントJedis、このクライアント接続はドッキングしたmasterですが、このmasterがダウンしたら、哨兵は新しいmasterを選出します.この時点で元のjedisクライアントは使用できません.
この場合、JAVAクライアントは新しいマスターを取得してリンクします.
そのため、使用するたびに、哨兵接続プールから新しいクライアントgetPool().getResource();
使用時にエラーが発生した場合は、クライアントjedis.close()を閉じる必要があります.
接続プール内のクライアントは数に制限があり、取り出して返さないと何度も操作するしかなく、その後も操作がブロックされます.したがって、jedisクライアントを使用するたびに、正常に接続されている場合は、poolConfig.returnResourceObject(jedis)に接続クライアントを返す必要があります.
この哨兵モードの使い方を大まかに検討してみましたが、なんだかもっと優れた使い方があるような気がします.
redis哨兵モードの使用
単機モードと主備モードは実は差が少なく、哨兵モードのサービスアーキテクチャ:master 1つ、複数のslave、複数の哨兵.
redisを配備したら、master./redis-4.0/src/redis-server.../conf/redis-master-6379.confをオンにします.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ip ,
bind 192.168.23.11 127.0.0.1
#
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
#
daemonize yes
#pid
pidfile "/var/run/redis_6379.pid"
loglevel notice
#
logfile "/home/smkapp/redislog/log6379.log"
#
databases 2
always-show-logo yes
slave./redis-4.0/src/redis-server.../conf/redis-slave-6380.conf
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ip ,
bind 192.168.23.11 127.0.0.1
#
port 6380
tcp-backlog 511
timeout 0
tcp-keepalive 300
#
daemonize yes
#pid
pidfile "/var/run/redis_6380.pid"
loglevel notice
#
logfile "/home/smkapp/redislog/log6380.log"
#
databases 2
slaveof 192.168.23.11 6379
always-show-logo yes
歩哨を開く./redis-4.0/src/redis-sentinel.../conf/redis-sentinel-26379.conf
# ip ,
bind 192.168.23.11 127.0.0.1
#
port 26380
tcp-backlog 511
timeout 0
tcp-keepalive 300
#
daemonize yes
#pid
pidfile "/var/run/redis_6380.pid"
loglevel notice
#
logfile "/home/smkapp/redislog/log6380.log"
# master
sentinel monitor luoyangmaster 192.168.23.11 6381 1
# 5
sentinel down-after-milliseconds luoyangmaster 5000
JAvaクライアント
ネット上でいくつかの歩哨モードのJAVAクライアントを探して、適当なことを探し当てていません.自分で1つのサンプルを書いて、基本的に走ることができて、マスターを切り替える時、やはり一定量の要求があって間違いを報告します
package com.redis;
import java.util.HashSet;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
public class RedisClientSentinel {
public static final int default_seconds = 300;
private static RedisClientSentinel client = null;
private JedisSentinelPool poolConfig = null;
private RedisClientSentinel() {
try {
getPool();
} catch (Exception e) {
e.printStackTrace();
}
}
public static synchronized RedisClientSentinel getInstance() {
if (null == client) {
client = new RedisClientSentinel();
}
return client;
}
/**
*
*
* @return
*/
private JedisSentinelPool getPool() {
if (poolConfig == null || poolConfig.isClosed()) {
Set sentinels = new HashSet<>();
sentinels.add("192.168.23.11:26379");
sentinels.add("192.168.23.11:26380");
JedisPoolConfig ab = new JedisPoolConfig();
ab.setMinIdle(Integer.parseInt("5"));
ab.setMaxTotal(5);
ab.setMaxIdle(5);
poolConfig = new JedisSentinelPool("luoyangmaster", sentinels, ab);
}
return poolConfig;
}
private Jedis getJedis() {
// master ip
System.out.println(poolConfig.getCurrentHostMaster());
//
return getPool().getResource();
}
/**
*
*
* @param key
* @return
*/
public String getStringValue(String key) {
Jedis j = getJedis();
String d = null;
try {
d = j.get(key);
// OK
poolConfig.returnResourceObject(j);
} catch (Exception e) {
//
System.out.println(" ");
//
j.close();
}
// j.close();
return d;
}
public static void main(String[] args) {
new Thread(new Tre()).start();
new Thread(new Tre()).start();
new Thread(new Tre()).start();
new Thread(new Tre()).start();
new Thread(new Tre()).start();
new Thread(new Tre()).start();
}
public static int i = 0;
public synchronized static void add() {
i++;
}
}
class Tre implements Runnable{
@Override
public void run() {
RedisClientSentinel s = RedisClientSentinel.getInstance();
while (true) {
try {
String d = s.getStringValue("username");
if(d == null) {
RedisClientSentinel.add();
}
System.out.println(RedisClientSentinel.i);
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
哨兵モードでは、取得した接続クライアントJedis、このクライアント接続はドッキングしたmasterですが、このmasterがダウンしたら、哨兵は新しいmasterを選出します.この時点で元のjedisクライアントは使用できません.
この場合、JAVAクライアントは新しいマスターを取得してリンクします.
そのため、使用するたびに、哨兵接続プールから新しいクライアントgetPool().getResource();
使用時にエラーが発生した場合は、クライアントjedis.close()を閉じる必要があります.
接続プール内のクライアントは数に制限があり、取り出して返さないと何度も操作するしかなく、その後も操作がブロックされます.したがって、jedisクライアントを使用するたびに、正常に接続されている場合は、poolConfig.returnResourceObject(jedis)に接続クライアントを返す必要があります.
この哨兵モードの使い方を大まかに検討してみましたが、なんだかもっと優れた使い方があるような気がします.