Fragmentação de JSONCompatible with Milvus 2.6.2+

A fragmentação de JSON acelera as consultas JSON convertendo o armazenamento tradicional baseado em linhas em armazenamento colunar optimizado. Enquanto mantém a flexibilidade do JSON para modelagem de dados, o Milvus realiza uma otimização colunar nos bastidores que melhora drasticamente o acesso e a eficiência da consulta.

A fragmentação de JSON é eficaz para a maioria dos cenários de consulta JSON. Os benefícios de desempenho tornam-se mais pronunciados com:

  • Documentos JSON maiores e mais complexos - Maiores ganhos de desempenho à medida que o tamanho do documento aumenta

  • Cargas de trabalho de leitura intensa - Filtragem, ordenação ou pesquisa frequentes em chaves JSON

  • Padrões de consulta mistos - As consultas em diferentes chaves JSON beneficiam da abordagem de armazenamento híbrido

Como funciona

O processo de fragmentação JSON ocorre em três fases distintas para otimizar os dados para uma recuperação rápida.

Fase 1: Ingestão e classificação de chaves

À medida que novos documentos JSON são escritos, o Milvus recolhe amostras e analisa-os continuamente para criar estatísticas para cada chave JSON. Esta análise inclui o rácio de ocorrência da chave e a estabilidade do tipo (se o seu tipo de dados é consistente entre documentos).

Com base nestas estatísticas, as chaves JSON são categorizadas nas seguintes categorias para um armazenamento optimizado.

Categorias de chaves JSON

Tipo de chave

Descrição

Chaves digitadas

Chaves que existem na maioria dos documentos e têm sempre o mesmo tipo de dados (por exemplo, todos os números inteiros ou todas as cadeias de caracteres).

Chaves dinâmicas

Chaves que aparecem frequentemente mas têm um tipo de dados misto (por exemplo, por vezes uma cadeia de caracteres, por vezes um número inteiro).

Chaves partilhadas

Chaves que aparecem com pouca frequência ou chaves aninhadas que ficam abaixo de um limite de frequência configurável.

Exemplo de classificação

Considere os dados JSON de amostra que contêm as seguintes chaves JSON:

{"a": 10, "b": "str1", "f": 1}
{"a": 20, "b": "str2", "f": 2}  
{"a": 30, "b": "str3", "f": 3}
{"a": 40, "b": 1, "f": 4}       // b becomes mixed type
{"a": 50, "b": 2, "e": "rare"}  // e appears infrequently

Com base nesses dados, as chaves seriam classificadas da seguinte forma:

  • Chaves digitadas: a e f (sempre um número inteiro)

  • Chaves dinâmicas: b (string mista/inteiro)

  • Chaves partilhadas: e (chave que aparece com pouca frequência)

Fase 2: Otimização do armazenamento

A classificação da fase 1 determina a disposição do armazenamento. Milvus usa um formato colunar optimizado para consultas.

Json Shredding Flow Fluxo de fragmentação Json

  • Colunas fragmentadas: Para chaves digitadas e dinâmicas, os dados são escritos em colunas dedicadas. Este armazenamento colunar permite uma pesquisa rápida e direta durante as consultas, uma vez que o Milvus pode ler apenas os dados necessários para uma determinada chave sem processar todo o documento.

  • Coluna partilhada: Todas as chaves partilhadas são armazenadas em conjunto numa única coluna JSON binária compacta. É criado um índice invertido de chave partilhada nesta coluna. Este índice é crucial para acelerar as consultas sobre chaves de baixa frequência, permitindo que o Milvus elimine rapidamente os dados, reduzindo efetivamente o espaço de pesquisa apenas às linhas que contêm a chave especificada.

Fase 3: Execução da consulta

A fase final aproveita o layout de armazenamento otimizado para selecionar de forma inteligente o caminho mais rápido para cada predicado de consulta.

  • Caminho rápido: As consultas em chaves digitadas/dinâmicas (por exemplo, json['a'] < 100) acedem diretamente a colunas dedicadas

  • Caminho optimizado: As consultas em chaves partilhadas (por exemplo, json['e'] = 'rare') utilizam o índice invertido para localizar rapidamente os documentos relevantes

Ativar a fragmentação JSON

Para ativar a funcionalidade, defina common.enabledJSONShredding para true no seu ficheiro de configuração milvus.yaml. Os novos dados accionam automaticamente o processo de trituração.

# milvus.yaml
...
common:
  enabledJSONShredding: true # Indicates whether to enable JSON key stats build and load processes
...

Uma vez ativado, o Milvus começará a analisar e a reestruturar os seus dados JSON após a ingestão, sem qualquer outra intervenção manual.

Ajuste de parâmetros

Para a maioria dos usuários, uma vez que a fragmentação JSON é ativada, as configurações padrão para outros parâmetros são suficientes. No entanto, é possível ajustar o comportamento da fragmentação de JSON usando esses parâmetros em milvus.yaml.

Parâmetro Nome

Descrição

Valor predefinido

Aconselhamento de afinação

common.enabledJSONShredding

Controla se os processos de compilação e carregamento de fragmentação JSON estão activados.

falso

Deve ser definido como true para ativar o recurso.

common.usingjsonShreddingForQuery

Controla se o Milvus usa dados fragmentados para aceleração.

true

Definido como false como uma medida de recuperação se as consultas falharem, revertendo para o caminho de consulta original.

queryNode.mmap.jsonShredding

Determina se o Milvus usa mmap ao carregar dados fragmentados.

Para obter detalhes, consulte Usar mmap.

true

Esta configuração é geralmente otimizada para desempenho. Ajuste-a apenas se tiver necessidades específicas de gestão de memória ou restrições no seu sistema.

dataCoord.jsonShreddingMaxColumns

O número máximo de chaves JSON que serão armazenadas em colunas fragmentadas.

Se o número de chaves que aparecem frequentemente exceder este limite, o Milvus dará prioridade às mais frequentes para serem destruídas, e as restantes chaves serão armazenadas na coluna partilhada.

1024

Isto é suficiente para a maioria dos cenários. Para JSON com milhares de chaves que aparecem frequentemente, pode ser necessário aumentar este valor, mas monitorize a utilização do armazenamento.

dataCoord.jsonShreddingRatioThreshold

O rácio mínimo de ocorrência que uma chave JSON deve ter para ser considerada para fragmentação numa coluna fragmentada.

Uma chave é considerada como aparecendo frequentemente se o seu rácio for superior a este limite.

0.3

Aumenta (por exemplo, para 0,5) se o número de chaves que cumprem os critérios de fragmentação exceder o limite dataCoord.jsonShreddingMaxColumns. Isto torna o limite mais rigoroso, reduzindo o número de chaves que se qualificam para destruição.

Diminua (por exemplo, para 0,1) se pretender destruir mais chaves que aparecem com menos frequência do que o limite predefinido de 30%.

Referências de desempenho

Os nossos testes demonstram melhorias significativas de desempenho em diferentes tipos de chaves JSON e padrões de consulta.

Ambiente e metodologia de teste

  • Hardware: cluster de 1 núcleo/8 GB

  • Conjunto de dados: 1 milhão de documentos do JSONBench

  • Tamanho médio do documento: 478,89 bytes

  • Duração do teste: 100 segundos medindo QPS e latência

Resultados: chaves digitadas

Este teste mediu o desempenho ao consultar uma chave presente na maioria dos documentos.

Expressão de consulta

Tipo de valor da chave

QPS (sem fragmentação)

QPS (com fragmentação)

Aumento de desempenho

json['time_us'] > 0

Inteiro

8.69

287.50

33x

json['kind'] == 'commit'

Cadeia de caracteres

8.42

126.1

14.9x

Resultados: chaves partilhadas

Este teste centrou-se na consulta de chaves esparsas e aninhadas que se enquadram na categoria "partilhada".

Expressão de consulta

Tipo de valor da chave

QPS (sem fragmentação)

QPS (com fragmentação)

Aumento de desempenho

json['identity']['seq'] > 0

Inteiro aninhado

4.33

385

88.9x

json['identity']['did'] == 'xxxxx'

Cadeia de caracteres aninhada

7.6

352

46.3x

Informações importantes

  • As consultas chave partilhadas apresentam as melhorias mais significativas (até 89x mais rápidas)

  • As consultas de chave digitada fornecem ganhos de desempenho consistentes de 15-30x

  • Todos os tipos de consulta beneficiam do JSON Shredding sem regressões de desempenho

PERGUNTAS FREQUENTES

  • Como é que verifico se a fragmentação JSON funciona corretamente?

    1. Primeiro, verifique se os dados foram criados usando o comando show segment --format table na ferramenta Birdwatcher. Se for bem sucedido, a saída conterá shredding_data/ e shared_key_index/ no campo Json Key Stats.

      Birdwatcher Output Saída do Birdwatcher

    2. Em seguida, verifique se os dados foram carregados executando show loaded-json-stats no nó de consulta. A saída exibirá detalhes sobre os dados fragmentados carregados para cada nó de consulta.

  • E se eu encontrar um erro?

    Se o processo de compilação ou carregamento falhar, você pode desativar rapidamente o recurso definindo common.enabledJSONShredding=false. Para limpar quaisquer tarefas restantes, use o comando remove stats-task <task_id> no Birdwatcher. Se uma consulta falhar, defina common.usingjsonShreddingForQuery=false para reverter para o caminho original da consulta, ignorando os dados fragmentados.

  • Como é que selecciono entre a fragmentação JSON e a indexação JSON?

    • A fragmentação JSON é ideal para chaves que aparecem frequentemente nos seus documentos, especialmente para estruturas JSON complexas. Combina as vantagens do armazenamento colunar e da indexação invertida, o que a torna adequada para cenários de leitura intensiva em que consulta muitas chaves diferentes. No entanto, não é recomendado para documentos JSON muito pequenos, pois o ganho de desempenho é mínimo. Quanto menor for a proporção do valor da chave em relação ao tamanho total do documento JSON, melhor será a otimização do desempenho da fragmentação.

    • A indexação JSON é melhor para a otimização direcionada de consultas específicas baseadas em chaves e tem uma sobrecarga de armazenamento inferior. É adequada para estruturas JSON mais simples. Observe que a fragmentação JSON não cobre consultas em chaves dentro de matrizes, portanto, é necessário um índice JSON para acelerar essas consultas.

    Para obter detalhes, consulte Visão geral do campo JSON.