Eu tenho um aplicativo que gerou uma discussão bastante acalorada entre alguns desenvolvedores.
Basicamente, é dividido em uma camada da web e uma camada de back-end. A camada da web coleta informações por um formulário da web simples, armazena esses dados como um documento JSON (literalmente, um arquivo .json) em uma pasta monitorada usada pelo back-end. O back-end pesquisa esta pasta a cada poucos segundos, pega o arquivo e executa suas funções.
Os arquivos em si são muito simples (ou seja, todos os dados da string, sem aninhamento) e cerca de 1-2k no máximo, com o sistema passando a maior parte do tempo ocioso (mas com até 100 mensagens a qualquer momento). A etapa de processamento de back-end leva cerca de 10 minutos por mensagem.
O argumento surge quando um desenvolvedor sugere que usar o sistema de arquivos como uma camada de mensagens é uma solução ruim, quando algo como um banco de dados relacional (MySQL), banco de dados noSQL (Redis) ou mesmo uma chamada simples à API REST deve ser usado.
Deve-se observar que o Redis é usado em outra parte da organização para o tratamento de mensagens na fila.
Os argumentos que ouvi foram detalhados da seguinte maneira
A favor de arquivos simples:
Os arquivos simples são mais confiáveis do que qualquer outra solução, já que o arquivo é movido apenas de uma pasta "watch" para uma pasta "processing" após a coleta e, finalmente, para uma pasta "done" quando terminar. Não há risco de mensagens desaparecerem, salvo erros de nível muito baixo, o que quebraria outras coisas de qualquer maneira.
Arquivos simples requerem menos sofisticação técnica para entender - apenas
cat
isso. Não há consultas a serem escritas, não há risco de sair acidentalmente da mensagem e deixá-la para sempre.O código de gerenciamento de arquivos é mais simples que as APIs do banco de dados do ponto de vista da programação, pois faz parte da biblioteca padrão de todos os idiomas. Isso reduz a complexidade geral da base de códigos e a quantidade de código de terceiros que deve ser trazido.
O princípio YAGNI declara que os arquivos simples funcionam muito bem no momento, não há necessidade demonstrada de mudar para uma solução mais complicada, então deixe-o.
A favor de um banco de dados:
É mais fácil dimensionar um banco de dados do que um diretório cheio de arquivos
Arquivos simples correm o risco de alguém copiar um arquivo "concluído" de volta para o diretório "watch". Devido à natureza desse aplicativo (gerenciamento de máquina virtual), isso pode resultar em perda de dados catastrófica.
Exigir mais sofisticação técnica para o T / S, o aplicativo significa que é menos provável que uma equipe sem instrução estrague tudo apenas cutucando as coisas.
O código de conexão do banco de dados, especialmente para algo como Redis, é pelo menos tão robusto quanto as funções de gerenciamento de arquivos de biblioteca padrão.
O código de conexão do banco de dados é visivelmente (se não funcionalmente) mais simples do ponto de vista do desenvolvedor, já que é mais alto que a manipulação de arquivos.
Pelo que posso ver, os dois desenvolvedores têm muitos pontos válidos.
Então, dessas duas pessoas, o desenvolvedor de arquivos profissionais ou o desenvolvedor de bancos de dados, qual está mais de acordo com as melhores práticas de engenharia de software e por quê?
Respostas:
Mudar para uma solução envolvendo bancos de dados ou sistemas de filas mencionados por Ewan
A movimentação / renomeação de arquivos em um único volume é garantida como atômica em todos os sistemas operacionais atuais, quaisquer que sejam suas dificuldades com relação a coisas como bloqueio de arquivos / registros. O gerenciamento de direitos no nível do sistema operacional deve ser suficiente para bloquear os não-lavados e impedir a manipulação indevida / acidental por operadores autorizados (admins / devs). Portanto, os bancos de dados não têm nada a oferecer, desde que o desempenho da solução atual seja satisfatório.
Em nossa empresa, usamos interfaces semelhantes baseadas em arquivos há décadas com grande sucesso. Muitas outras coisas aconteceram, mas essas interfaces permaneceram por causa de sua total simplicidade, confiabilidade e acoplamentos / dependências mínimos.
fonte
Não acho que nenhuma das soluções seja uma má prática, por isso é difícil responder qual é a melhor prática.
Não acredito que o diretor do YAGNI se aplique aqui se você estiver lidando com escala. "Trabalhar" é relativo, se você tem um forte potencial de perda de dados catastrófica e pouca capacidade de escalar, eu realmente não consideraria esse trabalho. Não sei exatamente a escala com a qual você está lidando, mas se você tiver uma quantidade enorme dessas entradas, será mais difícil para cada uma delas mudar para um novo sistema. Portanto, se esse for o caso, eu diria que um banco de dados é uma prática recomendada.
MongoDB ou redis (eu não tenho experiência com redis, leia apenas coisas boas) deve funcionar bem, pois seus dados já devem se encaixar muito bem nele (documentos json geralmente são alterados trivialmente para documentos BSON para MongoDB). Também possui uma vantagem adicional de manter muitos dados na memória, em vez de possíveis leituras / gravações freqüentes no disco o tempo todo. Também garante que as leituras / gravações simultâneas não levem a corrupção ou bloqueio.
Se o principal do YAGNI se aplicar aqui e os arquivos não forem um gargalo, eles escalam dentro do escopo e não têm problemas catastróficos, eu diria que manter os arquivos é uma "prática recomendada". Não há razão para mudar nada, se não houver problemas, talvez escreva alguns testes, enfatize e veja onde estão seus limites e gargalos.
Não tenho certeza se um banco de dados é a solução neste contexto de qualquer maneira. Se você está se comunicando com coisas no mesmo servidor, algum tipo de IPC pode ser feito, não?
fonte
Enquanto o bom é salvar um arquivo e copiá-lo para um diretório pronto, é um grampo de muitas camadas de comunicação, especialmente. com sistemas de quadros principais mais antigos e similares. Os caras 'anti' têm razão; na medida em que tem muitos problemas e casos extremos. É difícil lidar com isso se você precisar de 100% de confiabilidade e ocorrer com mais frequência à medida que aumenta a frequência e o volume dos arquivos.
Se você controlar os dois lados da transação, sugiro que você analise alguns dos muitos sistemas simples de filas disponíveis. ZeroMQ, RabbitMQ, MSMQ etc em vez de um banco de dados. Mas como você sugere, se não estiver quebrado ...
fonte
A solução de banco de dados é a correta. Ele resolve muita dependência de um host específico ou de condições de contorno.
Ambas são soluções semelhantes, exceto que o banco de dados não está hospedado em um host específico. Isso elimina os problemas de firewall / acesso ao sistema unix. Tivemos casos de exclusão "acidental" em sistemas de arquivos e ninguém para culpar.
Com o banco de dados, você também pode ter o mesmo problema, mas pode ativar a auditoria ou inserir apenas lógica para se livrar das exclusões.
Também no sistema de arquivos, se você precisar colocar o aplicativo no nome do arquivo, por exemplo, OASIS, será necessário criar os arquivos OASIS.john_doe.system1.20160202. Isso se torna tedioso e pode ser representado mais facilmente no banco de dados. Você pode até ter campos nulos no banco de dados e na lógica com base nesse
Também é fácil atualizar bancos de dados, em vez de um diretório de arquivos inteiro, no caso de quaisquer correções ou correções que você queira fazer nas tabelas. Claro que você pode fazer isso no sistema de arquivos, mas a atualização do banco de dados é mais intuitiva.
Por exemplo, você deseja executar novamente, mas com um sistema diferente do OASIS, diga DESERT e john_doe para doe_smith e data de 20160101 a 20151231
Fácil de gerar linhas para DESERT / doe_smith / 20151231 a partir do conjunto original, em vez de criar esses arquivos com shell script.
Portanto, pela legibilidade, a solução de banco de dados do ponto de vista da extensão é melhor.
fonte