Todos os produtos
Search
Central de documentação

Tair (Redis® OSS-Compatible):Use Msearch no TairSearch para pesquisar documentos por shard de dados

Última atualização: Jun 26, 2026

Quando uma única chave do TairSearch acumula muitos documentos, o uso de memória pode exceder a capacidade do shard de dados e causar um erro de out-of-memory (OOM). O comando TFT.MSEARCH resolve esse problema ao permitir a divisão de uma chave grande em chaves menores distribuídas por vários shards de dados, consultando todas elas em uma única solicitação. O TairProxy encaminha a solicitação para cada shard em paralelo; em seguida, pontua, classifica e agrega os resultados antes de retorná-los ao cliente.

Tipos de instância compatíveis

Recomendamos usar o TFT.MSEARCH com instâncias de divisão de leitura/gravação ou instâncias cluster no modo proxy que incluam o TairProxy. Não recomendamos usar o TFT.MSEARCH com instâncias cluster no modo de conexão direta ou com instâncias padrão sem o TairProxy.

Como funciona

O TairSearch oferece dois comandos de pesquisa:

Comando

Escopo

TFT.SEARCH

Consulta uma única chave

TFT.MSEARCH

Consulta várias chaves com a mesma configuração de schema

Caminho de escrita

Ao receber solicitações de escrita do cliente, o TairProxy roteia cada chave para o shard de dados apropriado com base nos hash slots.

Figura 1. Caminho de escrita: TairProxy distribuindo chaves para shards de dados TairProxy数据写入流程

Caminho de leitura

Quando o cliente envia uma solicitação TFT.MSEARCH, o TairProxy executa as seguintes etapas:

  1. Encaminha a consulta para cada shard de dados que contém as chaves solicitadas.

  2. Cada shard pesquisa suas chaves e retorna os documentos correspondentes.

  3. O TairProxy pontua, classifica e agrega todos os resultados.

  4. Retorna o conjunto final de resultados ao cliente.

Figura 2. Caminho de leitura: TFT.MSEARCH entre shards de dados Msearch读取

Importante

O TFT.MSEARCH exige a definição de uma lógica própria de divisão de chaves. O Tair não distribui documentos automaticamente entre as chaves. Você controla como os documentos são roteados e como as chaves são nomeadas.

Pré-requisitos

Antes de usar o TFT.MSEARCH:

  • Todas as chaves a serem pesquisadas devem compartilhar a mesma configuração de schema (mappings e settings idênticos).

  • Divida a chave grande em várias chaves menores e distribua-as pelos shards de dados de uma instância cluster. Se estiver usando uma instância standalone, atualize-a primeiro para uma instância cluster; depois, divida a chave grande em chaves menores e distribua-as aos shards de dados.

Pesquisar documentos entre shards de dados

Sintaxe do comando

TFT.MSEARCH <num_keys> <key1> [key2 ...] '<JSON query>'

O primeiro argumento após TFT.MSEARCH indica o número de chaves a pesquisar. Esse valor deve corresponder à quantidade de nomes de chaves listados. O corpo da consulta JSON usa a mesma sintaxe do TFT.SEARCH.

Exemplo: pesquisar dados recentes em chaves semanais

Este exemplo demonstra como usar o TFT.MSEARCH para buscar conteúdo em alta armazenado em chaves particionadas por tempo.

Configuração do cenário:

  • Cada chave armazena uma semana de dados recentes — aproximadamente 1.000.000 de documentos por dia (7.000.000 por chave).

  • Uma nova chave é criada no início de cada semana e mantida por duas semanas. Chaves expiradas são excluídas.

  • Os nomes das chaves seguem o formato FLOW_<start_date>_<end_date>.

  • Cada documento possui quatro campos: datetime (long), author (text), uid (long) e content (text, analisado com jieba).

Etapa 1: Criar índices

Crie duas chaves com configurações de schema idênticas. O nome da chave codifica o intervalo de datas.

TFT.CREATEINDEX FLOW_20230109_15 '{
    "mappings": {
        "properties": {
            "datetime": {
                "type": "long"
            },
            "author": {
                "type": "text"
            },
            "uid": {
                "type": "long"
            },
            "content": {
                "type": "text",
                "analyzer": "jieba"
            }
        }
    }
}'

TFT.CREATEINDEX FLOW_20230116_23 '{
    "mappings": {
        "properties": {
            "datetime": {
                "type": "long"
            },
            "author": {
                "type": "text"
            },
            "uid": {
                "type": "long"
            },
            "content": {
                "type": "text",
                "analyzer": "jieba"
            }
        }
    }
}'

Etapa 2: Adicionar documentos

TFT.ADDDOC FLOW_20230109_15 '{
    "datetime": 20230109001209340,
    "author": "Hot TV series",
    "uid": 7884455,
    "content": "The movie will be screened during the Spring Festival"
}'

TFT.ADDDOC FLOW_20230116_23 '{
    "datetime": 20230118011304250,
    "author": "Fashionable commodities",
    "uid": 100093,
    "content": "Launch a new line of zodiac series products for the Year of the Rabbit"
}'

Etapa 3: Consultar ambas as chaves

Pesquise conteúdo relacionado a "Chinese zodiac of the Year of the Rabbit" em ambas as chaves, ordenado por tempo:

TFT.MSEARCH 2 FLOW_20230109_15 FLOW_20230116_23 '{
    "query": {
        "match": {
            "content": "Chinese zodiac of the Year of the Rabbit"
        }
    },
    "sort": [
        {"datetime": {"order": "desc"}}
    ],
    "size": 10,
    "reply_with_keys_cursor": true,
    "keys_cursor": {
        "FLOW_2023010916": 0,
        "FLOW_202301623": 0
    }
}'

Saída esperada:

{
    "hits": {
        "hits": [
            {
                "_id": "20230118011304250",
                "_index": "FLOW_20230116_23",       // (1)
                "_score": 1,
                "_source": {
                    "datetime": 20230118011304250,
                    "author": "Fashionable commodities",
                    "uid": 100093,
                    "content": "Launch a new line of zodiac series products for the Year of the Rabbit"
                }
            }
        ],
        "max_score": 1,
        "total": {
            "relation": "eq",
            "value": 1
        }
    },
    "aux_info": {
        "index_crc64": 14159192555612760957,
        "keys_cursor": {                            // (2)
            "FLOW_20230109_15": 0,
            "FLOW_20230116_23": 1
        }
    }
}

(1) O campo _index identifica a chave de origem do documento.

(2) O campo aux_info.keys_cursor representa o estado de paginação para a próxima solicitação. Um valor igual a 0 indica que nenhum documento dessa chave foi incluído nesta página.

Paginação com TFT.MSEARCH

O TFT.SEARCH usa from + size para paginação. O TFT.MSEARCH emprega um mecanismo diferente, pois os resultados vêm de múltiplas chaves independentes: size controla quantos documentos retornar, enquanto keys_cursor rastreia a posição dentro de cada chave para que a próxima consulta continue de onde a anterior parou.

Parâmetros de paginação

Parâmetro

Tipo

Obrigatório

Descrição

size

integer

Sim

Quantidade de documentos a retornar nesta página

reply_with_keys_cursor

boolean

Não

Defina como true para incluir keys_cursor na resposta. Necessário para paginação.

keys_cursor

object

Não

Posição inicial dentro de cada chave para a próxima consulta. Padrão: 0 para cada chave (início do conjunto).

Funcionamento da paginação

  1. Execute o TFT.MSEARCH com size e "reply_with_keys_cursor": true. O Tair busca size documentos de cada chave; em seguida, pontua, classifica e agrega os melhores size resultados.

  2. A resposta inclui um objeto keys_cursor que registra quantos documentos de cada chave foram consumidos para gerar essa página.

  3. Passe o valor de keys_cursor recebido na resposta como parâmetro keys_cursor na próxima solicitação. O Tair retomará cada chave a partir da posição registrada.

Exemplo

Com size=10 e três chaves (key0, key1, key2):

  • O Tair busca 10 documentos de cada chave (30 no total), pontua e classifica-os, e retorna os 10 melhores.

  • Suponha que os 10 melhores resultados tenham sido extraídos dos primeiros 2 registros de key0, dos primeiros 5 de key1 e dos primeiros 3 de key2. A resposta incluirá:

    {"keys_cursor": {"key0": 2, "key1": 5, "key2": 3}}
  • Na próxima consulta, passe esse valor de keys_cursor. O Tair retomará a partir da posição 3 em key0, posição 6 em key1 e posição 4 em key2.

Tópicos relacionados