|
|
|
@ -32,6 +32,7 @@ import org.redisson.MasterSlaveServersConfig;
|
|
|
|
|
import org.redisson.client.BaseRedisPubSubListener;
|
|
|
|
|
import org.redisson.client.RedisClient;
|
|
|
|
|
import org.redisson.client.RedisConnection;
|
|
|
|
|
import org.redisson.client.RedisEmptySlotException;
|
|
|
|
|
import org.redisson.client.RedisPubSubConnection;
|
|
|
|
|
import org.redisson.client.RedisPubSubListener;
|
|
|
|
|
import org.redisson.client.codec.Codec;
|
|
|
|
@ -59,6 +60,8 @@ import io.netty.util.concurrent.Promise;
|
|
|
|
|
*/
|
|
|
|
|
public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
|
|
|
|
|
static final int MAX_SLOT = 16384;
|
|
|
|
|
|
|
|
|
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
|
|
|
|
|
|
|
|
|
private HashedWheelTimer timer;
|
|
|
|
@ -126,8 +129,8 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void initEntry(MasterSlaveServersConfig config) {
|
|
|
|
|
MasterSlaveEntry entry = new MasterSlaveEntry(this, config);
|
|
|
|
|
entries.put(Integer.MAX_VALUE, entry);
|
|
|
|
|
MasterSlaveEntry entry = new MasterSlaveEntry(0, MAX_SLOT, this, config);
|
|
|
|
|
entries.put(MAX_SLOT, entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void init(Config cfg) {
|
|
|
|
@ -187,7 +190,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
@Override
|
|
|
|
|
public int calcSlot(String key) {
|
|
|
|
|
if (entries.size() == 1 || key == null) {
|
|
|
|
|
return -1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int start = key.indexOf('{');
|
|
|
|
@ -196,7 +199,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
key = key.substring(start+1, end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int result = CRC16.crc16(key.getBytes()) % 16384;
|
|
|
|
|
int result = CRC16.crc16(key.getBytes()) % MAX_SLOT;
|
|
|
|
|
log.debug("slot {} for {}", result, key);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -234,14 +237,14 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int slot = -1;
|
|
|
|
|
int slot = 0;
|
|
|
|
|
RedisPubSubConnection conn = nextPubSubConnection(slot);
|
|
|
|
|
|
|
|
|
|
PubSubConnectionEntry entry = new PubSubConnectionEntry(conn, config.getSubscriptionsPerConnection());
|
|
|
|
|
entry.tryAcquire();
|
|
|
|
|
PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(channelName, entry);
|
|
|
|
|
if (oldEntry != null) {
|
|
|
|
|
returnSubscribeConnection(slot, entry);
|
|
|
|
|
releaseSubscribeConnection(slot, entry);
|
|
|
|
|
return oldEntry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -283,14 +286,14 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int slot = -1;
|
|
|
|
|
int slot = 0;
|
|
|
|
|
RedisPubSubConnection conn = nextPubSubConnection(slot);
|
|
|
|
|
|
|
|
|
|
PubSubConnectionEntry entry = new PubSubConnectionEntry(conn, config.getSubscriptionsPerConnection());
|
|
|
|
|
entry.tryAcquire();
|
|
|
|
|
PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(channelName, entry);
|
|
|
|
|
if (oldEntry != null) {
|
|
|
|
|
returnSubscribeConnection(slot, entry);
|
|
|
|
|
releaseSubscribeConnection(slot, entry);
|
|
|
|
|
return oldEntry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -332,14 +335,14 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int slot = -1;
|
|
|
|
|
int slot = 0;
|
|
|
|
|
RedisPubSubConnection conn = nextPubSubConnection(slot);
|
|
|
|
|
|
|
|
|
|
PubSubConnectionEntry entry = new PubSubConnectionEntry(conn, config.getSubscriptionsPerConnection());
|
|
|
|
|
entry.tryAcquire();
|
|
|
|
|
PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(channelName, entry);
|
|
|
|
|
if (oldEntry != null) {
|
|
|
|
|
returnSubscribeConnection(slot, entry);
|
|
|
|
|
releaseSubscribeConnection(slot, entry);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
synchronized (entry) {
|
|
|
|
@ -367,7 +370,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
if (type == PubSubType.UNSUBSCRIBE && channel.equals(channelName)) {
|
|
|
|
|
synchronized (entry) {
|
|
|
|
|
if (entry.tryClose()) {
|
|
|
|
|
returnSubscribeConnection(-1, entry);
|
|
|
|
|
releaseSubscribeConnection(0, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
@ -392,7 +395,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
if (type == PubSubType.PUNSUBSCRIBE && channel.equals(channelName)) {
|
|
|
|
|
synchronized (entry) {
|
|
|
|
|
if (entry.tryClose()) {
|
|
|
|
|
returnSubscribeConnection(-1, entry);
|
|
|
|
|
releaseSubscribeConnection(0, entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
@ -403,14 +406,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected MasterSlaveEntry getEntry() {
|
|
|
|
|
return getEntry(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected MasterSlaveEntry getEntry(int slot) {
|
|
|
|
|
if (slot == -1) {
|
|
|
|
|
slot = 0;
|
|
|
|
|
}
|
|
|
|
|
return entries.ceilingEntry(slot).getValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -444,14 +440,6 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void addSlave(String host, int port) {
|
|
|
|
|
getEntry().addSlave(host, port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void slaveUp(String host, int port) {
|
|
|
|
|
getEntry().slaveUp(host, port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void changeMaster(int endSlot, String host, int port) {
|
|
|
|
|
getEntry(endSlot).changeMaster(host, port);
|
|
|
|
|
}
|
|
|
|
@ -462,19 +450,27 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public RedisConnection connectionWriteOp(int slot) {
|
|
|
|
|
return getEntry(slot).connectionWriteOp();
|
|
|
|
|
MasterSlaveEntry e = getEntry(slot);
|
|
|
|
|
if (!e.isOwn(slot)) {
|
|
|
|
|
throw new RedisEmptySlotException("No node for slot: " + slot, slot);
|
|
|
|
|
}
|
|
|
|
|
return e.connectionWriteOp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public RedisConnection connectionReadOp(int slot) {
|
|
|
|
|
return getEntry(slot).connectionReadOp();
|
|
|
|
|
MasterSlaveEntry e = getEntry(slot);
|
|
|
|
|
if (!e.isOwn(slot)) {
|
|
|
|
|
throw new RedisEmptySlotException("No node for slot: " + slot, slot);
|
|
|
|
|
}
|
|
|
|
|
return e.connectionReadOp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RedisPubSubConnection nextPubSubConnection(int slot) {
|
|
|
|
|
return getEntry(slot).nextPubSubConnection();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void returnSubscribeConnection(int slot, PubSubConnectionEntry entry) {
|
|
|
|
|
protected void releaseSubscribeConnection(int slot, PubSubConnectionEntry entry) {
|
|
|
|
|
this.getEntry(slot).returnSubscribeConnection(entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|