Características de um sistema de dados
Tags: database, distributedsystems, architecture
Published: 2020-06-03 11:58:50

Parte da [série](https://dev.to/brenoferreira/designing-data-intensive-apps-um-resumo-2df9) sobre o resumo do livro [Designing Data Intensive Apps](https://amzn.to/2YaKEhB).


Em qualquer sistema que manipule dados (ou seja, todo sistema de informação), há tres pilares sobre os quais as pessoas responsáveis devem pensar:

* Reliability
* Scalability
* Maintainability

## Reliability
> Propriedade de um sistema de dados de tolerar falhas.

Falhas são invevitáveis, em qualquer sistema (mais sobre esse assunto nos próximos capítulos). O máximo que dá para fazer é tolerá-las. Ou seja, o sistema deveria continuar funcionado mesmo quando houver falhas. Essas falhas podem ser: falhas de hardware, erros de software e erros humanos.

### Falhas de hardware

Todo hardware falha. E conforme voce aumenta a escala do seu hardware, a probabilidade de falha aumenta. Em algum momento alguma coisa vai quebrar, e deveria haver hardware redundante para assumir o controle assim que um problema for detectado, idealmente de forma automatizada.

### Erros de software

Problemas no software podem causar falhas tão catastróficas quanto um rack no servidor desconectado. Esses podem ser as vezes bugs que podem ser detectados com uma suite de testes melhor e de maior cobertura, mas também podem ser coisas que as vezes são inesperadas, como por exemplo:

* Bugs em bibliotecas ou frameworks
* Crash do sistema operacional
* Algum processo que causa uso muito alto de algum recurso computacional (CPU, memoria, disco ou rede)

E o pior dos casos, quando em um sistema onde há dependencias entre modulos, uma falha em um módulo cascateia e gera falha em outros N módulos dependentes.

O que ajuda a melhorar a tolerancia a falhas de software: testes melhores, diminuir dependencias, restart automático de processos e monitoramento.

### Erros humanos

Humanos fazem e operam sistemas. E humanos são conhecidamente não muito confiaveis. E muitos problemas tem sua causa algum erro humano (update sem where em produção, alguém?).

Algumas estratégias para minimizar o impacto de falhas humanas:

* Construa o sistema de forma que minimize a chance de errors acontecerem. Boa documentação e interfaces que facilitem o uso e deixem facil fazer a coisa certa e mais dificil fazer a coisa errada.
* Desacople os lugares onde as pessoas podem cometer erros dos lugares onde elas causam falhas. Por exemplo, ter um ambiente de testes onde as pessoas podem testar o sistema de forma que erros não causam falhas em produção com maior impacto.
* Facilite rollback de mudanças
* Boas práticas de liderança para evitar apontar culpados quando falhas humanas acontecem.

## Scalability
> Primeiramente, precisamos descrever a carga atual do sistema; somente depois podemos discutir questões de crescimento.

Para se ter ideia da escalabilidade de um sistema, é necessario medir a carga e performance atual do sistema. A partir daí, será possível medir e investigar o que acontece quando a carga aumenta. Algumas coisas que é necessario medir:
* uso de recursos de hardware (CPU, Memoria, uso de rede, etc.)
* tempo de resposta, geralmente medido em percentis (p95, p99, p999). Ou seja, se seu tempo de resposta p95 é 50ms, significa de 95% dos requests responde em 50ms ou menos. Os outros 5% respondem em tempo maior. Aí entram no jogo possíveis SLAs definidos por contrato, que podem definir um p99 ou p999 (99.9%) com alguns limites.
* Latencia de comunicação. Não confundir latencia com tempo de resposta. Latencia é o tempo de transporte de mensagens, e não leva em consideração tempo de processamento. Geralmente dá pra assumir que tempo de resposta = latencia + processamento.

É claro que a arquitetura do sistema vai ter um impacto enorme na escalabilidade do sistema. Para definir a arquitetura do sistema, é necessario saber os parametros de carga com os quais o sistema irá trabalhar. Onde vai haver maior demanda? Vai ter mais escrita ou leitura? Qual o tamanho dos dados? Construir um sistema para responder 100K req/s, cada um processando alguns KBs de dados é bem diferente de um sistema que processa 10 de req/s processando 1GB.

## Maintainability
> Um sistema de facil manutenção torna a vida dos desenvolvedores e dos sys-admins mais facil.

Um sistema com boa manutenibilidade tenta minimizar as dores de manter e operar um sistema, focando em tres areas:

* *Operabilidade*: facilidade de operação do sistema que manter as coisas funcionando bem
* *Simplicidade*: facilidade de compreender como o sistema e suas partes funciona
* *Capacidade de evolução*: quão facil é fazer mudanças no sistema? Requerimentos e casos de uso mudam frequentemente. Complexidade que não é inerente ao problema sendo resolvido mas sim à implementação torna o software mais dificil de mudar e evoluir.

Os próximos capítulos do livro explicam como sistemas de dados diferentes impactam em cada uma dessas tres areas.

_originalmente postado em: https://medium.com/@breno_ferreira/designing-data-intensive-apps-um-resumo-1a62de5358f4_

Conteúdo sob a licensa CC-BY-NC