ES|QL Joins chegaram! Sim, Joins!

O Elasticsearch 8.18 inclui o comando LOOKUP JOIN do ES|QL, nosso primeiro JOIN no estilo SQL.

O Elasticsearch 8.18 inclui nosso primeiro JOIN no estilo SQL: o comando LOOKUP JOIN do ES|QL. Agora está disponível em prévia técnica e possibilita correlação e enriquecimento de dados com conjuntos de dados de consulta facilmente atualizáveis. Precisa adicionar informações de host e ativos aos seus eventos? Sem problema. Quer verificar quais endereços IP ou URLs estão nas listas de inteligência de ameaças? Claro! Fazer atualizações no conjunto de dados de consulta e usá-las imediatamente? Vamos nessa!

Lookup Join é um LEFT OUTER JOIN no estilo SQL que depende de um novo modo de índice chamado 
lookup para o lado direito. O índice de lookup pode incluir ativos, dados de inteligência sobre ameaças como IPs conhecidos como ruins, informações de pedidos, informações de funcionários ou clientes — há possibilidades infinitas.

procure o lado direito

Historicamente, o Elasticsearch não possuía capacidade de junção (join), embora ao longo do tempo algumas tentativas tenham sido feitas nessa direção, como os tipos de campo "nested", "_parent" e "join", além do recurso de enriquecimento (enrich). Costumávamos incentivar a desnormalização dos dados colocando os dados de referência junto com os eventos no mesmo índice, ou realizando junções no lado do cliente. Essas solutions prejudicam a escalabilidade para grandes volumes de dados e podem ser limitantes quando há uma grande variedade de dados e casos de uso. Chegou a hora de o Elasticsearch contar com junções. E agora isso é possível: ES|QL não é apenas uma linguagem é construída sobre um novo mecanismo de computação. O mecanismo ES|QL possibilita a execução de recursos avançados como junções.

Para ativar os Lookup Joins, criamos um novo modo de índice: lookup. Um índice lookup é basicamente como um índice normal (mode:standard é o padrão), o que significa que é diretamente atualizável. A principal diferença é que um índice lookup é apenas um shard. Assim, é limitado a 2 bilhões de documentos, um limite do Lucene para um shard. Isso deve ser mais do que suficiente para armazenar os dados do “lado direito” de alguns dos muitos casos de uso de junção lookup. A imposição desse limite nos ajuda a evitar alguns dos problemas associados a uniões totalmente distribuídas, reduzindo a cardinalidade de origem do lado direito da junção. Isso também nos diz quais conjuntos de dados você planeja usar como referências lookup para que possamos encontrar maneiras de otimizá-los no futuro. 

Além do modo de índice de consulta, não há restrições sobre os dados de origem nem qualquer preparação de dados necessária para realizar uma junção. Isso significa que é fácil adicionar conjuntos de dados de consulta e mantê-los atualizados. 

Parte disso já foi possível com o comando ENRICH em ES|QL. O ENRICH foi otimizado para consultas de tempo de ingestão em pipelines de ingestão e para conjuntos de dados pequenos que não mudam com frequência, sendo, portanto, conveniente, mas não ideal. Lookup Join é mais fácil de configurar e gerenciar do que ENRICH: 

  • Não há políticas de enriquecimento a serem criadas

  • Sem execução de políticas

  • Índices de consulta são graváveis

  • Há menos cópias dos dados

  • Melhor manejo de múltiplas correspondências — enquanto o enrich cria campos multivalorados quando há múltiplas correspondências, a join de busca cria múltiplas linhas. Isso facilita a realização de analíticas adicionais, como agrupamento e agregação, como bytes transferidos por usuário ou totais de pedidos.

  • O Lookup Join permite especificação em tempo real do campo de correspondência

Aqui estão apenas algumas das maneiras de usar um LOOKUP JOIN: 

  • Participar de eventos de segurança com inteligência de ameaças para enriquecer ainda mais o evento

  • Consultar meu conjunto atual de hosts em relação à última inteligência de ameaças ou metadados internos

  • Correlacionar leituras de IOT com metadados estáticos ou dinâmicos (fabricante, unidade de volume)

  • Combinar eventos de segurança com informações do host para obter mais contexto e facilitar a filtragem

  • Adicionar alguns fatos como criticidade de ativos (este usuário é um executivo)

  • Adicionar os AIDs do CrowdStrike a uma fonte que tenha nomes de host

  • Verificar se certos endereços IP estão nos feeds de inteligência de ameaças

  • Adicionar informações de funcionários aos eventos

As possibilidades são infinitas.

Exemplo de uso

Vamos olhar alguns exemplos reais para ver como isso pode ser fácil e poderoso. 

Como SRE, talvez seja necessário:

  • Adicionar um ambiente aos logs com base no endereço IP ou nome do host

  • Associar informações de funcionários a registros

  • Descobrir qual equipe é responsável por um servidor

Antes do LOOKUP JOIN, você teria que: 

  1. Colocar seus dados de referência (ambientes) em um índice

  2. Definir uma política de enriquecimento com base nesse índice, especificando o tipo de política, o campo de correspondência e os campos de enriquecimento

  3. Executar a política de enriquecimento uma vez para construir o índice de enriquecimento

  4. Repetir para cada conjunto de dados de referência (funcionários, equipes)

  5. Executar a política de enriquecimento sempre que os dados mudarem

Com o LOOKUP JOIN, basta inserir os dados de referência em um índice LOOKUP e pronto! 

Imagine que você recebeu um alerta de que há usuários recebendo erros no seu site de comércio eletrônico. Você encontra logs da web onde a resposta não é o código HTTP 200 para sucesso. Você gostaria de separar esses dados por ambiente para ver se os clientes de produção são afetados, mas os registros não têm campo de ambiente. Tudo bem — basta adicionar uma junção de busca no ambiente, talvez usando um arquivo como este:

clientip,environment
192.168.1.9,QA
192.168.14.2,Dev
192.168.12.3,Prod
…

Agora, adicione o LOOKUP JOIN no índice de pesquisa de ambientes (o meu se chama envs_lkp):

FROM kibana_sample_data_logs | WHERE response.keyword != "200" 
| LOOKUP JOIN envs_lkp ON clientip 
| STATS COUNT(*) by response, environment
Pesquisar join

Existem erros em Produção e Garantia de Qualidade (QA). Podemos fazer uma junção com uma lista de qual equipe é responsável por cada servidor web para ver com quem devemos entrar em contato:

host,team
www.elastic.co,Web team
artifacts.elastic.co,Delivery team
cdn.elastic-elastic-elastic.org,Cloud team
elastic-elastic-elastic.org,Web team
FROM kibana_sample_data_logs | WHERE response.keyword != "200"
| LOOKUP JOIN teams_lkp ON host
| STATS num = COUNT(*) by host, response.keyword, team
| SORT num DESC
lista de proprietários de equipes

Os analistas de segurança amam seus joins! Talvez eles queiram:

  • Identificar os IPs de clientes que estão solicitando URLs maliciosas conhecidas

  • Correlacionar com informações de ativos para agrupar eventos e atribuir prioridade ou risco

Você pode baixar uma lista de URLs maliciosas do URLhaus no Abuse.ch e carregá-la para um índice de busca.

FROM logs 
| LOOKUP JOIN urlhaus_lkp ON url 
| WHERE threat IS NOT NULL 
| KEEP @timestamp, url.keyword, clientip, threat
baixar lista de URLs maliciosas

Como criar pesquisas

Você vai precisar de pelo menos um índice lookup para usar o lookup join. Estamos criando formas de facilitar a criação e atualização de lookups no Kibana. Por enquanto, você pode começar criando um índice lookup de algumas maneiras  o detalhe principal é que o modo índice deve ser “lookup”.

Criar Índice de Pesquisa usando o Gerenciamento de Índices

No painel de navegação à esquerda do Kibana, clique em Stack Management e, em seguida, Gerenciamento de Índice. No lado direito, clique em Criar índice.

criar Índice de Pesquisa usando o Gerenciamento de Índices

Forneça um nome de índice e selecione "Pesquisa" no menu suspenso do modo índice:

Forneça um nome de índice

Clique em Criar para criar um índice de pesquisa vazio. 

Criar índice de pesquisa via APIs

Crie um índice de pesquisa usando a API de criação de índice — certifique-se de incluir o modo do índice:

PUT mylookupindex
{
 "settings": {
   "index.mode": "lookup"
 }
}

Criar índice de busca usando o carregador de arquivos ML

No painel de navegação à esquerda do Kibana, clique em Machine learning e, em seguida, File Data Visualizer (ou digite "carregar" na barra de busca do Kibana).

file data visualizer

Selecione ou arraste e solte seu arquivo — o CSV funciona bem para isso.

Depois de clicar em Importar, forneça um nome para o índice e clique em Avançado para revelar as configurações do índice. Aqui, adicione o index.mode: lookup.

avançado

Complete o carregamento do arquivo clicando em Importar. Um índice e um Data view serão criados. 

Em todos os casos, agora você pode consultar o índice de pesquisa no seu ES|QL.

Respondendo a perguntas comuns

Q: Quando não devo usar joins?
O Lookup Join é realmente poderoso, mas com grande poder... bem, você sabe. Joins podem ser operações caras, e cada join adiciona alguma latência à sua pesquisa. Ainda podem existir cenários em que uma join seja um exagero ou não seja a melhor opção. Por exemplo, se houver um campo que você frequentemente usa em muitas pesquisas, considere desnormalizá-lo no índice esquerdo. Adicione-o no momento da ingestão usando um processador de enriquecimento na ingestão, configuração do agente de envio de arquivos, use um Logstash filter, etc. Esse processamento único na ingestão é um compromisso entre um leve aumento no uso de armazenamento e consultas mais rápidas. Isso seria mais aplicável para valores de referência que não mudam com frequência (o nome do usuário de um ID de usuário) ou que nunca mudam (o fabricante de um host).

Q: Posso pesquisar um lookup diretamente?
Sim! Um índice lookup é basicamente "apenas um índice", então você pode consultá-lo com o ES|QL.

FROM <lookup_index> | …

Ou crie um data view. 

criar data view

P: Posso enviar dados do Logstash ou do agente?
Sim! Só tenha em mente que um índice de pesquisa não é um fluxo de dados e é apenas um shard, então você pode enviar "apenas" até 2 bilhões de documentos para cada índice de consulta.

O que vem a seguir?

Estamos trabalhando para remover algumas limitações conhecidas para que as joins de pesquisa estejam disponíveis para todos. Além disso, estamos projetando uma experiência de edição de primeira classe para os conjuntos de dados de pesquisa. Imagine poder criar e editar índices de busca diretamente no Kibana Discover, ou colocar um arquivo CSV no Discover para preencher o índice. Aqui está um protótipo de como isso pode ficar:

Mockup inicial da experiência de usuário de edição de buscas futuras
Protótipo inicial da experiência do usuário para edição de consultas futuras

E as joins de pesquisa são só o começo. Gostaríamos de oferecer outros tipos úteis de joins, como junções INNER ou subconsultas, e também permitir junção contra qualquer índice (não apenas índices de pesquisa).

Começar

Essa é a função join de pesquisa, disponível no Elasticsearch 8.18/9.0 como prévia técnica. 

 

Tudo pronto para começar? Elastic 8.18 e 9.0 estão agora disponíveis no Elastic Cloud — o Elasticsearch Service hospedado que inclui todos os novos recursos desta versão mais recente. Em nome da equipe do ES|QL, estamos ansiosos pelo seu feedback — você pode usar o botão "Enviar feedback" no editor do ES|QL no Discover. E olha só, conseguimos escrever este post sobre joins sem fazer nenhum trocadilho com junções... obrigado por acompanhar!

 

 

O lançamento e o tempo de amadurecimento de todos os recursos ou funcionalidades descritos neste artigo permanecem a exclusivo critério da Elastic. Os recursos ou funcionalidades não disponíveis no momento poderão não ser entregues ou não chegarem no prazo previsto.