Jedis 源代码阅读一 —— Jedis

这是jedis 源代码文件夹,我们接下来选择性阅读重要的接口以及实现。

└─redis
    └─clients
        ├─jedis
        │  │  BinaryClient.java
        │  │  BinaryJedis.java
        │  │  BinaryJedisCluster.java
        │  │  BinaryJedisPubSub.java
        │  │  BinaryShardedJedis.java
        │  │  BitOP.java
        │  │  BitPosParams.java
        │  │  Builder.java
        │  │  BuilderFactory.java
        │  │  Client.java
        │  │  Connection.java
        │  │  DebugParams.java
        │  │  GeoCoordinate.java
        │  │  GeoRadiusResponse.java
        │  │  GeoUnit.java
        │  │  HostAndPort.java
        │  │  Jedis.java
        │  │  JedisCluster.java
        │  │  JedisClusterCommand.java
        │  │  JedisClusterConnectionHandler.java
        │  │  JedisClusterInfoCache.java
        │  │  JedisFactory.java
        │  │  JedisMonitor.java
        │  │  JedisPool.java
        │  │  JedisPoolAbstract.java
        │  │  JedisPoolConfig.java
        │  │  JedisPubSub.java
        │  │  JedisSentinelPool.java
        │  │  JedisShardInfo.java
        │  │  JedisSlotBasedConnectionHandler.java
        │  │  MultiKeyPipelineBase.java
        │  │  Pipeline.java
        │  │  PipelineBase.java
        │  │  Protocol.java
        │  │  Queable.java
        │  │  Response.java
        │  │  ScanParams.java
        │  │  ScanResult.java
        │  │  ShardedJedis.java
        │  │  ShardedJedisPipeline.java
        │  │  ShardedJedisPool.java
        │  │  SortingParams.java
        │  │  Transaction.java
        │  │  Tuple.java
        │  │  ZParams.java
        │  │
        │  ├─commands
        │  │      AdvancedBinaryJedisCommands.java
        │  │      AdvancedJedisCommands.java
        │  │      BasicCommands.java
        │  │      BasicRedisPipeline.java
        │  │      BinaryJedisClusterCommands.java
        │  │      BinaryJedisCommands.java
        │  │      BinaryRedisPipeline.java
        │  │      BinaryScriptingCommands.java
        │  │      BinaryScriptingCommandsPipeline.java
        │  │      ClusterCommands.java
        │  │      ClusterPipeline.java
        │  │      Commands.java
        │  │      JedisClusterBinaryScriptingCommands.java
        │  │      JedisClusterCommands.java
        │  │      JedisClusterScriptingCommands.java
        │  │      JedisCommands.java
        │  │      MultiKeyBinaryCommands.java
        │  │      MultiKeyBinaryJedisClusterCommands.java
        │  │      MultiKeyBinaryRedisPipeline.java
        │  │      MultiKeyCommands.java
        │  │      MultiKeyCommandsPipeline.java
        │  │      MultiKeyJedisClusterCommands.java
        │  │      ProtocolCommand.java
        │  │      RedisPipeline.java
        │  │      ScriptingCommands.java
        │  │      ScriptingCommandsPipeline.java
        │  │      SentinelCommands.java
        │  │
        │  ├─exceptions
        │  │      InvalidURIException.java
        │  │      JedisAskDataException.java
        │  │      JedisClusterCrossSlotException.java
        │  │      JedisClusterException.java
        │  │      JedisClusterMaxRedirectionsException.java
        │  │      JedisConnectionException.java
        │  │      JedisDataException.java
        │  │      JedisException.java
        │  │      JedisMovedDataException.java
        │  │      JedisRedirectionException.java
        │  │
        │  └─params
        │      │  Params.java
        │      │
        │      ├─geo
        │      │      GeoRadiusParam.java
        │      │
        │      ├─set
        │      │      SetParams.java
        │      │
        │      └─sortedset
        │              ZAddParams.java
        │              ZIncrByParams.java
        │
        └─util
                ClusterNodeInformation.java
                ClusterNodeInformationParser.java
                Hashing.java
                IOUtils.java
                JedisByteHashMap.java
                JedisClusterCRC16.java
                JedisURIHelper.java
                KeyMergeUtil.java
                MurmurHash.java
                Pool.java
                RedisInputStream.java
                RedisOutputStream.java
                SafeEncoder.java
                Sharded.java
                ShardInfo.java
                Slowlog.java

Jedis.java

我们每次使用jedis都会初始化一个jedis对象,对下面代码肯定不会陌生:

public class Jedis extends BinaryJedis implements JedisCommands, MultiKeyCommands,
    AdvancedJedisCommands, ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands {

  protected JedisPoolAbstract dataSource = null;

  public Jedis() {
    super();
  }

  public Jedis(final String host) {
    super(host);
  }

  public Jedis(final String host, final int port) {
    super(host, port);
  }
............

Jedis对象调用父类BinaryJedis构造器:

public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKeyBinaryCommands,
        AdvancedBinaryJedisCommands, BinaryScriptingCommands, Closeable {
    protected Client client = null;
    protected Transaction transaction = null;
    protected Pipeline pipeline = null;

    public BinaryJedis() {
        client = new Client();
    }

    public BinaryJedis(final String host) {
        URI uri = URI.create(host);
        if (uri.getScheme() != null && uri.getScheme().equals("redis")) {
            initializeClientFromURI(uri);
        } else {
            client = new Client(host);
        }
    }

    public BinaryJedis(final String host, final int port) {
        client = new Client(host, port);
    }

    public BinaryJedis(final String host, final int port, final int timeout) {
        client = new Client(host, port);
        client.setConnectionTimeout(timeout);
        client.setSoTimeout(timeout);
    }

实际上,new Jedis()的初始化中。最重要的是new Client()这句代码。

Client 继承自 BinaryClient

public class Client extends BinaryClient implements Commands {

  public Client() {
    super();
  }

而BinaryClient又继承自Collection


public class BinaryClient extends Connection {
 ............
  private String password;

  private int db;

  private boolean isInWatch;

............
  public BinaryClient() {
    super();
  }
............

接着我们来看Collection代码:

    public class Connection implements Closeable {
    .....
    protected Connection sendCommand(final ProtocolCommand cmd, final String... args) {
        final byte[][] bargs = new byte[args.length][];
        for (int i = 0; i < args.length; i++) {
            // 对cmd判空并返回bytes
            bargs[i] = SafeEncoder.encode(args[i]);
        }
        return sendCommand(cmd, bargs);
    }

    protected Connection sendCommand(final ProtocolCommand cmd) {
        return sendCommand(cmd, EMPTY_ARGS);
    }

    protected Connection sendCommand(final ProtocolCommand cmd, final byte[]... args) {
        try {
            // 1.建立Socket连接
            connect();
            // 2.依照协议完毕IO操作,也就是命令的运行
            Protocol.sendCommand(outputStream, cmd, args);
            return this;
        } catch (JedisConnectionException ex) {
            /*
             * When client send request which formed by invalid protocol, Redis
             * send back error message before close connection. We try to read
             * it to provide reason of failure.
             */
            try {
                String errorMessage = Protocol.readErrorLineIfPossible(inputStream);
                if (errorMessage != null && errorMessage.length() > 0) {
                    ex = new JedisConnectionException(errorMessage, ex.getCause());
                }
            } catch (Exception e) {
                /*
                 * Catch any IOException or JedisConnectionException occurred
                 * from InputStream#read and just ignore. This approach is safe
                 * because reading error message is optional and connection will
                 * eventually be closed.
                 */
            }
            // Any other exceptions related to connection?

broken = true;
            throw ex;
        }
    }
    ...
    // 建立Sock连接
    public void connect() {
        if (!isConnected()) {
            try {

                socket = new Socket();
                // ->@wjw_add
                socket.setReuseAddress(true);
                socket.setKeepAlive(true); // Will monitor the TCP connection is
                // valid
                socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
                // ensure timely delivery of data
                socket.setSoLinger(true, 0); // Control calls close () method,
                // the underlying socket is closed
                // immediately
                // <[email protected]_add

                socket.connect(new InetSocketAddress(host, port), connectionTimeout);
                socket.setSoTimeout(soTimeout);
                outputStream = new RedisOutputStream(socket.getOutputStream());
                inputStream = new RedisInputStream(socket.getInputStream());
            } catch (IOException ex) {
                broken = true;
                throw new JedisConnectionException(ex);
            }
        }
    }
    ...

在这里完毕了Socket连接。并返回这个Socket.

每次我们使用Jedis去运行命令。都是这个持有Soket的client去运行的。

比方:

    /**
     * Get the value of the specified key. If the key does not exist null is
     * returned. If the value stored at key is not a string an error is returned
     * because GET can only handle string values.
     * <p>
     * Time complexity: O(1)
     *
     * @param key
     * @return Bulk reply
     */
    @Override
    public String get(final String key) {
        checkIsInMultiOrPipeline();// 检查是否在事物中;检查是否是哟好难过管道技术
        client.sendCommand(Protocol.Command.GET, key);// 使用Socket进行IO操作,运行命令
        return client.getBulkReply();
    }

jedis除了继承的BinaryJedis完毕主要的IO操作。还实现了 JedisCommands, MultiKeyCommands, AdvancedJedisCommands,ScriptingCommands, BasicCommands, ClusterCommands, SentinelCommands

这几个可使用的命令的接口。

你能够參考redis自带的 unitTest,更深入的理解。

http://download.csdn.net/detail/lemon89/9407039

关于soTimeout 与 connectionTimeOut

我不多说了,这个链接解释非常清楚。

http://stackoverflow.com/questions/7360520/connectiontimeout-versus-sockettimeout

时间: 2025-01-12 08:37:39

Jedis 源代码阅读一 —— Jedis的相关文章

OpenJDK 源代码阅读之 Collections

概要 类继承关系 java.lang.Object java.util.Collections 定义 public class Collections extends Object 实现 sort public static <T extends Comparable<? super T>> void sort(List<T> list) { Object[] a = list.toArray(); Arrays.sort(a); ListIterator<T&g

Notepad++源代码阅读——窗口元素组织与布局

1.1 前言 这两天在看notepad++ 1.0版本的源代码.看了许久终于把程序的窗口之间的关系搞清楚了现在把其组织的要点写于此,希望对大家有所帮助. 1.2 窗口元素之间的关系 Notepad++主要有以下窗口元素(见下图). 其中Notepad_plus 是程序的主要窗口,其他:工具栏.状态栏.主次编辑窗口.主次选项卡窗口以及对话框窗口均为主窗口的子窗口.     _mainDocTab 和 _subDocTab 为 类:DocTabView 其成员_pView 分别指向 _mainEdi

Linux-0.11源代码阅读一 加载操作系统

x86系列CPU可以在16位实模式和32位保护模式下运行,实模式的特点是地址总线只有20位,也就是只有1MB的寻址空间,为了兼容老的CPU,Intel x86系列CPU包括最新的CPU在上电时都运行在16位的实模式下,同时在硬件上强行将CS置成0xF000,IP置成0xFFF0,那么CS:IP就指向0xFFFF0这个地址,也就是上电瞬间代码从该处开始执行,而BIOS恰恰就存储在这个地方,可以想象一下,如果连BIOS都没有将会是一个什么结果. BIOS程序被存储在计算机主板上的一块ROM芯片里,首

linux0.11 源代码阅读记录

*/--> pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;}

淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成物理查询计划

SQL编译解析三部曲分为:构建语法树,制定逻辑计划,生成物理运行计划. 前两个步骤请參见我的博客<<淘宝数据库OceanBase SQL编译器部分 源代码阅读--解析SQL语法树>>和<<淘宝数据库OceanBase SQL编译器部分 源代码阅读--生成逻辑计划>>.这篇博客主要研究第三步,生成物理查询计划. 一. 什么是物理查询计划 与之前的阅读方法一致,这篇博客的两个主要问题是what 和how.那么什么是物理查询计划?物理查询计划可以直接运行并返回数据

TLD matlab源代码阅读(2)

今天继续,下面是开始要生成正负例来训练分类器了,首先: // TRAIN DETECTOR ========================================================== // Initialize structures tld.imgsize = size(tld.source.im0.input); //为fern准备的训练集 tld.X = cell(1,length(tld.source.idx)); //training data for fern

Linux-0.11源代码阅读二 实模式到保护模式

bootsect部分已经执行完成,程序也跳转到setup部分: start: ! ok, the read went well so we get current cursor position and save it for ! posterity. mov ax,#INITSEG ! this is done in bootsect already, but... mov ds,ax mov ah,#0x03 ! read cursor pos xor bh,bh int 0x10 ! sa

【转】Tomcat总体结构(Tomcat源代码阅读系列之二)

本文是Tomcat源代码阅读系列的第二篇文章,我们在本系列的第一篇文章:在IntelliJ IDEA 和 Eclipse运行tomcat 7源代码一文中介绍了如何在intelliJ IDEA 和 Eclipse中运行Tomcat源代码,本文介绍一下Tomcat的总体结构. 本文没有特别指明的地方,源代码都是针对tomcat7.0.42来说. Tomcat的总体结构 Tomcat即是一个Http服务器也是一个Servlet容器,它的总体结构我们可以用下图来描述: 通过上图我们可以看出Tomcat中

Hadoop源代码阅读环境搭建

Hadoop源代码阅读环境搭建 一.说明 作为一个学习hadoop的同学.必须在本机上搭建hadoop源代码阅读环境,这样,在方便阅读源代码的同一时候也方便进行调试和源代码改动. 好了.以下開始搭建好开发环境. 1.环境说明:hadoop 版本号:1.2.1. IDE:eclipse.操作系统:centos 2.网上有人是通过eclipse的新建项目指定文件夹的方式将hadoop文件夹转换成Eclipseproject同一时候导入eclipse,详细做法例如以下: File-->new-->J