paint-brush
Atualizações, inserções e exclusões do Elasticsearch: entendendo como funcionam e suas limitaçõespor@rocksetcloud
4,853 leituras
4,853 leituras

Atualizações, inserções e exclusões do Elasticsearch: entendendo como funcionam e suas limitações

por Rockset12m2024/05/20
Read on Terminal Reader

Muito longo; Para ler

Para um sistema como o Elasticsearch, os engenheiros precisam ter conhecimento profundo da arquitetura subjacente para ingerir dados de streaming com eficiência.
featured image - Atualizações, inserções e exclusões do Elasticsearch: entendendo como funcionam e suas limitações
Rockset HackerNoon profile picture


Introdução

Gerenciar dados de streaming de um sistema de origem, como PostgreSQL, MongoDB ou DynamoDB, para um sistema downstream para pesquisa e análise em tempo real é um desafio para muitas equipes. O fluxo de dados geralmente envolve ferramentas ETL complexas, bem como integrações de autogerenciamento para garantir que gravações de alto volume, incluindo atualizações e exclusões, não acumulem CPU ou afetem o desempenho do aplicativo final.


Para um sistema como o Elasticsearch , os engenheiros precisam ter conhecimento profundo da arquitetura subjacente para ingerir dados de streaming com eficiência . O Elasticsearch foi projetado para análise de logs onde os dados não mudam com frequência, apresentando desafios adicionais ao lidar com dados transacionais.


Rockset, por outro lado, é um banco de dados nativo da nuvem, eliminando muitas ferramentas e despesas gerais necessárias para inserir dados no sistema. Como o Rockset foi desenvolvido especificamente para pesquisa e análise em tempo real, ele também foi projetado para mutabilidade em nível de campo , diminuindo a CPU necessária para processar inserções, atualizações e exclusões.


Neste blog, compararemos como o Elasticsearch e o Rockset lidam com a ingestão de dados, bem como forneceremos técnicas práticas para usar esses sistemas para análises em tempo real.

Elasticsearch

Ingestão de dados no Elasticsearch

Embora existam muitas maneiras de ingerir dados no Elasticsearch, abordamos três métodos comuns para pesquisa e análise em tempo real:


  • Ingerir dados de um banco de dados relacional no Elasticsearch usando o plugin de entrada Logstash JDBC

  • Ingerir dados do Kafka no Elasticsearch usando o Kafka Elasticsearch Service Sink Connector

  • Ingerir dados diretamente do aplicativo no Elasticsearch usando a API REST e bibliotecas de cliente


Ingira dados de um banco de dados relacional no Elasticsearch usando o plugin de entrada Logstash JDBC. O plug-in de entrada Logstash JDBC pode ser usado para descarregar dados de um banco de dados relacional como PostgreSQL ou MySQL para Elasticsearch para pesquisa e análise.


Logstash é um pipeline de processamento de eventos que ingere e transforma dados antes de enviá-los ao Elasticsearch. Logstash oferece um plugin de entrada JDBC que pesquisa um banco de dados relacional, como PostgreSQL ou MySQL, para inserções e atualizações periodicamente. Para usar este serviço, seu banco de dados relacional precisa fornecer registros com carimbo de data/hora que possam ser lidos pelo Logstash para determinar quais alterações ocorreram.


Esta abordagem de ingestão funciona bem para inserções e atualizações, mas são necessárias considerações adicionais para exclusões. Isso ocorre porque não é possível para o Logstash determinar o que foi excluído do seu banco de dados OLTP. Os usuários podem contornar essa limitação implementando exclusões suaves, onde um sinalizador é aplicado ao registro excluído e é usado para filtrar dados no momento da consulta. Ou podem verificar periodicamente seu banco de dados relacional para obter acesso aos registros mais atualizados e reindexar os dados no Elasticsearch.


Ingira dados do Kafka no Elasticsearch usando o Kafka Elasticsearch Sink Connector . Também é comum usar uma plataforma de streaming de eventos como o Kafka para enviar dados de sistemas de origem para o Elasticsearch para pesquisa e análise em tempo real.


A Confluent e a Elastic fizeram parceria no lançamento do Kafka Elasticsearch Service Sink Connector , disponível para empresas que usam as ofertas gerenciadas Confluent Kafka e Elastic Elasticsearch. O conector requer instalação e gerenciamento de ferramentas adicionais, Kafka Connect.


Usando o conector, você pode mapear cada tópico no Kafka para um único tipo de índice no Elasticsearch. Se a digitação dinâmica for usada como tipo de índice, o Elasticsearch oferece suporte a algumas alterações de esquema, como adição de campos, remoção de campos e alteração de tipos.


Um dos desafios que surge ao usar o Kafka é a necessidade de reindexar os dados no Elasticsearch quando você deseja modificar o analisador, o tokenizer ou os campos indexados. Isso ocorre porque o mapeamento não pode ser alterado depois de já estar definido. Para executar uma reindexação dos dados, você precisará gravar duas vezes no índice original e no novo índice, mover os dados do índice original para o novo índice e, em seguida, interromper o trabalho do conector original.


Se você não usa serviços gerenciados do Confluent ou Elastic, você pode usar o plugin Kafka de código aberto para Logstash para enviar dados ao Elasticsearch.


Ingerir dados diretamente do aplicativo no Elasticsearch usando a API REST e bibliotecas de cliente O Elasticsearch oferece a capacidade de usar bibliotecas de cliente compatíveis, incluindo Java, Javascript, Ruby, Go, Python e muito mais, para ingerir dados por meio da API REST diretamente do seu aplicativo. Um dos desafios de usar uma biblioteca cliente é que ela precisa ser configurada para funcionar com enfileiramento e contrapressão caso o Elasticsearch não consiga lidar com a carga de ingestão. Sem um sistema de filas instalado, existe o potencial de perda de dados no Elasticsearch.

Atualizações, inserções e exclusões no Elasticsearch

Elasticsearch possui uma API de atualização que pode ser usada para processar atualizações e exclusões. A API de atualização reduz o número de viagens à rede e o potencial de conflitos de versão. A API de atualização recupera o documento existente do índice, processa a alteração e indexa os dados novamente. Dito isso, o Elasticsearch não oferece atualizações ou exclusões locais. Portanto, todo o documento ainda deve ser reindexado, uma operação que exige muito da CPU.


Nos bastidores, os dados do Elasticsearch são armazenados em um índice Lucene e esse índice é dividido em segmentos menores. Cada segmento é imutável, portanto os documentos não podem ser alterados. Quando uma atualização é feita, o documento antigo é marcado para exclusão e um novo documento é mesclado para formar um novo segmento. Para usar o documento atualizado, todos os analisadores precisam ser executados, o que também pode aumentar o uso da CPU. É comum que clientes com dados em constante mudança vejam as mesclagens de índices consumirem uma quantidade considerável de sua conta geral de computação do Elasticsearch.


Imagem 1: Os dados do Elasticsearch são armazenados em um índice Lucene e esse índice é dividido em segmentos menores.


Dada a quantidade de recursos necessários, a Elastic recomenda limitar o número de atualizações no Elasticsearch. Um cliente de referência do Elasticsearch, Bol.com , usou o Elasticsearch para pesquisa de sites como parte de sua plataforma de comércio eletrônico. Bol.com teve cerca de 700 mil atualizações por dia em suas ofertas, incluindo alterações de conteúdo, preços e disponibilidade. Originalmente, eles queriam uma solução que permanecesse sincronizada com quaisquer alterações que ocorressem. Porém, dado o impacto das atualizações no desempenho do sistema Elasticsearch, eles optaram por permitir atrasos de 15 a 20 minutos. O agrupamento de documentos em lote no Elasticsearch garantiu um desempenho de consulta consistente.


Desafios de exclusões e mesclagem de segmentos no Elasticsearch

No Elasticsearch, pode haver desafios relacionados à exclusão de documentos antigos e à recuperação de espaço.


O Elasticsearch conclui uma mesclagem de segmentos em segundo plano quando há um grande número de segmentos em um índice ou muitos documentos em um segmento marcados para exclusão. Uma mesclagem de segmentos ocorre quando os documentos são copiados de segmentos existentes para um segmento recém-formado e os segmentos restantes são excluídos. Infelizmente, Lucene não é bom em dimensionar os segmentos que precisam ser mesclados, criando potencialmente segmentos desiguais que impactam o desempenho e a estabilidade.


Após a mesclagem, você pode ver que os segmentos Lucene têm tamanhos diferentes. Esses segmentos desiguais afetam o desempenho e a estabilidade



Isso ocorre porque o Elasticsearch pressupõe que todos os documentos tenham tamanhos uniformes e toma decisões de mesclagem com base no número de documentos excluídos. Ao lidar com tamanhos de documentos heterogêneos, como costuma acontecer em aplicativos multilocatários, alguns segmentos crescerão mais rapidamente do que outros, diminuindo o desempenho dos maiores clientes do aplicativo. Nestes casos, a única solução é reindexar uma grande quantidade de dados.

Desafios de réplica no Elasticsearch

Elasticsearch usa um modelo de backup primário para replicação. A réplica primária processa uma operação de gravação recebida e depois encaminha a operação para suas réplicas. Cada réplica recebe esta operação e reindexa os dados localmente novamente. Isso significa que cada réplica gasta recursos computacionais dispendiosos de forma independente para reindexar o mesmo documento repetidamente. Se houver n réplicas, a Elastic gastaria n vezes a CPU para indexar o mesmo documento. Isso pode agravar a quantidade de dados que precisam ser reindexados quando ocorre uma atualização ou inserção.

API em massa e desafios de fila no Elasticsearch

Embora você possa usar a API Update no Elasticsearch, geralmente é recomendado agrupar alterações frequentes em lote usando a API em massa . Ao usar a API em massa, as equipes de engenharia geralmente precisarão criar e gerenciar uma fila para agilizar as atualizações no sistema.


Uma fila é independente do Elasticsearch e precisará ser configurada e gerenciada. A fila consolidará as inserções, atualizações e exclusões no sistema dentro de um intervalo de tempo específico, digamos 15 minutos, para limitar o impacto no Elasticsearch. O sistema de filas também aplicará um acelerador quando a taxa de inserção for alta para garantir a estabilidade da aplicação. Embora as filas sejam úteis para atualizações, elas não são boas para determinar quando há muitas alterações de dados que exigem uma reindexação completa dos dados. Isso pode ocorrer a qualquer momento se houver muitas atualizações no sistema. É comum que as equipes que executam a Elastic em escala tenham membros de operações dedicados gerenciando e ajustando suas filas diariamente.

Reindexando no Elasticsearch

Conforme mencionado na seção anterior, quando há uma série de atualizações ou você precisa alterar os mapeamentos de índice, ocorre uma reindexação dos dados. A reindexação é propensa a erros e tem o potencial de derrubar um cluster. O que é ainda mais assustador é que a reindexação pode acontecer a qualquer momento.


Se quiser alterar seus mapeamentos, você terá mais controle sobre o tempo em que a reindexação ocorre. O Elasticsearch possui uma API de reindexação para criar um novo índice e uma API de Aliases para garantir que não haja tempo de inatividade quando um novo índice estiver sendo criado. Com uma API de alias, as consultas são roteadas para o alias ou para o índice antigo, à medida que o novo índice é criado. Quando o novo índice estiver pronto, a API de aliases será convertida para ler dados do novo índice.


Com a API de aliases, ainda é complicado manter o novo índice sincronizado com os dados mais recentes. Isso ocorre porque o Elasticsearch só pode gravar dados em um índice. Portanto, você precisará configurar o upstream do pipeline de dados para gravar duas vezes no índice novo e no antigo.

Conjunto de foguetes

Ingestão de dados no Rockset

Rockset usa conectores integrados para manter seus dados sincronizados com os sistemas de origem. Os conectores gerenciados do Rockset são ajustados para cada tipo de fonte de dados para que os dados possam ser ingeridos e consultados em 2 segundos. Isso evita pipelines manuais que adicionam latência ou só podem ingerir dados em microlotes, digamos, a cada 15 minutos.


Em alto nível, o Rockset oferece conectores integrados para bancos de dados OLTP, fluxos de dados e data lakes e armazéns. Veja como eles funcionam:


Conectores integrados para bancos de dados OLTP O Rockset faz uma varredura inicial de suas tabelas em seu banco de dados OLTP e, em seguida, usa fluxos CDC para permanecer sincronizado com os dados mais recentes, com os dados sendo disponibilizados para consulta dentro de 2 segundos a partir de quando foram gerados pelo sistema de origem.


Conectores integrados para fluxos de dados Com fluxos de dados como Kafka ou Kinesis, o Rockset ingere continuamente quaisquer novos tópicos usando uma integração baseada em pull que não requer ajuste no Kafka ou Kinesis.


Conectores integrados para data lakes e armazéns O Rockset monitora constantemente atualizações e ingere quaisquer novos objetos de data lakes, como buckets S3. Geralmente descobrimos que as equipes desejam unir fluxos em tempo real com dados de seus data lakes para análises em tempo real.

Atualizações, inserções e exclusões no Rockset

Rockset possui uma arquitetura distribuída otimizada para indexar dados de forma eficiente em paralelo em várias máquinas.


Rockset é um banco de dados fragmentado de documentos , portanto ele grava documentos inteiros em uma única máquina, em vez de dividi-los e enviar os diferentes campos para máquinas diferentes. Por causa disso, é rápido adicionar novos documentos para inserções ou localizar documentos existentes, com base na chave primária _id para atualizações e exclusões.


Semelhante ao Elasticsearch, o Rockset usa índices para recuperar dados de forma rápida e eficiente quando eles são consultados. Ao contrário de outros bancos de dados ou mecanismos de pesquisa, o Rockset indexa os dados no momento da ingestão em um Índice Convergente , um índice que combina um armazenamento de colunas, um índice de pesquisa e um armazenamento de linhas. O Índice Convergente armazena todos os valores nos campos como uma série de pares de valores-chave. No exemplo abaixo você pode ver um documento e como ele está armazenado no Rockset.


O Índice Convergente do Rockset armazena todos os valores nos campos como uma série de pares de valores-chave em um índice de pesquisa, armazenamento de coluna e armazenamento de linha.


Nos bastidores, o Rockset usa RocksDB , um armazenamento de valores-chave de alto desempenho que torna as mutações triviais. RocksDB suporta gravações e exclusões atômicas em chaves diferentes. Se ocorrer uma atualização no campo name de um documento, exatamente 3 chaves precisarão ser atualizadas, uma por índice. Os índices de outros campos do documento não são afetados, o que significa que o Rockset pode processar atualizações com eficiência, em vez de desperdiçar ciclos atualizando índices de documentos inteiros todas as vezes.


Documentos e matrizes aninhados também são tipos de dados de primeira classe no Rockset, o que significa que o mesmo processo de atualização se aplica a eles também, tornando o Rockset adequado para atualizações de dados armazenados em formatos modernos como JSON e Avro.


A equipe da Rockset também construiu várias extensões personalizadas para RocksDB para lidar com altas gravações e leituras pesadas, um padrão comum em cargas de trabalho de análise em tempo real. Uma dessas extensões são as compactações remotas , que introduzem uma separação clara entre computação de consulta e computação de indexação no RocksDB Cloud. Isso permite que o Rockset evite que gravações interfiram nas leituras. Devido a essas melhorias, a Rockset pode dimensionar suas gravações de acordo com as necessidades dos clientes e disponibilizar novos dados para consulta, mesmo quando ocorrem mutações em segundo plano.

Atualizações, inserções e exclusões usando a API Rockset

Os usuários do Rockset podem usar o campo _id padrão ou especificar um campo específico para ser a chave primária. Este campo permite que um documento ou parte de um documento seja sobrescrito. A diferença entre Rockset e Elasticsearch é que Rockset pode atualizar o valor de um campo individual sem exigir a reindexação de um documento inteiro.


Para atualizar documentos existentes em uma coleção usando a API Rockset, você pode fazer solicitações ao endpoint Patch Documents. Para cada documento existente que você deseja atualizar, basta especificar o campo _id e uma lista de operações de patch a serem aplicadas ao documento.


A API Rockset também expõe um endpoint Add Documents para que você possa inserir dados diretamente em suas coleções a partir do código do seu aplicativo. Para excluir documentos existentes, basta especificar os campos _id dos documentos que você deseja remover e fazer uma solicitação ao endpoint Excluir Documentos da API Rockset.

Manipulação de réplicas no Rockset

Ao contrário do Elasticsearch, apenas uma réplica no Rockset faz a indexação e compactação usando compactações remotas RocksDB. Isso reduz a quantidade de CPU necessária para indexação, especialmente quando diversas réplicas estão sendo usadas para durabilidade.

Reindexando no Rockset

No momento da ingestão no Rockset, você pode usar uma transformação de ingestão para especificar as transformações de dados desejadas para aplicar nos dados de origem brutos. Se desejar alterar a transformação de ingestão posteriormente, você precisará reindexar seus dados.


Dito isso, o Rockset permitea ingestão sem esquema e digita dinamicamente os valores de cada campo de dados. Se o tamanho e a forma dos dados ou consultas mudarem, o Rockset continuará a ter desempenho e não exigirá que os dados sejam reindexados.


O Rockset pode ser dimensionado para centenas de terabytes de dados sem precisar ser reindexado. Isso remonta à estratégia de fragmentação do Rockset. Quando a computação que um cliente aloca em sua Instância Virtual aumenta, um subconjunto de fragmentos é embaralhado para obter uma melhor distribuição no cluster, permitindo indexação e execução de consultas mais paralelizadas e mais rápidas. Como resultado, a reindexação não precisa ocorrer nesses cenários.

Conclusão

O Elasticsearch foi projetado para análise de log onde os dados não são atualizados, inseridos ou excluídos com frequência. Com o tempo, as equipes expandiram o uso do Elasticsearch, muitas vezes usando o Elasticsearch como armazenamento de dados secundário e mecanismo de indexação para análises em tempo real de dados transacionais em constante mudança. Isso pode ser um empreendimento caro, especialmente para equipes que estão otimizando a ingestão de dados em tempo real, além de envolver uma quantidade considerável de sobrecarga de gerenciamento.


O Rockset, por outro lado, foi projetado para análises em tempo real e para disponibilizar novos dados para consulta dentro de 2 segundos após sua geração. Para resolver esse caso de uso, o Rockset oferece suporte a inserções, atualizações e exclusões no local, economizando computação e limitando o uso de reindexação de documentos. A Rockset também reconhece a sobrecarga de gerenciamento de conectores e ingestão e adota uma abordagem de plataforma, incorporando conectores em tempo real em sua oferta de nuvem.


No geral, vimos empresas que migraram do Elasticsearch para o Rockset para análises em tempo real economizarem 44% apenas na conta de computação. Junte-se à onda de equipes de engenharia que mudam do Elasticsearch para o Rockset em poucos dias. Comece seu teste gratuito hoje.