文章目录
- 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
<!--为了便于源码调试,这里我依赖的是我自己编译的jedis客户端,修改版本号即可。-->
<dependencies>
<!--不依赖原生的jedis客户端-->
<!--<dependency>-->
<!--<groupId>redis.clients</groupId>-->
<!--<artifactId>jedis</artifactId>-->
<!--<version>2.9.0</version>-->
<!--</dependency>-->
<!--依赖源码编译的jedis客户端-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<!--<version>2.9.0</version>-->
<version>3.0.1-mozping-SNAPSHOT</version>
</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");
}
}
六、参考
- [1] jedisPool实现原理及源码分析(1)----对象池的说明
- [2] java通过jedis操作redis(从JedisPool到JedisCluster)
- [3] Redis Resp协议