qual solução NoSQL para valores de data-point simples e baseados em tempo?

Eu leio muito sobre diferentes bancos de dados NoSQL, mas ainda estou indeciso sobre qual solução seria a mais apropriada na minha situação – provavelmente porque não tenho experiência com bancos de dados NoSQL – exceto o REDIS, que estou usando para o armazenamento em cache.

No meu cenário, tenho que armazenar valores históricos baseados no tempo (flutuação mista, número inteiro, valores booleanos com base no ponto de dados) por cerca de 200.000 datapoints. Normalmente, cada ponto de dados obterá um novo valor a cada 15 minutos, ou menos, totalizando algo na faixa de bilhões de valores por ano . Alguns pontos de dados podem até armazenar um valor a cada poucos segundos, até um máximo teórico de 31.536.000 valores por ano para um único ponto de dados (não precisamos de uma precisão de sub-segundo), mas isso será raro.

O número de pontos de dados pode duplicar facilmente no futuro, o que significa que deve ser um sistema escalável.

Leitura

Para visualizar os dados, deve ser possível analisar rapidamente os dados de um único ponto de dados em qualquer intervalo de tempo armazenado – seja isso algumas horas ou um ano inteiro. Nesse intervalo, eu preciso de valores mín / max / avg em uma resolução específica, normalmente o intervalo de tempo dividido em cerca de 1000.

No mySQL, isso seria feito assim:

SELECT TRUNCATE(Timestamp / 3600) AS slot, MIN(value), AVG(value), MAX(value) FROM data WHERE Timestamp >= [from] AND Timestamp < [to] AND DatapointID = [some ID] GROUP BY 1 

… que retornaria dados para um gráfico com a precisão de 1 hora.

Como isso pode ser feito com os bancos de dados NoSQL para que a informação esteja disponível em apenas alguns milissegundos?

Esta é a minha principal preocupação.

Escrevendo

Os dados são adicionados perto de tempo real, de modo que não deve haver muitas operações de gravação. As atualizações dos dados existentes devem ser possíveis, mas serão extremamente raras. Os dados chegarão em ordem do tempo, mas não posso realmente garantir isso.

Outros requisitos

  • Deve ser possível copiar rapidamente todas as partes (ou alternativamente) dos dados para máquinas de desenvolvimento externo, o que não deve exigir horas. Isso deve ser possível sem afetar o sistema de produção.
  • Deve ser possível fazer backup de todos os dados sem interromper o database (backup diário).
  • Temos que importar cerca de meio bilhão de dados existentes, que precisam ser concluídos em um prazo razoável.
  • O database deve estar acessível com o PHP.

O database NoSQL é mais adequado para essas necessidades e como a consulta de dados acima pode ser feita com ela?

Bem primeira pergunta que veio à minha mente, por que tem que ser um database NoSQL? Você explicou como você faria isso no MySQL, mas não leu porque você não quer usá-lo.

Primeiro de vocês sugeriu a seguinte consulta para o MySQL

 SELECT TRUNCATE(Timestamp / 3600) AS slot, MIN(value), AVG(value), MAX(value) FROM data WHERE Timestamp >= [from] AND Timestamp < [to] AND DatapointID = [some ID] GROUP BY 1 

Eu recomendaria a seguinte consulta;

 SELECT TRUNCATE(Timestamp / 3600) AS slot, MIN(value), AVG(value), MAX(value) FROM data WHERE DatapointID = [some ID] AND Timestamp >= [from] AND Timestamp < [to] GROUP BY 1 

Isso ocorre porque DatapointID deve ser um índice. Então, o MySQL pode limitar os registros no id e, em seguida, ver o Timestamp e não pesquisar todos os registros fazer algumas matemáticas e, em seguida, combinar no índice.

Dito sobre o MySQL de volta à sua pergunta sobre o NoSQL.

No ano passado verifiquei CouchDB, MongoDB vs MySQL para o meu estudo. Embora seja um caso de uso total diferente, eu poderia compartilhar alguns dos resultados.

MySQL

  • leia: 8.500 registros / s
  • escreva: 400 registros / s

MongoDB

  • ler: 17.500 registros / s
  • escreva: 13.000 registros / s

CouchDB

  • ler e escrever: 300 registros / s

Então, o CouchDB ficou lento no meu teste. Acabei de inserir registros simples, não tenho o código mais.

Um recurso agradável no MongoDB é que o ID também contém o carimbo de data / hora de quando eles foram criados. Embora seja complicado para quando você deseja usar MongoDB quando você já possui dados.

Também explicado pela consulta MySQL, você precisa de índices para manter sua velocidade alta. Bem, o MongoDB os suporta.

  1. MongoDB tem um equivalente a mysqldump, não sabe o quão rápido é para que você tenha que testar isso com seus próprios dados.
  2. Não tenho certeza sobre este
  3. Definir razoável, mas o MongoDB é 32,5 vezes mais rápido com a escrita do MySQL
  4. Bem, ele tem um driver PHP, então ele tem um driver.

Esperamos que a informação tenha ajudado, também ajuda a tentar alguns dos bancos de dados. Muitas vezes, um dia, apenas brincando com os bancos de dados, você oferece mais informações, depois uma semana lendo sobre eles

editar após o primeiro comentário

A consulta SQL seria semelhante à seguinte no MongoDB.

Usou os seguintes documentos

  • onde os documentos
  • encontrar documentos
  • documentos de agregação
  • documentos de correspondência

Então, com o MongoDB, a consulta tem duas partes, a cláusula where e a agregação.

Em sql, a cláusula where Timestamp >= [from] AND Timestamp < [to] AND DatapointID = [some ID]

O que há em MongoDB é realmente fácil de aprender (eu achei isso fácil) (veja onde documentos e achar documentos para mais informações).

Mas a parte de onde seria

 { DatapointID: ID, Timestamp: {$gte: from}, Timestamp: {$lte: till}, } 

ID , from e till são valores a serem preenchidos!

Então a parte difícil faz a agregação. Mas o inferno há documentos para tornar as coisas um pouco mais fáceis. Então veja documentos de agregação e documentos de correspondência para ver de onde recebi minhas informações.

Mas a function do grupo parecerá algo como o seguinte

 { _id: 1, minValues: {$min: value}, avgValue: {$avg: value}, maxValue: {$max: value}, } 
  • nota: não tenho certeza se _id: 1 funciona, mas caso contrário, você precisa de uma coluna válida

value é um nome de coluna na gravação.

Agora precisamos terminar a consulta. Então você pode executá-lo. Ele vai olhar para o final, então, como o seguinte:

 db.articles.aggregate( { $match : { DatapointID: ID, Timestamp: {$gte: from}, Timestamp: {$lte: till}, } }, { $group: { _id: 1, minValues: {$min: value}, avgValue: {$avg: value}, maxValue: {$max: value}, }} ); 

o código não é testado

Henriq tem excelentes pontos na sua resposta.

Seus números são razoáveis, IMHO, mas exigirá um design e seleção muito cuidadosa das ferramentas. Você não descreveu alguns requisitos críticos sobre f.ex. na área de ACID, e se você não precisa de “The D”, então você está bem seguro com quase qualquer coisa disponível.

Considerando o que você disse, dou alguns comentários:

  • Em vez de deixar o trabalho existente no MySQL, você pode tentar algumas abordagens criativas, como o DB de versão do IMDB, como o IBM SolidDB. Escala muito bem e os backups podem ser muito fáceis com algum design, pois você praticamente pode tirar uma cópia de arquivo para outro sistema sem quebrar o DB (com ACID completo)
  • Minha experiência de No / NewSQL é, naturalmente, limitada a essas situações que eu tive mãos em mim, mas tudo que eu vi suporte sobre as mesmas conclusões:
  • Cassandra é mais previsível em mãos experientes. MongoDB “fora da checkbox” oferece uma ótima promise, mas conseguir a escala pode ser uma dor. Aerospike é uma tecnologia comercial com forte funcionalidade (tem alquimiaDB background). VoltDB / HBase são promissores, mas parecem ter alguns problemas de escalabilidade que não tenho certeza de onde eles estão vindo (não investigado o suficiente).

Talvez você deva ter uma “tabela de requisitos” no lugar para poder decidir o caminho a seguir? Confie em mim, existem grandes diferenças entre as implementações do NoSQL.

Cheers, // Jari