Ola pessoal. Estou levantando os requisitos para a desenvolvimento de um sistema. Esse sistema se divide em 2 partes. Uma delas é um hardware que mandara dados brutos para o banco. Algo em torno de 1 milhão de dados por mês, por usuário e a outra parte é o aplicativo que terá cadastro, login e varias interações. inclusive tratamento e exibição destes dados brutos.
A minha duvida é a seguinte. O aplicativo irá utilizar o sgbd PostgreSql, más a equipe esta em conflito pois para o hardware uma parte da equipe sugere utilizar tudo no postgre e a outra equipe preferem o mongodb. Os dados serão tratados em NodeJs.
Com a experiência de vocês. O que vocês sugerem?
Performance do sistema
7 Respostas
Qual banco usar é um detalhe de implementacao, e não de requisitos.
Está muito vago. Sem os requisitos funcionais fica mais difícil o pessoal aqui analisar. Você também não apresentou as justificativas de cada lado da equipe.
Ok vou detalhar melhor.
O sistema se divide em 2 partes, uma delas será um aplicativo muito parecido com uma rede social e outra ser um hardware que enviara dados brutos em forma de json.
O hardware enviar latitude, longitude e outros dados que irão ser inseridos em uma unica tabela a cada 5 segundos. Em um mes terá mais ou menos 1 milhão de inserções por usuário que utiliza o sistema.
A minha duvida é se eu tenho perda de desempenho utilizando apenas o Postgre ou devo tuilizar um nosql como o MongoDB para os dados brutos e o PostregreSql para o aplicativo.
Uma equipe sugere que se use apenas o Postgree pois ele não sera afetado por essas inserções que terão um tamanho maximo de 80 kbyte. A outra equipe sugere separar pois a longo prazo, algo em torno de 2 anos o Postgre pode perder desempenho e performance.
Eu queria ouvir a opinião do pessoal experiente sobre este assunto. uma resposta simples e objetiva sobre qual escolher e porque.
OBS: Questão da regra de negocio, ignorem. A duvida é se o Postgree aguenta iso tudo ou devo dividir.
Uma inserção a cada 5 segundos são 12 inserções por minuto. Não é pouco, mas tb não é muito, mas provavelmente seu servidor SQL não vai ser usado só pra isso, vc tb vai querer executar queries complexas com muito joins, que é comum em aplicações de redes sociais. Internamente o postgre tb tem outras tarefas pra executar (locking, sincronização, indexação). Eventualmente o banco vai se tornar o gargalo do sistema.
Por outro lado, um sistema monolítico é mais simples do ponto de vista da arquitetura.
sugestão de quem processa 1.5 bilhão de dados por dia: foco na arquitetura.
quando falamos de MongoDB ou PostgreSQL não é apenas a velocidade, mas as consequencias. por exemplo, se vc tiver um cluster PostgreSQL e vc for fazer uma inserção, sob dadas condições vc tem o problema do “two-phase commit” onde rola um lock ate vc inserir o dado em todas as replicas do seu sistema e isso, sob um grande volume de dados por unidade de tempo, pode não ser aceitavel.
como saber se é aceitavel ou não?
-
meça. faça testes de stress. lembre-se que no mundo real existe latencia de rede, existe cache, existe load balance, IO bloqueante, firewalls, etc.
-
monitore. envie dados em real time para algo como ELK ( elasticsearch logstash kibana ), veja se vc pode usar New Relic, tenha logs efetivos, tenha triggers no Zabbix pra caso algo de errado, etc.
meu conselho: começe muito simples. não invente muito no começo.
agora bancos de dados NoSQL tem outras features. Riak, Couchbase, Cassandra, MongoDB vão te dar uma opção complementar no seu sistema, eles vem pra somar. Agora em muitos casos vc tem que fazer escolhas como, por exemplo, optar por consistência eventual ( Teorema CAP https://dzone.com/articles/better-explaining-cap-theorem etc ). Tem que ver se faz sentido no seu modelo, pode ser aceitável, pode ser proibitivo.
focando no seu problema: faz sentido separar as bases de dados sim ( dados do hardware e dados da app ). se vc usar um banco chave-valor e consistencia eventual vc pode escalar de forma simples: quando mais dados, mais instancias vc pode adicionar pra trabalhar em paralelo.
uma coisa que vc pode pensar é se não vale a pena fazer um insert de assincrono. vc pode receber a mensagem e ao inves de inserir vc pode adicionar em uma fila como RabbitMQ. e ai vc pode criar pequenos daemons que consomem da fila e inserem no banco. a vantagem disso é que se rolar uma explosão de dados o backend vai trabalhar no limite e apenas isso, e logo toda a fila sera consumida.
outra coisa interessante é verificar se vc pode rejeitar algumas informações. json com alguns campos repetidos talvez seja desnecessario. vc pode criar um cache no redis com informações e o seu sistema de coleta de dados pode verificar isso pra enviar pra fila ou não. eu tenho casos assim onde um cliente pode enviar 8 vezes o mesmo request por algum motivo doentio, e eu não perco tempo processando coisas reduntantes.
a modelagem de dados vai ser a chave ai. vai ser mais dificil mudar a modelagem do que mudar de mongodb pra outra coisa, por exemplo.
alias se o medo é que o PostgreSQL perca desempenho em 2 anos, nada impede de vc ter 2 databases diferentes ( app e dados vindos do hardware ). no dia que vc começar a ver queda de desempenho vc pode socar um mongoDB ali que vai ser sussa.
Minha experiencia com Riak 1.x : estável, otimo pra ler e escrever, péssimo para apagar (remove), não tem nenhuma feature nativa de expiração , a interface protocol buffers é rapida ( eu mesmo escrevi um driver pra Perl que era o mais rapido disponivel, o Riak::Light ) mas pesquisa por index secundario não era confiavel. Pior, num grande volume de acessos precisava-mos juntar Bloomd + Redis (com uns scripts lua muito loucos) pra fazer um cache aceitavel. Estamos falando de milhões de acessos por hora. não testamos as versões mais novas.
Minha experiencia com MongoDB: versões antigas falhava a escrita e vc não sabia. Um dia apagamos os indexes todos sem querer ( e sem warning ). eu fiquei com má impressão.
Minha experiencia com Couchbase: AMO. muito rapido, principalmente com 10% das chaves em memoria.
Minha experiencia com Redis: AMO. vc pode subir scripts lua e reusar. só lembre-se que tudo fica em memoria. ja usei como fila tambem ( com RPUSH, LPOP ) e funcionou BENZÃO.
Minha experiencia com coleta de dados: coletar deve ser eficiente. não perca tempo processando coisas sem necessidade SE O BIXO ESTIVER PEGANDO. por exemplo ao inves de criar uma servlet que vai receber os dados com um DAO e 99999 classes vc pode ter um PHPZÃO cru que recebe, faz uma checagem basica e envia pra onde for ( fila, banco, etc ). pode ser até codigo lua rodando em um modulo do NginX.
de repente Spark pode ser uma mão na roda
de novo: pense na sua arquitetura. pense em coisas como shared-nothing, escalabilidade, imutabilidade quando fizer sentido. foco em como vc vai escalar as coisas. foco em como vc vai monitorar. como vc vai alarmar caso aconteça X? etc.
Entre essas duas opções, seria mais indicado um banco de dados não relacional mesmo, para lidar com esse cenário de acesso a multidões assíduas por informações imediatas que são mais na linha de informações abertas e não informações críticas transacionais comuns do meio corporativo.
Obrigado!
Sua resposta foi excelente.