Eu preciso criar uma solução altamente escalável - onde os dispositivos de campo em milhares de sites estão fornecendo dados em tempo real para um sistema de back-end, e o SQL Azure parece se encaixar perfeitamente em termos de adição de bancos de dados SQL e servidores de aplicativos.
Cada dispositivo de campo está efetivamente enviando 400 valores de sensor a cada segundo - por cerca de duas horas por dia, e esses 400 valores de sensor a cada 5 minutos para todas as outras vezes para sempre. Além disso, quando ocorre um erro neste dispositivo de campo, ele também envia os dados de última hora para todos os 400 sensores (400 * 60 leituras) - causando uma inundação em massa de dados quando algo dá errado.
Eu realmente quero projetar o sistema de forma que os dispositivos de campo independentes e os dados que eles armazenam não possam afetar outros dispositivos. Permitir que cada dispositivo de campo não afete o desempenho de outros dispositivos de campo.
Comecei o projeto pensando em um único banco de dados contendo todos os dados do dispositivo - mas comecei a obter impasses ao simular vários dispositivos do site. Portanto, estou no processo de mudança para uma solução de vários bancos de dados. Onde um banco de dados mestre contém uma tabela de pesquisa para todos os dispositivos - retornando uma string de conexão para o banco de dados real
Nesta fase do projeto, é mais importante que eu seja capaz de passar esses dados de volta para interfaces de usuário em execução em navegadores da web em tempo real - atualizando suas telas a cada segundo.
Em estágios futuros do projeto, será necessário começar a agregar dados em vários dispositivos mostrando estatísticas como a soma do sensor X na região Y. Posso ver que isso será difícil de fazer com a abordagem de vários bancos de dados.
Então, valeria qualquer conselho, por exemplo
Você acha sensato usar Sql Azure para hospedar potencialmente 1000 bancos de dados e usar esse banco de dados mestre para apontar indiretamente para os reais?
Terei problemas com as conexões com os bancos de dados dos aplicativos - com problemas com o pool de conexões, por exemplo?
Como poderei agregar dados de todos esses diferentes bancos de dados no Sql Azure.
Estaria interessado em todos os seus comentários. Atenciosamente, Cris.
Como ninguém mais respondeu, vou compartilhar algumas opiniões e fazer alguns acenos de mão.
Contanto que você não esteja bloqueando recursos comuns ou bloqueando recursos na mesma ordem, não deverá ter problemas com impasses.
Eu olharia para tabelas separadas antes de bancos de dados separados. Cada banco de dados adicional definitivamente custará mais, mas tabelas adicionais não necessariamente custarão mais. Pode ser necessário usar mais de 1 banco de dados devido ao grande volume de dados que você armazenará ou devido à taxa na qual você precisa armazenar seu tráfego de rajada. Se você puder gerenciá-lo, acho que uma granularidade em nível de tabela será mais flexível e possivelmente muito mais barata do que começar com uma granularidade em nível de banco de dados.
O problema de colocar os dados de cada dispositivo em suas próprias tabelas é que isso dificulta o relatório, pois todos os nomes das tabelas serão diferentes.
Presumo que você tenha alguma maneira de detectar quando receber uma "falha no reenvio" dos dados. Você não deseja colocar o mesmo valor em uma tabela duas vezes e tenho certeza de que os dispositivos podem falhar (falha de energia local?) De maneiras que não têm nada a ver com o fato de os valores anteriores terem sido armazenados corretamente ou não.
WAG: Supondo que cada "valor" seja de 4 bytes, calculei cerca de 11,5 MB de dados coletados por dispositivo, por dia. (Isso ignora todos os tipos de coisas, como identificadores de dispositivos e carimbos de data/hora, mas acho que é uma estimativa aproximada.) Portanto, com "milhares" de sites, estamos analisando dezenas de GB por dia. Você não menciona nenhum tipo de tempo de vida nesses dados. O maior banco de dados do Azure atualmente atinge o máximo de 150 GB. Você poderia preenchê-los rapidamente.
Conseguir que algo aconteça em um navegador da Web em um curto período de tempo é duvidoso. Quando você está lendo (possivelmente vários) bancos de dados com GBs de dados, inserindo continuamente muitos novos dados nas tabelas que está lendo e interagindo com servidores da Web na Internet aberta, "tempo real" é uma ilusão. IMO. "Rápido o suficiente" é o objetivo usual.
Se você não conseguir manter todos os dados necessários em um único relatório em um banco de dados do SQL Azure, isso é um problema. Não há servidores vinculados ou exibições distribuídas (neste ponto). Não há uma maneira simples de agregar vários bancos de dados do Azure. Você teria que puxar todos os dados para um local central e relatar a partir daí. Eu acho que os dados agregados seriam muito grandes para armazenar em um único banco de dados do SQL Azure, então você teria que ir para o local ou talvez EC2. Um data mart ou warehouse com uma estrutura de esquema em estrela seria a resposta clássica, mas isso leva um tempo de processamento significativo e isso significa que não há "tempo real". Além disso, é potencialmente muito mais transferência de dados do Azure para onde quer que vá, e isso vai custar caro.
Eu não me comprometeria com essa estratégia sem um programa piloto primeiro. A primeira coisa a fazer seria construir uma única instância (ela pode lidar com 400 valores de sensor por segundo? (Isso é uma série de linhas, uma grande linha desnormalizada, um documento XML ou outra coisa? O formato dos dados recebidos afetará com que rapidez os dados podem ser armazenados. Você pode fazer inserções em massa ou precisa ser linha por linha?) Que tal 4.000 valores de sensor por segundo? É possível que uma única instância do SQL Azure não consiga armazenar isso muito rapidamente.) e veja como ele lida com as inserções nas taxas esperadas e veja como os relatórios podem funcionar. E eu falaria com a Microsoft também. Apenas lidar com o faturamento de centenas ou milhares de bancos de dados separados pode ser peculiar.
Não sei se isso se aplica a você, mas você já deu uma olhada no produto "Stream Insight" da Microsoft ? Parece ser destinado a situações como a sua. Ressalva: nunca usei.
A sinopse de marketing: analise com eficiência grandes quantidades de dados de eventos transmitidos de várias fontes. Obtenha insights de informações críticas quase em tempo real usando o Microsoft StreamInsight. Monitore, analise e atue em dados em movimento e tome decisões informadas quase que instantaneamente
Ao pesquisar rapidamente no Google, notei uma postagem no blog que afirma que o StreamInsight está disponível no SQL Azure como um CTP no ano passado. pode estar pronto para o horário nobre agora.
Boa sorte, parece um projeto interessante.
Pensei em postar uma resposta rápida sobre como o projeto realmente funcionou.
No final, não usamos o Azure. Usamos um servidor de banco de dados SQL padrão - com cada mecanismo em um banco de dados diferente. Em teoria, um banco de dados mestre contém as informações de conexão para cada mecanismo. Portanto, é possível armazenar diferentes mecanismos em diferentes servidores de banco de dados. Na prática, ainda não precisamos. Temos 200 bancos de dados de motores em uma máquina no momento. Eu uso o pool de conexões.
Os 400 sensores que chegam por segundo por engine, foram enviados em XML, convertidos em DataTable e batch inseridos no banco de dados SQL usando um tipo de dados customizado. Inserir 400 registros a cada segundo leva apenas 40ms - 70ms. Eu faço uma junção externa no conjunto de dados existente para lidar com a ocasião em que os dados existentes são reenviados.
O sistema foi escrito de tal forma que cada motor não deveria, em teoria, desacelerar o motor do outro. Cada mecanismo é efetivamente gerenciado dentro de seu próprio pool de threads. Esses conjuntos de encadeamentos podem existir em diferentes servidores. A escrita no banco de dados e a atualização de cada interface do usuário (navegador da web) eram feitas em threads separadas para que o usuário nunca tivesse que esperar que o banco de dados terminasse de inserir.
Estamos em uma posição agora, onde estamos prontos para levar esse conceito para o Azure. Não parece que haja tantas restrições no Azure agora quanto havia no momento da escrita.
Não tenho experiência com sistemas desse tipo, mas minha sugestão foi mais longa que um comentário então vou postar como resposta...
Você diz "enviando 400 valores de sensor a cada segundo". Isso significa 400 mensagens separadas por segundo e eu diria que cada mensagem aciona uma instrução INSERT separada? Em caso afirmativo, você poderia pegar todos esses dados, envolvê-los em uma única mensagem XML e enviá-los para um serviço da Web que armazenará essas mensagens recebidas em uma tabela/fila de retenção temporária e, em seguida, desmontá-los e processá-los como uma etapa separada? Isso pode resultar em um processamento um pouco mais lento, mas também pode ajudar a aliviar o problema de impasse sem a necessidade de recorrer a vários bancos de dados, pois nesse cenário, você tem um processo que gerencia todas as inserções de dados no banco de dados. Usamos filas de mensagens e serviços da Web para fins semelhantes aqui, embora não cheguemos nem perto desse tipo de volume.