{"id":4186,"date":"2022-05-10T09:47:47","date_gmt":"2022-05-10T12:47:47","guid":{"rendered":"https:\/\/elemarjr.com\/arquiteturadesoftware\/?p=4186"},"modified":"2024-01-12T09:51:14","modified_gmt":"2024-01-12T12:51:14","slug":"fundamentos-para-arquitetura-de-sistemas-escalaveis","status":"publish","type":"volume-1","link":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/","title":{"rendered":"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis"},"content":{"rendered":"<p><strong>A google define boa engenharia de software como a capacidade de suportar as mudan\u00e7as de escala, ao longo do tempo, preservando a efici\u00eancia<\/strong>. A arquitetura adequada \u00e9 fundamental para que sistemas &#8220;escalem bem&#8221;.<\/p>\nEmbora frequentemente mencionada, a escalabilidade nem sempre \u00e9 devidamente tratada nas arquiteturas. A consequ\u00eancia grave disso \u00e9 a incapacidade de atender o crescimento inesperado do <em>workload <\/em>e, quando n\u00e3o h\u00e1 componentes adequados de reten\u00e7\u00e3o,\u00a0instabilidades.\n<hr \/>\n<p>Arquiteturas n\u00e3o planejadas para a escalabilidade &#8211; onde todas as esperan\u00e7as para suportar aumentos s\u00fabitos de demanda ficam depositadas na utiliza\u00e7\u00e3o de\u00a0<i>load balancers\u00a0<\/i>ou na contrata\u00e7\u00e3o de recursos na nuvem &#8211; se convertem rapidamente em custo. Pior que isso, algumas vezes, nem mesmo &#8220;despejar dinheiro&#8221; \u00e9 suficiente.<\/p>\n<h2>Antes de falar sobre escalabilidade, disponibilidade<\/h2>\n<p>De pouco importam as <em>features\u00a0<\/em>de um sistema se elas n\u00e3o estiverem dispon\u00edveis quando os usu\u00e1rios precisam.<\/p>\n<p><strong>Um sistema est\u00e1 dispon\u00edvel quando est\u00e1 funcionando conforme esperado com desempenho adequado. Um servi\u00e7o, por exemplo, est\u00e1 dispon\u00edvel quando responde corretamente, em um\u00a0<em>response time <\/em>igual ou menor do que o acordado.<\/strong><\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Se o tempo de resposta de um servi\u00e7o for maior do que o acordado, mesmo que este responda corretamente, n\u00e3o poder\u00e1 ser considerado dispon\u00edvel.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>A f\u00f3rmula para calcular a disponibilidade de um sistema \u00e9:<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-4189 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2022\/05\/disponibilidade_.png\" alt=\"\" width=\"274\" height=\"122\" \/><\/p>\n<p>Onde\u00a0<em>Tu\u00a0<\/em>representa em <em>u<\/em><em>ptime, <\/em>quando tudo est\u00e1 funcionando com desempenho adequado, e\u00a0<em>Td<\/em> representa o\u00a0<em>downtime,\u00a0<\/em>quando o comportamento do sistema est\u00e1 incorreto ou o desempenho \u00e9 insuficiente.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Manuten\u00e7\u00f5es programadas e paradas planejadas devem ser consideradas tempo em <em>downtime<\/em>, logo afetando a disponibilidade.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>Definindo escalabilidade (e elasticidade)<\/h2>\n<p><strong>Um sistema \u00e9 escal\u00e1vel quando consegue suportar varia\u00e7\u00f5es nos <em>workloads\u00a0<\/em>&#8211; aumentos ou redu\u00e7\u00f5es -, mantendo-se dispon\u00edvel, com ajustes proporcionalmente favor\u00e1veis nos recursos alocados.<\/strong> Ou seja, um sistema web, por exemplo, ser\u00e1 escal\u00e1vel se conseguir suportar o dobro de usu\u00e1rios ativos, no m\u00e1ximo, dobrando a infra.<\/p>\n<p>Quanto mais favor\u00e1veis forem as demandas de aloca\u00e7\u00e3o de recursos frente ao aumento das cargas, melhor ser\u00e1 a escalabilidade de um sistema.<\/p>\n<p>As mudan\u00e7as nos recursos podem acontecer pelo <em>scaling up\/down<\/em> (vertical) &#8211;\u00a0a\u00a0atualiza\u00e7\u00e3o dos dispositivos computacionais utilizados em termos de mem\u00f3ria, processador, etc &#8211; ou pelo <em>scaling out, <\/em>modificando a quantidade de dispositivos computacionais.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> A escalabilidade horizontal \u00e9 prefer\u00edvel a vertical pois mitiga riscos de indisponibilidade.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>A diferen\u00e7a principal da escalabilidade para a elasticidade \u00e9 que a segunda acontece de forma r\u00e1pida e din\u00e2mica, incrementando recursos quando o\u00a0<em>workload <\/em>cresce ou decrementando quando diminui. A elasticidade \u00e9 extremamente importante na nuvem, quando o investimento \u00e9 determinado pelo uso.<\/p>\n<h2>A necessidade da escalabilidade (e elasticidade)<\/h2>\n<p>No passado, sistemas eram desenvolvidos para serem utilizados em contextos bem demarcados. Tanto volume de dados quanto taxas de mudan\u00e7a eram caracter\u00edsticas relativamente f\u00e1ceis de serem previstas. Entretanto, em tempos de transforma\u00e7\u00e3o digital,\u00a0 tudo mudou.<\/p>\n<p>Hoje, as empresas usam tecnologia para estreitar rela\u00e7\u00f5es com clientes, fornecedores e parceiros &#8211; sistemas de <em>software<\/em> inicialmente desenvolvidos para utiliza\u00e7\u00e3o dentro das empresas, est\u00e3o &#8220;vazando&#8221; para uso externo. Dessa forma, aumentos significativos de <em>workloads\u00a0<\/em>tem acontecido rapidamente e, n\u00e3o raro, de maneira inesperada.<\/p>\n<h2>O impacto da escalabilidade no custo<\/h2>\nPlanejar um sistema para escalar implica em priorizar tamb\u00e9m disponibilidade e desempenho, impactando diretamente o custo.\n<hr \/>\n<p>Suportar disponibilidade implica em aplicar redund\u00e2ncia como forma de suportar manuten\u00e7\u00f5es previstas ou dificuldades imprevistas.<\/p>\n<p>Quase todos os padr\u00f5es e estilos arquiteturais voltados para a escalabilidade tamb\u00e9m exercem press\u00e3o de custos de <em>deploy<\/em> e <em>opera\u00e7\u00e3o\u00a0<\/em>para, por exemplo, suportar orquestra\u00e7\u00e3o e mensageria.<\/p>\n<h2>Escalar \u00e9 a &#8220;arte de gerenciar gargalos&#8221;<\/h2>\n<p><strong>Em todo sistema que precisa escalar, h\u00e1 sempre, um elemento que oferece a restri\u00e7\u00e3o. N\u00e3o raro, esse recurso \u00e9 o banco de dados.<\/strong><\/p>\n<p>O trabalho da arquitetura de software, nessa perspectiva, \u00e9 identificar esse gargalo e adotar estrat\u00e9gias de mitigar riscos inerentes dele.<\/p>\n<div class=\"nota-youtube\">\r\n<table class=\"tabelayoutube\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-youtube-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/><\/td>\r\n<td class=\"nota-youtube-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/>\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">Usando Teoria das Restri\u00e7\u00f5es para melhorar a escalabilidade e performance de sistemas<\/p>\r\nA teoria das restri\u00e7\u00f5es \u00e9 frequentemente associada a gest\u00e3o fabril, mas tem, tamb\u00e9m aplica\u00e7\u00e3o direta para a arquitetura de software. Nesse v\u00eddeo, explico com mais detalhes como usar teoria das restri\u00e7\u00f5es para projetar sistemas escal\u00e1veis.\r\n<p><a class=\"botao-youtube\" href=\"https:\/\/youtu.be\/HNeww3nlE-k\" target=\"_blank\" rel=\"noopener\" style=\"margin-top: 20px;\">Acessar v\u00eddeo<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>A teoria das restri\u00e7\u00f5es nos ensina que h\u00e1 tr\u00eas medidas para tratar gargalos:<\/p>\n<ol>\n<li>elevar a capacidade de vaz\u00e3o &#8211; seja com otimiza\u00e7\u00e3o, <em>scale up<\/em> ou <em>scale out &#8211;<\/em>\u00a0&#8220;quebrando&#8221; a restri\u00e7\u00e3o;<\/li>\n<li>subordinar toda a arquitetura aos limites do gargalo, estabelecendo alguma esp\u00e9cie de\u00a0<em>rate limiting<\/em><\/li>\n<li>admitir a forma\u00e7\u00e3o de um &#8220;pulm\u00e3o&#8221; maior, frente a restri\u00e7\u00e3o, tornando todas as suas interfaces ass\u00edncronas.<\/li>\n<\/ol>\n<hr \/>\n<p>A segunda &#8220;solu\u00e7\u00e3o&#8221;, na pr\u00e1tica, raramente \u00e9 aplic\u00e1vel pois restringe as capacidades do sistema de suportar a nova escala e deve ser adotada, apenas para preservar a estabilidade.<\/p>\nDe qualquer forma, \u00e9 importante lembrar que sempre que um gargalo \u00e9 &#8220;quebrado&#8221;, emerge um outro gargalo. Por exemplo, &#8220;escalar&#8221; servidores de aplica\u00e7\u00e3o que n\u00e3o est\u00e3o conseguindo suportar a demanda, frequentemente move o gargalo para o &#8220;cache&#8221; ou para o banco. Ent\u00e3o, ao &#8220;escalar&#8221; estes componentes, a restri\u00e7\u00e3o volta a ser, com muita frequ\u00eancia os servidores de aplica\u00e7\u00e3o. <strong>O ponto importante \u00e9: ajustar a arquitetura para suportar a escala implica em, sempre, fazer an\u00e1lise hol\u00edstica &#8211; a for\u00e7a de uma corrente \u00e9 sempre determinada pelo seu elo mais fraco.<\/strong>\n<h2>Escalar \u00e9 a &#8220;arte de gerenciar filas&#8221;<\/h2>\n<p><strong>Na medida que identificamos, em nossos sistemas, componentes com diferentes n\u00edveis de capacidade para processamento, \u00e9 necess\u00e1rio reconhecer que, eventualmente, &#8220;fazer o todo funcionar&#8221; implica em tratar adequadamente as filas que se formam.<\/strong><\/p>\n<p>A necessidade, por exemplo, de escalar na horizontal um servidor de aplica\u00e7\u00e3o \u00e9 demonstrada quando a <span style=\"text-decoration: underline;\">ritmo de chegada<\/span> de novas requisi\u00e7\u00f5es \u00e9 maior de que a <span style=\"text-decoration: underline;\">ritmo de atendimento.<\/span><\/p>\n<p>Segue algumas ideias fundamentais para come\u00e7armos a avaliar filas em sistemas:<\/p>\n<ul>\n<li>Servidor &#8211; componente(s) respons\u00e1vel por atender algum tipo de requisi\u00e7\u00e3o;<\/li>\n<li>Cliente &#8211; componente de onde partem requisi\u00e7\u00f5es<\/li>\n<li>Tempo de espera (<em>Wait time<\/em>) &#8211; Tempo em que um &#8220;cliente&#8221; aguarda em uma fila para ter sua demanda atendida<\/li>\n<li>Tempo de servi\u00e7o (<em>Service time<\/em>) &#8211; Tempo de &#8220;trabalho&#8221; de um componente servidor gerando a resposta para a requisi\u00e7\u00e3o do cliente<\/li>\n<li>Tempo de resposta (R<em>esponse time<\/em>) &#8211; soma dos tempos de espera e de servi\u00e7o<\/li>\n<li>Ritmo de chegada (<em>arrival rate<\/em>) &#8211; ritmo de chegada de novas requisi\u00e7\u00f5es na fila<\/li>\n<li>Ritmo de servi\u00e7o (<em>service rate<\/em>)\u00a0<em>&#8211;\u00a0<\/em>ritmo de &#8220;atendimento&#8221; das demandas (considerando apenas o tempo em &#8220;trabalho&#8221; dos componentes servidor)<\/li>\n<li>Utiliza\u00e7\u00e3o (<em>utilization<\/em>) &#8211; propor\u00e7\u00e3o entre &#8220;tempo trabalhando&#8221; e &#8220;tempo total&#8221; de cada componente servidor<\/li>\n<li>Tamanho da fila (<em>queue length<\/em>) &#8211; n\u00famero total de requisi\u00e7\u00f5es na fila<\/li>\n<li>\u00a0<em>Throughput<\/em> &#8211; Quantidade de requisi\u00e7\u00f5es atendidas em um determinado intervalo de tempo.<\/li>\n<\/ul>\n<hr \/>\n<p>Um sistema ser\u00e1 escal\u00e1vel quando conseguir preservar tempos de resposta ou <em>throughput\u00a0<\/em>dentro de par\u00e2metros aceit\u00e1veis, mediante ajuste proporcional favor\u00e1vel entre componentes servidores e o ritmo de chegada de requisi\u00e7\u00f5es.<\/p>\n<p>Boas medidas visando a melhoria da escalabilidade buscam:<\/p>\n<ul>\n<li><strong>Minimizar o <span style=\"text-decoration: underline;\">tempo de espera<\/span>,<\/strong> aperfei\u00e7oando a efici\u00eancia dos componentes &#8220;servidor&#8221;, disponibilizando mais inst\u00e2ncias de suas inst\u00e2ncias, ou minimizando o volume de requisi\u00e7\u00f5es por parte dos componentes &#8220;cliente&#8221;.<\/li>\n<li><strong>Minimizar o <span style=\"text-decoration: underline;\">tempo de servi\u00e7o<\/span><\/strong>, atrav\u00e9s do aperfei\u00e7oamento do desempenho dos componentes &#8220;servidor&#8221;.<\/li>\n<\/ul>\n<h2>Leis que governam a escalabilidade<\/h2>\n<p>H\u00e1 duas leis que &#8220;governam&#8221; a escalabilidade: Amdahl e Ghunter. Na pr\u00e1tica, essas leis ensinam que um sistema ter\u00e1 mais potencial para escalabilidade na medida em que tiver menos partes sequenciais ou demandas por coer\u00eancia.<\/p>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> Todas as a\u00e7\u00f5es para melhoria da escalabilidade visam reduzir os tempos de conten\u00e7\u00e3o e atrasos para coer\u00eancia.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h4>Lei de Amdahl<\/h4>\n<p>A\u00a0<b>lei de Amdahl<\/b>, \u00e9 usada para encontrar a m\u00e1xima melhora poss\u00edvel no desempenho de um sistema (<em>throughput<\/em>) como um todo, para um determinado processamento,\u00a0 quando apenas uma \u00fanica parte do trabalho pode ser paralelizada.<\/p>\n<div style=\"background-color: #f0eef4; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px;\">\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 28px; font-family: Montserrat; color: #432b75;\">Argumento de Amdahl<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d;\">O <em>speedup<\/em> de um processo usando m\u00faltiplos agentes paralelos \u00e9 limitado pelo tempo necess\u00e1rio para completar parte n\u00e3o paraleliz\u00e1vel deste processo.<\/p>\r\n<\/div>\n<p>Segundo a lei, por exemplo, um processamento de 20 horas, onde 1 hora de trabalho \u00e9 n\u00e3o paraleliz\u00e1vel, restringe o tempo m\u00ednimo a essa 1 hora. Ou seja, o <em>speedup\u00a0<\/em>m\u00e1ximo ser\u00e1 de 20 vezes.<\/p>\n<p><strong>O tempo n\u00e3o paraleliz\u00e1vel de um processo \u00e9 chamada de &#8220;tempo de conten\u00e7\u00e3o&#8221;.<\/strong><\/p>\n<h4>Lei de Ghunter<\/h4>\n<p>Al\u00e9m da conten\u00e7\u00e3o, o atraso da coer\u00eancia \u00e9 outro fator que afeta as melhorias.<\/p>\n<div style=\"background-color: #f0eef4; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px;\">\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 28px; font-family: Montserrat; color: #432b75;\">Atraso da coer\u00eancia<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d;\">Tempo demandado, em um sistema distribu\u00eddo com diversos n\u00f3s quem precisam compartilhar um estado coerente (mesmo n\u00edvel de atualiza\u00e7\u00e3o), para que todos os n\u00f3s atinjam coer\u00eancia.<\/p>\n<hr \/>\n<p>Em um cluster de banco de dados, por exemplo, \u00e9 o tempo para que altera\u00e7\u00f5es realizadas em um n\u00f3 sejam replicadas para os demais.<\/p>\r\n<\/div>\n<p>Basicamente, a lei de Ghunter postula que o aumento de n\u00f3s com demanda de coer\u00eancia, em um sistema, aumenta o atraso da coer\u00eancia. Eventualmente, anulando os efeitos da adi\u00e7\u00e3o de n\u00f3s de processamento.<\/p>\n<div style=\"background-color: #f0eef4; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px;\">\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 28px; font-family: Montserrat; color: #432b75;\">Argumento de Ghunter<\/p>\r\n<p style=\"font-size: 16px; font-weight: Regular; line-height: 20px; font-family: Roboto; color: #45365d;\">Na medida em que adotamos <em>scale up <\/em>em um componente de um sistema que demande coer\u00eancia, os custo de comunica\u00e7\u00e3o e coordena\u00e7\u00e3o aumentam at\u00e9 eventualmente superar quaisquer benef\u00edcios adjacentes.<\/p>\r\n<\/div>\n<h2>Tr\u00eas estrat\u00e9gias gen\u00e9ricas para arquiteturas escal\u00e1veis (segundo a AKF)<\/h2>\n<p>Projetar sistemas escal\u00e1veis demanda organiza\u00e7\u00e3o e estrutura. Dentre os m\u00e9todos mais comuns para obter sistemas escal\u00e1veis, destacam-se tr\u00eas estrat\u00e9gias gen\u00e9ricas previstas no &#8220;cubo da escalabilidade&#8221;.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-2302 aligncenter\" src=\"https:\/\/elemarjr.com\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/116-2.jpg\" alt=\"\" width=\"731\" height=\"385\" srcset=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/116-2.jpg 1366w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/116-2-300x158.jpg 300w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/116-2-1024x540.jpg 1024w, https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/06\/116-2-768x405.jpg 768w\" sizes=\"(max-width: 731px) 100vw, 731px\" \/><\/p>\n<p>O &#8220;cubo da escalabilidade&#8221;, proposto pela consultoria <a href=\"https:\/\/akfpartners.com\">AKF<\/a>, \u00a0\u00e9 um modelo consolidado para segmenta\u00e7\u00e3o de sistemas em servi\u00e7os que cria uma linguagem comum para que equipes discutam op\u00e7\u00f5es relacionadas \u00e0 escalabilidade no projeto de solu\u00e7\u00f5es.<\/p>\n<p>O modelo prescreve tr\u00eas estrat\u00e9gias para escalabilidade:<\/p>\n<ol>\n<li>Escala X &#8211; Escalar na horizontal<\/li>\n<li>Escala Y &#8211; Decomposi\u00e7\u00e3o em servi\u00e7os<\/li>\n<li>Escala Z &#8211; Decomposi\u00e7\u00e3o por\u00a0<em>sharding\u00a0<\/em>ou\u00a0<em>podding<\/em><\/li>\n<\/ol>\n<hr \/>\n<p>As tr\u00eas estrat\u00e9gias podem ser aplicadas de maneira independente ou combinada.<\/p>\n<h4>Escala X &#8211; Escalar na horizontal<\/h4>\n<p>A primeira estrat\u00e9gia prevista no &#8220;cubo da escalabilidade&#8221; consiste em clonar inst\u00e2ncias de aplica\u00e7\u00f5es ou replicar bases de dados, consumidas atrav\u00e9s de um\u00a0<em>load balancer.<\/em><\/p>\n<p>Trata-se de uma abordagem simples, relativamente r\u00e1pida de implementar, que depende da &#8220;elimina\u00e7\u00e3o de recursos compartilhados&#8221;. Aplic\u00e1vel sobretudo quando a taxa de leituras e grava\u00e7\u00f5es seja de 5:1 ou mais.<\/p>\n<h4>Escala Y &#8211; Decomposi\u00e7\u00e3o em servi\u00e7os<\/h4>\n<p>A segunda estrat\u00e9gia prevista no &#8220;cubo da escalabilidade&#8221; consiste em decompor aplica\u00e7\u00f5es em servi\u00e7os e conjuntos de dados independentes, por caracter\u00edsticas funcionais.<\/p>\n<p>Trata-se de uma abordagem significativamente mais complexa e lenta para implementar. Entretanto, tem vantagens de permitir tamb\u00e9m o crescimento da organiza\u00e7\u00e3o (em fun\u00e7\u00e3o da lei de Conway) e isolamento de falhas (melhor resili\u00eancia).<\/p>\n<h4>Escala Z &#8211; Decomposi\u00e7\u00e3o por <em>sharding\u00a0<\/em>ou\u00a0<em>podding<\/em><\/h4>\n<p>A terceira estrat\u00e9gia prevista no &#8220;cubo da escalabilidade&#8221; consistem em decompor aplica\u00e7\u00f5es, segmentando demanda em recursos dedicados. A ideia simples \u00e9 utilizar um mesmo bloco de c\u00f3digo para processar subconjuntos (ou\u00a0<em>shards<\/em>) de dados.<\/p>\n<h2>Considera\u00e7\u00f5es fundamentais sobre <em>caching<\/em><\/h2>\n<div class=\"nota-insight\">\r\n<table class=\"tabelainsight\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-insight\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/ico-lamp-2.png\" alt=\"\" width=\"70\" height=\"70\" \/> \u00c9 praticamente imposs\u00edvel falar sobre escalabilidade sem, em algum momento, falar sobre <em>caching<\/em>.<\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<div class=\"nota-youtube\">\r\n<table class=\"tabelayoutube\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-youtube-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/><\/td>\r\n<td class=\"nota-youtube-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/youtube.png\" alt=\"\" width=\"80\" height=\"80\" \/>\r\n<p style=\"font-size: 24px; font-weight: bold; line-height: 1.1; font-family: Montserrat; margin-bottom: 10px;\">Estrat\u00e9gias gen\u00e9ricas para escalar software de poucos usu\u00e1rios para milh\u00f5es<\/p>\r\nNesse v\u00eddeo mostro como <em>caching,<\/em> combinado com estrat\u00e9gias de <em>scaling out<\/em>, tem import\u00e2ncia fundamental na jornada para a escalabilidade.\r\n<p><a class=\"botao-youtube\" href=\"https:\/\/youtu.be\/2j2Az0qG7Ro\" target=\"_blank\" rel=\"noopener\" style=\"margin-top: 20px;\">Acessar v\u00eddeo<\/a><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Cache \u00e9 uma forma de armazenamento de dados intermedi\u00e1rio (hardware ou software) que pode servir seus dados mais r\u00e1pido do que a fonte de dados original (banco de dados, servi\u00e7o da web, etc.).<\/p>\n<p>O armazenamento em cache \u00e9 essencial porque pode melhorar o desempenho do aplicativo significativamente, economizando o tempo dos usu\u00e1rios e o dinheiro da empresa. Entretanto, com certeza, introduz uma nova categoria de complexidades arquitet\u00f4nicas e de implementa\u00e7\u00e3o (onde complexidade significa custo). Mas, se um aplicativo depende muito de rede, disco e outros recursos lentos, uma estrat\u00e9gia de cache adequada pode salvar o dia.<\/p>\n<h4><span id=\"When_caching_is_important\">Quando\u00a0cache pode ajudar<\/span><\/h4>\n<p>A ado\u00e7\u00e3o de <em>caching\u00a0<\/em>pode ajudar consideravelmente a melhorar a performance e a escalabilidade de um sistema de software quando \u00e9 necess\u00e1rio:<\/p>\n<ul>\n<li>acessar recursos hospedados externamente (em outro contexto de hospedagem);<\/li>\n<li>recuperar recursos que\u00a0<strong>n\u00e3o<\/strong>\u00a0mudam com frequ\u00eancia;<\/li>\n<li>recuperar representa\u00e7\u00f5es dos mesmos recursos continuamente;<\/li>\n<li>produzir a mesma sa\u00edda para demandas de computa\u00e7\u00e3o frequentemente;<\/li>\n<li>executar c\u00e1lculos de agrega\u00e7\u00e3o extensos m\u00faltiplas vezes.<\/li>\n<\/ul>\n<hr \/>\n<h4><span id=\"Where_the_cache_should_run\">Onde implementar <em>caching<\/em><\/span><\/h4>\n<p>Para aplicativos cliente-servidor, um cache pode ser:<\/p>\n<ul>\n<li><strong>do lado do cliente<\/strong>\u00a0, implementado no cliente (por exemplo, o navegador)<\/li>\n<li><strong>lado do servidor,<\/strong>\u00a0implementado no servidor<\/li>\n<li><strong>em algum lugar no meio (CDN)<\/strong><\/li>\n<\/ul>\n<hr \/>\n<p>Em cen\u00e1rios distribu\u00eddos, o cache pode ser:<\/p>\n<ul>\n<li><strong>local<\/strong>\u00a0, na mesma m\u00e1quina (n\u00f3) onde o aplicativo est\u00e1 rodando<\/li>\n<li><strong>remoto<\/strong>\u00a0, em outro computador, acess\u00edvel atrav\u00e9s da infraestrutura de rede.<\/li>\n<\/ul>\n<hr \/>\n<p>Finalmente, sempre que o cache \u00e9 implementado localmente, pode ser:<\/p>\n<ul>\n<li><strong>em processo<\/strong>\u00a0, executando no mesmo processo do sistema operacional do aplicativo de consumo (na mem\u00f3ria)<\/li>\n<li><strong>fora do processo<\/strong>\u00a0, em execu\u00e7\u00e3o em outro processo do sistema operacional.<\/li>\n<\/ul>\n<hr \/>\n<p>Existem pr\u00f3s e contras para cada um desses tipos.\u00a0A op\u00e7\u00e3o certa depende do contexto.<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Cuidado com o GC!<\/p>\r\n<\/p>\n<p>C\u00f3digo, tanto em .NET quanto em Java, \u00e9 dito gerenciado. Isso significa que programadores t\u00eam a liberdade de programar sem codificar a &#8220;desaloca\u00e7\u00e3o&#8221; de mem\u00f3ria. Isso, entretanto, n\u00e3o significa que n\u00e3o seja necess\u00e1rio se preocupar com isso.<\/p>\n<p>De forma simplificada, de tempos em tempos o\u00a0<em>runtime\u00a0<\/em>interrompe a execu\u00e7\u00e3o do sistema para &#8220;coletar&#8221; objetos que n\u00e3o estejam mais referenciados. A frequ\u00eancia e a dura\u00e7\u00e3o das interrup\u00e7\u00f5es est\u00e1 relacionada com a &#8220;voracidade&#8221; do sistema para criar objetos que possam ser descartados. Objetos que &#8220;sobrevivem&#8221; a coletas acabam, pelas heur\u00edsticas dos coletores, permanecem mais tempo na mem\u00f3ria, podendo gerar press\u00e3o sobre os sistemas.<\/p>\n<p>Objetos em cache local, no processo, podem causar &#8220;confus\u00e3o&#8221; ao funcionamento do GC. Por isso, esta abordagem precisa ser criteriosa.<\/p>\n<p><\/div>\n<h4><span id=\"Cache_writing_strategies\">Estrat\u00e9gias gen\u00e9ricas para &#8220;hidratar&#8221; o cache<\/span><\/h4>\n<p>Existem duas estrat\u00e9gias comuns para gravar dados em um cache:<\/p>\n<ol>\n<li><strong>Pr\u00e9-caching de dados<\/strong>, para pequenos peda\u00e7os de dados, geralmente durante a inicializa\u00e7\u00e3o do aplicativo, antes de qualquer solicita\u00e7\u00e3o.<\/li>\n<li><strong>Sob demanda<\/strong>, verificando primeiro se os dados solicitados est\u00e3o no cache (se os dados forem encontrados, \u00e9 chamado de\u00a0<em>acerto de cache<\/em>), utilizando-os, melhorando o desempenho da aplica\u00e7\u00e3o.\u00a0Sempre que os dados solicitados n\u00e3o forem gravados no cache (<em>perda de cache<\/em>), o aplicativo precisar\u00e1 recuper\u00e1-los da fonte mais lenta e, em seguida, gravar os resultados no cache, economizando tempo nas solicita\u00e7\u00f5es subsequentes dos mesmos dados.<\/li>\n<\/ol>\n<hr \/>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 30px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Montserrat;\">Caching no Netflix<\/p>\r\n<\/p>\n<p>Um dos &#8220;segredos&#8221; do Netflix para suportar a escala \u00e9 o uso intensivo de\u00a0<em>caching.<\/em><\/p>\n<p>A empresa mant\u00e9m um CDN pr\u00f3prio, replicando seu conte\u00fado de\u00a0<em>streaming,\u00a0<\/em>utilizando estrat\u00e9gia de\u00a0<em>pr\u00e9-caching<\/em>.<\/p>\n<p>A ideia por tr\u00e1s de um CDN \u00e9 simples: colocar os v\u00eddeos o mais pr\u00f3ximo poss\u00edvel dos usu\u00e1rios, espalhando os computadores pelo mundo. Assim, quando um usu\u00e1rio quiser assistir a um v\u00eddeo, bastar\u00e1 encontrar o computador mais pr\u00f3ximo com o v\u00eddeo e fazer streaming para o dispositivo a partir dele. Os maiores benef\u00edcios, al\u00e9m da <span style=\"text-decoration: underline;\">escalabilidade<\/span>, para o Netflix, do CDN s\u00e3o <span style=\"text-decoration: underline;\">velocidade<\/span> e <span style=\"text-decoration: underline;\">confiabilidade<\/span>.<\/p>\n<p><\/div>\n<h4><span id=\"Cache_replacement_strategies\">Estrat\u00e9gias de substitui\u00e7\u00e3o de cache<\/span><\/h4>\n<p>Freq\u00fcentemente, o cache tem um tamanho fixo limitado.\u00a0Portanto, sempre que voc\u00ea precisar gravar no cache (normalmente, ap\u00f3s uma falha no cache), \u00e9 preciso determinar se os dados recuperados da fonte mais lenta devem ou n\u00e3o ser gravados no cache e se o limite de tamanho foi atingido e, nesse caso, quais dados precisariam ser removidos dele.<\/p>\n<p>Infelizmente, n\u00e3o existe uma solu\u00e7\u00e3o global.\u00a0Algumas vezes, a melhor estrat\u00e9gia seria remover do cache os dados menos solicitados recentemente.\u00a0Mas, h\u00e1 situa\u00e7\u00f5es em que ser\u00e1 necess\u00e1rio levar em considera\u00e7\u00e3o outros aspectos, como, por exemplo, o custo de recuperar os dados da fonte mais lenta.<\/p>\n<p>Qualquer estrat\u00e9gia de substitui\u00e7\u00e3o de cache ter\u00e1 suas desvantagens e ser\u00e1 necess\u00e1rio considerar o contexto de cada aplicativa aplicativo.\u00a0<strong>A melhor abordagem ser\u00e1 aquela que resulta em menos <em>hit fails<\/em><\/strong>.<\/p>\n<h4><span id=\"Cache_invalidation_strategies\">Estrat\u00e9gias de invalida\u00e7\u00e3o de cache<\/span><\/h4>\n<p>A invalida\u00e7\u00e3o do cache \u00e9 o processo de determinar se um dado no cache deve ou n\u00e3o ser usado para atender a solicita\u00e7\u00f5es subsequentes.<\/p>\n<div class=\"nota-alerta\">\r\n<table class=\"tabelaalerta\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img loading=\"lazy\" decoding=\"async\" class=\"img-citacao\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img loading=\"lazy\" decoding=\"async\" class=\"nota-img\" src=\"\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2021\/11\/ico-citacao-2.png\" alt=\"\" width=\"60\" height=\"60\" \/> <em>Existem apenas duas coisas dif\u00edceis na Ci\u00eancia da Computa\u00e7\u00e3o: invalida\u00e7\u00e3o de cache e nomes de coisas.\u00a0<\/em>\r\n<p><strong>Phil Karlton<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<p>Visto que o aplicativo raramente deve servir dados obsoletos ou inv\u00e1lidos aos usu\u00e1rios, devemos sempre projetar algum mecanismo para invalidar os dados armazenados em cache.<\/p>\n<p>As estrat\u00e9gias mais comuns para invalida\u00e7\u00e3o de cache s\u00e3o:<\/p>\n<ul>\n<li><strong>Tempo de expira\u00e7\u00e3o<\/strong>\u00a0, onde o aplicativo sabe por quanto tempo os dados ser\u00e3o v\u00e1lidos.\u00a0Ap\u00f3s este tempo, os dados devem ser removidos do cache causando uma \u201cperda de cache\u201d em uma solicita\u00e7\u00e3o subsequente;<\/li>\n<li><strong>Verifica\u00e7\u00e3o de atualiza\u00e7\u00e3o em cache<\/strong>\u00a0, em que o aplicativo executa um procedimento leve para determinar se os dados ainda s\u00e3o v\u00e1lidos sempre que s\u00e3o recuperados.\u00a0A desvantagem dessa alternativa \u00e9 que ela produz algum overhead de execu\u00e7\u00e3o;<\/li>\n<li><strong>Invalida\u00e7\u00e3o ativa<\/strong>\u00a0, em que o aplicativo invalida ativamente os dados no cache, normalmente quando alguma mudan\u00e7a de estado \u00e9 identificada.<\/li>\n<\/ul>\n<h2>Consolidando<\/h2>\n<p><span style=\"font-size: 16px;\">Escalabilidade \u00e9 um atributo desej\u00e1vel mas que sempre representa incremento na complexidade e, eventualmente, no custo. Por isso, \u00e9 importante ter clareza sobre a prioridade deste atributo frente aos demais.<\/span><\/p>\nA experi\u00eancia ensina que a primeira medida para suportar a escala \u00e9 <em>caching\u00a0<\/em>agressivo e a ado\u00e7\u00e3o de modelos ass\u00edncronos de comunica\u00e7\u00e3o. Depois, a solu\u00e7\u00e3o mais pragm\u00e1tica \u00e9 preparar os sistemas para o <em>scale out<\/em>. Eventualmente, pode ser necess\u00e1rio particionar o sistema por dados. Finalmente, depois de tudo isso, particionar o sistema por funcionalidades (servi\u00e7os).\n<h2><span id=\"TODO\">\/\/ TODO<\/span><\/h2>\n<p>Antes de avan\u00e7ar para o pr\u00f3ximo cap\u00edtulo, recomendo as seguintes reflex\u00f5es:<\/p>\n<ol>\n<li>Os sistemas em que voc\u00ea trabalha tem &#8220;suporte&#8221; para escalabilidade?<\/li>\n<li>Quais das estrat\u00e9gias gen\u00e9ricas para escalabilidade est\u00e1 mais habituado a adotar?<\/li>\n<li>Qual relev\u00e2ncia de\u00a0<em>caching\u00a0<\/em>para sua aplica\u00e7\u00e3o?<\/li>\n<\/ol>\n","protected":false},"featured_media":3827,"parent":0,"comment_status":"open","ping_status":"closed","template":"","url":[72],"sessoes":[58],"apendices":[],"capitulos":[38],"class_list":["post-4186","volume-1","type-volume-1","status-publish","has-post-thumbnail","hentry","url-permanente","sessoes-secao-2","capitulos-capitulo-2-2"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis - Manual do Arquiteto de Software<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis - Manual do Arquiteto de Software\" \/>\n<meta property=\"og:description\" content=\"A google define boa engenharia de software como a capacidade de suportar as mudan\u00e7as de escala, ao longo do tempo, preservando a efici\u00eancia. A arquitetura adequada \u00e9 fundamental para que sistemas &#8220;escalem bem&#8221;. Arquiteturas n\u00e3o planejadas para a escalabilidade &#8211; onde todas as esperan\u00e7as para suportar aumentos s\u00fabitos de demanda ficam depositadas na utiliza\u00e7\u00e3o de\u00a0load [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/\" \/>\n<meta property=\"og:site_name\" content=\"Manual do Arquiteto de Software\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/eximiaco\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-12T12:51:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"600\" \/>\n\t<meta property=\"og:image:height\" content=\"338\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@eximiaco\" \/>\n<meta name=\"twitter:label1\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data1\" content=\"16 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/\",\"name\":\"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis - Manual do Arquiteto de Software\",\"isPartOf\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg\",\"datePublished\":\"2022-05-10T12:47:47+00:00\",\"dateModified\":\"2024-01-12T12:51:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#primaryimage\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg\",\"width\":600,\"height\":338},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Volume 1\",\"item\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"name\":\"Manual do Arquiteto de Software\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization\",\"name\":\"EximiaCo\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"contentUrl\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg\",\"width\":150,\"height\":150,\"caption\":\"EximiaCo\"},\"image\":{\"@id\":\"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/eximiaco\",\"https:\/\/x.com\/eximiaco\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis - Manual do Arquiteto de Software","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/","og_locale":"pt_BR","og_type":"article","og_title":"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis - Manual do Arquiteto de Software","og_description":"A google define boa engenharia de software como a capacidade de suportar as mudan\u00e7as de escala, ao longo do tempo, preservando a efici\u00eancia. A arquitetura adequada \u00e9 fundamental para que sistemas &#8220;escalem bem&#8221;. Arquiteturas n\u00e3o planejadas para a escalabilidade &#8211; onde todas as esperan\u00e7as para suportar aumentos s\u00fabitos de demanda ficam depositadas na utiliza\u00e7\u00e3o de\u00a0load [&hellip;]","og_url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/","og_site_name":"Manual do Arquiteto de Software","article_publisher":"https:\/\/facebook.com\/eximiaco","article_modified_time":"2024-01-12T12:51:14+00:00","og_image":[{"width":600,"height":338,"url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@eximiaco","twitter_misc":{"Est. tempo de leitura":"16 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/","name":"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis - Manual do Arquiteto de Software","isPartOf":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website"},"primaryImageOfPage":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#primaryimage"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#primaryimage"},"thumbnailUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg","datePublished":"2022-05-10T12:47:47+00:00","dateModified":"2024-01-12T12:51:14+00:00","breadcrumb":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#primaryimage","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/03\/2.2.jpg","width":600,"height":338},{"@type":"BreadcrumbList","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/fundamentos-para-arquitetura-de-sistemas-escalaveis\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/"},{"@type":"ListItem","position":2,"name":"Volume 1","item":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/volume-1\/"},{"@type":"ListItem","position":3,"name":"Cap 2.2 Fundamentos para arquitetura de sistemas escal\u00e1veis"}]},{"@type":"WebSite","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#website","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","name":"Manual do Arquiteto de Software","description":"","publisher":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#organization","name":"EximiaCo","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/","url":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","contentUrl":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-content\/uploads\/2022\/04\/simbolo-eximiaco.jpg","width":150,"height":150,"caption":"EximiaCo"},"image":{"@id":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/eximiaco","https:\/\/x.com\/eximiaco"]}]}},"_links":{"self":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1\/4186","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/volume-1"}],"about":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/types\/volume-1"}],"replies":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/comments?post=4186"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media\/3827"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/media?parent=4186"}],"wp:term":[{"taxonomy":"url","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/url?post=4186"},{"taxonomy":"sessoes","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/sessoes?post=4186"},{"taxonomy":"apendices","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/apendices?post=4186"},{"taxonomy":"capitulos","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/arquiteturadesoftware\/wp-json\/wp\/v2\/capitulos?post=4186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}