Todos os produtos
Search
Central de documentação

Tair (Redis® OSS-Compatible):Pipelining

Última atualização: Aug 20, 2026

Use o mecanismo de pipelining do Redis para executar operações em lote ou melhorar o desempenho na execução de comandos. O pipelining envia vários comandos ao servidor simultaneamente, o que reduz a latência de rede e aumenta o desempenho. Tair (Redis OSS-compatible) oferece suporte ao pipelining nativo do Redis.

Introdução ao pipelining

Normalmente, clientes e servidores Redis utilizam um padrão de interação ping-pong. Nesse modelo, o cliente envia um comando e aguarda a resposta do servidor antes de enviar o próximo.

O Redis também suporta o modo pipeline, que funciona como uma linha de montagem. O cliente envia um comando e não espera pela resposta antes de transmitir os subsequentes. Após enviar todos os comandos, o cliente lê todas as respostas e as associa aos comandos originais na ordem correta. Na maioria das implementações de clientes Redis para o modo pipeline, os comandos são enviados em lote. Depois que todos os resultados são recebidos, eles retornam à aplicação.

A figura a seguir ilustra a comunicação de rede para os padrões ping-pong e pipeline.pipeline

O pipelining aumenta a eficiência e o desempenho do programa ao reduzir o tempo de ida e volta da rede (RTT). Ele também diminui a quantidade de chamadas de sistema read() e write(), além de reduzir as trocas de contexto de processo.

Essa técnica é muito eficaz em determinados cenários. Por exemplo, se você precisar enviar vários comandos ao servidor rapidamente sem exigir uma resposta imediata para cada um, utilize o pipelining como ferramenta de processamento em lote para otimizar o desempenho.

Importante

Ao usar pipelining, o cliente obtém uso exclusivo da conexão com o servidor. Durante esse período, não é possível realizar outras operações fora do pipeline até que ele seja fechado. Para executar outras tarefas simultaneamente, crie uma conexão separada para a operação de pipeline, mantendo-a isolada das operações regulares.

Para mais informações, consulte Pipeline.

Precauções

  • O pipelining não garante atomicidade.

    Ele apenas altera o método de envio do cliente para um lote de comandos. O servidor ainda analisa o fluxo de dados em comandos individuais e os executa sequencialmente. Cada comando é independente, o que significa que o servidor pode processar solicitações de outros clientes durante esse intervalo. Para garantir atomicidade, use transações ou scripts Lua.

  • Não há suporte para rollback caso ocorra um erro durante a execução do pipeline.

    Como o pipelining não possui as propriedades de uma transação, evite utilizá-lo quando os comandos a serem executados tiverem dependências entre si.

    Nota

    Alguns clientes, como o redis-py, usam os comandos de transação MULTI e EXEC para simular um pipeline. Ao utilizar esses clientes, fique atento às diferenças entre pipelining e transações para evitar erros. Para mais detalhes sobre as limitações das transações, consulte Transactions.

  • Servidores e alguns clientes possuem limites de buffer. Evite incluir muitos comandos em um único pipeline.

  • O pipelining é um padrão de interação cliente-servidor independente da arquitetura do servidor. Portanto, instâncias com arquitetura cluster em modo proxy, arquitetura cluster em modo de conexão direta ou arquitetura de divisão de leitura/escrita suportam essa funcionalidade.

    Nota

    A arquitetura cluster tem suas próprias restrições. Por exemplo, ela não permite acessar chaves em slots diferentes com um único comando. Se tentar acessar dados que não pertencem ao nó atual, ocorrerá um erro -MOVED. Ao usar pipelining em uma arquitetura cluster, certifique-se de que os comandos dentro do pipeline atendam às condições de execução dessa arquitetura. Para mais informações sobre as limitações, consulte Command limitations for cluster and read/write splitting instances.

Exemplos de código

Comparação de desempenho

O código abaixo demonstra a diferença de desempenho entre o uso e o não uso de pipeline.

package pipeline.kvstore.aliyun.com;
import java.util.Date;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
public class RedisPipelinePerformanceTest {
        static final String host = "xxxxxx.m.cnhza.kvstore.aliyuncs.com";
        static final int port = 6379;
        static final String password = "password";
        public static void main(String[] args) {
            Jedis jedis = new Jedis(host, port);
                // The password of the Tair instance
                String authString = jedis.auth(password);// password
                if (!authString.equals("OK")) {
                    System.err.println("AUTH Failed: " + authString);
                    jedis.close();
                    return;
                }
                // Run multiple commands consecutively.
                final int COUNT=5000;
                String key = "KVStore-Tanghan";
                // 1 ---Operation without a pipeline---
                jedis.del(key);// Initialize the key.
                Date ts1 = new Date();
                for (int i = 0; i < COUNT; i++) {
                    // Send a request and receive a response.
                    jedis.incr(key);
                }
                Date ts2 = new Date();
                System.out.println("Without pipeline > value is:"+jedis.get(key)+" > Time elapsed: " + (ts2.getTime() - ts1.getTime())+ "ms");
                //2 ----Comparison with a pipeline operation---
                jedis.del(key);// Initialize the key.
                Pipeline p1 = jedis.pipelined();
                Date ts3 = new Date();
                for (int i = 0; i < COUNT; i++) {
                    // Send the request. 
                    p1.incr(key);
                }
                // Receive the response.
                p1.sync();
                Date ts4 = new Date();
                System.out.println("With pipeline > value is:"+jedis.get(key)+" > Time elapsed: " + (ts4.getTime() - ts3.getTime())+ "ms");
                jedis.close();
        }
    }

Após insira o endpoint e a senha corretos da instância Tair (Redis OSS-compatible) e execute o programa Java, o sistema retorna a saída abaixo. Esse resultado mostra que o uso de pipeline é significativamente mais rápido.

Without pipeline > value is:5000 > Time elapsed: 5844ms
With pipeline > value is:5000 > Time elapsed: 78ms

Como tratar dados de resposta

Existem duas formas de tratar os dados de resposta de um pipeline Jedis. Consulte o exemplo de código a seguir para mais detalhes.

package pipeline.kvstore.aliyun.com;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
    public class PipelineClientTest {
        static final String host = "xxxxxxxx.m.cnhza.kvstore.aliyuncs.com";
        static final int port = 6379;
        static final String password = "password";
        public static void main(String[] args) {
            Jedis jedis = new Jedis(host, port);
                // Instance password
                String authString = jedis.auth(password);// password
                if (!authString.equals("OK")) {
                    System.err.println("AUTH Failed: " + authString);
                    jedis.close();
                    return;
                }
                String key = "KVStore-Test1";
                jedis.del(key);// Initialize
                // -------- Method 1
                Pipeline p1 = jedis.pipelined();
                System.out.println("-----Method 1-----");
                for (int i = 0; i < 5; i++) {
                    p1.incr(key);
                    System.out.println("Pipeline sends request");
                }
                // Requests sent. Start receiving responses.
                System.out.println("Requests sent. Start receiving responses.");
                List<Object> responses = p1.syncAndReturnAll();
                if (responses == null || responses.isEmpty()) {
                    jedis.close();
                    throw new RuntimeException("Pipeline error: No response received");
                }
                for (Object resp : responses) {
                    System.out.println("Pipeline receives response: " + resp.toString());
                }
                System.out.println();
                //-------- Method 2
                System.out.println("-----Method 2-----");
                jedis.del(key);// Initialize
                Pipeline p2 = jedis.pipelined();  
                // You must declare the Response object first.
                Response<Long> r1 = p2.incr(key); 
                System.out.println("Pipeline sends request");
                Response<Long> r2 = p2.incr(key);
                System.out.println("Pipeline sends request");
                Response<Long> r3 = p2.incr(key);
                System.out.println("Pipeline sends request");
                Response<Long> r4 = p2.incr(key);  
                System.out.println("Pipeline sends request");
                Response<Long> r5 = p2.incr(key);
                System.out.println("Pipeline sends request");
                try{  
                    r1.get();  // This operation fails because the client has not started to receive responses.
                }catch(Exception e){  
                    System.out.println(" <<< Pipeline error: The client has not started to receive responses. >>> ");  
                }  
             // Requests sent. Start receiving responses.
                System.out.println("Requests sent. Start receiving responses.");
                p2.sync();  
                System.out.println("Pipeline receives response: " + r1.get());  
                System.out.println("Pipeline receives response: " + r2.get());  
                System.out.println("Pipeline receives response: " + r3.get());
                System.out.println("Pipeline receives response: " + r4.get());
                System.out.println("Pipeline receives response: " + r5.get());
                jedis.close();
            }
    }

Depois de insira o endpoint e a senha corretos da instância Tair (Redis OSS-compatible) e execute o programa Java, a aplicação retorna a seguinte saída:

-----Method 1-----
Pipeline sends request
Pipeline sends request
Pipeline sends request
Pipeline sends request
Pipeline sends request
Requests sent. Start receiving responses.
Pipeline receives response: 1
Pipeline receives response: 2
Pipeline receives response: 3
Pipeline receives response: 4
Pipeline receives response: 5

-----Method 2-----
Pipeline sends request
Pipeline sends request
Pipeline sends request
Pipeline sends request
Pipeline sends request
 <<< Pipeline error: The client has not started to receive responses. >>> 
Requests sent. Start receiving responses.
Pipeline receives response: 1
Pipeline receives response: 2
Pipeline receives response: 3
Pipeline receives response: 4
Pipeline receives response: 5