Это плохая практика для передачи экземпляра джедая между методами?

Я имел в виду этот вопрос SO, и я сделал несколько дополнений в этом тесте. Основная проблема заключается в том, что мой API замедляется по мере увеличения нагрузки на сервер. Я использую конфигурацию пула джедаев.

// get a new instance
    public synchronized Jedis getJedi() {
    try {
        return jedisPool.getResource();
    } catch (Exception e) {
        log.fatal("REDIS CONN ERR:", e);
        return null;
    }
    }

// intialize at start
    public void initialize() {
    if (jedisPool == null) {
        IniUtils cp = PropertyReader.getConnPoolIni();

        String host = cp.get(REDIS, REDIS_HOST);
        int port = Integer.parseInt(cp.get(REDIS, REDIS_PORT));
        String password = cp.get(REDIS, REDIS_PASSWORD);
        int timeout = Integer.parseInt(cp.get(REDIS, REDIS_TIMEOUT));

        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(Integer.parseInt(cp.get(REDIS, REDIS_MAX_TOTAL_CONNECTIONS)));
        poolConfig.setMaxIdle(Integer.parseInt(cp.get(REDIS, REDIS_MAX_IDLE)));
        poolConfig.setMinIdle(Integer.parseInt(cp.get(REDIS, REDIS_MIN_IDLE)));
        poolConfig.setMaxWaitMillis(Long.parseLong(cp.get(REDIS, REDIS_MAX_WAIT_TIME_MILLIS)));

        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);

        if (password != null && !password.trim().isEmpty()) {
        jedisPool = new JedisPool(poolConfig, host, port, timeout, password);
        } else {
        jedisPool = new JedisPool(poolConfig, host, port, timeout);
        }

        test();

      }
    }

    @Override
    public void destroy() {
      if (jedisPool.isClosed() == false)
          jedisPool.destroy();
    }

    private void test() {
      try (Jedis test = getJedi()) {
        log.info("Testing Redis:" + test.ping());
      }
    }

И во время использования я получаю экземпляр Jedis в try-with-resources и работаю над ним. Я использую очень мало конвейерной обработки и есть различные вызовы Redis, поэтому каждый раз, когда вызывается метод, создается новый экземпляр jedis.

Согласно такому разделенному вопросу, моя реализация приведет к очень медленным результатам. Итак, могу ли я передать экземпляр Jedis методам и работать с конвейером в соответствии с бизнес-логикой. Что-то вроде этого -

  public void push5(int n) {
    try (Jedis jedi = redisFactory.getJedi()) {
        pushWithResource(n, jedi, 0);
    }
  }

  public void pushWithResourceAndPipe(int n, Jedis jedi, int k) {
    if (k >= n)
        return;
    Pipeline pipeline = jedi.pipelined();
    map.put("id", "" + i);
    map.put("name", "lyj" + i);
    pipeline.hmset("m" + i, map);
    ++i;
    pushWithResourceAndPipe(n, jedi, ++k);
    pipeline.sync();
  }

    public void pushWithResource(int n, Jedis jedi, int k) {
    if (k >= n)
        return;
    map.put("id", "" + i);
    map.put("name", "lyj" + i);
    jedi.hmset("m" + i, map);
    ++i;
    pushWithResource(n, jedi, ++k);
  }

Есть ли способ улучшить вызовы API? Не могли бы вы порекомендовать некоторые проекты, которые используют jedis на стороне сервера, поэтому у меня будет лучшее понимание того, как эффективно использовать jedis.

Конфигурация Redis / Jedis

Версия Jedis:2.8.1 Версия Redis:2.8.4 Версия Java:1.8

1 ответ

  1. getJedi не нужно синхронизировать, так как JedisPool является потокобезопасным.
  2. Если ваша логика может допускать добавление задержки из setTestOnBorrow, вы можете отключить другие вещи (setTestOnReturn, setTestWhileIdle). Если ваша логика может терпеть повторные попытки, отключение setTestOnBorrow должно помочь. (так как это всегда делает проверку пинг-понга для каждого заимствования)
  3. Ваш pushWithResourceAndPipe имеет ошибку: вы создаете экземпляр конвейера для каждого рекурсивного вызова, который может быть "медленнее", чем pushWithResource. Я думаю, что вы намеревались добавить все запросы в один конвейер и синхронизировать, а затем вам нужно передать экземпляр конвейера и вызвать синхронизацию от вызывающей стороны.
Другие вопросы по тегам