private ByteBuffer readRemoteByteBuffer(ClientBlockInfo blockInfo, long offset, long len) {
    ByteBuffer buf = null;

    try {
      List<NetAddress> blockLocations = blockInfo.getLocations();
      LOG.info("Block locations:" + blockLocations);

      for (int k = 0; k < blockLocations.size(); k++) {
        String host = blockLocations.get(k).mHost;
        int port = blockLocations.get(k).mSecondaryPort;

        // The data is not in remote machine's memory if port == -1.
        if (port == -1) {
          continue;
        }
        if (host.equals(InetAddress.getLocalHost().getHostName())
            || host.equals(InetAddress.getLocalHost().getHostAddress())) {
          String localFileName = CommonUtils.concat(TFS.getRootFolder(), blockInfo.blockId);
          LOG.warn("Master thinks the local machine has data " + localFileName + "! But not!");
        }
        LOG.info(
            host
                + ":"
                + port
                + " current host is "
                + InetAddress.getLocalHost().getHostName()
                + " "
                + InetAddress.getLocalHost().getHostAddress());

        try {
          buf =
              retrieveByteBufferFromRemoteMachine(
                  new InetSocketAddress(host, port), blockInfo.blockId, offset, len);
          if (buf != null) {
            break;
          }
        } catch (IOException e) {
          LOG.error(e.getMessage());
          buf = null;
        }
      }
    } catch (IOException e) {
      LOG.error("Failed to get read data from remote " + e.getMessage());
      buf = null;
    }

    return buf;
  }
  /**
   * Reads from a remote byte buffer.
   *
   * @param tachyonFS a TachyonFS
   * @param blockInfo the block information
   * @param offset offset to start the read at
   * @param len number of bytes to read
   * @param conf Tachyon configuration
   * @return <code>ByteBuffer</code> containing the bytes read
   */
  public ByteBuffer readRemoteByteBuffer(
      TachyonFS tachyonFS, ClientBlockInfo blockInfo, long offset, long len, TachyonConf conf) {
    ByteBuffer buf = null;

    try {
      List<NetAddress> blockLocations = blockInfo.getLocations();
      LOG.info("Block locations:" + blockLocations);
      String localhost = NetworkAddressUtils.getConnectHost(ServiceType.WORKER_RPC, conf);

      for (NetAddress blockLocation : blockLocations) {
        String host = blockLocation.mHost;
        int port = blockLocation.mSecondaryPort;

        // The data is not in remote machine's memory if primary port == -1. We check primary port
        // because if the data is in the under storage, the secondary port (data transfer port)
        // will be set.
        if (blockLocation.mPort == -1) {
          continue;
        }

        if (host.equals(InetAddress.getLocalHost().getHostName())
            || host.equals(InetAddress.getLocalHost().getHostAddress())
            || host.equals(localhost)) {
          LOG.warn(
              "Master thinks the local machine has data, but not!"
                  + "(or local read is disabled) blockId:{}",
              blockInfo.blockId);
        }
        LOG.info(
            host
                + ":"
                + port
                + " current host is "
                + localhost
                + " "
                + NetworkAddressUtils.getLocalIpAddress(conf));

        try {
          buf =
              retrieveByteBufferFromRemoteMachine(
                  new InetSocketAddress(host, port), blockInfo.blockId, offset, len, conf);
          if (buf != null) {
            break;
          }
        } catch (IOException e) {
          LOG.error(
              "Fail to retrieve byte buffer for block "
                  + blockInfo.blockId
                  + " from remote "
                  + host
                  + ":"
                  + port
                  + " with offset "
                  + offset
                  + " and length "
                  + len,
              e);
          buf = null;
        }
      }
    } catch (IOException e) {
      LOG.error("Failed to get read data from remote ", e);
      buf = null;
    }

    return buf;
  }