Como armazenar com eficiência grandes dados de séries temporais?

27

Preciso armazenar e poder consultar dados de séries temporais de quantidades muito grandes.

As propriedades dos dados são as seguintes:

  • número de séries: cerca de 12.000 (doze mil)
  • número de pontos de dados, globalmente: cerca de 500.000.000 por mês (quinhentos milhões)
  • tipos de valor misto: a maioria dos pontos de dados são valores de ponto flutuante, o restante são cadeias
  • período de amostragem: variável entre séries e dentro de uma série
  • registros de data e hora: precisão de milissegundos
  • período de retenção de dados: vários anos, sem deterioração ou redução da amostragem
  • os arquivos de dados precisam ser criados quase em tempo real, mas um atraso razoável (~ 1 hora) é aceitável
  • dados passados ​​podem ser reconstruídos, se necessário, mas a um custo elevado
  • Às vezes, mas muito raramente, alguns dados anteriores precisam ser atualizados

Propriedades das consultas previstas:

  • a maioria das consultas nos dados será baseada em timestamp; variando de um dia a vários meses / anos. Mais de 90% serão consultas nos dados mais recentes

Outros requerimentos:

  • a solução deve ser livre como na cerveja grátis e preferencialmente de código aberto

Meu pensamento inicial era usar PyTables / Pandas com arquivos HDF5 como armazenamento de back-end em vez de um banco de dados SQL.

Questões :

  1. Supondo que o PyTables / Pandas seja a melhor "rota", seria melhor dividir os dados em vários arquivos HDF, cada um deles em um determinado período de tempo, ou colocar tudo em um único arquivo que se tornaria enorme?

  2. Devo preferir o formato fixo ou a tabela? Para mim, o formato fixo parece bom se eu mantiver um arquivo HDF por mês, pois dessa forma uma série inteira provavelmente se encaixa na RAM e posso fatiar na memória sem precisar de um índice de formato de tabela. Estou correcto ?

E se essa não é a melhor abordagem, como devo estruturar esse armazenamento de dados ou quais tecnologias devo considerar? Não sou o primeiro a lidar com o armazenamento de grandes conjuntos de dados de séries temporais. Qual é a abordagem geral para resolver esse desafio?


Outras abordagens que considerei:

  • bancos de dados de matriz: eles são ótimos para séries temporais com período de amostragem constante, pois você só precisa armazenar os horários de início e término e o período de amostragem da matriz e, em seguida, apenas os valores na matriz e a indexação são fáceis. Porém, com períodos de amostragem variáveis ​​dentro das próprias séries, preciso manter uma relação de carimbo de data / hora mais próxima - de valor, que, na minha opinião, não é tão adequada para DBMS de matriz.
  • banco de dados SQL padrão com registro de data e hora, paramID, valor como colunas, mas por sua natureza, eles solicitam muita E / S de disco para qualquer consulta
flyingmig
fonte
Você deve considerar os bancos de dados de matriz - en.wikipedia.org/wiki/Array_DBMS#List_of_Array_DBMS . Não estou dizendo que um deles seria a resposta certa, ou mesmo a melhor ou até a suficientemente boa, apenas para que eles entrem em seus pensamentos. Além das entradas nessa lista, existe o sistema kdb ( kx.com ), embora esteja longe de ser gratuito.
High Performance Mark
Obrigdo por sua contribuição. Eu considerei bancos de dados de matriz, mas o problema encontrado com eles é que eles são excelentes para séries temporais com período de amostragem constante , pois você só precisa armazenar os horários de início e término e o período de amostragem da matriz e, em seguida, apenas valores em a matriz em si e a indexação é fácil. Porém, com períodos de amostragem variáveis nas próprias séries, preciso manter uma relação de carimbo de data / hora mais próxima - de valor, que, a meu ver, não é tão adequada para DBMS de matriz. Com isso dito, eu ficaria feliz em provar que estou errado.
flyingmig
editar a questão para adicionar o que tenho considerado até agora
flyingmig
Pergunta: você precisa armazenar todos os dados? Os dados podem deteriorar-se ao longo do tempo e / ou há algum nível aceitável de precisão para as séries baseadas em float?
J Trana
1
@ moinuddin-quadri Acabei usando objetos DataFrame do pandas suportados por arquivos HDF5 mensais usando o formato de tabela. O sistema está em funcionamento há mais de um ano e mostrou-se muito estável e rápido, nem mesmo usando discos SSD. Tentarei escrever tudo isso como resposta quando tiver tempo. Caso contrário, fique à vontade para me PM.
flyingmig 19/05/19

Respostas:

5

Você pode dar uma olhada no carbono e no sussurro , parte do projeto de grafite . O carbono pode lidar com grandes quantidades de dados de séries temporais. No entanto, agora que li os documentos (faz alguns anos desde que o usei), é apenas para dados numéricos. Você disse que também possui dados de sequência, portanto, pode não achar isso útil. No entanto, você poderá obter um pouco de sabedoria sobre como eles são capazes de processar grandes quantidades de dados rapidamente.

Para ter uma idéia de quão bem ela é dimensionada, quando a grafite foi colocada em produção pela primeira vez em Orbitz, ela estava processando 160.000 métricas por minuto .

Bryan Oakley
fonte
Obrigado pela sugestão, mas, pelo meu entendimento, o sussurro não se encaixa porque sua precisão é a segunda quando eu preciso de precisão de milissegundos e, como você corretamente apontou, também tenho dados de string que não podem ser armazenados lá.
flyingmig
1
@flyingmig Não escreva sussurro tão rápido. Seus registros de data e hora são valores da época do Unix. E os "dados da string" que você descreveu na pergunta parecem mais enumerações, e geralmente são armazenados como pequenos valores inteiros.
Ross Patterson
A Sears está usando Carbono / Grafite / Ceres para armazenar 4 milhões de pontos de dados exclusivos por minuto. Não é perfeito e requer cluster de grafite e SSDs, mas funciona. Todas as outras soluções lá fora, não podem se adaptar a este nível, que nós encontramos, mas se você tem idéias, sinta-se livre para badalar no.
Kevin J. Rice,
3

O InfluxDB é um banco de dados de código aberto escrito em Go. Ele foi escrito especialmente para lidar com dados de séries temporais, e eles publicaram benchmarks mostrando um desempenho muito melhor do que o Cassandra :

O InfluxDB superou o Cassandra em todos os três testes com taxa de transferência de gravação 4.5x maior, usando 10.8x menos espaço em disco e oferecendo tempos de resposta até 168x mais rápidos para consultas testadas.

Dan Dascalescu
fonte
2

convém verificar bancos de dados orientados a colunas. Não sei ao certo o que você quer dizer com bancos de dados de matriz, mas com minha abordagem sugerida você pode ter um número dinâmico de valores por período de tempo. Você também pode ter vários valores para o mesmo registro de data e hora. A parte interessante é que, se você tiver valores medidos no mesmo registro de data e hora, poderá salvá-los como colunas adicionais (por exemplo, um sensor que mede temperatura e umidade, no preço de negociação de ações e tamanho de uma negociação, ...). Devido à natureza orientada a colunas, você pode ter tabelas com 100 colunas, mas se sua consulta acessar apenas cinco colunas, o banco de dados lê apenas os dados das cinco colunas.

Escrevi uma série sobre a criação de seu próprio banco de dados de séries temporais. Você pode dar uma olhada:

hellomichibye
fonte