jedis操作set_Redis的客户端Jedis及Jedis操作Redis命令详解

http://donald-draper.iteye.com/blog/2347121

Redis Protocol specification:https://redis.io/topics/protocol

redis协议:http://doc.redisfans.com/topic/protocol.html

上一篇中,我们探究了一下Jedis获取Redis连接过程,具体如下:

JedisPoolConfig的功能主要是配置连接最大空闲时间,存活数量,及等待时间;

JedisPoolConfig的父类Config为GenericObjectPool的静态内部类,与连接池有关的属性在Config中,而属性的设置在JedisPoolConfig中;JedisPool的初始化主要是GenericObjectPool初始化,主要是初始化连接池,连接数,空闲时间,等待时间,连接池,候选连接池,初始化候选连接初始化执行器,JedisFactory。JedisFactory工厂为JedisPool的内部类,JedisFactory的属性有host,port,timeout,password和database;JedisFactory的主要功能为管理(创建,关闭,验证)redis连接jedis。从连接池获取jedis连接资源,实际上看是从JedisPool的父类pool中获取,而pool又委托给JedisFactory,最后由JedisFactory创建redis连接jedis。

今天我们来看一下,jedis客户端如何操作redis服务器:

public class Jedis extends BinaryJedis

implements JedisCommands

{

//这个在前面JedisFactory创建jedis客户端时,所用的构造方法

public Jedis(String host, int port, int timeout)

{

super(host, port, timeout);

}

}

来看其父类BinaryJedis

//BinaryJedis

public class BinaryJedis

implements BinaryJedisCommands

{

protected Client client;//redis连接客户端

public BinaryJedis(String host, int port, int timeout)

{

client = null;

client = new Client(host, port);

client.setTimeout(timeout);

}

}

//再来看Client的构造

public class Client extends BinaryClient

implements Commands

{

public Client(String host, int port)

{

super(host, port);

}

}

再看BinaryClient

public class BinaryClient extends Connection

{

private boolean isInMulti;//是否是事务

private String password;//密码

private long db;//数据库

public BinaryClient(String host, int port)

{

super(host, port);

}

}

再来看Connection

public class Connection

{

private String host;//ip

private int port;//端口

private Socket socket;//与redis连接socket

private RedisOutputStream outputStream;//输出流

private RedisInputStream inputStream;//输入流

private int pipelinedCommands;//管道命令数

private int timeout;//超时时间

public Connection(String host, int port)

{

this.port = 6379;

pipelinedCommands = 0;

timeout = 2000;

this.host = host;

this.port = port;

}

}

从JedisFactory创建redis连接jedis的构造方法,来看Jedis构造所做的事情为,初始化

BinaryJedis,即初始化Client的host和port,BinaryJedis有个Client,;Client初始化,其实

是初始化BinaryClient,即初始化Connection,Connection为实际与redis通信的连接,

BinaryClient有连三个属性分别为 isInMulti(是否是事务)password,db(数据库),

Connection有几个内部变量分别为host,port,socket,outputStream,inputStream,pipelinedCommands,timeout

下面再来看Jedis的另一种构造方式

public Jedis(JedisShardInfo shardInfo)

{

super(shardInfo);

}

//JedisShardInfo

public class JedisShardInfo extends ShardInfo

{

private int timeout;

private String host;

private int port;

private String password;

private String name;

public JedisShardInfo(String host, int port, int timeout)

{

this(host, port, timeout, 1);

}

public Jedis createResource()

{

return new Jedis(this);

}

//创建jedis客户端

public volatile Object createResource()

{

return createResource();

}

}

//ShardInfo

public abstract class ShardInfo

{

public ShardInfo()

{

}

public ShardInfo(int weight)

{

this.weight = weight;

}

public int getWeight()

{

return weight;

}

protected abstract Object createResource();

public abstract String getName();

private int weight;

}

从JedisShardInfo可以看出,JedisShardInfo创建jedis客户端,实际上为Jedis,及JedisShardInfo依托于Jedis。

下面看一jedis的验证

jedis.auth("redis");

//Jedis

public String auth(String password)

{

//检查是否是事务

checkIsInMulti();

//验证密码

client.auth(password);

//返回redis恢复字符串

return client.getStatusCodeReply();

}

分3步来看:

1.检查是否是事务

checkIsInMulti();

//Jedis

protected void checkIsInMulti()

{

if(client.isInMulti())

throw new JedisDataException("Cannot use Jedis when in Multi. Please use JedisTransaction instead.");

else

return;

}

//Client

public boolean isInMulti()

{

return isInMulti;

}

2.验证密码

client.auth(password);

//Client

public void auth(String password)

{

//设置密码

setPassword(password);

//发送命令

sendCommand(Protocol.Command.AUTH, new String[] {

password

});

}

//设置密码

public void setPassword(String password)

{

this.password = password;

}

//发送命令

protected transient Connection sendCommand(Protocol.Command cmd, String args[])

{

//将发送内容,转换编码字节

byte bargs[][] = new byte[args.length][];

for(int i = 0; i < args.length; i++)

bargs[i] = SafeEncoder.encode(args[i]);

//发送字节流

return sendCommand(cmd, bargs);

}

编码字符

//SafeEncoder

public static byte[] encode(String str)

{

if(str == null)

throw new JedisDataException("value sent to redis cannot be null");

return str.getBytes("UTF-8");

}

发送字节流

protected transient Connection sendCommand(Protocol.Command cmd, byte args[][])

{

//连接redis

connect();

//协议发送命令

Protocol.sendCommand(outputStream, cmd, args);

pipelinedCommands++;

return this;

}

创建连接redis Socket

connect();

//Connection

public void connect()

{

if(!isConnected())

try

{

//如果没有redis建立连接则,则创建socket,并初始化RedisOutputStream,RedisInputStream

socket = new Socket();

socket.setReuseAddress(true);

socket.setKeepAlive(true);

socket.setTcpNoDelay(true);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值