02-Redis 客户端

文章目录

  • Redis客户端
    • 一、命令行
    • 二、Jedis
      • 1.1 示例
      • 2.2 关键参数
    • 三、JedisPool
    • 四、JedisCluster
    • 五、手写Jedis简单客户端
    • 六、参考

Redis客户端

一、命令行

  • 命令行是Redis自带的一个很方便的客户端,相关的操作在第一篇文章中有介绍。为了提高redis的效率,可以批量设值,mset k1 v1 k2 v2,在前面一篇文章中提到过了

二、Jedis

  • Jedis是java的redis客户端,也是使用最广泛的java客户端。

1.1 示例

  • pom

<dependencies>
        
            
                
                
                
            
        
        <dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
            
            <version>3.0.1-mozping-SNAPSHOTversion>
        dependency>
    dependencies>
  • 代码
public class MyRedisClient1 {

    public static final String REDIS_HOST = "192.168.11.27";
    public static final String REDIS_PASSWORD = "Intellifusion@20190108";
    public static final int REDIS_PORT = 6379;
    public static final Jedis JEDIS = new Jedis(REDIS_HOST);

    static {
        JEDIS.auth(REDIS_PASSWORD);
    }
    
    public static void main(String[] args) throws InterruptedException {
        String rsp = JEDIS.set("name", "mozping");
        System.out.println("响应:" + rsp);
        String ping = JEDIS.ping();
        System.out.println("ping的响应:" + ping);
    }
}
打印:
响应:OK
ping的响应:PONG

2.2 关键参数

  • Jedis的构造方法处理地址和端口之外,还有几个关键的参数
public Jedis(final String host, final int port, final int connectionTimeout, final int soTimeout,final boolean ssl)
connectionTimeout:表示连接超时时间。默认2秒
soTimeout:表示读取数据超时时间。默认2秒
ssl:ssl安全连接,布尔类型,默认false

参数默认值:
private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
private int soTimeout = Protocol.DEFAULT_TIMEOUT;
public static final int DEFAULT_TIMEOUT = 2000;

三、JedisPool

  • JedisPool是Jedis连接池。可以通过JedisPool来封装jedis客户端的工具类,避免频繁的创建jedis连接对象。
    如果使用了Spring,可以使用bean的方式来初始化JedisPool,如果没有的话可以使用静态代码块的方式来初始化。
/**
 * Redis通用工具类
 */
//在使用Spring集成的时候,使用该注解,在无参构造方法中初始化JedisPool
//@Component
public class JedisUtils {

    private JedisPool pool = null;
    private String ip = "192.168.42.111";
    private int port = 6379;
    private String auth = "12345678";

    /**
     * 无参构造方法初始化redisPool
     */
    public JedisUtils() {
        if (pool == null) {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(500);
            config.setMaxIdle(5);
            config.setMaxWaitMillis(100);
            config.setTestOnBorrow(true);
            pool = new JedisPool(config, this.ip, this.port, 100000, this.auth);
        }
    }

    /**
     * 获取key对应的value
     *
     * @param key
     * @return 成功返回value 失败返回null
     */
    public String get(String key) {
        Jedis jedis = null;
        String value = null;
        try {
            jedis = pool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return value;
    }

    /**
     * 存储键值对,并释放连接资,如果key已经存在 则覆盖
     *
     * @param key
     * @param value
     * @return 成功 返回OK 失败返回 0
     */
    public String set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();//每次操作时向pool借用个jedis对象,用完即还?
            return jedis.set(key, value);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            return "0";
        } finally {
            returnResource(jedis);
        }
    }


    /**
     * 删除指定的key,也可以传入一个包含key的数组
     *
     * @param keys 个key 也可以使 string 数组
     * @return 返回删除成功的个
     */
    public Long del(String... keys) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.del(keys);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            return 0L;
        } finally {
            returnResource(jedis);
        }
    }


    /**
     * 判断key是否存在
     *
     * @param key
     * @return true OR false
     */
    public Boolean exists(String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.exists(key);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            return false;
        } finally {
            returnResource(jedis);
        }
    }


    /**
     * 设置key value并制定这个键值的有效间
     *
     * @param key
     * @param value
     * @param seconds 单位:
     * @return 成功返回OK 失败和异常返回null
     */
    public String setex(String key, String value, int seconds) {
        Jedis jedis = null;
        String res = null;
        try {
            jedis = pool.getResource();
            res = jedis.setex(key, seconds, value);
        } catch (Exception e) {
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            returnResource(jedis);
        }
        return res;
    }


    /**
     * 返还到连接池
     *
     * @param redis
     */
    public static void returnResource(Jedis jedis) {
        try {
            if (jedis != null) {
                //高版本jedis close 取代池回收
                jedis.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 更多方法可以根据需要再编写。

四、JedisCluster

  • JedisCluster是连接redis集群的客户端。目前尚未分析道redis的架构演变(单机->分片->集群)。后续再分析,
    可以阅读参考文献[2]

五、手写Jedis简单客户端

  • 手写redis实际上就是了解RESP协议。不了解协议结构,可以阅读参考文献[3]

public class MySimpleRedisClient {


    static class RedisClient {
        private static Socket socket;
        private static OutputStream write;
        private static InputStream read;

        public RedisClient(String host, int port) throws IOException {
            socket = new Socket(host, port);
            write = socket.getOutputStream();;
            read = socket.getInputStream();
        }

        public void set(String key, String val) throws IOException {
            StringBuffer sb = new StringBuffer();
            sb.append("*3").append("\r\n");//代表3个参数
            sb.append("$3").append("\r\n");//第一个参数的长度
            sb.append("SET").append("\r\n");//第一个参数的内容

            sb.append("$").append(key.getBytes().length).append("\r\n");//第二个参数长度
            sb.append(key).append("\r\n");//第二个参数内容

            sb.append("$").append(val.getBytes().length).append("\r\n");//第三个参数长度
            sb.append(val).append("\r\n");//第三个参数内容

            write.write(sb.toString().getBytes());
            byte[] bytes = new byte[1024];
            read.read(bytes);
            System.out.println("set " + key + " -- > " + val + ", success," + new String(bytes));
        }

        public void get(String key) throws IOException {
            StringBuffer sb = new StringBuffer();
            sb.append("*2").append("\r\n");//代表2个参数
            sb.append("$3").append("\r\n");//第一个参数长度
            sb.append("GET").append("\r\n");//第一个参数的内容

            sb.append("$").append(key.getBytes().length).append("\r\n");//第二个参数长度
            sb.append(key).append("\r\n");//第二个参数内容

            write.write(sb.toString().getBytes());
            byte[] bytes = new byte[1024];
            read.read(bytes);
            System.out.println("get" + key + " success," + new String(bytes));
            System.out.println(new String(bytes));
        }
    }

    public static void main(String[] args) throws IOException {
        RedisClient jedis = new RedisClient("127.0.0.1", 6379);
        jedis.set("test", "001");
        jedis.get("test");
    }
}

  • image

六、参考

  • [1] jedisPool实现原理及源码分析(1)----对象池的说明
  • [2] java通过jedis操作redis(从JedisPool到JedisCluster)
  • [3] Redis Resp协议

你可能感兴趣的:(Redis和缓存)