Использование конвейерной технологии Redis

Redis

содержание

Конвейерная технология Redis

Redis a.客户端-服务端模型(C/S模型)а также请求/响应协议Сервис TCP.

Это означает, что обычно запрос следует следующим шагам:

  • Клиент отправляет запрос на сервер и ожидает возврата сокета, обычно в режиме блокировки, ожидая ответа сервера.

  • Сервер обрабатывает команду и возвращает результат клиенту.

Это обычная модель запроса.

普通请求模型

Так называемое RTT (время круговного времени) - задержка круговой поездки. Это важный показатель производительности в компьютерных сетях, указывая на то, что он начинается с отправителя, отправляющих данные отправителю, получающее подтверждение от приемника (после приемника Получает данные) подтверждение отправляется немедленно), общая задержка пережила.

Обычно считается, что односторонняя задержка = задержка передачи t1 + задержка распространения t2 + задержка постановки в очередь t3.

Чтобы решить эту проблему, Redis поддерживает конвейеры для снижения RTT.

通过管道减少RTT

SpringDataRedis с использованием конвейера

SpringDataRedis предоставляетexecutePipelinedспособ поддержки трубопроводов.

Ниже приведена работа с очередью Redis, которая помещается в конвейер для работы.

package net.ijiangtao.tech.framework.spring.ispringboot.redis.pipelining;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.time.Duration;
import java.time.Instant;

/**
 * Redis Pipelining
 *
 * @author ijiangtao
 * @create 2019-04-13 22:32
 **/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class RedisPipeliningTests {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String RLIST = "test_redis_list";

    @Test
    public void test() {

      Instant beginTime2 = Instant.now();

      redisTemplate.executePipelined(new RedisCallback<Object>() {
          @Override
          public Object doInRedis(RedisConnection connection) throws DataAccessException {
              for (int i = 0; i < (10 * 10000); i++) {
                  connection.lPush(RLIST.getBytes(), (i + "").getBytes());
              }
              for (int i = 0; i < (10 * 10000); i++) {
                  connection.rPop(RLIST.getBytes());
              }
              return null;
          }
      });

      log.info(" ***************** pipeling time duration : {}", Duration.between(beginTime2, Instant.now()).getSeconds());

  }
}

УведомлениеexecutePipelinedсерединаdoInRedisМетод всегда возвращает какnull.

Тестирование производительности пайплайнов Redis

Вышеприведенное кратко демонстрирует, как используется конвейер, так какова его производительность?

Давайте проверим это вместе.

Во-первых, Redis предоставляетredis-benchmarkЧтобы проверить производительность инструмента, я открыл командную строку через cmd на своем компьютере, не используя каналы, и выполнил миллион операций установки и получения.Эффект следующий:

$ redis-benchmark -n 1000000 -t set,get -q
SET: 42971.94 requests per second
GET: 46737.71 requests per second

В среднем обрабатывается более 40 000 запросов на операцию в секунду.

пройти через-PКоманда использует конвейер, и эффект следующий:

$ redis-benchmark -n 1000000 -t set,get -P 16 –q
SET: 198098.27 requests per second
GET: 351988.72 requests per second

После использования труб скорость установки и получения стала почти 200 000 и 350 000 раз в секунду.

Затем на сервере я протестировал использование SpringDataRedis.rpopПроизводительность 2000 деков.

Используйте однопоточную Deckeue, 32-нить одновременную очередью одновременного выпуска и однопоточный трубопровод, соответственно. Вот результаты теста:

管道出队测试结果

Согласно статистическим данным, удаление из очереди 2000 раз в одном потоке занимает около 6 секунд, одновременный запрос 32 потоков занимает около 2 секунд, а использование конвейера в одном потоке занимает всего около 70 миллисекунд.

Меры предосторожности при использовании трубопроводной техники

Когда вы делаете частые запросы Redis, вам следует использовать конвейерную технологию для лучшей производительности и более низкого RTT.

Но если через конвейер отправляется слишком много запросов, это также приведет к высокой загрузке ЦП Redis.

Ниже показано использование ЦП очередью для мониторинга очереди путем отправки команды удаления из очереди в Redis в цикле:

监听队列的CUP使用情况

Когда в конвейере накапливается большое количество запросов, загрузка ЦП быстро возрастает до 100%, что является очень опасной операцией.

Для сценария прослушивания очереди простой метод заключается в том, чтобы позволить потоку заснуть на несколько секунд, когда содержимое, возвращаемое очередью, окажется пустым, и дождаться накопления определенного количества данных в очереди, прежде чем получение его через конвейер, так что вы можете наслаждаться Высокая производительность, обеспечиваемая конвейером, позволяет избежать риска чрезмерной загрузки ЦП.

Thread.currentThread().sleep(10 * 1000);

пример кода

Github-ispringboot-redis