jedis客户端操作redis主要三种模式:单台模式、分片模式(ShardedJedis)、含有哨兵的分片模式(JedisSentinel)、集群模式(BinaryJedisCluster),分片模式是一种轻量级集群。
1、单台模式:直接通过jedis获取实例就可以
2、分片模式:
JedisPoolConfig config =new JedisPoolConfig();
config.setMinIdle(minIdel);
config.setMaxIdle(intMaxIdel);
config.setMaxTotal(maxSize);
config.setMaxWaitMillis(readTimeOut);
config.setMaxIdle(intMaxIdel);
config.setTestWhileIdle(checkAlive);
ShardedJedisPool sharedPool = new ShardedJedisPool(config,jdsInfoList);‘
sharedPool.getResource();3、含有哨兵的分片模式由于程序连接配置了主服务器的连接,但是此时主服务器挂调,哨兵会将从服务器变成主服务器,但程序是不知道的,出现无法连接异常。Jedis提供了对jedis sentinel pool的封装,所以发生主从切换的时候,web server都不需要重新配置和deploy,对客户端完全透明。高可用性的极佳体现啊。
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
public class TestSentinel {
@Test
public void test1() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
String masterName = "mymaster";
Set<String> sentinels = new HashSet<String>();
sentinels.add("192.168.1.97:26379");
sentinels.add("192.168.1.96:26379");
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, poolConfig);
HostAndPort currentHostMaster = jedisSentinelPool.getCurrentHostMaster();
System.out.println(currentHostMaster.getHost()+"--"+currentHostMaster.getPort());//获取主节点的信息
Jedis resource = jedisSentinelPool.getResource();
String value = resource.get("a");
System.out.println(value);//获得键a对应的value值
resource.close();
}
}4、集群模式import java.util.HashSet;
import java.util.Set;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
public class TestCluster {
@Test
public void test1() throws Exception {
JedisPoolConfig poolConfig = new JedisPoolConfig();
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
HostAndPort hostAndPort = new HostAndPort("192.168.1.99", 7000);//只给集群里一个实例就可以
HostAndPort hostAndPort1 = new HostAndPort("192.168.1.99", 7001);
HostAndPort hostAndPort2 = new HostAndPort("192.168.1.99", 7002);
HostAndPort hostAndPort3 = new HostAndPort("192.168.1.99", 7003);
HostAndPort hostAndPort4 = new HostAndPort("192.168.1.99", 7004);
HostAndPort hostAndPort5 = new HostAndPort("192.168.1.99", 7005);
nodes.add(hostAndPort);
nodes.add(hostAndPort1);
nodes.add(hostAndPort2);
nodes.add(hostAndPort3);
nodes.add(hostAndPort4);
nodes.add(hostAndPort5);
JedisCluster jedisCluster = new JedisCluster(nodes, poolConfig);//JedisCluster中默认分装好了连接池.
//redis内部会创建连接池,从连接池中获取连接使用,然后再把连接返回给连接池
String string = jedisCluster.get("a");
System.out.println(string);
}
}初始化 代码:private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig) {
//遍历所有从配置文件读取的节点
for (HostAndPort hostAndPort : startNodes) {
Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
try {
cache.discoverClusterNodesAndSlots(jedis);
//这个break是个重点,虽然使用的for循环遍历,但是此处的break让此循环立刻跳出
break;
} catch (JedisConnectionException e) {
// try next nodes
} finally {
if (jedis != null) {
jedis.close();
}
}
}
for (HostAndPort node : startNodes) {
cache.setNodeIfNotExist(node);
}
}注意上面代码段for循环里面的break: 它让for循环立刻跳出,导致for循环实际上只执行了一次,也就是说只使用了配置文件中所有节点配置的第一个,如此说来,集群配置文件中节点配置一个和配置多个效果一致。
同时还要注意到:通过获取的第一个节点配置实例化了一个Jedis jedis,如果配置文件中第一个节点指向的服务挂机或无法连接,将导致程序无法使用整个集群,虽然redis集群中其它节点是可用的。
补充:
不管是主从还是分片集群模式注意设置:
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
这样的话在每次发送请求的时候就不用去ping一下服务端是否可用了,降低流量请求,理论上可减少一半
总结连接模板:
主从
// 数据库链接池配置
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数, 应用自己评估,不要超过Redis每个实例最大的连接数
config.setMaxTotal(100);
//最大空闲连接数, 应用自己评估,不要超过Redis每个实例最大的连接数
config.setMaxIdle(50);
config.setMinIdle(20);
config.setMaxWaitMillis(6 * 1000);
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
String host = "*192.168.0.1"; //域名
String password = "please input your password"; //密码
int port = 2222; //端口
int timeout = 3000; //建立连接超时时间
JedisPool pool = new JedisPool(config, host, port, timeout, password);
Jedis jedis = null;
try {
jedis = pool.getResource();
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
System.out.println(foobar);
jedis.set("name", "zhangsan");
System.out.println(jedis.get("name"));
} finally {
if (jedis != null) {
jedis.close();
}
}
/// ... when closing your application:
pool.destroy();//分片集群
import redis.clients.jedis.*;
import java.util.HashSet;
import java.util.Set;
// 数据库连接池配置
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数, 应用自己评估,不要超过Redis每个实例最大的连接数
config.setMaxTotal(100);
//最大空闲连接数, 应用自己评估,不要超过Redis每个实例最大的连接数
config.setMaxIdle(50);
config.setMinIdle(20);
config.setMaxWaitMillis(6 * 1000);
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
// Redis集群的节点集合
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
jedisClusterNodes.add(new HostAndPort("192.168.0.1", 2222)); //域名 端口
jedisClusterNodes.add(new HostAndPort("192.168.0.2", 3333));
jedisClusterNodes.add(new HostAndPort("192.168.0.3", 4444));
int timeout = 2000; //连接建立超时时间
int maxAttempts = 5; //最多重定向次数
JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, timeout, maxAttempts, config);
String keyPrefix = "__test";
String value = "";
for (int i=1; i <= 10; i++){
String key = keyPrefix+i;
value = "value"+i;
System.out.println(value);
// 存数据
jedisCluster.set(key, value);
// 取数据
value= jedisCluster.get(key);
System.out.println(key + "=" + value);
//删除数据
jedisCluster.del(key);
value = jedisCluster.get(key);
System.out.println(key + "=" + value);
System.out.println();
}版权声明:本文为liyantianmin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。