一、相关类分析,但是没有多redis的API有一个系统的认识

然后在resources新建jedis.properties,通过@Resource注解获取JedisPool实例对象,然后在resources新建jedis.properties,通过@Resource注解获取JedisPool实例对象,Redis提供了多种语言的API,撸一下Redis相关的API的实现,redis.clients.util.Pool.getResource会从JedisPool实例池中返回一个可用的redis连接,extends redis.clients.util.Pool .而Pool是通过,初始化非切片连接池示例,一、相关类分析

配置jedis

我们将jedis相关配寄放在单独的Spring
Config中,在resources/spring目录新建applicationContext-jedis.xml。

     <!-- 加载配置属性文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath*:jedis.properties"/>

    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="300"/> <!-- 最大能够保持idel状态的对象数  -->
        <property name="maxTotal" value="60000"/> <!-- 最大分配的对象数 -->
        <property name="testOnBorrow" value="true"/> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
    </bean>

    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="jedisPoolConfig"/>
        <constructor-arg index="1" value="${redis.host}" type="java.lang.String"/>
        <constructor-arg index="2" value="${redis.port}" type="int"/>
    </bean>

 

本节指标

透过JedisPool获取Jedis示例,并做到对redis 轻便的Key-value读写操作。

总体代码结构如下:

图片 1

一、Jedis项目布局###\

当下jedis的代码托管在github,笔者也是fork了一下jedis的代码,以便于自身进行疏解,github的链接如下:https://github.com/xetorthio/jedis.git
fork之后clone到本地,用idea打开后:

Paste_Image.png

代码是比较轻松的,而且相当多类也尚未那么多的虚幻和继续,其实是相比好懂的。commands包里面首若是包装的redis帮助的各样吩咐,命令确实是多啊。
exception包重倘诺包装了有个别redis的exception。
在jedis包下的是有个别redis的Client。
jedis的代码结构大意上便是上述这几个,这里大家就以最简便的jedis类来看一下读写的流水生产线。

行使redis也可能有端时间了,未来讲开荒中遭逢的多少个科学普及万分总括如下:

JedisPoolConfig类是JedisPool的配置类

测试

加上单元测量检验,通过@Resource评释获取JedisPool实例对象。

@Resource
private JedisPool jedisPool;

 

下一场调用jedisPool对象的getResource()方法就足以拿走到Jedis实例了。

Jedis jedis = jedisPool.getResource();

 

先测验个最主旨的get,set操作

    @Test
    public void TestRedis() {
        Jedis jedis = jedisPool.getResource();

        String key = "a";
        jedis.set(key, "111");

        String data = jedis.get(key);

        System.out.println(data);

    }

运行结果:111

 

再测验个列表操作:

@Test
    public  void testList(){
        Jedis jedis=jedisPool.getResource();

        String key="articles";

        jedis.lpush(key,"文章1");
        jedis.lpush(key,"文章2");
        jedis.lpush(key,"文章3");

        List<String> articles=jedis.lrange(key,0,3);
        for(String article:articles){
            System.out.println(article);
        }
    }

 

运营结果:

文章3
文章2
文章1

 

再来个汇集操作:

@Test
    public void testSet(){
        Jedis jedis=jedisPool.getResource();

        String key="tags";
        jedis.sadd(key,"宝马");
        jedis.sadd(key,"豪车");
        jedis.sadd(key,"SUV");
        jedis.sadd(key,"SUV");

        Set<String> tags=jedis.smembers(key);
        for(String tag:tags){
            System.out.println(tag);
        }
    }

运转结果:

宝马
豪车
SUV

 

先到那边吧,SO EASY!!

 

源码地址:

本节目的 通过JedisPool获取Jedis示例,并产生对redis
轻易的Key-value读写操作。 完整代码结构如下:…

配置jedis

小编们将jedis相关配贮存在单独的Spring
Config中,在resources/spring目录新建applicationContext-jedis.xml。

     <!-- 加载配置属性文件 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath*:jedis.properties"/>

    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="300"/> <!-- 最大能够保持idel状态的对象数  -->
        <property name="maxTotal" value="60000"/> <!-- 最大分配的对象数 -->
        <property name="testOnBorrow" value="true"/> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->
    </bean>

    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="jedisPoolConfig"/>
        <constructor-arg index="1" value="${redis.host}" type="java.lang.String"/>
        <constructor-arg index="2" value="${redis.port}" type="int"/>
    </bean>

 

四、JedisPool的应用和贯彻

JedisPool是Jedis提供的一种对Redis的连接池,利用连接池能够很好的对Jedis的连年做四个很好的掌握控制,能幸免制造和销毁的开辟,同期能够进行期限的保活,能防止频仍的创导连接。
下边是三个JedisPool例子:

    JedisPoolConfig config = new JedisPoolConfig();
    config.setTestOnBorrow(true);
    JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(), 2000, "foobared");
    Jedis jedis = pool.getResource();
    jedis.set("foo", "bar");
    jedis.close();

能够观察新创制了叁个JedisPoolConfig,用于对JedisPool的安排。这里未有使用从前JedisPool的returnResource。因为jedis.close()已经做了有关的returnResource方法。
大家先看一下JedisPoolConfig是如何:

public class JedisPoolConfig extends GenericObjectPoolConfig {
  public JedisPoolConfig() {
    // defaults to make your life with connection pool easier :)
    setTestWhileIdle(true);
    setMinEvictableIdleTimeMillis(60000);
    setTimeBetweenEvictionRunsMillis(30000);
    setNumTestsPerEvictionRun(-1);
  }
}

JedisPoolConfig承继了GenericObjectPoolConfig,GenericObjectPoolConfig是ApacheCommonspool提供的贰个对象池的配置。JedisPool使用了ApacheCommonspool来开始展览连接池的贯彻。GenericObjectPoolConfig提供了重重的参数,大家得以采纳JedisPoolConfig也足以运用GenericObjectPoolConfig。上边列出部分重视的参数:

maxActive:调整一个pool可分配几个jedis实例,通过pool.getResource()来博取;假设赋值为-1,则表示不限量;假使pool已经分配了maxActive个jedis实例,则此时pool的情形为exhausted。
maxIdle:调整贰个pool最多有稍许个情形为idle(空闲)的jedis实例;
whenExhaustedAction:表示当pool中的jedis实例都被allocated完时,pool要动用的操作;暗中同意有二种。
WHEN_EXHAUSTED_FAIL –>
表示无jedis实例时,间接抛出NoSuchElementException;
WHEN_EXHAUSTED_BLOCK –>
则象征阻塞住,也许达到maxWait时抛出JedisConnectionException;
WHEN_EXHAUSTED_GROW –>
则意味新建叁个jedis实例,也就说设置的maxActive无用;
maxWait:表示当borrow一个jedis实例时,最大的等待时间,借使赶过等待时间,则直接抛出JedisConnectionException;
testOnBorrow:在borrow贰个jedis实例时,是或不是提前实行alidate操作;借使为true,则获得的jedis实例均是可用的;
testOnReturn:在return给pool时,是还是不是提前开展validate操作;
testWhileIdle:如若为true,表示有四个idle object evitor线程对idle
object实行扫描,假设validate失利,此object会被从pool中drop掉;这一项独有在timeBetweenEvictionRunsMillis大于0时才有含义;
timeBetweenEvictionRunsMillis:表示idle object
evitor四次扫描之间要sleep的皮秒数;
numTestsPerEvictionRun:表示idle object evitor每便扫描的最多的对象数;
minEvictableIdleTimeMillis:表示四个目的至少停留在idle状态的最长期,然后手艺被idle
object
evitor扫描并赶走;这一项唯有在timeBetweenEvictionRuns米尔is大于0时才有意义;
softMinEvictableIdleTimeMillis:在minEvictableIdleTimeMillis基础上,参加了最少minIdle个对象已经在pool里面了。假如为-1,evicted不会依附idle
time驱逐任何对象。假如minEvictableIdleTimeMillis>0,则此项设置无意义,且独有在timeBetweenEvictionRunsMillis大于0时才有含义;

布局比非常多,这里笔者不计划详细的写康芒斯Pool的贯彻机制,只是说说JedisPool是怎么落实的。

JedisPool的实例化进程如下:

  public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
      int timeout, final String password) {
    this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE, null);
  }
    public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
      int timeout, final String password, final int database, final String clientName) {
    this(poolConfig, host, port, timeout, timeout, password, database, clientName, false,
        null, null, null);
  }
    public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
      final int connectionTimeout, final int soTimeout, final String password, final int database,
      final String clientName, final boolean ssl, final SSLSocketFactory sslSocketFactory,
      final SSLParameters sslParameters, final HostnameVerifier hostnameVerifier) {
    super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
        database, clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier));
  }

这里实例化了叁个JedisFactory,这一个工厂类非常要害,那些工厂类是Commonspool来进展多对象池对象开始展览田间处理的三个厂子,对于具备指标的成立、销毁、激活和管事校验都以在JedisFactory中开展的:

class JedisFactory implements PooledObjectFactory<Jedis> {
  private final AtomicReference<HostAndPort> hostAndPort = new AtomicReference<HostAndPort>();
  private final int connectionTimeout;
  private final int soTimeout;
  private final String password;
  private final int database;
  private final String clientName;
  private final boolean ssl;
  private final SSLSocketFactory sslSocketFactory;
  private SSLParameters sslParameters;
  private HostnameVerifier hostnameVerifier;

  public JedisFactory(final String host, final int port, final int connectionTimeout,
      final int soTimeout, final String password, final int database, final String clientName,
      final boolean ssl, final SSLSocketFactory sslSocketFactory, final SSLParameters sslParameters,
      final HostnameVerifier hostnameVerifier) {
    this.hostAndPort.set(new HostAndPort(host, port));
    this.connectionTimeout = connectionTimeout;
    this.soTimeout = soTimeout;
    this.password = password;
    this.database = database;
    this.clientName = clientName;
    this.ssl = ssl;
    this.sslSocketFactory = sslSocketFactory;
    this.sslParameters = sslParameters;
    this.hostnameVerifier = hostnameVerifier;
  }

JedisFactory落成了PooledObjectFactory接口,PooledObjectFactory是CommonsPool提供的接口。PooledObjectFactory提供了累累的点子:

public interface PooledObjectFactory<T> {
    PooledObject<T> makeObject() throws Exception;

    void destroyObject(PooledObject<T> var1) throws Exception;

    boolean validateObject(PooledObject<T> var1);

    void activateObject(PooledObject<T> var1) throws Exception;

    void passivateObject(PooledObject<T> var1) throws Exception;
}

makeObject为创制对象的法门。
destroyObject为销毁对象的措施。
validateObject为校验对象有新闻的情势。
activateObject为激活对象的法子。
passivateObject为钝化对象的点子。

对于对象池对目的的治本应用了PooledObjectFactory中的方法,也算达成了“解耦”,自个儿的事物自个儿管,CommonsPool 不侵略任何逻辑。

在开立好了JedisPool之后呢,在利用的时候利用getResource来博取jedis的客户端:

  public Jedis getResource() {
    Jedis jedis = super.getResource();
    jedis.setDataSource(this);
    return jedis;
  }
   public T getResource() {
    try {
      return internalPool.borrowObject();
    } catch (NoSuchElementException nse) {
      throw new JedisException("Could not get a resource from the pool", nse);
    } catch (Exception e) {
      throw new JedisConnectionException("Could not get a resource from the pool", e);
    }
  }

internalPool是二个Commons pool。大家在获得jedis的时候调用了Commonspool的borrowObject。表面包车型大巴野趣正是借一个链接。同不时候将JedisPool的援用交给jedis,便于在close的时候举办链接的返还:

  @Override
  public void close() {
    if (dataSource != null) {
      if (client.isBroken()) {
        this.dataSource.returnBrokenResource(this);
      } else {
        this.dataSource.returnResource(this);
      }
    } else {
      client.close();
    }
  }

在jedis调用close方法时候,调用dataSource.returnResource进行链接的返还。

这么jedis和JedisPool的完结就剖析完了,然则对于CommonsPool对我们依然黑盒的,接下去会写三个对Commonspool的贯彻原理的笔记。同不常间呢对于jedis
Pool只可以拓展单实例的链接操作,可是对于数据量大的时候,单实例不能够满足供给。这年就需求对实例进行“分片”。Jedis也是提供了分片的辅助,后边也会总计三个jedis分片的落实。

MaxWait: 最大等待时间,单位微秒(million seconds)。

 

JAVA入门[22]-Jedis操作redis示例,-jedisredis

redis服务端

在本土运转redis-server.exe,然后在resources新建jedis.properties:

redis.host=localhost
redis.port=6379

 

对于一般支付,Redis由于单线程的产出模型、丰裕的数据结商谈归纳的API,深受周边技术员的热爱。Redis提供了多样语言的API,像java、c和python等。从前一向都是采纳redis,然则未有多redis的API有二个系统的认知。忙里偷闲,撸一下Redis相关的API的兑现,由于本人是三个java猿,那么本人根本学习了一下jedis的源码,来深入分析一下Redis的读写流程。

MaxIdle: 最大空闲数。

// 构造池
shardedJedisPool = new ShardedJedisPool(config, shards);

本节指标

由此JedisPool获取Jedis示例,并完结对redis 轻巧的Key-value读写操作。

完整代码结构如下:

redis服务端

在地头运营redis-server.exe,然后在resources新建jedis.properties:

redis.host=localhost
redis.port=6379

 

测试

增加单元测量检验,通过@Resource表明获取JedisPool实例对象。

@Resource
private JedisPool jedisPool;

 

下一场调用jedisPool对象的getResource()方法就足以博得到Jedis实例了。

Jedis jedis = jedisPool.getResource();

 

先测验个最主旨的get,set操作

    @Test
    public void TestRedis() {
        Jedis jedis = jedisPool.getResource();

        String key = "a";
        jedis.set(key, "111");

        String data = jedis.get(key);

        System.out.println(data);

    }

运营结果:111

 

再测量试验个列表操作:

@Test
    public  void testList(){
        Jedis jedis=jedisPool.getResource();

        String key="articles";

        jedis.lpush(key,"文章1");
        jedis.lpush(key,"文章2");
        jedis.lpush(key,"文章3");

        List<String> articles=jedis.lrange(key,0,3);
        for(String article:articles){
            System.out.println(article);
        }
    }

 

运营结果:

文章3

文章2

文章1

 

再来个汇聚操作:

@Test
    public void testSet(){
        Jedis jedis=jedisPool.getResource();

        String key="tags";
        jedis.sadd(key,"宝马");
        jedis.sadd(key,"豪车");
        jedis.sadd(key,"SUV");
        jedis.sadd(key,"SUV");

        Set<String> tags=jedis.smembers(key);
        for(String tag:tags){
            System.out.println(tag);
        }
    }

运转结果:

宝马

豪车

SUV

 

先到那边吧,SO EASY!!

 

源码地址:

三、用set方法分析Redis的伏乞流程

由于Jedis实现了各样接口,导致它里面包车型客车方法丰盛的多,这里大家使用贰个简短的德姆o来学学一下Jedis:

    Jedis jed = new Jedis("locahost",6379);
    jed.set("hello","123");
    String out = jed.get("hello");

率先看Jedis的实例化进程:

public Jedis(final String host, final int port) {  super(host, port);}

public BinaryJedis(final String host, final int port) {  client = new Client(host, port);}

Jedis因为延续了BinaryJedis,超越58%的操作都以在BinaryJedis中贯彻的,在BinaryJedis的构造方法中就实例化了Client。
Client的连续结构如下:

Paste_Image.png

BinaryJedis中的方法首倘若对Client做了代理,Client承接了BinaryClient,BinaryClient承继了Connection,达成了Commands接口。Client首要做了一部分编解码的劳作,BinaryClient做了Command的发送操作,而颇具与redisServer交互的工作由Connection达成。

首先看Set方法:

  /**
   * Set the string value as value of the key. The string can't be longer than 1073741824 bytes (1
   * GB).
   * <p>
   * Time complexity: O(1)
   * @param key
   * @param value
   * @return Status code reply
   */
  @Override
  public String set(final String key, String value) {
    checkIsInMultiOrPipeline();
    client.set(key, value);
    return client.getStatusCodeReply();
  }

此间最重要委托给Client进行拍卖。

  @Override
  public void set(final String key, final String value) {
    set(SafeEncoder.encode(key), SafeEncoder.encode(value));
  }

那边关键是调用了BinaryClient的set方法。

  public void set(final byte[] key, final byte[] value) {
    sendCommand(Command.SET, key, value);
  }

此间根本是委托了Connection的sendCommand方法。接下来到了关键部分:

  public Connection sendCommand(final ProtocolCommand cmd, final byte[]... args) {
    try {
      connect();
      Protocol.sendCommand(outputStream, cmd, args);
      return this;
    } catch (JedisConnectionException ex) {
      /*
       * When client send request which formed by invalid protocol, Redis send back error message
       * before close connection. We try to read it to provide reason of failure.
       */
      try {
        String errorMessage = Protocol.readErrorLineIfPossible(inputStream);
        if (errorMessage != null && errorMessage.length() > 0) {
          ex = new JedisConnectionException(errorMessage, ex.getCause());
        }
      } catch (Exception e) {
        /*
         * Catch any IOException or JedisConnectionException occurred from InputStream#read and just
         * ignore. This approach is safe because reading error message is optional and connection
         * will eventually be closed.
         */
      }
      // Any other exceptions related to connection?
      broken = true;
      throw ex;
    }
  }
  1. 调用connect()方法举办连接:

  public void connect() {
    if (!isConnected()) {
      try {
        socket = new Socket();
        // ->@wjw_add
        socket.setReuseAddress(true);
        socket.setKeepAlive(true); // Will monitor the TCP connection is
        // valid
        socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
        // ensure timely delivery of data
        socket.setSoLinger(true, 0); // Control calls close () method,
        // the underlying socket is closed
        // immediately
        // <-@wjw_add

        socket.connect(new InetSocketAddress(host, port), connectionTimeout);
        socket.setSoTimeout(soTimeout);

        if (ssl) {
          if (null == sslSocketFactory) {
            sslSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
          }
          socket = (SSLSocket) sslSocketFactory.createSocket(socket, host, port, true);
          if (null != sslParameters) {
            ((SSLSocket) socket).setSSLParameters(sslParameters);
          }
          if ((null != hostnameVerifier) &&
              (!hostnameVerifier.verify(host, ((SSLSocket) socket).getSession()))) {
            String message = String.format(
                "The connection to '%s' failed ssl/tls hostname verification.", host);
            throw new JedisConnectionException(message);
          }
        }

        outputStream = new RedisOutputStream(socket.getOutputStream());
        inputStream = new RedisInputStream(socket.getInputStream());
      } catch (IOException ex) {
        broken = true;
        throw new JedisConnectionException("Failed connecting to host " 
            + host + ":" + port, ex);
      }
    }
  }

那边根本选取Socket通信来贯彻命令的出殡,连接使用长连接来减小创设连接的支出。并实例化了RedisOutputStream和RedisInputStream。在每回举办query的时候都会调用connect方法来保管以前线总指挥部是失效之后能新建连接并操作成功。

  1. 调用Protocol的sendCommand方法开始展览发送:

  public static void sendCommand(final RedisOutputStream os, final ProtocolCommand command,
      final byte[]... args) {
    sendCommand(os, command.getRaw(), args);
  }
  private static void sendCommand(final RedisOutputStream os, final byte[] command,
      final byte[]... args) {
    try {
      os.write(ASTERISK_BYTE);
      os.writeIntCrLf(args.length + 1);
      os.write(DOLLAR_BYTE);
      os.writeIntCrLf(command.length);
      os.write(command);
      os.writeCrLf();

      for (final byte[] arg : args) {
        os.write(DOLLAR_BYTE);
        os.writeIntCrLf(arg.length);
        os.write(arg);
        os.writeCrLf();
      }
    } catch (IOException e) {
      throw new JedisConnectionException(e);
    }
  }

此间代码比较明晰,利用了Protocol提供的某个伸手头来布局一个需要。这里具体的交涉内容就不细深入分析了,发送完诉求之后回到。

日后调用client.getStatusCodeReply();进行再次回到状态的拿走:

  public String getStatusCodeReply() {
    flush();
    final byte[] resp = (byte[]) readProtocolWithCheckingBroken();
    if (null == resp) {
      return null;
    } else {
      return SafeEncoder.encode(resp);
    }
  }

第一调用了flush方法,保证在此之前的写入能发送出去,之后调用了readProtocolWithCheckingBroken来赢得响应。

  protected Object readProtocolWithCheckingBroken() {
    try {
      return Protocol.read(inputStream);
    } catch (JedisConnectionException exc) {
      broken = true;
      throw exc;
    }
  }

调用Protocol.read实行对RedisInputStream进行读取,在那进度中可能会抛出连接极度。

public static Object read(final RedisInputStream is) {  return process(is);}
  private static Object process(final RedisInputStream is) {

    final byte b = is.readByte();
    if (b == PLUS_BYTE) {
      return processStatusCodeReply(is);
    } else if (b == DOLLAR_BYTE) {
      return processBulkReply(is);
    } else if (b == ASTERISK_BYTE) {
      return processMultiBulkReply(is);
    } else if (b == COLON_BYTE) {
      return processInteger(is);
    } else if (b == MINUS_BYTE) {
      processError(is);
      return null;
    } else {
      throw new JedisConnectionException("Unknown reply: " + (char) b);
    }
  }

最终在read的时候对回到的响应举办了决断,枚举出了两种响应措施,对两样的响应实行不一致的拍卖。
那边能够看看,整个交互进度正是叁个Socket通讯进程。遵照一定的会谈发送央浼,之后读取重回结果。然而此地也会有三个难题正是线程安全问题,分明Jedis实例是线程不安全的,对于八线程分享jedis实例是会十分的。同临时候一向利用jedis无法防止的内需频仍的创导和销毁Socket,费用相当的大。所以就引出了背后的jedisPool的施用。

当连接池中无可用连接时会会进展等待maxWait时间,若高于泽抛Could not get a
resource from the pool非凡。

Jedis类是操作redis的大旨类

二、Jedis承继结构###\

这里是jedis的UML图:

Paste_Image.png

public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands,
    AdvancedJedisCommands, ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands, ModuleCommands {

Jedis 承继了BinaryJedis
同一时候完成了一多元的Commands接口,BinaryJedis里根本和redis
Server进行互动,一密密麻麻Commands接口首若是对redis协理的接口举办分类,像BasicCommands重要富含了info、flush等操作,BinaryJedisCommands
主要含有了get、set等操作,MultiKeyBinaryCommands主要涵盖了一部分批量操作的接口例如mset等。

at redis.clients.jedis.Protocol.read(Protocol.java:131)

 

      }

2、JedisPool(ShardedJedisPool)类分析

那就是说Redis操作怎会冒出几秒的过期时间?

初阶化切成条连接池示例

亟待验证的是,Redis
server是单线程实践全部连接发送过来的指令的,也正是说不管并发中有稍许个client在出殡和埋葬命令,redis-server端是单线程管理的,并遵照暗中认可的FIFO格局处理央浼,

3、Jedis类

纯属级数据量,二回操作超时时间在秒级是很平常的,况兼机器质量很好的情事下一度这么。

开首化非切成条连接池示例

at redis.clients.util.Pool.getResource(Pool.java:22)

JedisShardInfo类是Jedis切丝消息类

client.sadd(key, members);

package com.my.redis.redisTest.test;

import java.util.ArrayList;
import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

public class Test1 {

    private static Jedis jedis;//非切片客户端连接
    private  JedisPool jedisPool;//非切片连接池
    private  ShardedJedis shardedJedis;//切片客户端连接
    private  ShardedJedisPool shardedJedisPool;//切片连接池

    public Test1(){
        initialPool(); 
//        initialShardedPool(); 
//        shardedJedis = shardedJedisPool.getResource(); 
        jedis = jedisPool.getResource(); 

    }

    public static void main(String[] args) {
        Test1 test = new Test1();

        jedis.set("name", "limouren");
        System.out.print(jedis.get("name"));
        jedis.del("name");
        System.out.print(jedis.get("name"));
    }

    /**
     * @Description: 初始化非切片连接池  
     * @author lige
     */
    public void initialPool(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(5); 
        config.setMaxWaitMillis(1000l); 
        config.setTestOnBorrow(true);
        jedisPool = new JedisPool(config,"127.0.0.1",6379,0,"Abc12345");
    }

    /**
     * @Description: 初始化切片连接池 
     * @author lige
     */
    public void initialShardedPool(){
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(5); 
        config.setMaxWaitMillis(1000l); 
        config.setTestOnBorrow(true);

        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); 
        shards.add(new JedisShardInfo("127.0.0.1", 6379, "master")); 

        // 构造池 
        shardedJedisPool = new ShardedJedisPool(config, shards); 
    }
}