Jedis源码分析(二)-Jedis的内部实现(Client,Pipeline,Transact
Jedis源码分析共有四个章节,以下为各章链接:
1 Jedis的类结构? 首先看Jedis的内部结构,图2-1中用橘色框标出了主要支架,为突出主要架构,或有稍许内容没有标出。
图1-1 Jedis的类结构 ? Jedis以输入的命令参数是否为二进制,将处理请求的具体实现部署在两个类中,例如 2 Jedis的初始化流程Jedis jedis = new Jedis("localhost",6379,15000); Transaction t = jedis.multi(); Pipeline pipeline = jedis.pipelined(); ? Jedis通过传入Redis服务器地址(host,port)开始初始化,然后在BinaryJedis里实例化Client。Client通过Socket维持客户端与Redis服务器的连接与沟通。 //BinaryJedis类 public Transaction multi() { client.multi(); transaction = new Transaction(client); return transaction; } public Pipeline pipelined() { pipeline = new Pipeline(); pipeline.setClient(client); return pipeline; } ? 下面通过发送一个 3 Jedis工作模式的调用流程3.1 client请求模式? 以 jedis.get("foo");
? 图3-1和3-2是client模式下,发送请求,读取回复的具体实现。可以清楚看到,在每次发送命令前,会先通过
? Protocol是一个通讯工具类,将Redis的各类执行关键字存储为静态变量,可以直观调用命令,例如 3.2 Pipeline和Transaction模式
? 图3-3 是Transaction和Pipeline两个类的的类结构。可以看到Pipeline和Transaction都继承自 Pipeline p = jedis.pipelined(); //只发送命令,不读取结果,此时的Response<T>没有数据 Response<String> string = p.get("string"); Response<String> list = p.lpop("list"); Response<String> hash = p.hget("hash","foo"); Response<Set<String>> zset = p.zrange("zset",-1); Response<String> set = p.spop("set"); //一次读取所有response.此时的Response<T>有数据 p.sync(); assertEquals("foo",string.get()); assertEquals("foo",list.get()); assertEquals("bar",hash.get()); assertEquals("foo",zset.get().iterator().next()); assertEquals("foo",set.get()); Transactions使用方法: //开启事务 Transaction t = jedis.multi(); //命令进入服务端的待执行队列 Response<String> string = t.get("string"); Response<String> list = t.lpop("list"); Response<String> hash = t.hget("hash","foo"); Response<Set<String>> zset = t.zrange("zset",-1); Response<String> set = t.spop("set"); //发送EXEC指令,执行所有命令,并返回结果 t.exec(); assertEquals("foo",set.get());
? 图3-4,3-5 显示了Pipeline从发送请求到读取回复的具体实现,Transaction的实现与其类似,因而没有另外做图说明。由上图可见,Pipeline通过Client发送命令,Client在
? 刚发送消息后, ? 在执行 以上就是Pipeline的主要工作流程。Transaction的 public List<Object> exec() { // 清空inputstream里面的所有数据,忽略QUEUED or ERROR回复 client.getMany(getPipelinedResponseLength()); //发送EXEC指令,让服务端执行所有命令 client.exec(); //事务结束 inTransaction = false; //从inputStream中读取所有回复 List<Object> unformatted = client.getObjectMultiBulkReply(); if (unformatted == null) { return null; } //和sync()一样 List<Object> formatted = new ArrayList<Object>(); for (Object o : unformatted) { try { formatted.add(generateResponse(o).get()); } catch (JedisDataException e) { formatted.add(e); } } return formatted; } 本节虽未将Pipeline和Transaction的方法实现尽述,但也大同小异。关键点在于理解第一章介绍的3类请求逻辑。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |