Talvez eu não consiga dar o título certo para a pergunta. Mas aqui está,
Estamos desenvolvendo um portal financeiro para gerenciamento de patrimônio. Esperamos que mais de 10000 clientes usem o aplicativo. O portal calcula várias análises de desempenho com base na análise técnica do mercado de ações.
Desenvolvemos muitas das funcionalidades por meio de procedimentos armazenados, funções definidas pelo usuário, gatilhos etc. por meio do banco de dados. Pensamos que poderíamos obter um grande aumento de desempenho fazendo coisas diretamente no banco de dados do que através do código C #. Na verdade, conseguimos um enorme aumento de desempenho.
Quando tentei me gabar da conquista do nosso CTO, ele questionou minha decisão de ter a funcionalidade implementada no banco de dados, e não no código. Segundo ele, essas aplicações sofrem problemas de escalabilidade. Nas palavras dele: "Atualmente, as coisas são mantidas na memória / cache. É difícil gerenciar dados em cluster ao longo do tempo. Facebook, Google não tem nada no banco de dados. É a era dos servidores thin e dos clientes grossos. O banco de dados é usado apenas para armazenar dados simples e a funcionalidade deve ser completamente dissociada do banco de dados ".
Vocês podem me dar algumas sugestões sobre se o que ele diz está certo. Como projetar um aplicativo desse tipo?
fonte
Respostas:
Em suma, eu concordo com o seu CTO. Você provavelmente ganhou algum desempenho às custas da escalabilidade (se esses termos forem confusos, esclareceremos abaixo). Minhas duas maiores preocupações seriam a manutenção e a falta de opções para escalar horizontalmente (supondo que você precise disso).
Proximidade dos dados: vamos dar um passo atrás. Existem algumas boas razões para inserir código em um banco de dados. Eu argumentaria que o maior deles seria a proximidade com os dados - por exemplo, se você espera que um cálculo retorne um punhado de valores, mas essas são agregações de milhões de registros, enviando milhões de registros (sob demanda) a rede a ser agregada em outro lugar é um grande desperdício e pode matar facilmente o seu sistema. Dito isso, é possível alcançar essa proximidade de dados de outras maneiras, essencialmente usando caches ou bancos de dados de análise nos quais parte da agregação é feita antecipadamente.
Desempenho do código no banco de dados:Efeitos de desempenho secundários, como "armazenamento em cache de planos de execução", são mais difíceis de argumentar. Às vezes, os planos de execução em cache podem ser uma coisa muito negativa, se o plano de execução errado foi armazenado em cache. Dependendo do seu RDBMS, você pode tirar o máximo proveito disso, mas na maioria dos casos não obterá muito mais do SQL parametrizado (esses planos geralmente também são armazenados em cache). Eu também argumentaria que a maioria das linguagens compiladas ou JIT 'normalmente apresentam desempenho melhor que seus equivalentes SQL (como T-SQL ou PL / SQL) para operações básicas e programação não relacional (manipulação de strings, loops etc.), portanto, você não não estará perdendo nada lá, se você usou algo como Java ou C # para fazer o processamento de números. A otimização refinada também é bastante difícil - no banco de dados, você muitas vezes é preso a uma árvore B genérica (índice) como sua única estrutura de dados. Para ser justo, uma análise completa, incluindo coisas como transações mais demoradas, escalação de bloqueios, etc., pode encher livros.
Manutenção: SQL é uma linguagem maravilhosa para o que foi projetado para fazer. Não tenho certeza se é um ótimo ajuste para a lógica do aplicativo. A maioria das ferramentas e práticas que tornam nossa vida suportável (TDD, refatoração etc.) é difícil de aplicar à programação de banco de dados.
Desempenho versus escalabilidade:Para esclarecer esses termos, quero dizer o seguinte: desempenho é a rapidez com que você esperaria que uma única solicitação passasse pelo seu sistema (e retorne ao usuário), assumindo, por um momento, pouca carga. Geralmente, isso é limitado por fatores como o número de camadas físicas pelas quais passa, quão otimizadas são essas camadas, etc. Escalabilidade é como o desempenho muda com o aumento do número de usuários / carga. Você pode ter desempenho médio / baixo (digamos, 5 segundos ou mais para uma solicitação), mas uma escalabilidade incrível (capaz de suportar milhões de usuários). No seu caso, você provavelmente terá um bom desempenho, mas sua escalabilidade será limitada pelo tamanho do servidor que você pode construir fisicamente. Em algum momento, você atingirá esse limite e será forçado a recorrer a coisas como sharding, que podem não ser possíveis, dependendo da natureza do aplicativo.
Otimização prematura: acho que você cometeu o erro de otimizar prematuramente. Como outros já apontaram, você realmente não tem medições mostrando como as outras abordagens funcionariam. Bem, nem sempre podemos criar protótipos em larga escala para provar ou refutar uma teoria ... Mas, em geral, eu sempre hesitaria em escolher uma abordagem que negocie a capacidade de manutenção (provavelmente a qualidade mais importante de um aplicativo) para desempenho .
EDIT: Em uma nota positiva, a escala vertical pode se estender bastante em alguns casos. Até onde eu sei, o SO funcionou em um único servidor por algum tempo. Não tenho certeza de como ele corresponde aos seus 10.000 usuários (acho que depende da natureza do que eles estão fazendo no seu sistema), mas dá uma idéia do que pode ser feito (na verdade, existem exemplos mais impressionantes, esse é apenas um popular que as pessoas podem entender facilmente).
EDIÇÃO 2: Para esclarecer e comentar algumas coisas levantadas em outros lugares:
fonte
A escalabilidade não tem nada a ver com a localização dos dados ou como a computação acontece. A escalabilidade é sobre como você gerencia o estado global e a interdependência de dados. Se sua arquitetura é complicada com todos os tipos de interdependências de dados, não importa onde você coloca o código para transformar esses dados. As interdependências vão forçar sua mão e reduzir qualquer potencial de escalar coisas. Se, por outro lado, seus dados estiverem fracamente acoplados e houver muito pouco ou nenhum estado global, mais uma vez, não importa onde o cálculo ocorre. Escalar as coisas será muito mais fácil.
Não tenho certeza de onde seu CTO está obtendo informações sobre problemas de escalabilidade, mas pelo que você disse, não parece que ele tenha motivos reais para questionar a decisão arquitetural atual, além das tendências de moda de software. Basear decisões arquitetônicas nessas tendências geralmente é uma má idéia.
fonte
Scalability is all about how you manage global state and data inter-dependence.
Eu acho que você precisa definir uma referência de desempenho e começar a construir seu protótipo primeiro. Manter toda a lógica no DB é uma velha escola (imho, não tenho nada contra) de lidar com a arquitetura cliente-servidor. Embora tenha suas vantagens, há várias desvantagens que precisam ser consideradas.
A abordagem usual para esse tipo de aplicações vendáveis é feita através da SOA . Porque, a longo prazo, essa é a maneira mais fácil de adicionar novos aplicativos clientes ao seu projeto.
Você também mencionou gatilhos. O uso do gatilho pode se tornar uma grande armadilha mais tarde no ciclo de vida de suporte do aplicativo, eu tomaria o dobro de cuidado com ele e tentaria pular seu uso.
fonte
Seu CTO está 100% errado.
Seus números financeiros devem somar sempre. Isso significa que você precisa que o ACID e o banco de dados relacional sejam o melhor lugar para garantir isso. Os ganhos de desempenho do NoSql DB geralmente são pagos pelo ACID e isso é bom para o Google e o Facebook, mas NÃO para um sistema que contém informações financeiras.
Dizer que o C # tem um desempenho melhor que o código SQL também é idiotice…
fonte
Sempre que alguém menciona escalabilidade e Google / Facebook / Twitter / etc, é um arenque vermelho. A menos que você esteja fornecendo essencialmente o mesmo serviço, o que funciona para eles pode não ser apropriado para você. Em geral, se você pode escalar de uma única máquina para um cluster de oito máquinas, provavelmente já cobriu todas as suas bases. A menos que você tenha um requisito comercial difícil de atender a 20 milhões de visualizações de página por dia, não se preocupe com o aumento de escala. Faça o que faz sentido para os requisitos reais do seu aplicativo e se preocupe com a expansão quando isso se tornar óbvio. E não se esqueça, a maioria dos servidores de banco de dados também pode ser agrupada em cluster, apenas porque está tudo em um banco de dados não significa que esteja em um servidor.
fonte