@Override public String quit() { for (RedisClient slave : slaves) { slave.quit(); } return master.quit(); }
@Override public void close() { master.close(); for (RedisClient slave : slaves) { slave.close(); } }
@Override public RedisClient route(String key) { if (this.ketamaClients == null || this.ketamaClients.size() == 0) { return null; } long hash = HashAlgorithm.KETAMA_HASH.hash(key); RedisClient client = this.getClientByHash(hash); int tries = 0; while ((client == null || client.isAvailable()) && tries++ < MAX_TRIES) { hash = this.nextHash(hash, key, tries); client = this.getClientByHash(hash); } return client; }
/** * Construct a new ketamaRouter * * @param redisClientMap key is redis client, value is weight, must > 0. */ public KetamaRouter(Map<RedisClient, Integer> redisClientMap) { this.redisClientMap = redisClientMap; ketamaClients = new TreeMap<Long, List<RedisClient>>(); // build ke for (RedisClient client : redisClientMap.keySet()) { String hashKey = client.hashKey(); int numReps = NUM_REPS * redisClientMap.get(client); for (int i = 0; i < numReps / 4; i++) { byte[] digest = HashAlgorithm.computeMd5(hashKey + "-" + i); for (int h = 0; h < 4; h++) { long k = (long) (digest[3 + h * 4] & 0xFF) << 24 | (long) (digest[2 + h * 4] & 0xFF) << 16 | (long) (digest[1 + h * 4] & 0xFF) << 8 | digest[h * 4] & 0xFF; this.getClientList(ketamaClients, k).add(client); } } } }
public MSRedisClient(RedisConnection masterConnection, List<RedisConnection> slaveConnections) { this.masterConnection = masterConnection; this.slaveConnections = slaveConnections; master = new SyncRedisClient(masterConnection); virtualSlaves = new CopyOnWriteArrayList<RedisClient>(); slaves = new LinkedBlockingQueue<RedisClient>(slaveConnections.size()); StringBuilder builder = new StringBuilder(); builder.append(String.format("%s|%s", masterConnection.address, masterConnection.db)); for (final RedisConnection connection : slaveConnections) { final RedisClient redisClient = new SyncRedisClient(connection); slaves.add(redisClient); builder.append(";").append(String.format("%s|%s", connection.address, connection.db)); // 根据权重将slave node放到虚拟节点中,权重高的放的越多。被访问的次数也就越多 for (int i = 0; i < connection.weight; i++) { virtualSlaves.add(redisClient); } // redis 连接异常时自动从slave列表中删除 redisClient.setClosedHandler( new AsyncRedisClient.ClosedHandler() { @Override public void onClosed(AsyncRedisClient client) { slaves.remove(redisClient); while (virtualSlaves.remove(redisClient)) {} } }); // redis 重连成功时重新加入slave列表 redisClient.setConnectedHandler( new AsyncRedisClient.ConnectedHandler() { @Override public void onConnected(AsyncRedisClient client) { slaves.add(redisClient); for (int i = 0; i < connection.weight; i++) { virtualSlaves.add(redisClient); } } }); } hashKey = builder.toString(); }
@Override public Long zremRangeByScore(String key, String min, String max) { return master.zremRangeByScore(key, min, max); }
@Override public Long smove(String source, String destination, Object member) { return master.smove(source, destination, member); }
@Override public String flushAll() { return master.flushAll(); }
@Override public String scriptFlush() { return master.scriptFlush(); }
@Override public Long scriptExists(String script) { return master.scriptExists(script); }
@Override public Reply evalSha(String sha1, String[] keys, byte[]... args) { return master.evalSha(sha1, keys, args); }
@Override public Long zadd(String key, double score, Object member, ZEntity... others) { return master.zadd(key, score, member, others); }
@Override public Long sunionStore(String destination, String key, String... keys) { return master.sunionStore(destination, key, keys); }
@Override public List<?> sunion(String key, String... keys) { return master.sunion(key, keys); }
@Override public List<?> srandomMember(String key, int count) { return master.srandomMember(key, count); }
@Override public Object srandomMember(String key) { return master.srandomMember(key); }
@Override public Object spop(String key) { return master.spop(key); }
@Override public Double zscore(String key, Object member) { return master.zscore(key, member); }
@Override public Reply eval(String script, String[] keys, byte[]... args) { return master.eval(script, keys, args); }
@Override public Long zcard(String key) { return master.zcard(key); }
@Override public String scriptLoad(String script) { return master.scriptLoad(script); }
@Override public Long zcount(String key, String min, String max) { return master.zcount(key, min, max); }
@Override public List<Integer> scriptExists(String[] scripts) { return master.scriptExists(scripts); }
@Override public Double zincrBy(String key, double increment, Object member) { return master.zincrBy(key, increment, member); }
@Override public String scriptKill() { return master.scriptKill(); }
@Override public Long zunionStore( String destination, String[] keys, int[] weights, ZSetAggregate aggregate) { return master.zunionStore(destination, keys, weights, aggregate); }
@Override public boolean isAvailable() { return master.isAvailable(); }
@Override public Long zremRangeByRank(String key, int start, int stop) { return master.zremRangeByRank(key, start, stop); }
@Override public Long zrem(String key, Object... members) { return master.zrem(key, members); }
@Override public Long sisMember(String key, Object member) { return master.sisMember(key, member); }