Estou escrevendo um aplicativo que precisa armazenar e analisar grandes quantidades de dados elétricos e de temperatura.
Basicamente, preciso armazenar grandes quantidades de medições horárias de uso de eletricidade nos últimos anos e nos próximos anos para dezenas de milhares de locais e depois analisar os dados de uma maneira não muito complexa.
As informações que preciso armazenar (por enquanto) são ID de local, carimbo de data e hora (data e hora), temperatura e uso de eletricidade.
Sobre a quantidade de dados que precisa ser armazenada, é uma aproximação, mas algo nesse sentido:
mais de 20.000 locais, 720 registros por mês (medições horárias, aproximadamente 720 horas por mês), 120 meses (há 10 anos) ) e muitos anos no futuro. Cálculos simples produzem os seguintes resultados:
20 000 locais x 720 registros x 120 meses (10 anos atrás) = 1 728 000 000 registros .
Como são os registros anteriores, novos registros serão importados mensalmente, ou seja, aproximadamente 20 000 x 720 = 14 400 000 novos registros por mês .
O total de locais também aumentará constantemente.
Em todos esses dados, as seguintes operações precisarão ser executadas:
- Recupere os dados para uma determinada data E período: todos os registros para um determinado ID de local entre as datas 01.01.2013 e 01.01.2017 e entre 07:00 e 13:00.
- Operações matemáticas simples para uma determinada data E intervalo de tempo, por exemplo, temperatura MIN, MAX e AVG e uso de eletricidade para um determinado ID de local por 5 anos entre as 07:00 e as 13:00.
Os dados serão gravados mensalmente, mas serão lidos por centenas de usuários (pelo menos) constantemente, portanto a velocidade de leitura é significativamente mais importante.
Não tenho experiência com bancos de dados NoSQL, mas, pelo que reuni, eles são a melhor solução para usar aqui. Eu li nos bancos de dados NoSQL mais populares, mas como eles são bastante diferentes e também permitem uma arquitetura de tabela muito diferente, não pude decidir qual é o melhor banco de dados a ser usado.
Minhas principais escolhas foram Cassandra e MongoDB, mas desde que eu tenho um conhecimento muito limitado e nenhuma experiência real quando se trata de grandes dados e NoSQL, não tenho muita certeza. Também li que o PostreSQL também lida bem com essas quantidades de dados.
Minhas perguntas são as seguintes:
- Devo usar um banco de dados NoSQL para quantidades tão grandes de dados. Caso contrário, posso manter o MySQL?
- Qual banco de dados devo usar?
- Devo manter a data e a hora em colunas separadas e indexadas (se possível) para recuperar e processar os dados rapidamente por determinados períodos de data e hora, ou isso pode ser feito mantendo o registro de data e hora em uma única coluna?
- Uma abordagem de modelagem de dados de séries temporais é apropriada aqui e, se não, você poderia me dar dicas para um bom design de tabela?
Obrigado.
Respostas:
É exatamente isso que faço todos os dias, exceto que, em vez de usar os dados horários, uso os dados de 5 minutos. Eu faço o download de cerca de 200 milhões de registros todos os dias, portanto, o valor que você fala aqui não é um problema. Os dados de 5 minutos têm cerca de 2 TB de tamanho e eu tenho dados meteorológicos que remontam 50 anos a um nível horário por local. Então, deixe-me responder a perguntas com base na minha experiência:
Dica geral: eu armazeno a maioria dos dados entre dois bancos de dados, o primeiro são dados de séries temporais diretas e é normalizado. Meu segundo banco de dados está muito normalizado e contém dados pré-agregados. Tão rápido quanto meu sistema, eu não sou cego para o fato de que os usuários nem querem esperar 30 segundos para que um relatório seja carregado - mesmo que eu pessoalmente pense que 30 segundos para processar 2 TB de dados são extremamente rápidos.
Para explicar por que recomendo armazenar a hora separada da data, aqui estão alguns motivos pelos quais faço dessa maneira:
DATETIME
coluna.Como eu disse acima, tudo isso é baseado na minha experiência pessoal e, deixe-me dizer, foram alguns anos difíceis e muitas redesigns para chegar onde estou agora. Não faça o que fiz, aprenda com meus erros e certifique-se de envolver os usuários finais do seu sistema (ou desenvolvedores, autores de relatórios etc.) ao tomar decisões sobre seu banco de dados.
fonte
Índices PostgreSQL e BRIN
Teste você mesmo. Este não é um problema em um laptop de 5 anos com um ssd.
Foram necessários 22 minutos para criar a tabela. Em grande parte, porque a tabela é de 97GB modestos. Em seguida, criamos os índices,
Demorou um bom tempo para criar os índices também. Embora sejam BRIN, têm apenas 2 a 3 MB e armazenam-se facilmente em memória RAM. Ler 96 GB não é instantâneo, mas não é um problema real para o meu laptop com a sua carga de trabalho.
Agora, consultamos.
Atualizar com timestamps
Aqui, geramos uma tabela com registros de data e hora diferentes para satisfazer a solicitação de indexação e pesquisa em uma coluna de registro de data e hora, a criação demora um pouco mais porque
to_timestamp(int)
é substancialmente mais lenta do quenow()
(armazenada em cache para a transação)Agora podemos executar uma consulta em um valor de carimbo de data e hora ,,
Resultado:
Assim, em 83,321 ms, podemos agregar 86.401 registros em uma tabela com 1,7 bilhões de linhas. Isso deve ser razoável.
Hora final
Também é muito fácil calcular o término da hora, truncar os carimbos de data e hora e simplesmente adicionar uma hora.
É importante observar que ele não está usando um índice na agregação, embora possa. Se essa é a sua consulta típica, provavelmente você quer um BRIN
date_trunc('hour', tsin)
nela.date_trunc
Existe um pequeno problema que não é imutável, então você deve primeiro envolvê-la para fazê-lo.Particionamento
Outro ponto importante de informação no PostgreSQL é que o PG 10 traz DDL de particionamento . Assim, você pode, por exemplo, criar partições facilmente para cada ano. Dividindo seu banco de dados modesto em bancos de dados menores, pequenos. Ao fazer isso, você poderá usar e manter índices btree em vez do BRIN, o que seria ainda mais rápido.
Como queiras.
fonte
Me surpreende que ninguém aqui tenha mencionado benchmarking - até que o @EvanCarroll veio com sua excelente contribuição!
Se eu fosse você, passaria algum tempo (e sim, eu sei que é uma mercadoria preciosa!) Configurando sistemas, executando o que você pensa que será (obtenha a entrada do usuário final aqui!), Digamos, suas 10 perguntas mais comuns.
Meus próprios pensamentos:
As soluções NoSQL podem funcionar muito bem em casos de uso específicos, mas geralmente são inflexíveis para consultas ad-hoc. Para uma visão divertida do NoSQL de Brian Aker - ex-arquiteto-chefe do MySQL, veja aqui !
Concordo com @ Mr.Brownstone que seus dados são eminentemente adequados a uma solução relacional (e essa opinião foi confirmada por Evan Carroll )!
Se eu me comprometer com qualquer despesa, seria com a minha tecnologia de disco! Eu gastaria qualquer dinheiro que tivesse à minha disposição em NAS ou SAN ou talvez em alguns discos SSD para armazenar meus dados agregados raramente gravados!
Primeiro, eu examinaria o que tenho disponível agora . Execute alguns testes e mostre os resultados aos tomadores de decisão. Você já tem um proxy na forma de trabalho da CE ! Porém, um teste rápido ou dois reunidos em seu próprio hardware seria mais convincente!
Então pense em gastar dinheiro! Se você vai gastar dinheiro, observe primeiro o hardware, e não o software. AFAIK, você pode contratar a tecnologia de disco por um período de teste ou, melhor ainda, apresentar algumas provas de conceito na nuvem.
Minha primeira chamada pessoal para um projeto como esse seria o PostgreSQL. Isso não quer dizer que eu descartaria uma solução proprietária, mas as leis da física e dos discos são as mesmas para todos! "Você não pode melhorar as leis da física Jim" :-)
fonte
Se você ainda não o fez, dê uma olhada em DBMS de séries temporais, pois ele é otimizado para armazenar e consultar dados em que o foco principal é o tipo de data / hora. Normalmente, os bancos de dados de séries temporais são usados para gravar dados nos intervalos de minuto / segundo / sub-segundo, portanto, não tenho certeza se ainda é apropriado para incrementos de hora em hora. Dito isto, parece que vale a pena examinar esse tipo de DBMS. Atualmente, o InfluxDB parece ser o banco de dados de séries temporais mais estabelecido e amplamente utilizado.
fonte
Claramente, este não é um problema NoSQL, mas eu sugeriria que, embora uma solução RDBMS funcionasse, acho que uma abordagem OLAP se ajustaria muito melhor e, dados os intervalos de dados muito limitados envolvidos, sugeriria fortemente a investigação do uso de um banco de dados baseado em coluna em vez de uma linha com base. Pense dessa maneira: você pode ter 1,7 bilhão de dados, mas ainda precisa de apenas 5 bits para indexar todos os valores possíveis de hora ou dia do mês.
Tenho experiência com um domínio de problemas semelhante em que o Sybase IQ (agora SAP IQ) é usado para armazenar até 300 milhões de contadores por hora de dados de gerenciamento de desempenho de equipamentos de telecomunicações, mas duvido que você tenha o orçamento para esse tipo de solução. Na arena do código aberto, o MariaDB ColumnStore é um candidato muito promissor, mas eu recomendaria também investigar o MonetDB.
Como o desempenho da consulta é um fator importante para você, considere como as consultas serão formuladas. É aqui que o OLAP e o RDBMS mostram suas maiores diferenças: - com o OLAP, você normaliza o desempenho da consulta, para não reduzir a repetição, reduzir o armazenamento ou mesmo reforçar a consistência. Portanto, além do registro de data e hora original (você lembrou de capturar o fuso horário, espero?), Tenha um campo separado para o registro de data e hora UTC, outros para a data e hora e ainda mais para o ano, mês, dia, hora, minuto e deslocamento UTC. Se você tiver informações adicionais sobre locais, fique à vontade para mantê-lo em uma tabela de locais separada que possa ser procurada sob demanda e fique à vontade para manter a chave dessa tabela em seu registro principal, mas mantenha o nome completo da localização em sua tabela principal, como bem, afinal,
Como sugestão final, use tabelas separadas para dados agregados populares e use tarefas em lote para preenchê-los. Dessa forma, você não precisará repetir o exercício para todo e qualquer relatório que use um valor agregado e faça consultas que sejam comparadas entre atual e histórico ou histórico para histórico muito mais fácil e muito, muito mais rápido.
fonte