Redis客户端Jedis的使用

添加Pom依赖

  <dependency>
       <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
       <version>2.9.0</version>
  </dependency>

测试类JedisTest

public class JedisTest {

    /**
     * 连接单机版
     * @throws Exception
     */
    @Test
    public void testJedis() throws Exception{
        //创建一个链接Jedis对象,参数:host,port
        Jedis jedis=new Jedis("192.168.25.130",6379);
        //直接使用jedis操作redis,所有jedis的命令都对应一个方法
        jedis.set("test123","my first jedis test");
        String string=jedis.get("test123");
        System.out.println(string);
        //关闭连接
        jedis.close();

    }


    /**
     * 连接单机版,用连接池
     * @throws Exception
     */
    @Test
    public void testJedisPool() throws Exception{
        //创建一个连接池对象,两个参数host,port
        JedisPool jedisPool=new JedisPool("192.168.25.130",6379);
        //从连接池获得一个连接,就是一个jedis对象
        Jedis jedis=jedisPool.getResource();
        //使用jedis操作redis
        String string=jedis.get("test123");
        System.out.println(string);
        //关闭连接,每次使用完后关闭连接。连接池回收资源
        jedis.close();
        //关闭连接池
        jedisPool.close();
    }


    /**
     * 操作redis集群
     * @throws Exception
     */
    @Test
    public void testJedisCluster()throws Exception{
        //创建一个JedisCluster对象。他自带连接池。有一个参数nodes是一个set类型。set中包含若干个HostAndPort对象
        Set<HostAndPort> nodes=new HashSet<>();
        nodes.add(new HostAndPort("192.168.25.130",7001));
        nodes.add(new HostAndPort("192.168.25.130",7002));
        nodes.add(new HostAndPort("192.168.25.130",7003));
        nodes.add(new HostAndPort("192.168.25.130",7004));
        nodes.add(new HostAndPort("192.168.25.130",7005));
        nodes.add(new HostAndPort("192.168.25.130",7006));

        JedisCluster jedisCluster=new JedisCluster(nodes);
        //直接使用jedisCluster对象操作jedis
        jedisCluster.set("test","123");
        String string=jedisCluster.get("test");
        System.out.println(string);
        //关闭JedisCluster对象
        jedisCluster.close();
    }

实际项目中不会把这些ip和端口信息放在业务类中,如果更换信息还需要修改代码,那要怎么做那???而且单机版和集群版切换怎么做??

在项目中建立一个jedis的工具包,存放如下三个文件:接口JedisClient、两个实现类单机版类JedisClientPool、集群版类JedisClientCluster

public interface JedisClient {

    String set(String key, String value);
    String get(String key);
    Boolean exists(String key);
    Long expire(String key, int seconds);
    Long ttl(String key);
    Long incr(String key);
    Long hset(String key, String field, String value);
    String hget(String key, String field);
    Long hdel(String key, String... field);
}
public class JedisClientPool implements JedisClient {

    private JedisPool jedisPool;

    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    @Override
    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.set(key, value);
        jedis.close();
        return result;
    }

    @Override
    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get(key);
        jedis.close();
        return result;
    }

    @Override
    public Boolean exists(String key) {
        Jedis jedis = jedisPool.getResource();
        Boolean result = jedis.exists(key);
        jedis.close();
        return result;
    }

    @Override
    public Long expire(String key, int seconds) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.expire(key, seconds);
        jedis.close();
        return result;
    }

    @Override
    public Long ttl(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.ttl(key);
        jedis.close();
        return result;
    }

    @Override
    public Long incr(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.incr(key);
        jedis.close();
        return result;
    }

    @Override
    public Long hset(String key, String field, String value) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hset(key, field, value);
        jedis.close();
        return result;
    }

    @Override
    public String hget(String key, String field) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.hget(key, field);
        jedis.close();
        return result;
    }

    @Override
    public Long hdel(String key, String... field) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hdel(key, field);
        jedis.close();
        return result;
    }

}
public class JedisClientCluster implements JedisClient {


    private JedisCluster jedisCluster;

    public void setJedisCluster(JedisCluster jedisCluster) {
        this.jedisCluster = jedisCluster;
    }

    @Override
    public String set(String key, String value) {
        return jedisCluster.set(key, value);
    }

    @Override
    public String get(String key) {
        return jedisCluster.get(key);
    }

    @Override
    public Boolean exists(String key) {
        return jedisCluster.exists(key);
    }

    @Override
    public Long expire(String key, int seconds) {
        return jedisCluster.expire(key, seconds);
    }

    @Override
    public Long ttl(String key) {
        return jedisCluster.ttl(key);
    }

    @Override
    public Long incr(String key) {
        return jedisCluster.incr(key);
    }

    @Override
    public Long hset(String key, String field, String value) {
        return jedisCluster.hset(key, field, value);
    }

    @Override
    public String hget(String key, String field) {
        return jedisCluster.hget(key, field);
    }

    @Override
    public Long hdel(String key, String... field) {
        return jedisCluster.hdel(key, field);
    }

}

spring目录下建立一个配置文件applicationContent-reids.xml,在单机版还是集群版打开其注释就可以,不用修改代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">

   <!-- 连接池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="30"/>
        <!-- 最大空闲连接数 -->
        <property name="maxIdle" value="10"/>
        <!-- 每次释放连接的最大数目 -->
        <property name="numTestsPerEvictionRun" value="1024"/>
        <!-- 释放连接的扫描间隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="30000"/>
        <!-- 连接最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="1800000"/>
        <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="10000"/>
        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
        <property name="maxWaitMillis" value="1500"/>
        <!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testOnBorrow" value="true"/>
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="true"/>
        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="blockWhenExhausted" value="false"/>
    </bean>

    <!--连接jedis单机版-->
    <!--<bean id="jedisClientPool" class="cn.e3mall.common.jedis.JedisClientPool">-->
        <!--<property name="jedisPool" ref="jedisPool"/>-->
    <!--</bean>-->

    <!--<bean id="jedisPool" class="redis.clients.jedis.JedisPool">-->
        <!--<constructor-arg name="host" value="192.168.25.130"/>-->
        <!--<constructor-arg name="port" value="6379"/>-->
    <!--</bean>-->

    <!--连接redis集群-->
    <bean id="jedisClientCluster" class="cn.e3mall.common.jedis.JedisClientCluster">
        <property name="jedisCluster" ref="jedisCluster"/>
    </bean>

    <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
        <constructor-arg name="nodes">
            <set>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                    <constructor-arg name="port" value="7001"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                    <constructor-arg name="port" value="7002"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                    <constructor-arg name="port" value="7003"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                    <constructor-arg name="port" value="7004"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                    <constructor-arg name="port" value="7005"></constructor-arg>
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg name="host" value="192.168.25.130"></constructor-arg>
                    <constructor-arg name="port" value="7006"></constructor-arg>
                </bean>
            </set>
        </constructor-arg>
         <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>

    </bean>

</beans>

测试类:JedisClientTest

public class JedisClientTest {

    @Test
    public void testJedisClient()throws Exception{
        //初始化spring容器
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath:spring/applicationContext-redis.xml");
        //从容器中获得JedisClient对象
        JedisClient jedisClient=applicationContext.getBean(JedisClient.class);
        jedisClient.set("mytest","jedisClient");
        String string=jedisClient.get("mytest");
        System.out.println(string);
    }
}

Jedis连接池介绍:

Jedis连接分为直连和连接池方式;

直连指Jedis每次都会新建TCP连接,使用后再断开连接,对于频繁访问Redis的场景并不是高校的使用方式。

Jedis连接池是指Jedis对象预先放在池子中JedisPool,每次要连接Redis,只需要在池子中借,用完了归还。

客户端连接Redis使用的是TCP协议,直连的方式每次需要建立TCP连接,而连接池的方式可以预先初始化好Jedis连接,所以每次只需要从Jedis连接池借用,借用和归还操作是在本地进行的,只有少量的并发同步开销,远远小于新建TCP连接的开销。

直连 vs 连接池
直连:
优点:

  • 简单方便,适用于少量长期连接的场景

    缺点:

  • 存在每次新建关闭TCP连接开销

  • 资源无法控制,极端情况会出现内存泄漏
  • Jedis对象线程不安全

连接池:
优点:
- 无需每次连接都生成Jedis对象,降低开销
- 使用连接池的形式保护和控制资源的使用

缺点:

  • 相当于直连,使用相对麻烦,尤其在资源管理上需要很多参数来保证,一旦规划不合理也会出现问题。

连接池一些参数介绍

  • maxActive 连接池中最大连接数
  • maxIdle 连接池中最大空闲的连接数
  • minIdle 连接池中最少空闲的连接数
  • maxWaitMillis 当连接池资源用尽后,调用者的最大等待时间(毫秒),默认-1 永远不超时一直等,不建议使用
  • jmxEnabled 是否开启jmx监控,如果应用开启了jmx端口并且jmxEnabled设置为true,就可以通过jconsole或者jvisualvm看到关于连接池的相关统计,有助于了解连接池的使用情况,并且可以针对其做监控统计
  • minEvictableIdleTimeMillis 连接的最小空闲时间,达到此值后空闲连接将被移除
  • numTestsPerEvictionRun 做空闲连接检测时,每次的采样数
  • testOnBorrow 向连接池借用连接时是否做连接有效性检测(ping),无效连接会被移除,每次借用执行一次ping命令
  • testOnReturn 向连接池归还连接时是否做连接有效性检测,无效连接会被移除,每次归还多执行一次ping命令
  • testWhileIdle 向连接池借用连接时是否做连接空闲检测,空闲超时的连接会被移除。
  • timeBetweenEvictionRunsMillis 空闲连接的检测周期(毫秒)
  • blockWhenExhausted 当连接池用尽后,调用者是否要等待,这个参数和maxWaitMillis对应的,只有当参数为true时,maxWaitMillis才会生效。

Redis的Pipeline
当我们做批量操作的时候,如果用for循环性能就特别低,Redis提供了mget和mset方法,单机版的时候可以直接用,但是如果是cluster这些原子命令就用不了了,需要借助于pipeline去做。如果自己写mdel的方法,也需要借助pipeline。

可以参考:https://blog.csdn.net/Vi_NSN/article/details/78704587

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值