Pergunta

Eu tenho um programa que recebe dados em tempo real em 1000 tópicos. Ele recebe - em média - 5000 mensagens por segundo. Cada mensagem consiste de duas cordas, um tópico, e um valor de mensagem. Eu gostaria de salvar essas cordas, juntamente com um timestamp indicando o tempo de chegada da mensagem.

Eu estou usando 32 bits do Windows XP no 'Core 2' hardware e programação em C #.

Eu gostaria de salvar esses dados em 1000 arquivos - um para cada tópico. Sei que muitas pessoas vão querer me dizer para salvar os dados em um banco de dados, mas eu não quero ir por esse caminho.

Eu considerei algumas abordagens:

1) Abra 1000 arquivos e escrever em cada um como os dados chegam. Eu tenho duas preocupações sobre esta. Eu não sei se é possível abrir 1000 arquivos simultaneamente, e eu não sei qual o efeito que isso terá sobre a fragmentação do disco.

2) Escrever em um arquivo e - de alguma forma -. Processá-lo mais tarde para produzir 1000 arquivos

3) Manter tudo na RAM até o final do dia e, em seguida, escrever um arquivo de cada vez. Eu acho que isso iria funcionar bem se eu tiver RAM suficiente embora eu preciso movimentar a 64 bit para superar o limite de 2 GB.

Como você abordar esse problema?

Foi útil?

Solução

Eu concordo com Oliver, mas eu sugiro uma modificação: tem 1000 filas, uma para cada tópico / arquivo. Um segmento recebe as mensagens, timestamps-los, em seguida, fura-los na fila apropriada. O outro simplesmente gira através das filas, ver se eles têm dados. Se assim for, ele lê as mensagens, em seguida, abre o arquivo correspondente e escreve as mensagens para ele. Depois que ele fecha o arquivo, ele se move para a próxima fila. Uma vantagem disso é que você pode adicionar tópicos de escrita de arquivos adicionais se não se pode manter-se com o tráfego. Eu provavelmente primeiro tentar definir um limite de gravação, embora (adiar o processamento de uma fila até que ele tem mensagens N) para lote suas gravações. Dessa forma, você não se atolar abrir e fechar um arquivo para escrever apenas uma ou duas mensagens.

Outras dicas

Eu não posso imaginar por que você não iria querer usar um banco de dados para isso. Isto é o que eles foram construídos para. Eles são bons bastante para ele.

Se você não está disposto a ir por esse caminho, armazená-los na memória RAM e rodando-os para o disco a cada hora pode ser uma opção, mas lembre-se que se você tropeçar no cabo de alimentação, você perdeu uma grande quantidade de dados.

A sério. Banco de Dados-lo.

Editar: Devo acrescentar que a obtenção de uma solução de backup de banco de dados robusto, replicada e completa levaria menos de um dia se você tivesse o hardware pronto para ir.

Fazendo esse nível de proteção de transações em qualquer outro ambiente que vai levá-lo semanas mais tempo para configurar e teste.

Como n8wrl Eu também recomendaria um DB. Mas se você realmente não gosta esse recurso ...

Vamos procurar outra solução; -)

Em uma etapa mínimos eu levaria dois threads. Primeiro é um trabalhador, recebendo todos os dados e colocar cada objeto (timestamp, duas cordas) em uma fila.

Outro segmento irá verificar essa fila (talvez por informações por evento ou, verificando a propriedade Count). Esta discussão vai desenfileirar cada objeto, abra o arquivo específico, anotá-la, feche o arquivo e siga o próximo evento.

Com esta primeira abordagem eu iria começar e dar uma olhada no desempenho. Se é uma porcaria, fazer alguma medição, onde está o problema e tentar realizá-lo (colocar os arquivos abertos em um dicionário (nome, streamWriter), etc).

Mas, por outro lado, uma DB seria tão bem para este problema ... Uma mesa, quatro colunas (id, timestamp, tópico de mensagens), um índice adicional sobre o tema, pronto.

Eu gostaria de explorar um pouco mais por que você não quer perder pitada de usar um DB - eles são grandes em coisas como esta! Mas para as suas opções ...

  1. 1000 identificadores de arquivo aberto não bom som. Esqueça a fragmentação do disco -. O / S recursos vai sugar
  2. Esta é perto de db-ish-ness! Também soa como mais problemas do que vale a pena.
  3. RAM = volátil. Você passar o dia todo acumulação de dados e ter uma queda de energia em 5pm.

Como eu iria abordar isso? DB! Porque então eu pode consultar o índice, analisar, etc. etc.

:)

Em primeiro lugar calcular a largura de banda! 5000 mensagens / seg cada 2kb = 10MB / seg. Cada minuto - 600MB. Bem, você poderia cair que na RAM. Em seguida, lave cada hora.

Edit: erro corrigido. Desculpe, meu mau.

Eu concordo com Kyle e ir com um produto pacote como PI. Esteja ciente de PI é muito caro.

Se você está procurando uma solução personalizada eu iria com Estêvão com algumas modificações. Ter um servidor recebe as mensagens e deixá-los em uma fila. Você não pode usar um arquivo embora a mão fora a mensagem para outro processo, porque o seu vai ter problemas de bloqueio constantemente. Provavelmente usar algo como MSMQ (MS Message Queuing), mas não tenho certeza sobre a velocidade do que isso.

Eu também recomendo o uso de um db para armazenar seus dados. Você vai querer fazer inserções em bloco de dados no db, porém, como eu acho que você iria precisar de algum hardware heafty para permitir SQL fazer fazer 5000 transações por segundo. O seu melhor para fazer um volume inserção cada digamos 10000 mensagens que se acumulam na fila.

Dados TAMANHOS:

50 bytes Média ~ Mensagem -> pequena datetime = 4bytes + Topic (~ 10 caracteres não unicode) = 10bytes + Mensagem -.> 31characters (não Unicode) = 31 bytes

50 * 5000 = 244kb / seg -> 14mb / min -> 858mb / hora

Talvez você não quer que a sobrecarga de um DB instalar?

Nesse caso, você pode tentar um banco de dados com base filesystem-like sqlite:

SQLite é uma biblioteca de software que implementa um auto-contido, serverless, com configuração zero, motor de banco de dados SQL transacional. SQLite é o SQL mais amplamente implantada motor de banco de dados no mundo. o código-fonte para SQLite está no domínio público.

Gostaria de fazer 2 programas distintos: um para tomar as solicitações de entrada, formatá-los e gravá-los para um único arquivo, e outro para ler a partir desse ficheiro e escrever os pedidos de fora. Fazendo as coisas desta forma permite que você minimizar o número de identificadores de arquivo aberto e ainda lidar com as solicitações recebidas em tempo real. Se você fizer o primeiro formato de programa a sua saída corretamente, em seguida, processá-lo para os arquivos individuais devem ser simples.

Eu manteria um buffer das mensagens recebidas, e periodicamente escreve os 1000 arquivos sequencialmente em um segmento separado.

Gostaria de olhar para a compra de um pacote historiador de dados em tempo real. Algo como um historiador PI System ou dados Wonderware. Tentei coisas como esta em arquivos e um banco de dados MS SQL antes e ele não saiu bom (Era uma exigência do cliente e eu não sugerir). Estes produtos têm API de e eles ainda têm pacotes onde você pode fazer consultas aos dados como se fosse SQL.

Não me permitiria postar hiperlinks para apenas google esses 2 produtos e você vai encontrar informações sobre eles.

Editar

Se você usar um banco de dados como a maioria das pessoas estão sugerindo que eu recomendaria uma tabela para cada tópico para dados históricos e considerar particionamento de tabelas, índices, e quanto tempo você está indo para armazenar os dados.

Por exemplo, se você está indo para armazenar um valor de dias e sua tabela um para cada tópico, você está olhando para 5 atualizações por segundo x 60 segundos em um minuto x 60 minutos em uma hora x 24 horas = 432000 registros por dia . Depois de exportar os dados Imagino que você teria que limpar os dados para o dia seguinte que irá causar um bloqueio para que você terá que ficar na fila que você escreve para o banco de dados. Então, se você estiver indo para reconstruir o índice de modo que você pode fazer qualquer consulta sobre ele que irá causar um bloqueio de modificação de esquema e MS SQL Enterprise Edition para a reconstrução de índice online. Se você não limpar os dados todos os dias você terá que certificar-se de que você tem a abundância de espaço em disco para jogar nele.

Basicamente o que eu estou dizendo que pesar o custo da compra de um produto confiável contra a construção de seu próprio país.

Se você não quiser usar um banco de dados (e eu o faria, mas supondo que você não), eu ia escrever os registros em um único arquivo, operações de anexação são rápidos quanto eles podem ser, e usar um separado processo / serviço para dividir o arquivo para os 1000 arquivos. Você poderia até mesmo roll-over o arquivo a cada X minutos, de modo que, por exemplo, a cada 15 minutos você começa um novo arquivo e outro processo começa dividindo-os em 1000 arquivos separados.

Tudo isso levanta a questão de por que não um DB, e por que você precisa 1000 arquivos diferentes - você pode ter uma razão muito boa - mas, novamente, talvez você deve repensar você estratégia e ter certeza que é som raciocínio antes de ir para longe por este caminho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top