Redis Gerenciado pelo Azure: pesquisa vetorial, HNSW, FLAT, Hash e JSON
Projete recuperação semântica de baixa latência com dimensões exatas, métricas adequadas, consultas KNN e por intervalo, filtros de metadados, ajuste mensurável do HNSW e uma escolha consciente entre Hash e JSON.
Tempo de estudo sugerido: 120 minutos • Nível intermediário • Reescrita autoral completa com versão resumida de cada tópico, avaliação comentada e laboratório guiado em Python
Por João Ricardo Dutra••Conteúdo autoral completo
1. O problema da recuperação semântica e os objetivos
Um assistente corporativo pode guardar milhões de documentos técnicos enquanto os usuários esperam uma resposta relevante em milissegundos. Palavras-chave isoladas não capturam bem a intenção; por isso, o aplicativo transforma documentos e perguntas em embeddings de alta dimensão. Conceitos relacionados ficam próximos no espaço vetorial, tornando a distância útil para pesquisa semântica, recomendações e RAG.
Uma solução de produção também precisa manter dimensão e tipo numérico, armazenar pesquisáveis, escolher indexação exata ou aproximada, atualizar registros, aplicar filtros de departamento ou autorização e medir latência, recall, memória e custo. O exemplo usa 1.536 dimensões sem pressupor que todo modelo tenha esse tamanho.
Criar esquemas vetoriais do RediSearch e ingerir embeddings com redis-py.
Executar consultas KNN, por intervalo e híbridas com filtros de .
Escolher FLOAT32 ou FLOAT64, métrica de distância e FLAT ou HNSW a partir de medições.
Selecionar Redis ou Redis e planejar migrações e reindexações seguras.
Construir e validar um aplicativo Python de pesquisa semântica no .
Resumo do tópico
Recuperação vetorial envolve um contrato completo: saída do modelo, esquema, , índice, parâmetros de execução e métricas operacionais devem ser compatíveis.
2. Provisione o para vetores
O oferece pesquisa vetorial pelo módulo gerenciado RediSearch. Habilite-o na criação, pois não é possível adicionar módulos depois. A configuração atual também exige política de clustering Enterprise, política NoEviction e uma camada em memória compatível: Otimizado para Memória, Balanced ou Otimizado para Computação. Otimizado para Flash não oferece RediSearch.
Dimensione registros e sobrecarga do índice secundário. Use ; prefira autenticação do quando suportada pelo cliente; e avalie Link Privado, alta disponibilidade, diagnósticos e recuperação. Como o gerencia as versões dos módulos, teste o comportamento da versão do serviço em vez de presumir um módulo instalado manualmente.
Decisões de provisionamento que não podem ser adiadas
Decisão
Validação
Módulo
RediSearch habilitado na criação
Clustering
Política Enterprise selecionada
Remoção
NoEviction para não expulsar silenciosamente dados do índice
Camada
Otimizado para Memória, Balanced ou Otimizado para Computação
Capacidade
Vetores, , índice, réplicas e crescimento incluídos
Segurança
, identidade ou chaves, isolamento de rede e diagnósticos
Resumo do tópico
A pesquisa vetorial começa no provisionamento: RediSearch, clustering Enterprise, NoEviction, camada compatível e memória suficiente precisam ser definidos antes.
3. Do conteúdo aos resultados indexados
O aplicativo divide as fontes em unidades recuperáveis, gera um embedding para cada uma e grava vetor, identidade, origem, categoria, data, locatário e controle de acesso. O RediSearch acompanha chaves do prefixo indexado e atualiza o índice secundário. A pergunta passa pelo mesmo modelo e pré-processamento antes da comparação KNN ou por intervalo.
restringem candidatos e dão rastreabilidade à resposta. Em RAG, o aplicativo recupera conteúdo e procedência, monta contexto fundamentado e o entrega ao modelo generativo. Distância vetorial classifica candidatos; ela não autoriza acesso nem comprova que uma afirmação é verdadeira.
Diagrama original: conteúdo e ficam juntos; a pergunta usa o mesmo modelo antes da recuperação vetorial filtrada.
Resumo do tópico
Use o mesmo contrato de embeddings na indexação e na consulta, guarde procedência e acesso com o vetor e trate recuperação como ranking, não como autorização.
4. Defina um índice vetorial sobre Redis
O esquema do RediSearch descreve campos pesquisáveis e retornáveis. O campo vetorial declara algoritmo, TYPE, DIM e DISTANCE_METRIC; texto e tags habilitam filtros híbridos. IndexDefinition limita a indexação por prefixo e informa se a origem é ou .
O exemplo usa HNSW, FLOAT32, 1.536 dimensões e distância de cosseno. M e EF_CONSTRUCTION afetam conectividade, memória, construção e recall. O prefixo doc: impede que chaves alheias entrem no índice. A criação do esquema deve ser uma etapa versionada de implantação com reversão, não uma ação implícita em toda inicialização.
Resumo do tópico
O índice deve combinar algoritmo, tipo, dimensão, métrica, , estrutura de origem e prefixo em um esquema estável.
5. Armazene vetores e corretamente
Campos vetoriais em usam blobs binários compactos. Converta a saída para o dtype exato do índice, confira o formato unidimensional e só então use tobytes(). Os demais campos continuam legíveis. Um embedding FLOAT32 de 1.536 valores ocupa 6.144 bytes antes da sobrecarga dos objetos Redis, , replicação e índice.
import numpy as np
embedding = np.asarray(model_embedding, dtype=np.float32)
if embedding.shape != (1536,):
raise ValueError("The embedding must contain exactly 1536 values")
client.hset("doc:917", mapping={
"title": "Model deployment runbook",
"department": "engineering",
"content": "Operational steps for model deployment...",
"embedding": embedding.tobytes(),
})
Divergências de dimensão ou dtype podem invalidar a indexação ou a consulta. Não corte, preencha ou reinterprete vetores silenciosamente. Registre modelo e versão nos ; uma troca de modelo normalmente requer campo ou índice separado até que vetores e clientes adotem o novo contrato.
Resumo do tópico
No , serialize o dtype exato, valide DIM, preserve úteis e versione o contrato de embeddings.
6. em lotes, atualizações e visibilidade
Uma ida à rede por documento custa caro em uma carga grande. O do redis-py agrupa comandos. transaction=False deixa claro que o objetivo é reduzir viagens, não criar uma única transação tudo-ou-nada. Use lotes limitados para não pressionar memória do cliente, filas do servidor e tentativas.
with client.pipeline(transaction=False) as pipe:
for document in documents:
vector = np.asarray(document["embedding"], dtype=np.float32)
pipe.hset(f'doc:{document["id"]}', mapping={
"title": document["title"],
"department": document["department"],
"content": document["content"],
"embedding": vector.tobytes(),
})
responses = pipe.execute()
# Batching reduces network round trips; it does not make the whole load atomic.
assert all(result >= 0 for result in responses)
O RediSearch mantém o índice conforme as chaves mudam. Depois da carga, confira contagens e consultas representativas. Chaves determinísticas tornam repetições idempotentes. Registre falhas de execute(), use recuo e observe transições de modelo. O ganho do depende de rede, carga e ; meça em vez de prometer um multiplicador fixo.
Resumo do tópico
reduzem viagens, chaves determinísticas protegem tentativas e validações pós-carga comprovam que o índice está utilizável.
7. Execute uma consulta KNN
KNN pede uma quantidade fixa de vizinhos. A sintaxe informa K, campo vetorial, parâmetro binário e alias da distância. Retorne apenas os campos necessários e ordene pela distância. Consultas vetoriais usam dialeto 2; versões recentes do redis-py já o solicitam, mas declará-lo torna o exemplo explícito.
Com COSINE, menor distância significa maior proximidade: zero indica direção idêntica e o valor pode se aproximar de dois para direções opostas. O score não é probabilidade universal. Calibre limites com exemplos rotulados do modelo, idioma, domínio e estratégia de fragmentação reais.
Resumo do tópico
KNN devolve os K registros mais próximos; envie o vetor como bytes, ordene pelo alias e interprete distância apenas dentro de uma carga calibrada.
8. Combine similaridade e filtros de
A pesquisa híbrida restringe candidatos pelos e os classifica pela distância vetorial. É possível limitar por produto, departamento, locatário e classificação permitida. Portanto, filtros fazem parte da correção e da segurança, não são apenas uma otimização.
Valores de tags com caracteres reservados precisam ser escapados ou modelados com cuidado. Aplique predicados obrigatórios de autorização no servidor e revalide o retorno no aplicativo. Meça seletividade: bons filtros podem acelerar a comparação, mas distribuição enviesada ou índice inadequado muda a latência.
Resumo do tópico
Consultas híbridas unem restrições obrigatórias e ranking vetorial; campos devem ser indexados, escapados e tratados como parte da fronteira de autorização.
9. Use VECTOR_RANGE para limites de distância
KNN tenta retornar uma quantidade fixa mesmo quando os vizinhos são ruins. VECTOR_RANGE devolve todos os registros dentro de uma distância máxima, podendo retornar nenhum. Isso atende semântico, detecção de duplicidade e RAG que precisa recusar uma resposta sem fonte suficientemente próxima.
Defina o raio com dados de avaliação. O mesmo número muda de significado entre COSINE, L2, e modelos diferentes. A consulta por intervalo com HNSW também aceita EPSILON, ampliando a exploração e potencialmente o recall ao custo de tempo.
Resumo do tópico
Use KNN para K candidatos ranqueados e VECTOR_RANGE quando a regra é aceitar apenas itens dentro de um limite calibrado.
10. Faça tipo numérico e dimensões coincidirem
Representações vetoriais comuns
Propriedade
FLOAT32
FLOAT64
Bytes por dimensão
4
8
com 1.536 dimensões
6.144 bytes (~6 KiB)
12.288 bytes (~12 KiB)
Precisão típica
Cerca de 7 dígitos decimais
Cerca de 15 dígitos decimais
Uso comum
Maioria dos embeddings de IA
Caso especializado que demonstre necessidade
FLOAT32 é a escolha normal para embeddings e reduz pela metade o em relação a FLOAT64. Redis atuais podem expor tipos quantizados adicionais, mas o controla a versão do módulo; confirme compatibilidade e recall antes de adotá-los. O módulo-fonte concentra-se em FLOAT32 e FLOAT64.
DIM vem do modelo: 384, 768, 1.024, 1.536 e 3.072 são exemplos, não opções intercambiáveis. Índice, registro e consulta precisam ter a mesma quantidade de elementos e tipo. Mudar de modelo exige re-embedding e reindexação planejados.
Resumo do tópico
FLOAT32 é o padrão usual; DIM e dtype precisam coincidir exatamente no modelo, bytes armazenados, esquema e consulta.
11. Escolha COSINE, L2 ou produto interno
Métricas de distância
Métrica
O que mede
Ponto de partida
COSINE
Ângulo entre vetores; quase ignora magnitude
Texto e modelos treinados para cosseno
L2
Distância euclidiana; direção e magnitude importam
Imagens ou espaço quando o modelo especifica L2
Produto interno
Vetores normalizados ou ranking projetado para dot product
O contrato do modelo e a avaliação determinam a métrica. Uma opção matematicamente válida ainda pode classificar mal se o modelo foi treinado para outra comparação. Normalize somente quando o modelo e a métrica exigirem.
Resumo do tópico
Use a métrica esperada pelo modelo e valide a qualidade de recuperação com perguntas rotuladas e representativas.
12. FLAT exato versus HNSW aproximado
FLAT compara a pergunta com todo vetor e produz busca exaustiva. É simples e exato, porém cresce linearmente. HNSW constrói um grafo navegável em camadas e visita nós promissores. Em escala, costuma reduzir bastante a latência, aceitando que uma busca aproximada pode perder um vizinho verdadeiro.
Diagrama original: FLAT examina candidatos; HNSW percorre uma hierarquia até a região próxima.
Escolha do índice
Necessidade
Início sugerido
Motivo
Conjunto pequeno, linha de base ou exatidão exaustiva
FLAT
Varredura exata e baseline de recall
Conjunto grande com meta rígida de latência
HNSW
Grafo aproximado escala melhor
Embeddings de texto
FLOAT32 + COSINE e medição
Contrato comum, não regra universal
Embeddings de imagem
FLOAT32 + métrica do modelo
L2 é comum, mas o modelo decide
Limiares como dez mil ou um milhão de registros são heurísticas, não garantias. Dimensão, camada, seletividade, concorrência, recall e memória alteram a transição. Use FLAT como referência exata ao medir recall do HNSW.
Resumo do tópico
FLAT é exaustivo; HNSW troca parte do recall por latência escalável. Escolha com benchmarks, não por uma contagem fixa.
13. Ajuste e avalie HNSW
M aumenta conexões do grafo e tende a melhorar navegação, consumindo memória. EF_CONSTRUCTION amplia vizinhos analisados na construção, elevando tempo e frequentemente recall. EF_RUNTIME controla candidatos em cada KNN: valores maiores tendem a melhorar recall e aumentar latência. Padrões são somente pontos de partida.
query = Query(
"*=>[KNN 10 @embedding $query_vec EF_RUNTIME $ef AS vector_distance]"
).sort_by("vector_distance").dialect(2)
for ef_runtime in (10, 50, 100, 200):
started = time.perf_counter()
result = client.ft("idx:documents").search(
query,
query_params={
"query_vec": query_vector,
"ef": ef_runtime,
},
)
latency_ms = (time.perf_counter() - started) * 1000
evaluate(ef_runtime, latency_ms, result.docs)
Crie um conjunto rotulado e meça latências p50, p95 e p99, throughput, memória, duração da construção e recall@K contra FLAT. Teste concorrência e filtros reais. Escolha a configuração de menor custo que cumpra o objetivo e repita após mudanças de modelo, dados, camada ou tráfego.
Resumo do tópico
Ajuste M e EF_CONSTRUCTION na construção e EF_RUNTIME na consulta; compare recall com FLAT e meça cauda de latência, vazão e memória.
14. Modele vetores em ou Redis
representa um registro plano e guarda o vetor em bytes compactos; é um bom padrão quando o esquema é simples e memória e operações diretas importam. Redis preserva objetos e matrizes aninhados; o vetor é uma matriz numérica, mas a consulta continua enviando bytes. JSONPath e aliases deixam o esquema pesquisável legível.
Diagrama original: para registros planos e compactos; Redis para documentos aninhados ou em evolução.
Compromissos entre e
Fator
Redis
Representação vetorial
Bytes binários
Matriz numérica no documento
Formato
Campos planos
Objetos e matrizes aninhados
Caminhos
Nomes de campos
JSONPath com aliases
Melhor ponto de partida
Registros compactos
Documentos complexos ou já em
Método de decisão
Medir memória e latência
Medir benefício da flexibilidade e sobrecarga
Resumo do tópico
Escolha para registros planos compactos e para documentos aninhados; origem, representação e IndexDefinition devem coincidir.
15. Migre estruturas e versões de índice com segurança
Converter em muda o tipo da chave e o índice. Uma migração segura grava documentos sob novo prefixo, cria índice , valida contagens e consultas, troca leitores de modo controlado e mantém a origem durante a janela de reversão. Sobrescrever uma chave com não é um plano seguro.
# Write transformed documents under a new prefix; do not overwrite Hash keys.
for key in client.scan_iter(match="product:*"):
source = client.hgetall(key)
vector = np.frombuffer(source[b"embedding"], dtype=np.float32)
target = {
"name": source[b"name"].decode(),
"price": float(source[b"price"]),
"category": source[b"category"].decode(),
"embedding": vector.tolist(),
}
client.json().set(f"j{key.decode()}", Path.root_path(), target)
# Build and validate the JSON index, then switch reads deliberately.
# Keep the old index until validation and rollback windows are complete.
A mesma estratégia azul-verde atende mudança de modelo: novo campo ou prefixo, índice versionado, backfill, comparação, corte e remoção posterior. Monitore falhas de indexação, memória, gravações rejeitadas, latência e recall.
Resumo do tópico
Use novos prefixos e índices versionados, valide antes do corte e preserve reversão até provar o novo caminho.
O exercício-fonte cria um recurso compatível com Enterprise, baixa arquivos iniciais, completa a lógica Python, carrega vetores, grava vetores com , recupera por chave, calcula similaridade de cosseno e procura produtos relacionados. Reserve cerca de 40 minutos após preparar o ambiente.
Pré-requisitos
Assinatura do com permissão para criar a camada e configuração necessárias do .
, Python 3.12 ou posterior, CLI do atual e extensão redisenterprise.
Recurso com RediSearch, clustering Enterprise, NoEviction, e capacidade adequada.
Conjunto inicial com modelo, dimensões, dtype e métrica documentados.
az extension add --name redisenterprise
az redisenterprise show --resource-group <resource-group> --cluster-name <cache-name>
python -m venv .venv
# Activate the virtual environment for your shell.
python -m pip install --upgrade redis numpy azure-identity
python app.py
Conecte com segurança e confirme PING.
Crie índice versionado e verifique o esquema.
Carregue amostras em limitados e confira contagens.
Implemente leitura por chave e cosseno independente para testes.
Execute KNN, KNN filtrado e VECTOR_RANGE com exemplos conhecidos.
Compare FLAT e HNSW em latência e recall e registre os parâmetros.
Exclua o recurso de laboratório ao terminar, se ele não for mais necessário.
Resumo do tópico
O laboratório comprova o ciclo inteiro: recurso seguro, esquema correto, , leitura, cálculo, consultas semânticas e escolha medida do índice.
17. Revisão da avaliação e checklist de produção
Respostas centrais
Pergunta
Resposta
Motivo
Métrica típica para embeddings de texto
COSINE
Contrato comum para direção semântica
Conjunto grande e consulta rápida com aproximação aceitável
HNSW
Busca aproximada baseada em grafo
Tipo padrão para a maioria dos embeddings
FLOAT32
Precisão adequada com menor memória
Registros planos com eficiência máxima
Representação vetorial binária compacta
Função de EF_RUNTIME
Equilíbrio velocidade-recall
Controla candidatos explorados por consulta HNSW
Em produção, confirme módulo e camada, contrato do modelo, filtros obrigatórios, prefixos, automação de versões, folga de memória, , identidade, rede, limitada, tentativas idempotentes, painéis, alertas, suíte rotulada de relevância e reversão. Nenhum número isolado de latência, recall ou tamanho substitui testes com vetores e tráfego reais.
Memorize o contrato: COSINE é comum em texto, FLOAT32 é o padrão, HNSW é a opção aproximada escalável, atende registros planos e toda decisão de produção precisa ser medida e protegida.