Armazenamento de dados de séries temporais, relacionais ou não?

185

Estou criando um sistema que pesquisa dispositivos em busca de dados sobre diferentes métricas, como utilização da CPU, utilização do disco, temperatura etc. em (provavelmente) intervalos de 5 minutos usando SNMP. O objetivo final é fornecer visualizações para um usuário do sistema na forma de gráficos de séries temporais.

Eu observei o uso do RRDTool no passado, mas o rejeitei, pois armazenar os dados capturados indefinidamente é importante para o meu projeto, e quero acesso de nível mais alto e flexível aos dados capturados. Então, minha pergunta é realmente:

O que é melhor: um banco de dados relacional (como MySQL ou PostgreSQL) ou um banco de dados não relacional ou NoSQL (como MongoDB ou Redis) com relação ao desempenho ao consultar dados para gráficos.

Relacional

Dado um banco de dados relacional, eu usaria uma data_instancestabela, na qual seriam armazenadas todas as instâncias de dados capturados para cada métrica medida em todos os dispositivos, com os seguintes campos:

Campos: id fk_to_device fk_to_metric metric_value timestamp

Quando quero desenhar um gráfico para uma métrica específica em um dispositivo específico, devo consultar esta tabela singular filtrando os outros dispositivos e as outras métricas analisadas para esse dispositivo:

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

O número de linhas nesta tabela seria:

d * m_d * f * t

onde dé o número de dispositivos , m_dé o número acumulado de métricas sendo registradas para todos os dispositivos, fé a frequência com que os dados são pesquisados ​​e té a quantidade total de tempo que o sistema coleta dados.

Para um usuário que grava 10 métricas para 3 dispositivos a cada 5 minutos durante um ano, teríamos pouco menos de 5 milhões de registros.

Índices

Sem índices ativados fk_to_devicee fk_to_metricvarredura, essa tabela em expansão contínua levaria muito tempo. Portanto, é necessário indexar os campos mencionados e também timestamp(para criar gráficos com períodos localizados).

Não relacional (NoSQL)

O MongoDB tem o conceito de coleção , ao contrário das tabelas, elas podem ser criadas programaticamente sem configuração. Com eles, eu poderia particionar o armazenamento de dados para cada dispositivo, ou mesmo cada métrica registrada para cada dispositivo.

Não tenho experiência com o NoSQL e não sei se eles fornecem recursos de aprimoramento do desempenho da consulta, como a indexação; no entanto, o parágrafo anterior propõe a maior parte do trabalho tradicional de consulta relacional na estrutura pela qual os dados são armazenados no NoSQL.

Indeciso

Uma solução relacional com indexação correta reduziria a um rastreamento dentro de um ano? Ou a estrutura baseada em coleta das abordagens NoSQL (que corresponde ao meu modelo mental dos dados armazenados) oferece um benefício notável?

Marcus Whybrow
fonte
1
Pergunta muito válida, eu mesmo ponderei sobre se o banco de dados relacional é o caminho certo para armazenar uma estrutura de dados que é realmente hierárquica (estrutura SNMP). Às vezes, quando escrevo uma consulta para buscar até dados triviais, a consulta é complicada demais, senti que os dados precisavam ser confundidos com um formulário que não fosse o seu. Por exemplo, combinar ifnames e seus índices é supostamente uma tarefa trivial, sendo ambos filhos do mesmo pai oid. Mas a maneira como ele é armazenado no banco de dados relacional não se relaciona à sua estrutura original e acho que é mais eficiente armazená-lo de maneira hierárquica.
21912 Benny
"Para um usuário que grava 10 métricas para 3 dispositivos a cada 5 minutos durante um ano, teríamos pouco menos de 5 milhões de registros". 10 * 3 * 365 * 24 * 12 não é aproximadamente igual a 3 milhões, o que não é pouco menos de 5 milhões?
Mathieu Borderé

Respostas:

152

Definitivamente relacional. Flexibilidade e expansão ilimitadas.

Duas correções, tanto no conceito quanto na aplicação, seguidas por uma elevação.

Correção

  1. Não é "filtrar os dados desnecessários"; está selecionando apenas os dados necessários. Sim, é claro, se você possui um Índice para suportar as colunas identificadas na cláusula WHERE, é muito rápido e a consulta não depende do tamanho da tabela (pegar 1.000 linhas de uma tabela de 16 bilhões de linhas é instantâneo) .

  2. Sua mesa tem um sério impedimento. De acordo com sua descrição, a PK real é (dispositivo, métrica, data e hora). (Por favor, não o chame de TimeStamp, isso significa outra coisa, mas esse é um problema menor.) A exclusividade da linha é identificada por:

       (Device, Metric, DateTime)
    
    • A Idcoluna não faz nada, é total e completamente redundante.

      • Uma Idcoluna nunca é uma chave (linhas duplicadas, que são proibidas em um banco de dados relacional, devem ser evitadas por outros meios).
      • A Idcoluna requer um índice adicional, que obviamente impede a velocidade de INSERT/DELETE, e aumenta o espaço em disco usado.

      • Você pode se livrar disso. Por favor.

Elevação

  1. Agora que você removeu o impedimento, talvez não o reconheça, mas sua tabela está na Sexta Forma Normal. Velocidade muito alta, com apenas um índice no PK. Para entender, leia esta resposta no O que é a sexta forma normal? seguindo em frente.

    • (Eu tenho apenas um índice, não três; nos Não-SQLs, você pode precisar de três índices).

    • Eu tenho exatamente a mesma tabela (sem a Id"chave", é claro). Eu tenho uma coluna adicional Server. Eu apoio múltiplos clientes remotamente.

      (Server, Device, Metric, DateTime)

    A tabela pode ser usada para dinamizar os dados (ou seja, Devicesna parte superior e Metricsinferior do lado ou dinâmicos) usando exatamente o mesmo código SQL (sim, alterne as células). Uso a tabela para montar uma variedade ilimitada de gráficos e tabelas para os clientes quanto ao desempenho do servidor.

    • Monitorar modelo de dados estatísticos .
      (Grande demais para embutido; alguns navegadores não podem carregar embutido; clique no link. Além disso, essa é a versão demo obsoleta; por razões óbvias, não posso mostrar o DM do produto comercial.)

    • Ele me permite produzir gráficos como este , seis pressionamentos de tecla depois de receber um arquivo de estatísticas de monitoramento bruto do cliente, usando um único comando SELECT . Observe o mix-and-match; SO e servidor no mesmo gráfico; uma variedade de pivôs. Obviamente, não há limite para o número de matrizes de estatísticas e, portanto, para os gráficos. (Usado com a permissão gentil do cliente.)

    • Os leitores que não estão familiarizados com o Padrão para Modelagem de Bancos de Dados Relacionais podem achar útil a Notação IDEF1X .

Mais uma coisa

Por último, mas não menos importante, o SQL é um padrão IEC / ISO / ANSI. O freeware é realmente não-SQL; é fraudulento usar o termo SQL se eles não fornecerem o Padrão. Eles podem fornecer "extras", mas estão ausentes o básico.

PerformanceDBA
fonte
1
@PerformanceDBA você usaria o esquema sugerido para uma instalação que precisa lidar com ~ 3 milhões de medidas com uma frequência de 1 minuto? Como você solicitaria o PK para essa mesa? Device, Metric, DateTime não criariam fragmentação e forçariam o RDBMS a muita divisão de página? Em vez disso, colocar o DateTime primeiro reduziria a fragmentação (estou assumindo inserções ordenadas por tempo), mas tornaria as leituras piores.
marcob
1
@Buchi. Eu uso o Sybase ASE. Mas esse não é um problema de plataforma (com certeza, as plataformas altas oferecem desempenho com ordens de grandeza melhores do que o low-end; três ordens de grandeza melhores que o Oracle, mas esse não é o ponto), ereção do gráfico da tabela " funciona "em qualquer plataforma. Use a ferramenta certa para o trabalho. O RDBMS é uma ferramenta de banco de dados, não uma ferramenta gráfica. gnuplot, o Apple Numbers (ou se você gosta de pagar dez vezes mais, pela metade do valor do MS Excel) são ferramentas de gráficos, não ferramentas de banco de dados. Atualmente, usamos camadas de ferramentas para produzir um resultado, o monólito é um dinossauro.
PerformanceDBA
1
@marcob. Sua pergunta é boa, mas não pode ser respondida adequadamente nos comentários. Se você abrir uma nova pergunta e me enviar um email (vá para o perfil), eu responderei. Para a resposta rápida aqui. (1) ~ 3 milhões de métricas. Ótimo, quanto mais, ele espalha os pontos INSERT lindamente, o seu garantiria conflitos na última página. O servidor é multiencadeado, sim? Particione a tabela. Use FILLFACTOR e deixe espaço para inserções e, assim, evite divisões de página. (2) ~ 3 Moinho indica que as Métricas não estão Normalizadas; se você corrigir isso, será ainda mais rápido.
PerformanceDBA
1
@marcob. (3) Utilizo o índice fornecido precisamente para espalhar as pastilhas sob carga, o que garante que não haja conflitos. (4) Portanto, o meu método obtém ambas as inserções, sem conflitos e de alto desempenho em SELECTs.
PerformanceDBA
2
@Loic. Por que diabos alguém, que possui um investimento (dados; código) em uma plataforma SQL, que lida com dados de séries temporais com facilidade e com desempenho muito alto (conforme detalhado na resposta), migraria para um TSDB sem SQL; velocidade desconhecida para qualquer coisa, exceto dados de séries temporais? Por que alguém que tem um requisito que excede apenas dados de séries temporais não usa uma plataforma SQL? A mente confunde. O TSDB é mais rápido que o Relacional apenas na instância triste quando os dados são armazenados em um banco de dados, mas não são normalizados Relacionalmente. Por exemplo. quando Idcolunas são usadas, como "chaves". Como recomendado pelos "teóricos".
PerformanceDBA
21

Achei muito interessante as respostas acima. Tentando adicionar mais algumas considerações aqui.

1) Envelhecimento de dados

O gerenciamento de séries temporais geralmente precisa criar políticas antigas. Um cenário típico (por exemplo, CPU do servidor de monitoramento) requer o armazenamento:

  • Amostras brutas de 1 segundo por um curto período (por exemplo, 24 horas)

  • Amostras agregadas detalhadas de 5 minutos por um período médio (por exemplo, 1 semana)

  • Detalhes de 1 hora sobre isso (por exemplo, até 1 ano)

Embora os modelos relacionais tornem possível (minha empresa implementou bancos de dados centralizados maciços para alguns grandes clientes com dezenas de milhares de séries de dados) gerenciá-los adequadamente, a nova geração de armazenamentos de dados adiciona funcionalidades interessantes a serem exploradas, como:

  • limpeza automática de dados (consulte o comando EXPIRE do Redis)

  • agregações multidimensionais (por exemplo, tarefas de redução de mapa à la Splunk)

2) Coleta em tempo real

Ainda mais importante, alguns armazenamentos de dados não relacionais são inerentemente distribuídos e permitem uma coleta de dados em tempo real (ou quase em tempo real) muito mais eficiente que pode ser um problema com o RDBMS devido à criação de pontos de acesso (gerenciando a indexação ao inserir no uma única tabela). Esse problema no espaço RDBMS geralmente é resolvido revertendo para os procedimentos de importação em lote (nós o gerenciamos dessa maneira no passado), enquanto as tecnologias no-sql tiveram êxito na coleta e agregação em tempo real maciça (consulte Splunk, por exemplo, mencionado nas respostas anteriores) .

Paolo Bozzola
fonte
7

Sua tabela possui dados em uma única tabela. Portanto, relacional vs não relacional não é a questão. Basicamente, você precisa ler muitos dados sequenciais. Agora, se você possui RAM suficiente para armazenar dados valiosos por um ano, nada como usar Redis / MongoDB etc.

Basicamente, os bancos de dados NoSQL armazenam seus dados no mesmo local no disco e em formato compactado para evitar o acesso múltiplo ao disco.

O NoSQL faz a mesma coisa que criar o índice na identificação do dispositivo e na métrica, mas à sua maneira. Com o banco de dados, mesmo se você fizer isso, o índice e os dados poderão estar em locais diferentes e haverá muitas E / S de disco.

Ferramentas como o Splunk estão usando back-end NoSQL para armazenar dados de séries temporais e, em seguida, usando o map reduzir para criar agregados (que podem ser o que você deseja posteriormente). Portanto, na minha opinião, usar o NoSQL é uma opção, pois as pessoas já tentaram em casos de uso semelhantes. Mas um milhão de linhas fará o rastreamento do banco de dados (talvez não, com hardware decente e configurações adequadas).

Ravindra
fonte
1
Você poderia explicar como a tabela é "des-normalizada"? Marcus tem um erro na tabela, mas não é um erro de normalização.
PerformanceDBA
vou me corrigir, as tabelas são normalizadas no sentido tradicional. Eu quis dizer desnormalizado no sentido de que o caso de uso tem todos os dados em uma tabela aqui.
Ravindra
4

Crie um arquivo, denomine 1_2.data. idéia estranha? o que você ganha:

  • Você economiza até 50% de espaço porque não precisa repetir os valores fk_to_device e fk_to_metric para cada ponto de dados.
  • Você economiza ainda mais espaço porque não precisa de índices.
  • Salve pares de (timestamp, metric_value) no arquivo anexando os dados para obter um pedido por timestamp gratuitamente. (supondo que suas fontes não enviem dados fora de ordem para um dispositivo)

=> As consultas por carimbo de data e hora são incrivelmente rápidas, porque você pode usar a pesquisa binária para encontrar o lugar certo no arquivo para ler.

se você gosta ainda mais otimizado, comece a pensar em dividir seus arquivos assim;

  • 1_2_january2014.data
  • 1_2_february2014.data
  • 1_2_march2014.data

ou use o kdb + em http://kx.com porque eles fazem tudo isso para você :) O que pode ajudá-lo é orientado a colunas.

Existe uma solução orientada a colunas baseada em nuvem, então você pode querer dar uma olhada em: http://timeseries.guru

hellomichibye
fonte
Eu escrevi um post sobre o assunto. com Traduz Google que você pode achar útil: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye
3

Se você está procurando pacotes GPL, o RRDTool é um bom exemplo. É uma boa ferramenta para armazenar, extrair e representar graficamente dados de séries temporais. Seu caso de uso se parece exatamente com dados de séries temporais.

tomar sol
fonte
2

Esse é um problema que tivemos que resolver no ApiAxle. Nós escreveu um post sobre como nós o fizemos usando Redis. Não existe há muito tempo, mas está provando ser eficaz.

Também usei o RRDTool para outro projeto que foi excelente.

Phil Jackson
fonte
2

Eu acho que a resposta para esse tipo de pergunta deve girar principalmente sobre a maneira como seu banco de dados utiliza armazenamento. Alguns servidores de banco de dados usam RAM e disco, outros usam apenas RAM (opcionalmente disco para persistência), etc. As soluções mais comuns de banco de dados SQL estão usando memória + armazenamento em disco e gravam os dados em um layout baseado em linha (cada bruto inserido é gravado da mesma maneira localização física). Para lojas de séries temporais, na maioria dos casos, a carga de trabalho é algo como: Intervalo relativamente baixo de grande quantidade de inserções, enquanto as leituras são baseadas em colunas (na maioria dos casos, você deseja ler um intervalo de dados de uma coluna específica, representando uma métrica)

Eu descobri que os bancos de dados colunares (no Google, você encontrará o MonetDB, InfoBright, parAccel, etc.) estão fazendo um ótimo trabalho para séries temporais.

Quanto à sua pergunta, que pessoalmente acho um tanto inválida (como todas as discussões usando o termo de falha NoSQL - IMO): Você pode usar um servidor de banco de dados que possa falar sobre SQL por um lado, facilitando sua vida, pois todos conhecem SQL para muitos anos e esse idioma foi aperfeiçoado repetidamente para consultas de dados; mas ainda utiliza RAM, cache da CPU e disco de maneira colunar, tornando sua solução a mais adequada para séries temporais

Shay
fonte
2

5 milhões de linhas não são nada para os dados torrenciais de hoje. Espere que os dados estejam na TB ou PB em apenas alguns meses. Nesse ponto, o RDBMS não se ajusta à tarefa e precisamos da escalabilidade linear dos bancos de dados NoSql. O desempenho seria alcançado para a partição colunar usada para armazenar os dados, adicionando mais conceito de colunas e menos linhas para aumentar o desempenho. Aproveite o trabalho do Open TSDB feito sobre o HBASE ou o MapR_DB, etc.

Juan Asenjo
fonte
"RDBMS não se adapta à tarefa" - por que não? code.facebook.com/posts/190251048047090/...
Zathrus Escritor
1

Enfrento requisitos semelhantes regularmente e recentemente comecei a usar o Zabbix para reunir e armazenar esse tipo de dados. O Zabbix possui sua própria capacidade de representação gráfica, mas é fácil extrair os dados do banco de dados do Zabbix e processá-los da maneira que desejar. Se você ainda não fez o check-out do Zabbix, pode achar que vale a pena fazê-lo.

monch1962
fonte
Sim, o Zabbix é bom e já se integra ao monitoramento SNMP. O Zabbix pode usar MySQL ou PostgreSQL e funciona mais ou menos imediatamente no Ubuntu.
precisa saber é o seguinte
Obrigado, tenho conhecimento do Zabbix e de muitas outras ferramentas SNMP. No entanto, estou desenvolvendo este projeto como um processo educacional, no tópico discutido aqui e em muitos outros aspectos. Um bom ponto!
Marcus Whybrow
0

Você deve procurar no banco de dados de séries temporais . Foi criado para esse fim.

Um banco de dados de séries temporais (TSDB) é um sistema de software otimizado para manipular dados de séries temporais, matrizes de números indexados por tempo (uma data e hora ou intervalo de data e hora).

Exemplo popular de banco de dados de séries temporais InfluxDB

Adão
fonte
adicione timescaledb a esta lista agora
PirateApp