Armazenando grandes quantidades de dados de uma matriz de sensores

14

Fui encarregado de implementar uma solução (app e db) para armazenar as amostras de dados de uma enorme variedade de sensores. Atualmente, a matriz consiste em cerca de 20.000 sensores, mas que em breve crescerá, até 100.000 sensores. Cada sensor envia uma amostra de dados a cada 10 segundos e cada amostra tem 28 bytes de tamanho.

Fazer as somas leva a:

  • 8640 amostras por sensor por dia
  • 242kB de dados por sensor por dia
  • 864 milhões de amostras por dia

Agora eu estava me perguntando qual seria a melhor maneira de armazenar / recuperar os dados? Entrei neste projeto depois que o software já foi especificado, portanto ele precisa ser implementado em uma plataforma Windows usando o SQL Server.

A solução atual em minha cabeça é criar um banco de dados com duas tabelas para armazenar as amostras de dados. O primeiro serve como uma espécie de índice para o segundo que armazena as amostras agrupadas em um campo binário por dia por sensor:

Table 1:

  RecordID - BigInt - Identity
  SensorID - BigInt - Primary Key
  Date - DateTime - Primary Key (yyyy-mm-dd)

Table 2:

  RecordID - BigInt - Primary Key (from an insert into Table 1)
  Data - Binary 

Basicamente, escreverei as amostras de todos os sensores em arquivos temporários (1 por sensor). No final de cada dia, criarei uma entrada na Tabela 1, use o RecordID gerado e despejo do arquivo no campo Dados da Tabela 2.

Dessa forma, acabo com apenas 100.000 entradas na tabela por dia, em vez de 864 milhões de entradas. Os dados devem estar disponíveis na LAN ou WAN de alta velocidade, portanto, a recuperação dos dados do sensor em um dia inteiro seria aceitável.

Embora todos os dados precisem ser armazenados, a maioria provavelmente nunca será lida. Portanto, a quantidade de leituras nas tabelas não será muito maior do que as gravações.

Eu sei que eu poderia implementar algo usando o sistema de arquivos apenas armazenando o caminho para os arquivos de dados, mas li que o SQL Server supera o NTFS enquanto seus campos binários são menos agradecidos a 256kB. (Existe uma área cinza entre 256kB e 1 MB, enquanto o NTFS supera em muito o SQL Server para tamanhos binários> 1 MB).

Também tenho um pouco de cautela em armazenar dados de 100.000 sensores em seus próprios arquivos sem causar problemas no sistema de arquivos, pois possui grandes quantidades de arquivos em uma pasta ou uma estrutura em árvore complexa com alguns arquivos em cada pasta, enquanto não mesmo levando em consideração a fragmentação do arquivo.

  1. Alguém pode me oferecer alguns conselhos práticos / comentários sobre o exposto?

  2. Existem armadilhas óbvias nas quais vou cair?

  3. Os dados de amostra são compactados bastante bem. Um arquivo de 242 kB é compactado para cerca de 85 kB. No entanto, posso implementar algum tipo de compactação no nível do banco de dados para que os dados de amostra (coluna) sejam compactados automaticamente?

  4. O SQL Server é uma escolha obviamente errada para este projeto?

  5. O meu design das duas tabelas é sábio ou seria possível combiná-lo em uma única tabela que ainda será tão "eficiente" quanto as duas tabelas?

Oliver
fonte
5
O SQL Server oferece suporte à compactação no nível da linha e da tabela para coisas como esta.
JNK
2
Como há apenas 1 entrada / sensor / dia, você precisa da Tabela1?
GalacticJello
2
O que você planeja fazer com esses dados, uma vez que estão no banco de dados? Não consigo imaginar poder agregar dados do sensor em um formato binário, pelo menos não fácil ou rapidamente nesses níveis.
datagod
1
100.000 sensores X 10 amostras por segundo X 28Bytes por amostra x 24 horas por dia = 2,2 TB por dia. Isso é muito para colocar em duas tabelas.
datagod
2
@AlexKuznetsov: Fiquei pensando na escolha do SQL Server, mas eles são parceiros de ouro da Microsoft, então acho que esse é o principal motivo.
Oliver

Respostas:

12

Sim, existe uma grande armadilha na qual você encontrará rapidamente, e isso é com o tamanho e a manutenção das tabelas. Você está no caminho certo dizendo que deseja colocar seus dados em uma tabela temporária diariamente e depois movê-los para sua tabela permanente, mas em breve terá problemas com esse esquema.

Por exemplo, digamos que você queira "lançar" os dados do mês mais antigo depois de dois anos. No seu design, você precisaria emitir uma instrução DELETE em sua grande e grande mesa. Isso provavelmente será um pouco lento, dependendo do número de índices que você possui. Além disso, causará fragmentação do índice e a única maneira de corrigir isso seria reconstruir ou reorganizar os índices nessa tabela muito grande, o que também causaria problemas de desempenho. Há uma série de outras questões com um grande design de tipo de tabela única. Por exemplo, com uma tabela grande e única, você não pode fazer backups baseados em FILEGROUP , o que significa que, se você quiser ter um backup completo do seu banco de dados, será GRANDE e demorará muito tempo para concluir.

Qual a solução? Particionamento de tabela. Leia sobre isso em profundidade, em todos os lugares que puder. Basicamente, o particionamento permite que você divida seus dados em "tabelas dentro de tabelas" - cada partição compartilha o mesmo esquema e é acessada através do objeto de tabela, mas pode ser indexada e mantida de forma diferente. Partições são basicamente tabelas, cortadas por alguma tecla útil. No seu caso, provavelmente será a data. Eles podem ser eliminados da mesma forma que as tabelas (e tão rapidamente quanto), o que significa que, se você particionar suas tabelas de big data por data, poderá simplesmente soltar partições antigas instantaneamente, sem nenhum efeito adverso nos índices de qualquer outra partição. Você pode colocar partições em diferentes grupos de arquivos, o que significa que as partições mais antigas podem ser retiradas ou transferidas para um armazenamento mais barato, se não for usado com frequência. Por último, mas não menos importante, no SQL 2012 vocênas partições antigas, somente leitura , enquanto possui um esquema de indexação diferente e mais orientado a inserção na partição ativa em que você está inserindo todos os dados do sensor.

Espero que isto ajude. Você tem uma boa quantidade de pesquisa a fazer sobre particionamento e esquemas de particionamento, mas espero que agora você saiba a direção que precisa seguir.

PS: Ah, e eu esqueci sua lista de perguntas com marcadores ... Respostas 1, 2 e 5. Veja acima. Resposta 3: No SQL Server, você pode compactar partições por partição; portanto, compactar agressivamente as partições antigas usando a compactação PAGE. Mas acredito que seus tipos de dados grandes fora da linha não serão compactados se você fizer isso. Novamente, você pode aliviar esse problema normalizando os valores do sensor. Resposta 4: Absolutamente não, mas se tudo o que você deseja fazer é armazenar dados estáticos por dia e nunca procurá-los de outra maneira, os arquivos simples compactados podem ser um caminho muito mais fácil.

PPS: Ah, e outra coisa. Você não precisa da sua solução de duas mesas para fazer tudo isso funcionar. Dados grandes de sensores binários devem ser do tipo VARBINARY (MAX) porque seus valores podem ser armazenados " fora da linha ", mas ainda assim podem ser uma coluna em uma única tabela (consulte a documentação sp_tableoption ). Você pode considerar a normalização de alguns dos seus dados de sensor a partir dos dados binários que você possui na tabela, porque seu banco de dados não será bom para muito além da recuperação de blocos de dados de sensor por tempo, se você não o fizer.

Dave Markle
fonte
Informação impressionante, obrigado. Não tenho muita certeza do que você quer dizer com "normalizar" neste caso. Suponho, porém, que você queira dizer que eu deveria extrair alguns dos campos mais úteis nos blocos de dados e armazená-los em suas próprias colunas. Nesse caso, o motivo de eu não querer fazer isso inicialmente é que isso significa que vou terminar com 864 milhões de linhas por dia. Agrupar tudo e armazená-lo em um pedaço significa apenas 100.000 linhas por dia. Ou há um jeito melhor ?
Oliver
1
Se você estiver usando um banco de dados, sim, é exatamente isso que eu quero dizer. 864 milhões de linhas por dia podem ser tratadas com eficiência se você tiver o hardware, o esquema de indexação e o particionamento certos para fazê-lo funcionar. Tudo depende do que realmente são seus requisitos e por que você está armazenando todos esses dados. Se for apenas para fins de arquivamento, a coluna binária está correta. Se você deseja extrair valor comercial usando o SQL Server, é uma história completamente diferente.
Dave Markle
0

Considere uma solução Hadoop. 2 Tb / dia aumenta rapidamente. Considere também registrar apenas registros delta, ou seja, um valor inicial, e somente quando ocorrer uma alteração.

Carter Shore
fonte