SlideShare uma empresa Scribd logo
21.1 Introdução
21.2 Introdução ao estudo de caso: Google
21.3 Arquitetura global e filosofia de projeto
21.4 Paradigmas de comunicação
21.5 Serviços de armazenamento de dados e coordenação
21.6 Serviços de computação distribuída
21.7 Resumo
Projeto de Sistemas
Distribuídos – Estudo
de Caso: Google
21
A capacidade de criar um projeto eficiente é uma habilidade importante em sistemas distribuídos, exigindo
o conhecimento das diferentes escolhas tecnológicas apresentadas por todo o livro e um entendimento
completo dos requisitos do domínio de aplicação relevante. O objetivo final é propor uma arquitetura de
sistema distribuído coerente, que incorpore um conjunto consistente e completo de escolhas de projeto ca-
pazes de atender aos requisitos globais. Essa é uma tarefa desafiadora, que exige experiência considerável
no desenvolvimento de sistemas distribuídos.
Ilustraremos o projeto distribuído por meio de um estudo de caso de peso, examinando em detalhes
o projeto da infraestrutura do Google, uma plataforma e middleware associado que suportam a pesquisa
no Google e um conjunto de serviços e aplicativos Web associados, incluindo o Google Apps. Isso engloba
o estudo de importantes componentes subjacentes, como a infraestrutura física que serve de alicerce para
o Google, os paradigmas de comunicação oferecidos pela infraestrutura do Google e os serviços básicos
associados para armazenamento e computação.
É dada ênfase nos principais princípios de projeto por trás da infraestrutura do Google e em como
eles permeiam a arquitetura de sistema global, resultando em um projeto consistente e eficiente.
Coulouris_21.indd 915
Coulouris_21.indd 915 23/05/13 09:26
23/05/13 09:26
916 Sistemas Distribuídos, Conceitos e Projeto
21.1 Introdução
Este livro abordou os principais conceitos que servem de base para o desenvolvimento
de sistemas distribuídos, dando ênfase ao tratamento dos principais desafios dos sistemas
distribuídos, incluindo heterogeneidade, abertura, segurança, escalabilidade, tratamento
de falhas, concorrência, transparência e qualidade de serviço. O tratamento subsequente
inevitavelmente se concentra nas partes que compõem um sistema distribuído, incluin-
do paradigmas de comunicação, como a invocação remota e suas alternativas indiretas;
as abstrações de programação oferecidas pelos objetos, componentes ou serviços Web;
serviços específicos dos sistemas distribuídos para suporte à segurança, atribuição de
nomes e sistema de arquivos; e soluções algorítmicas, como coordenação e acordo. Con-
tudo, é igualmente importante considerar o projeto global dos sistemas distribuídos e
como as partes componentes são reunidas, tratando dos inevitáveis compromissos entre
os diferentes desafios para produzir uma arquitetura de sistema global que satisfaça os
requisitos de um domínio de aplicação e um ambiente operacional de larga escala. Um
tratamento mais completo dos métodos de projeto de sistemas distribuídos necessaria-
mente nos levaria para o campo das metodologias de engenharia de software para siste-
mas distribuídos. Isso está fora dos objetivos deste livro; os interessados nesse assunto
devem consultar o quadro a seguir, que traz alguns tópicos e fontes relevantes. Em vez
disso, optamos por dar uma ideia desta área apresentando o estudo de caso de um siste-
ma distribuído complexo, destacando as decisões de projeto e compromissos envolvidos
nesse projeto.
Para motivar os estudos, o Capítulo 1 apresentou, em linhas gerais, três exemplos
de importantes domínios de aplicação que representam muitos dos maiores desafios nos
sistemas distribuídos: pesquisa na Web, games online para múltiplos jogadores e sis-
temas financeiros. Poderíamos ter escolhido qualquer uma dessas áreas e apresentado
um estudo de caso atraente e esclarecedor, mas optamos por nos concentrar na primeira
delas: pesquisa na Web (e, na verdade, vamos além da pesquisa na Web, examinando o
suporte mais geral para serviços em nuvem baseados na Web). Em particular, apresen-
tamos neste capítulo um estudo de caso sobre a infraestrutura de sistema distribuído que
serve de base para o Google (daqui em diante referida como infraestrutura do Google).
O Google é um dos maiores sistemas distribuídos em uso atualmente e sua infraestrutura
tem lidado com êxito com uma variedade de requisitos exigentes, conforme discutido a
seguir. A arquitetura subjacente e a escolha de conceitos também são muito interessantes,
Engenharia de software para sistemas distribuídos
Remetemos o leitor aos avanços significativos feitos em áreas como:
• projeto orientado a objetos, incluindo o uso de notações de modelagem, como UML [Booch et
al. 2005];
• engenharia de software baseada em componentes (CBSE) e sua relação com as arquiteturas
empresariais [Szyperski 2002];
• padrões arquitetônicos destinados aos sistemas distribuídos [Bushmann et al. 2007];
• engenharia baseada em modelos, que busca gerar sistemas complexos, incluindo sistemas
distribuídos, a partir de abstrações de nível mais alto (modelos) [France e Rumpe 2007].
Coulouris_21.indd 916
Coulouris_21.indd 916 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 917
reunindo muitos dos tópicos básicos apresentados neste livro. Portanto, um estudo da
infraestrutura do Google oferece uma maneira perfeita de encerrar nosso estudo sobre
sistemas distribuídos. Note que, além de dar um exemplo de como suportar pesquisa na
Web, a infraestrutura do Google também se revelou um exemplo importante de computa-
ção em nuvem, conforme ficará claro nas descrições a seguir.
A Seção 21.2 apresenta o estudo de caso, fornecendo informações básicas sobre o
Google. Em seguida, a Seção 21.3 apresenta o projeto global da infraestrutura do Google,
considerando o modelo físico subjacente e a arquitetura de sistema associada. A Seção
21.4 examina o nível mais baixo da arquitetura de sistema, os paradigmas de comunica-
ção suportados pela infraestrutura do Google; as duas seções subsequentes, Seções 21.5
e 21.6, discutem os serviços básicos fornecidos pela infraestrutura do Google, apresen-
tando os serviços de armazenamento e processamento de grandes volumes de dados.
Juntas, as Seções 21.3 a 21.6 descrevem um middleware completo para pesquisa na Web
e computação em nuvem. Por fim, a Seção 21.7 resume os principais pontos que surgem
de nossa discussão sobre a infraestrutura do Google. Por toda a apresentação, será dada
ênfase na identificação e na justificativa das principais decisões de projeto e os compro-
missos inerentes associados.
21.2 Introdução ao estudo de caso: Google
O Google [www.google.com III] é uma corporação dos Estados Unidos, sediada em
Mountain View, Califórnia (a Googleplex), oferecendo pesquisa na Internet e aplica-
ções Web mais gerais, obtendo seus lucros principalmente com os anúncios ligados
a tais serviços. O nome é um trocadilho com a palavra googol, o número 10
100
(ou 1
seguido por cem zeros), enfatizando a enorme escala das informações disponíveis na
Internet atualmente. A missão do Google é dominar esse enorme volume de informa-
ções: “organizar as informações do mundo e torná-las universalmente acessíveis e
úteis” [www.google.com III].
O Google nasceu de um projeto de pesquisa na Universidade de Stanford, com a
empresa sendo inaugurada em 1998. Desde então, ela cresceu até ter uma fatia dominan-
te do mercado da pesquisa na Internet, principalmente devido à eficiência do algoritmo
de classificação subjacente utilizado em seu mecanismo de busca (discutido com mais
detalhes a seguir). De forma significativa, o Google diversificou e, além de fornecer um
mecanismo de busca, agora tem uma importante participação na computação em nuvem.
Da perspectiva dos sistemas distribuídos, o Google oferece um fascinante estudo
de caso, com requisitos extremamente exigentes, particularmente em termos de escala-
bilidade, confiabilidade, desempenho e abertura (veja a discussão sobre esses desafios
na Seção 1.5). Por exemplo, em termos de pesquisa, vale notar que o sistema subjacente
tem se adaptado muito bem ao crescimento da empresa. Desde seu sistema de produção
inicial (em 1998), até lidar com mais de 88 bilhões de pesquisas por mês (em 2010),
seu principal mecanismo de busca nunca sofreu uma interrupção em todo esse tempo
e seus usuários podem esperar resultados de consulta em torno de 0,2 segundos [goo-
gleblog.blogspot.com I]. O estudo de caso apresentado aqui examinará as estratégias
e decisões de projeto por trás desse sucesso e dará uma ideia do projeto de sistemas
distribuídos complexos.
Antes de passarmos para o estudo de caso, contudo, é instrutivo ver com mais deta-
lhes o mecanismo de busca e também o Google como provedor de nuvem.
Coulouris_21.indd 917
Coulouris_21.indd 917 23/05/13 09:26
23/05/13 09:26
918 Sistemas Distribuídos, Conceitos e Projeto
O mecanismo de busca do Google • A função do mecanismo de busca do Google, assim
como para qualquer mecanismo de pesquisa na Web, é receber determinada consulta e
retornar uma lista ordenada com os resultados mais relevantes que satisfazem essa con-
sulta, pesquisando o conteúdo da Web. Os desafios derivam do tamanho da Web e de sua
taxa de mudança, assim como do requisito de fornecer os resultados mais relevantes do
ponto de vista de seus usuários.
Fornecemos a seguir uma breve visão geral do funcionamento da pesquisa no Goo-
gle; uma descrição mais completa do funcionamento do mecanismo de busca do Goo-
gle pode ser encontrado em Langville e Meyer [2006]. Como exemplo, consideraremos
como o mecanismo de busca responde à consulta “livro sistemas distribuídos”.
O mecanismo de busca consiste em um conjunto de serviços para esquadrinhar a
Web e indexar e classificar as páginas descobertas, conforme discutido a seguir.
Esquadrinhamento (crawling): a tarefa do crawler é localizar e recuperar o conteúdo da
Web e passá-lo para o subsistema de indexação. Isso é realizado por um serviço de soft-
ware chamado Googlebot, que lê determinada página Web recursivamente, coletando to-
dos os links dessa página Web e programando mais operações de esquadrinhamento para
os links coletados (uma técnica conhecida como pesquisa em profundidade, altamente
eficiente em buscar praticamente todas as páginas na Web).
No passado, devido ao tamanho da Web, o esquadrinhamento geralmente era feito
uma vez a cada poucas semanas. Entretanto, para certas páginas Web isso era insuficien-
te. Por exemplo, é importante que os mecanismos de busca sejam capazes de informar
precisamente sobre notícias de última hora ou mudanças em preços de ações. Portanto, o
Googlebot tomava nota do histórico de alterações em páginas Web e revisitava frequen-
temente as que mudavam, com um período aproximadamente proporcional à frequência
das mudanças. Com a introdução do Caffeine, em 2010 [googleblog.blogspot.com II],
o Google mudou de uma estratégia em lotes para um processo mais contínuo de esqua-
drinhamento, destinado a oferecer resultados de busca mais atualizados. O Caffeine foi
construído usando um novo serviço de infraestrutura, chamado de Percolator, que supor-
ta a atualização incremental de grandes conjuntos de dados [Peng e Dabek 2010].
Indexação: embora o esquadrinhamento seja uma função importante em termos de reco-
nhecer o conteúdo da Web, ele não nos ajuda na busca de ocorrências de “livro sistemas
distribuídos”. Para entendermos como isso é processado, precisamos examinar mais de
perto a indexação.
A função da indexação é produzir um índice para o conteúdo da Web que seja
semelhante a um índice do final de um livro, mas em uma escala muito maior. Mais
precisamente, a indexação produz o que conhecido como índice invertido, mapeando as
palavras que aparecem em páginas Web e outros recursos Web textuais (incluindo docu-
mentos nos formatos .pdf, .doc e outros) nas posições em que ocorrem nos documentos,
incluindo a posição exata no documento e outras informações relevantes, como tamanho
da fonte e se há uso de letras maiúsculas (que são usadas para determinar a importância,
conforme veremos a seguir). O índice também é classificado para suportar consultas efi-
cientes de palavras em relação às localizações.
Além de manter um índice de palavras, o mecanismo de busca do Google também
mantém um índice de links, monitorando quais páginas estão ligadas a determinado site.
Isso é usado pelo algoritmo PageRank, conforme discutido a seguir.
Vamos voltar ao nosso exemplo de consulta. Esse índice invertido nos permitirá desco-
brir páginas Web que incluem os termos de busca “distribuídos”, “sistemas” e “livro” e, por
meio de uma análise cuidadosa, poderemos descobrir páginas que incluam todos os termos.
Por exemplo, o mecanismo de busca poderá identificar que todos os três termos podem ser
Coulouris_21.indd 918
Coulouris_21.indd 918 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 919
encontrados em amazon.com, www.cdk5.net e em muitos outros sites.Assim, usando o índi-
ce é possível reduzir o conjunto de páginas Web candidatas de bilhões para talvez dezenas de
milhares, dependendo do nível de diferenciação nas palavras-chave escolhidas.
Classificação: o problema da indexação é que ela não fornece nenhuma informação sobre a
importância relativa das páginas Web que contêm um conjunto de palavras-chave em parti-
cular – apesar de isso ser fundamental para se determinar a relevância em potential de uma
página. Portanto, todos os mecanismos de busca modernos dão ênfase significativa a um
sistema de classificação por meio do qual uma classificação mais alta seja uma indicação
da importância de uma página e seja usada para garantir que a página será retornada mais
perto da parte superior da lista de resultados do que as páginas com classificação mais bai-
xa. Conforme mencionado anteriormente, grande parte do sucesso do Google pode ser cre-
ditado à eficiência de seu algoritmo de classificação, PageRank [Langville e Meyer 2006].
O algoritmo PageRank foi inspirado no sistema de classificação de artigos acadêmi-
cos baseado na análise de citações. No mundo acadêmico, um artigo é considerado impor-
tante se tem muitas citações feitas por outros acadêmicos da área. Analogamente, no Page-
Rank, uma página será considerada importante se for ligada a um grande número de outras
páginas (usando os dados de link mencionados anteriormente). O PageRank também vai
além de uma simples análise de “citação”, examinando a importância dos sites que contêm
links para determinada página. Por exemplo, um link para bbc.co.uk será considerado como
mais importante do que um link para a página Web pessoal de Gordon Blair.
No Google, a classificação leva diversos outros fatores em conta, incluindo a proxi-
midade de palavras-chave em uma página e se estão em uma fonte grande ou se as letras
são maiúsculas (com base nas informações armazenadas no índice invertido).
Voltando ao nosso exemplo, após fazer uma pesquisa de índice em cada uma das
três palavras da consulta, a função de busca classifica todas as referências de página
resultantes, de acordo com a importância percebida. Por exemplo, a classificação esco-
lheria certas referências de página sob amazon.com e www.cdk5.net por causa do grande
número de links para essas páginas em outros sites “importantes”. A classificação dará
prioridade às páginas onde os termos “distribuídos”, “sistemas” e “livro” aparecem bem
próximos. Analogamente, a classificação extrairia as páginas em que as palavras apare-
cem próximas ao início da página ou em letras maiúsculas, talvez indicando uma lista de
livros-texto sobre sistemas distribuídos. O resultado final deve ser uma lista classificada
de resultados na qual as entradas que estão no início são as mais importantes.
Anatomia de um mecanismo de busca: os fundadores do Google, Sergey Brin e Larry Page,
escreveram um artigo de referência sobre a “anatomia” do mecanismo de busca do Goo-
gle, em 1998 [Brin e Page 1998], fornecendo ideias interessantes sobre como seu meca-
nismo de busca foi implementado. A arquitetura global descrita nesse artigo está ilustrada
na Figura 21.1, extraída do original. Nesse diagrama, fazemos distinção entre os serviços
que suportam pesquisa na Web diretamente, desenhados como elipses, e os componentes
da infraestrutura de armazenamento subjacente, ilustrados como retângulos.
Embora não seja o objetivo deste capítulo apresentar essa arquitetura em detalhes,
uma breve visão geral ajudará na comparação com a infraestrutura do Google mais so-
fisticada disponível atualmente. A função básica do esquadrinhamento já foi descrita an-
teriormente. Ele recebe como entrada listas de URLs a serem buscados, fornecidos pelo
servidor de URL, com as páginas buscadas resultantes colocadas no servidor de armaze-
namento. Então, esses dados são compactados e colocados no repositório para mais aná-
lise, em particular criando o índice para pesquisa. A função de indexação é executada em
dois estágios. Primeiramente, o indexador descompacta os dados do repositório e produz
um conjunto de acessos (hits), no qual um hit é representado pelo ID do documento, a
Coulouris_21.indd 919
Coulouris_21.indd 919 23/05/13 09:26
23/05/13 09:26
920 Sistemas Distribuídos, Conceitos e Projeto
palavra, a posição no documento e outras informações, como o tamanho da palavra e o
uso de maiúsculas. Então, esses dados são armazenados em um conjunto de barris, um
importante elemento de armazenamento na arquitetura inicial. Essas informações são
armazenadas pelo ID do documento. Então, o classificador pega esses dados e os clas-
sifica por ID de palavra para produzir o índice invertido necessário (conforme discutido
anteriormente). O indexador também executa outras duas funções muito importantes ao
analisar os dados: ele extrai informações sobre links em documentos, armazenando essas
informações em um arquivo de âncoras, e produz um léxico para os dados analisados
(o qual, quando a arquitetura inicial foi usada, consistia em 14 milhões de palavras).
O arquivo de âncoras é processado por um solucionador de URL, o qual executa várias
funções sobre esses dados, incluindo transformar URLs relativos em URLs absolutos,
antes de produzir um banco de dados de links, como uma entrada para os cálculos de Pa-
geRank. O solucionador de URL também cria um doc index, o qual fornece entrada para
o servidor de URL em termos de mais páginas a esquadrinhar. Por fim, o pesquisador
implementa o recurso de pesquisa básico do Google, recebendo entrada do doc index, de
PageRank, do índice invertido mantido nos barris e também do léxico.
Algo extraordinário em relação a essa arquitetura é que, embora seus detalhes es-
pecíficos tenham mudado, os principais serviços que suportam pesquisa na Web – isto
é, esquadrinhamento, indexação (incluindo a ordenação), classificação (através de Page-
Rank) – permanecem os mesmos.
Servidor de URL Crawlers
Servidor de
armazenagem
Repositório
Indexador
Léxico
Âncoras
Solucionador de URL
Barris de armazenamento
Índice
de docs.
Links
PageRank Pesquisador
Classificador
Figura 21.1 Esboço da arquitetura do mecanismo de busca original do Google [Brin e
Page 1998].
Coulouris_21.indd 920
Coulouris_21.indd 920 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 921
Igualmente notável é que, conforme ficará claro a seguir, a infraestrutura mudou
radicalmente, desde as primeiras tentativas de identificar uma arquitetura para pesquisa
na Web até o sofisticado suporte para sistemas distribuídos fornecido atualmente, tanto
em termos de identificar blocos de construção mais reutilizáveis para comunicação, ar-
mazenamento e processamento, como em termos de generalização da arquitetura para
além da pesquisa.
Google como provedor de nuvem • O Google diversificou significativamente e, agora,
além de pesquisa oferece uma ampla variedade de aplicações baseadas na Web, incluin-
do o conjunto promovido como Google Apps [www.google.com I]. Mais geralmente,
o Google agora é um forte participante na área da computação em nuvem. Lembre-se
de que a computação em nuvem foi apresentada no Capítulo 1 e definida como “um
conjunto de serviços de aplicativos, armazenamento e computação baseados na Internet,
suficientes para suportar as necessidades da maioria dos usuários, permitindo, assim, que
eles prescindam em grande medida ou totalmente do software local de armazenamento
de dados ou de aplicativo”. É exatamente isso que agora o Google se esforça em oferecer,
em particular com produtos significativos nas áreas de software como serviço e plata-
forma como serviço (conforme apresentado na Seção 7.7.1). Examinaremos cada uma
dessas áreas por sua vez, a seguir.
Software como serviço: essa área ocupa-se em oferecer software em nível de aplicação
pela Internet, como aplicativos Web. Um exemplo importante é o Google Apps, um con-
junto de aplicações baseadas na Web que incluem Gmail, Google Docs, Google Sites,
Google Talk e Google Calendar. O objetivo do Google é substituir os tradicionais conjun-
tos para escritório por aplicações que suportam preparação compartilhada de documen-
tos, calendários online e diversas ferramentas de colaboração que suportam e-mail, wikis,
Voice over IP e troca instantânea de mensagens.
Recentemente, foram desenvolvidas várias outras aplicações inovadoras baseadas
na Web; elas e o Google Apps original estão resumidos na Figura 21.2. Uma das princi-
Aplicação Descrição
Gmail Sistema de correio com mensagens hospedadas pelo Google, mas com gerenciamento de mensagens do tipo área de trabalho.
Google Docs Conjunto de escritório baseado na web, suportando edição compartilhada de documentos mantidos nos servidores do Google.
Google Sites Sites no estilo wiki, com recursos de edição compartilhada.
Google Talk Suporta troca de mensagens de texto instantâneas e Voice over IP.
Google Calendar Calendário baseado na web, com todos os dados hospedados nos servidores do Google.
Google Wave Ferramenta de colaboração que integra e-mail, troca de mensagens instantânea, wikis e redes sociais.
Google News Site agregador de notícias totalmente automatizado.
Google Maps Mapa-múndi baseado na Web, incluindo imagens de alta resolução e sobreposições
ilimitadas, geradas pelos usuários.
Google Earth Visão do globo terrestre quase tridimensional e escalonável, com sobreposições ilimitadas, geradas pelos usuários.
Google App
Engine
Infraestrutura distribuída do Google, disponibilizada para terceiros como um serviço (plataforma como
serviço).
Figura 21.2 Exemplo de aplicações do Google.
Coulouris_21.indd 921
Coulouris_21.indd 921 23/05/13 09:26
23/05/13 09:26
922 Sistemas Distribuídos, Conceitos e Projeto
pais observações para os propósitos deste capítulo é que o Google estimula uma estraté-
gia aberta para a inovação dentro da organização e, assim, novas aplicações estão surgin-
do o tempo todo. Isso impõe uma demanda específica sobre a infraestrutura de sistemas
distribuídos subjacente, um ponto que será revisitado na Seção 21.3.2.
Plataforma como serviço: essa área ocupa-se em oferecer APIs de sistema distribuído
como serviços pela Internet, sendo essas APIs usadas para suportar o desenvolvimento e
a hospedagem de aplicações Web (note que, infelizmente, o uso do termo “plataforma”
nesse contexto é incoerente com a maneira como é utilizado em outras partes deste livro,
em que se refere ao hardware e ao sistema operacional). Com o lançamento do Google
App Engine, o Google foi além do software como serviço e agora oferece sua infraestru-
tura de sistemas distribuídos, conforme discutido por todo este capítulo como serviço de
nuvem. Mais especificamente, já está previsto que os negócios do Google utilizem essa
infraestrutura de nuvem internamente para dar suporte a todas as suas aplicações e servi-
ços, incluindo seu mecanismo de pesquisa na Web. Agora, o Google App Engine oferece
acesso externo como parte dessa infraestrutura, permitindo que outras organizações exe-
cutem suas próprias aplicações Web na plataforma Google.
Veremos mais detalhes da infraestrutura do Google no decorrer deste capítulo; para
mais detalhes sobre o Google App Engine, consulte o site do Google [code.google.com IV].
21.3 Arquitetura global e filosofia de projeto
Esta seção considera a arquitetura global do sistema Google, examinando:
• a arquitetura física adotada pelo Google;
• a arquitetura de sistema associada que oferece serviços comuns para o mecanismo
de busca na Internet e as muitas aplicações Web oferecidas pelo Google.
21.3.1 Modelo físico
A principal filosofia do Google em termos de infraestrutura física é o uso de núme-
ros muito grandes de PCs comuns para produzir um ambiente de custo reduzido para
armazenamento e computação distribuídos. As decisões de compra são baseadas na
obtenção do melhor desempenho por dólar, em vez do desempenho absoluto, com um
gasto típico em um único PC girando em torno de US$1.000. Um PC normalmente terá
cerca de 2 terabytes de armazenamento em disco, em torno de 16 gigabytes de memória
DRAM (Dynamic Random Access Memory – memória de acesso aleatório dinâmico)
e executará uma versão reduzida do núcleo Linux. (Essa filosofia de construção de
sistemas a partir de PCs comuns reflete os primórdios do projeto de pesquisa original,
quando Sergey Brin e Larry Page construíram o primeiro mecanismo de busca do Goo-
gle a partir de hardware de refugo, recolhido próximo ao laboratório da Universidade
de Stanford.)
Optando por tomar o caminho dos PCs comuns, o Google reconhecia que partes de
sua infraestrutura falharia e, assim, conforme veremos a seguir, projetou a infraestrutura
usando diversas estratégias para tolerar tais falhas. Hennessy e Patterson [2006] relatam
as seguintes características de falha do Google:
• De longe, a fonte de falha mais comum é em razão do software, com cerca de 20
máquinas precisando ser reinicializadas por dia. (É interessante notar que o proces-
so de reinicialização é totalmente manual.)
Coulouris_21.indd 922
Coulouris_21.indd 922 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 923
• As falhas de hardware representam cerca de 1/10 das falhas em razão do software,
com cerca de 2 a 3% dos PCs falhando anualmente, devido ao hardware. Dessas,
95% se devem a falhas nos discos ou na memória DRAM.
Isso justifica a decisão de adquirir PCs comuns; dado que a ampla maioria das falhas é
em razão do software, não vale a pena investir em hardware mais caro e confiável. Outro
artigo, de Pinheiro et al. [2007], também relata as características de falha dos discos co-
muns utilizados na infraestrutura física do Google, dando uma ideia interessante sobre os
padrões de falha de armazenamento em disco em implantações de larga escala.
A arquitetura física é construída como segue [Hennessy e Patterson 2006]:
• Os PCs são organizados em racks contendo entre 40 e 80 PCs cada um. Os racks
têm dois lados, com metade dos PCs em cada um. Cada rack tem um switch Ether-
net que fornece conectividade para ele e também para o mundo externo (veja a
seguir). Esse switch é modular, organizado como um número de lâminas (blades),
com cada lâmina suportando 8 interfaces de rede de 100 Mbps ou uma interface
de 1 Gbps. Para 40 PCs, 5 lâminas contendo cada uma oito interfaces de rede são
suficientes para garantir a conectividade dentro da prateleira. Mais duas lâminas,
cada uma suportando uma interface de rede de 1 Gbps, são usadas para conexão
com o mundo externo.
• Os racks são organizados em clusters (conforme discutido na Seção 1.3.4), que são
uma unidade de gerenciamento importante, determinando, por exemplo, a locali-
zação e a replicação de serviços. Normalmente, um cluster consiste em 30 ou mais
racks e dois switches de alta largura de banda, fornecendo conectividade para o
mundo externo (a Internet e outros centros do Google). Por redundância, cada rack
é conectado aos dois switches; além disso, para ter ainda mais redundância, cada
switch tem enlaces redundantes para o mundo externo.
• Os clusters ficam em centros de dados do Google espalhados pelo mundo. Em
2000, o Google contava com importantes centros de dados no Vale do Silício (dois
centros) e na Virgínia, nos Estados Unidos. Quando este livro estava sendo produzi-
do, o número de centros de dados tinha aumentado significativamente e agora exis-
tem centros em muitos lugares nos Estados Unidos, além de em Dublin (Irlanda),
Saint-Ghislain (Bélgica), Zurique (Suiça), Tóquio (Japão) e Pequim (China). Um
mapa dos centros de dados conhecidos em 2008 pode ser encontrado em [royal.
pingdom.com].
Uma visão simplificada dessa organização global aparece na Figura 21.3. Essa infra-
estrutura física proporciona ao Google recursos de armazenamento e computacionais
enormes, junto à redundância necessária para a construção de sistemas de larga escala e
tolerantes a falhas (note que, para evitar confusão, essa figura mostra apenas as conexões
Ethernet de um dos clusters para os enlaces externos).
Capacidade de armazenamento: consideremos a capacidade de armazenamento
disponível no Google. Se cada PC oferece 2 terabytes de armazenamento, então um
rack com 80 PCs fornecerá 160 terabytes, com um cluster de 30 racks oferecendo
4,8 petabytes. Não se sabe exatamente quantas máquinas o Google tem no total, pois
a empresa mantém estrito sigilo a respeito desse aspecto de seu negócio, mas pode-
mos supor que tenha perto de 200 clusters, oferecendo uma capacidade de armaze-
namento total de 960 petabytes ou quase 1 exabyte de armazenamento (10
18
bytes).
É provável que esse valor seja conservador, pois a vice-presidente do Google, Ma-
rissa Mayer, já fala sobre a explosão de dados à faixa da exaescala [www.parc.com].
Coulouris_21.indd 923
Coulouris_21.indd 923 23/05/13 09:26
23/05/13 09:26
924 Sistemas Distribuídos, Conceitos e Projeto
No restante deste capítulo, veremos como o Google utiliza esse recurso de armazena-
mento e computacional extensivo e a redundância associada para oferecer serviços básicos.
21.3.2 Arquitetura de sistema global
Antes de examinarmos a arquitetura de sistema global, é interessante verificarmos os
principais requisitos com mais detalhes:
Escalabilidade: o primeiro e mais óbvio requisito para a infraestrutura do Goo-
gle é controlar a escalabilidade e, em particular, ter estratégias que se adaptem
ao que é um sistema distribuído ULS (Ultra-Large Scale), conforme apresentado
no Capítulo 2. Para o mecanismo de busca, o Google vê o problema da escala-
bilidade em termos de três dimensões: i) ser capaz de lidar com mais dados (por
exemplo, à medida que o volume de informações na Web aumenta por meio de
iniciativas como a digitalização de bibliotecas), ii) ser capaz de tratar de mais
consultas (à medida que aumenta o número de pessoas que usam o Google em
suas casas e locais de trabalho) e iii) procurar resultados melhores (particular-
mente importante, pois esse é um fator determinante no funcionamento de um
mecanismo de pesquisa na Web). Essa visão do problema da escalabilidade está
ilustrada na Figura 21.4.
A escalabilidade exige o uso de estratégias (sofisticadas) de sistemas distri-
buídos. Vamos ilustrar isso com uma análise simples extraída da ideia básica de
Racks
......
Cluster
Racks
......
Cluster
Racks
......
Cluster
Arquitetura do centro de dados
Para outros centros de dados e para a Internet
X
Switches
Switches
X
X X
X X
X
X X
X X
X
X
X X X
X X X
X
(Para simplificar o diagrama, é mostrada a conexão Ethernet de um dos clusters com a Internet.)
Figura 21.3 Organização da infraestrutura física do Google.
Coulouris_21.indd 924
Coulouris_21.indd 924 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 925
Jeff Dean no PACT’06 [Dean 2006]. Ele presumiu que a Web consiste em cerca
de 20 bilhões de páginas com 20 quilobytes cada uma. Isso significa um tamanho
total de cerca de 400 terabytes. Examinar esse volume de dados exigiria mais de
4 meses para um único computador, supondo que esse computador possa ler 30
megabytes por segundo. Em contraste, 1.000 máquinas podem ler esse volume de
dados em menos de 3 horas. Além disso, conforme vimos na Seção 21.2, pesqui-
sar não envolve apenas esquadrinhar. Todas as outras funções, incluindo indexar,
classificar e pesquisar, exigem soluções altamente distribuídas para que seja pos-
sível fazer a adaptação.
Confiabilidade: o Google tem requisitos de confiabilidade rigorosos, especial-
mente com relação à disponibilidade de serviços. Isso é particularmente impor-
tante para a funcionalidade de pesquisa, em que há necessidade de oferecer dis-
ponibilidade 24 horas por dia, sete dias por semana (notando, contudo, que é
intrinsecamente fácil mascarar falhas em pesquisas, pois o usuário não tem como
saber se todos os resultados foram retornados). Esse requisito também serve para
outras aplicações Web e é interessante notar que o Google oferece um acordo de
nível de serviço de 99,9% (efetivamente uma garantia de sistema) para clientes
que pagam pelo Google Apps, cobrindo o Gmail, o Google Calendar, o Goo-
gle Docs, o Google Sites e o Google Talk. A empresa tem um excelente recorde
global em termos de disponibilidade de serviços, mas a conhecida interrupção
do Gmail em 1º de setembro de 2009 serve como um lembrete dos contínuos
desafios nessa área. (Essa interrupção, que durou 100 minutos, foi causada por
um problema em cascata de servidores sobrecarregados durante um período de
manutenção de rotina). Note que o requisito da confiabilidade deve ser satisfeito
no contexto das escolhas de projeto na arquitetura física, o que significa que as
falhas (de software e hardware) são antecipadas com frequência razoável. Isso
exige detecção de falhas e a adoção de estratégias para mascarar ou tolerar tais
falhas. Essas estratégias contam pesadamente com a redundância na arquitetura
física subjacente. Veremos exemplos dessas estratégias à medida que os detalhes
da arquitetura de sistema surgirem.
Desempenho: o desempenho global do sistema é fundamental para o Google, es-
pecialmente na obtenção de baixa latência de interações do usuário. Quanto melhor
Mais dados
Mais consultas
Melhores resultados
Figura 21.4 O problema da escalabilidade no Google.
Coulouris_21.indd 925
Coulouris_21.indd 925 23/05/13 09:26
23/05/13 09:26
926 Sistemas Distribuídos, Conceitos e Projeto
o desempenho, mais provável será que um usuário retorne com mais consultas que,
por sua vez, aumentam a exposição de anúncios, potencialmente aumentando os
lucros. A importância do desempenho é exemplificada, por exemplo, com a meta
de concluir operações de pesquisa na Web em 0,2 segundos (conforme menciona-
do anteriormente) e obter o desempenho de saída exigido para responder a todas
as requisições recebidas, enquanto lida com conjuntos de dados muito grandes.
Isso se aplica a uma ampla variedade de funções associadas à operação do Google,
incluindo esquadrinhamento da Web, indexação e classificação. Também é impor-
tante notar que o desempenho é uma propriedade fim-a-fim, exigindo que todos os
recursos associados funcionem juntos, incluindo recursos de rede, armazenamento
e computacionais.
Abertura: de muitas maneiras, os requisitos anteriores são óbvios para o Google
suportar seus serviços e aplicações básicos. Há também um forte requisito de aber-
tura, particularmente para suportar mais desenvolvimento na variedade de aplica-
ções Web oferecidas. Sabe-se que o Google, como organização, estimula e cultiva
a inovação, e isso fica mais evidente no desenvolvimento de novas aplicações Web.
Isso só é possível com uma infraestrutura extensível e que dê suporte para o desen-
volvimento de novas aplicações.
O Google tem respondido a essas necessidades desenvolvendo a arquitetura
de sistema global mostrada na Figura 21.5. Essa figura mostra a plataforma de
computação na parte inferior (isto é, a arquitetura física descrita anteriormente)
e os conhecidos serviços e aplicações do Google na parte superior. A camada do
meio define uma infraestrutura distribuída comum que fornece suporte de midd-
leware para pesquisa e computação em nuvem. Isso é fundamental para o suces-
so do Google. A infraestrutura fornece os serviços de sistema distribuído comuns
para os desenvolvedores de serviços e aplicações Google e encapsula as principais
estratégias para lidar com escalabilidade, confiabilidade e desempenho. O forne-
cimento de uma infraestrutura comum bem projetada como essa pode promover
o desenvolvimento de novas aplicações e serviços por meio da reutilização dos
serviços de sistema subjacentes e, mais sutilmente, fornece uma coerência global
para o crescimento da base de código do Google, impondo estratégias e princípios
de projeto comuns.
Aplicações e serviços do Google
Plataforma do Google
Infraestrutura do Google (middleware)
Figura 21.5 A arquitetura global de sistemas do Google.
Coulouris_21.indd 926
Coulouris_21.indd 926 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 927
Infraestrutura do Google • O sistema é construído como um conjunto de serviços distri-
buídos que oferecem funcionalidade básica para os desenvolvedores (veja a Figura 21.6).
Esse conjunto de serviços é naturalmente dividido nos seguintes subconjuntos:
• os paradigmas de comunicação subjacentes, incluindo serviços para invocação re-
mota e comunicação indireta:
– o componente buffers de protocolo oferece um formato de serialização co-
mum para o Google, incluindo a serialização de requisições e respostas na
invocação remota.
– o serviço de publicar-assinar do Google suporta a disseminação eficiente de
eventos para números potencialmente grandes de assinantes.
• serviços de dados e coordenação, fornecendo abstrações não estruturadas e semies-
truturadas para o armazenamento de dados acoplado a serviços para suportar o
acesso coordenado aos dados:
– O GFS oferece um sistema de arquivos distribuído otimizado para os requisitos
específicos de aplicações e serviços do Google (incluindo o armazenamento de
arquivos muito grandes).
– O Chubby suporta serviços de coordenação e a capacidade de armazenar volu-
mes de dados menores.
– A Bigtable fornece um banco de dados distribuído que dá acesso a dados
semiestruturados.
• serviços de computação distribuída, que oferecem meios para executar computação
paralela e distribuída na infraestrutura física:
– O MapReduce suporta computação distribuída em conjuntos de dados potencial-
mente muito grandes (por exemplo, armazenados na Bigtable).
Publicar-assinar
GFS Chubby Bigtable
Sawzall
Paradigmas de comunicação
Dados e coordenação
Computação distribuída
MapReduce
Buffers de protocolo
Figura 21.6 Infraestrutura do Google.
Coulouris_21.indd 927
Coulouris_21.indd 927 23/05/13 09:26
23/05/13 09:26
928 Sistemas Distribuídos, Conceitos e Projeto
– A Sawzall é uma linguagem de nível mais alto para a execução de tais computa-
ções distribuídas.
Examinaremos cada um desses componentes por vez, nas Seções 21.4 a 21.6. Primeiro,
contudo, é instrutivo refletir sobre os principais princípios de projeto associados à arqui-
tetura como um todo.
Princípios de projeto • Para se entender completamente o projeto da infraestrutura do
Google, é importante entender também as principais filosofias de projeto que permeiam
a organização:
• O princípio de projeto mais importante por trás do software Google é a simplicida-
de: o software deve fazer apenas uma coisa e fazê-la bem, evitando projetos cheios
de recursos, quando possível. Por exemplo, Bloch [2006] discute como esse prin-
cípio se aplica no projeto da API, implicando que a API deva ser a menor possível
(um exemplo da aplicação de Razor de Occam).
• Outro importante princípio de projeto é uma forte ênfase no desempenho no desen-
volvimento de software de sistemas, capturada na frase “cada milissegundo conta”
[www.google.com IV]. Em uma exposição de princípios básicos na LADIS’09,
Jeff Dean (membro do Google Systems Infrastructure Group) enfatizou a impor-
tância de ser possível estimar o desempenho de um projeto de sistema conhecendo-
-se os custos do desempenho de operações primitivas, como acesso à memória e
ao disco, envio de pacotes por uma rede, travamento e destravamento de um mu-
tex, etc., acoplado ao que ele se referiu como cálculos no “verso do envelope”
[www.cs.cornell.edu].
• Um último princípio é defender regimes de teste rigorosos no software,
capturado pelo slogan “se não quebrou, você não se esforçou o bastante”
[googletesting.blogspot.com]. Isso é complementado por uma forte ênfase no re-
gistro e rastreamento para detectar e resolver falhas no sistema.
Com essas informações, estamos prontos para examinar as várias partes constituin-
tes da infraestrutura do Google, começando com os paradigmas de comunicação sub-
jacentes. Para cada área, apresentaremos o projeto global e destacaremos as principais
decisões de projeto e compromissos associados.
21.4 Paradigmas de comunicação
Recordando os Capítulos 3 a 6, fica claro que a escolha do paradigma (ou paradigmas) de
comunicação subjacente é fundamental para o sucesso de um projeto de sistema global.
As opções incluem:
• usar diretamente um serviço de comunicação entre processos subjacente, como o
oferecido pelas abstrações de soquete (descritas no Capítulo 4 e suportadas por
todos os sistemas operacionais modernos);
• usar um serviço de invocação remota (como um protocolo de requisição-resposta,
chamadas de procedimento remoto ou invocação a método remoto, conforme dis-
cutido no Capítulo 5), oferecendo suporte para interações cliente-servidor;
• usar um paradigma de comunicação indireta, como comunicação em grupo, estraté-
gias baseadas em eventos distribuídos, espaços de tupla ou estratégias de memória
compartilhada distribuída (conforme discutido no Capítulo 6).
Coulouris_21.indd 928
Coulouris_21.indd 928 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 929
De conformidade com os princípios de projeto identificados na Seção 21.3, o Google
adota um serviço de invocação remota simples, mínimo e eficiente que é uma variante de
uma estratégia de chamada de procedimento remoto.
Os leitores se lembrarão de que a comunicação por chamada de procedimento re-
moto exige um componente de serialização para converter os dados da invocação de
procedimento (nome do procedimento e parâmetros, possivelmente estruturados) de sua
representação binária interna para um formato plano ou serializado neutro quanto ao
processador, pronto para transmissão ao parceiro remoto. A serialização para RPC Java
foi descrita na Seção 4.3.2. XML surgiu mais recentemente como um formato de dados
serializados “universal”, mas sua generalidade apresenta sobrecargas substantiais. Por-
tanto, o Google desenvolveu um componente de serialização simplificado e de alto de-
sempenho, conhecido como buffers de protocolo, que é usado pela maioria significativa
das interações dentro da infraestrutura. Isso pode ser usado em qualquer mecanismo de
comunicação subjacente para fornecer um recurso de RPC. Existe uma versão de código-
-fonte aberto do componente buffers de protocolo [code.google.com II].
Um serviço de publicar-assinar separado também é usado, reconhecendo a im-
portante função que esse paradigma pode oferecer em muitas áreas do projeto de sis-
tema distribuído, incluindo a disseminação de eventos eficiente e em tempo real para
vários participantes. Em comum com muitas outras plataformas de sistema distribuído,
a infraestrutura do Google oferece uma solução mista, permitindo aos desenvolvedores
selecionar o melhor paradigma de comunicação para seus requisitos. O protocolo de
publicação-assinatura não é uma alternativa ao componente buffers de protocolo na infra-
estrutura do Google, mas um acréscimo, oferecendo um serviço de valor agregado onde
for mais apropriado.
Examinaremos o projeto dessas duas estratégias, a seguir, com ênfase no compo-
nente buffers de protocolo (detalhes completos sobre o protocolo de publicar-assinar ain-
da não estão publicamente disponíveis).
21.4.1 Invocação remota
O componente buffers de protocolo enfatiza a descrição e a subsequente serialização
dos dados e, assim, o conceito é mais bem comparado com as alternativas diretas, como
XML. O objetivo é fornecer uma maneira, neutra quanto à linguagem e quanto à platafor-
ma, de especificar e serializar dados de modo simples, altamente eficiente e extensível;
os dados serializados podem, então, ser usados para armazenamento subsequente ou para
transmissão, usando um protocolo de comunicação subjacente, ou mesmo para qualquer
outro propósito que exija um formato de serialização para dados estruturados. Veremos,
posteriormente, como isso pode ser utilizado como base para troca estilo RPC.
No componente buffers de protocolo, é fornecida uma linguagem para a especifi-
cação de mensagens. Apresentamos os principais recursos dessa linguagem (simples)
por meio de um exemplo, com a Figura 21.7 mostrando como uma mensagem Book
poderia ser especificada.
Como pode ser visto, a mensagem Book consiste em uma série de campos numera-
dos exclusivamente, cada um representado por um nome e pelo tipo do valor associado.
O tipo pode ser:
• um tipo de dados primitivo (incluindo inteiro, ponto flutuante, booleano, string ou
bytes brutos);
• um tipo enumerado;
• uma mensagem aninhada, permitindo uma estruturação de dados hierárquica.
Coulouris_21.indd 929
Coulouris_21.indd 929 23/05/13 09:26
23/05/13 09:26
930 Sistemas Distribuídos, Conceitos e Projeto
Podemos ver exemplos de cada um na Figura 21.7.
Os campos são anotados com um de três rótulos:
• os campos required devem estar presentes na mensagem;
• os campos optional podem estar presentes na mensagem;
• os campos repeated podem existir zero ou mais vezes na mensagem (os desen-
volvedores do componente buffers de protocolo veem isso como um tipo de vetor
dimensionado dinamicamente).
Novamente, podemos ver o uso de cada uma dessas anotações no formato da mensagem
Book ilustrados na Figura 21.7.
A numeração exclusiva (=1, =2, etc.) representa a marca (tag) que um campo em
particular tem na codificação binária da mensagem.
Essa especificação está contida em um arquivo .proto e é compilada pela ferramen-
ta protoc. A saída dessa ferramenta é código gerado que permite aos programadores ma-
nipular o tipo de mensagem específico, em particular atribuir/extrair valores a/de men-
sagens. Em mais detalhes, a ferramenta protoc gera uma classe construtor que fornece
métodos getter e setter para cada campo, junto a métodos adicionais para testar se um
método foi ativado e para limpar um campo com o valor nulo associado. Por exemplo, os
seguintes métodos seriam gerados para o campo title:
public boolean hasTitle();
public java.lang.String getTitle();
public Builder setTitle(String value);
public Builder clearTitle();
A importância da classe construtor é que, embora as mensagens sejam imutáveis no com-
ponente buffers de protocolo, os construtores são mutáveis e usados para construir e ma-
nipular novas mensagens.
Para campos repeated, o código gerado é um pouco mais complicado, com méto-
dos fornecidos para retornar uma contagem do número de elementos na lista associada,
para obter ou configurar campos específicos na lista, para anexar um novo elemento
message Book {
required string title = 1;
repeated string author = 2;
enum Status {
IN_PRESS = 0;
PUBLISHED = 1;
OUT_OF_PRINT = 2;
}
message BookStats {
required int32 sales = 1;
optional int32 citations = 2;
optional Status bookstatus = 3 [default = PUBLISHED];
}
optional BookStats statistics = 3;
repeated string keyword = 4;
}
Figura 21.7 Exemplo de buffers de protocolo.
Coulouris_21.indd 930
Coulouris_21.indd 930 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 931
em uma lista e para adicionar um conjunto de elementos na lista (o método addAll).
Ilustramos isso por meio de um exemplo, listando os métodos gerados para o campo
keyword:
public List<string> getKeywordList();
public int getKeywordCount();
public string getKeyword(int index);
public Builder setKeyword(int index, string value);
public Builder addKeyword(string value);
public Builder addAllKeyword(Iterable<string> value);
public Builder clearKeyword();
O código gerado também fornece diversos outros métodos para manipular mensagens,
incluindo métodos como toString para fornecer uma representação legível da mensagem
(frequentemente usada para depuração, por exemplo) e também uma série de métodos
para analisar as mensagens recebidas.
Como se pode ver, esse é um formato muito simples, comparado com XML (por
exemplo, compare a especificação anterior com as especificações equivalentes em XML,
mostradas na Seção 4.3.3), e que seus desenvolvedores dizem ser de 3 a 10 vezes menor
do que os equivalentes em XML e de 10 a 100 vezes mais rápido na operação. A interface
de programação associada que dá acesso aos dados também é consideravelmente mais
simples do que as equivalentes para XML.
Note que essa é uma comparação um tanto injusta, por dois motivos. Primeiramen-
te, a infraestrutura do Google é um sistema relativamente fechado e, assim, ao contrário
de XML, não trata da operação conjunta de sistemas abertos. Em segundo lugar, XML é
significativamente mais rica, pois gera mensagens autodescritivas que contêm os dados
e os metadados associados descrevendo a estrutura das mensagens (veja a Seção 4.3.3).
O componente buffers de protocolo não fornece essa facilidade diretamente (embora seja
possível obter esse efeito, conforme descrito nas páginas Web relevantes, em uma seção
sobre técnicas [code.google.com II]). Em linhas gerais, isso é obtido pedindo-se para que
o compilador protoc gere um FileDescriptorSet contendo autodescrições das mensagens
e, então, incluindo-se isso explicitamente nas descrições da mensagem. Contudo, os de-
senvolvedores do componente buffers de protocolo enfatizam que isso não é visto como
um recurso particularmente útil e que raramente é usado no código da infraestrutura do
Google.
Suporte para RPC • Conforme mencionado anteriormente, o componente buffers de pro-
tocolo é um mecanismo geral que pode ser usado para armazenamento ou comunicação.
Contudo, o uso mais comum de buffers de protocolo é na especificação de trocas RPC na
rede, e isso é realizado com uma sintaxe extra na linguagem. Novamente, ilustraremos a
sintaxe por meio de um exemplo:
service SearchService {
rpc Search (RequestType) returns (ResponseType);
}
Esse trecho de código especifica uma interface de serviço chamada SearchService con-
tendo uma operação remota, Search, que recebe um parâmetro de tipo RequestType e re-
torna um parâmetro de tipo ResponseType. Por exemplo, os tipos poderiam corresponder
a uma lista de palavras-chave e uma lista de livros (Books) correspondendo a esse con-
Coulouris_21.indd 931
Coulouris_21.indd 931 23/05/13 09:26
23/05/13 09:26
932 Sistemas Distribuídos, Conceitos e Projeto
junto de palavras-chave respectivamente. O compilador protoc pega essa especificação
e produz uma interface abstrata SearchService e um stub que suporta chamadas no estilo
RPC seguras quanto ao tipo para o serviço remoto, usando buffers de protocolo.
Além de ser neutro quanto à linguagem e quanto à plataforma, o componente
buffers de protocolo também é agnóstico com relação ao protocolo RPC subjacente.
Em particular, o stub presume que existem implementações para duas interfaces abs-
tratas RpcChannel e RpcController, a primeira oferecendo uma interface comum para
as implementações RPC subjacentes e a última oferecendo uma interface de controle
comum, por exemplo, para manipular as configurações associadas a essa implementa-
ção. O programador deve fornecer implementações dessas interfaces abstratas, efeti-
vamente selecionando a implementação de RPC desejada. Por exemplo, isso poderia
passar mensagens serializadas usando HTTP ou TCP, ou poderia mapear em uma de
várias implementações de RPC de terceiros disponíveis e vinculadas do local do com-
ponente buffers de protocolo [code.google.com III].
Note que uma interface de serviço pode suportar várias operações remotas, mas
cada operação deve obedecer ao padrão de pegar um único parâmetro e retornar ape-
nas um resultado (sendo ambas mensagens de buffer de protocolo). Isso é incomum,
comparado aos projetos de sistemas RPC e RMI – como vimos no Capítulo 5 –, pois
as invocações remotas podem ter um número arbitrário de parâmetros e, no caso da
RMI, os parâmetros ou resultados podem ser objetos ou mesmo referências de objeto
(embora deva ser notado que a RPC da Sun, conforme documentado na Seção 5.3.3,
adota uma estratégia semelhante ao componente buffers de protocolo). O fundamento
lógico para se ter uma requisição e uma resposta é para dar suporte à capacidade de
extensão e à evolução do software; embora os estilos mais gerais de interface possam
mudar significativamente com o passar do tempo, há uma maior probabilidade de que
este estilo mais restrito de interface permaneça constante. Essa estratégia também
joga a complexidade para os dados, de uma maneira que lembra a filosofia REST,
com seu conjunto de operações restrito e sua ênfase nos recursos de manipulação
(veja a Seção 9.2).
21.4.2 Publicar-assinar
O componente buffers de protocolo é usado extensivamente, mas não exclusivamente,
como paradigma de comunicação na infraestrutura do Google. Para complementar o
componente buffers de protocolo, a infraestrutura também suporta um sistema de publi-
cação-assinatura destinado a ser usado quando eventos distribuídos precisam ser disse-
minados em tempo real e com garantias de confiabilidade para números potencialmente
grandes de destinatários. Conforme mencionado anteriormente, o serviço de publicação-
-assinatura é acréscimo ao componente buffers de protocolo e, na verdade, utiliza esse
componente para sua comunicação subjacente.
Um uso importante do sistema de publicar-assinar, por exemplo, é servir de base
para o sistema Google Ads, reconhecendo que, no Google, os anúncios têm abragência
mundial e que sistemas anunciantes de qualquer lugar na rede precisam saber, em uma
fração de segundo, a eligibilidade de certas propagandas que podem ser mostradas em
resposta a uma consulta.
O sistema RPC descrito anteriormente seria claramente inadequado e altamente
ineficiente para esse estilo de interação, especialmente por causa dos números poten-
cialmente grandes de assinantes e das garantias exigidas pelas aplicações associadas.
Coulouris_21.indd 932
Coulouris_21.indd 932 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 933
Em particular, o remetente precisaria conhecer a identidade de todos os outros sistemas
anunciantes, o que poderia ser muito grande. As RPCs precisariam ser enviadas para
todos os sistemas individuais, consumindo muitas conexões e um enorme espaço de
buffer associado no remetente, sem mencionar os requisitos de largura de banda para
enviar os dados pelos enlaces de rede de longo alcance. Em contraste, uma solução
publicar-assinar, com seu inerente desacoplamento temporal e espacial, supera essas
dificuldades e também oferece suporte natural para falha e recuperação de assinantes
(veja a Seção 6.1).
O Google não tornou disponível publicamente os detalhes do sistema de publi-
car-assinar. Portanto, restringiremos nossa discussão a alguns recursos de alto nível
do sistema.
O Google adota um sistema de publicar-assinar baseado em tópicos, fornecendo
vários canais para fluxos de evento, com os canais correspondendo a tópicos em particu-
lar. Foi escolhido um sistema baseado em tópicos por sua facilidade de implementação
e sua relativa previsibilidade em termos de desempenho, em comparação com as estraté-
gias baseadas em conteúdo – isto é, a infraestrutura pode ser configurada e personaliza-
da para distribuir eventos relacionados a determinado tópico. O inconveniente é a falta
de poder expressivo na especificação de eventos de interesse. Como um compromisso,
o sistema de publicar-assinar do Google permite assinaturas aprimoradas, definidas não
somente pela seleção de um canal, mas também pela seleção de subconjuntos de eventos
dentro desse canal. Em particular, um evento consiste em um cabeçalho, um conjunto de
palavras-chave associadas e uma carga útil, que é opaca para o programador. As requi-
sições de assinatura especificam o canal, junto a um filtro definido sobre o conjunto de
palavras-chave. Os canais se destinam a ser usados para fluxos de dados relativamente
estáticos e brutos, exigindo alto desempenho de saída de eventos (pelo menos 1 Mbps),
de modo que a capacidade adicional de expressar assinaturas refinadas usando filtros
ajuda muito. Por exemplo, se um tópico gerar menos do que esse volume de dados,
eles serão incluídos dentro de outro tópico, mas poderão ser identificados pela palavra-
-chave.
O sistema de publicar-assinar é implementado como uma sobreposição de despa-
chantes na forma de um conjunto de árvores, onde cada árvore representa um tópico. A
raiz da árvore é o publicador e os nós-folha representam os assinantes. Quando filtros são
introduzidos, eles são colocados o mais abaixo na árvore possível para minimizar tráfego
desnecessário.
Ao contrário dos sistemas de publicar-assinar discutidos no Capítulo 6, há uma
forte ênfase na entrega confiável e oportuna:
• Em termos de confiabilidade, o sistema mantém árvores redundantes; em particu-
lar, são mantidas duas sobreposições de árvore separados por canal (tópico) lógico.
• Em termos de entrega dentro de prazos, o sistema implementa uma técnica de ge-
renciamento de qualidade de serviço para controlar os fluxos de mensagem. Em
particular, um esquema de controle de taxa simples é introduzido, com base em um
limite de taxa obrigatório, imposto de acordo com o usuário/tópico. Isso substitui
uma estratégia mais complexa e gerencia a utilização antecipada de recursos na
árvore em termos de memória, CPU e taxas de mensagem e bytes.
Inicialmente, as árvores são construídas e constantemente reavaliadas de acordo com um
algoritmo de caminho mais curto (veja o Capítulo 3).
Coulouris_21.indd 933
Coulouris_21.indd 933 23/05/13 09:26
23/05/13 09:26
934 Sistemas Distribuídos, Conceitos e Projeto
21.4.3 Resumo das principais escolhas de projeto para a comunicação
As escolhas de projeto globais relacionadas aos paradigmas de comunicação no Google
estão resumidas na Figura 21.8. Essa tabela destaca as decisões mais importantes asso-
ciadas ao projeto global e aos elementos constituintes (buffers de protocolo e o sistema
de publicar-assinar) e resume o fundamento lógico e os compromissos específicos asso-
ciados a cada escolha.
No todo, vimos uma estratégia mista que oferece dois paradigmas de comunicação
distintos, projetados para suportar diferentes estilos de interação dentro da arquitetura.
Isso permite aos desenvolvedores escolher o melhor paradigma para cada domínio de
problema em particular.
Vamos repetir esse estilo de análise ao final de cada uma das seções a seguir, for-
necendo, assim, uma perspectiva global das principais decisões de projeto relacionadas à
infraestrutura do Google.
Elemento Escolha de projeto Fundamento lógico Compromissos
Buffers de protocolo O uso de uma linguagem
para especificar formatos
de dados
Flexível, pois a mesma
linguagem pode ser
usada para serializar
dados para armazena-
mento ou comunicação
–
Simplicidade da
linguagem
Implementação
eficiente
Falta de expressividade
quando comparado,
por exemplo, com XML
Suporte para um estilo
de RPC (recebendo uma
única mensagem como
parâmetro e retornando
uma única mensagem
como resultado)
Mais eficiente,
extensível e suporta
evolução do serviço
Falta de expressividade
quando comparado
com outros pacotes
de RPC ou RMI
Projeto agnóstico
quanto ao protocolo
Podem ser usadas
diferentes implemen-
tações de RPC
Nenhuma semântica
comum para trocas RPC
Publicar-assinar Estratégia baseada
em tópicos
Suporta implementação
eficiente
Menos expressiva do
que as estratégias
baseadas em conteúdo
(atenuado pelos recursos
de filtragem adicionais)
Garantias de tempo
real e confiabilidade
Suporta a manutenção
de modos de exibição
consistentes de maneira
oportuna
Suporte para algoritmo
adicional exigido com
sobregarga associada
Figura 21.8 Resumo das escolhas de projeto relacionadas aos paradigmas de comunicação.
Coulouris_21.indd 934
Coulouris_21.indd 934 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 935
21.5 Serviços de armazenamento de dados e coordenação
Apresentaremos agora os três serviços que, juntos, fornecem serviços de dados e coorde-
nação para aplicações e serviços de nível mais alto: o Google File System, o Chubby e a
Bigtable. São serviços complementares na infraestrutura do Google:
• O Google File System é um sistema de arquivos distribuído que oferece servi-
ço semelhante ao do NFS e do AFS, conforme discutido no Capítulo 12. Ele dá
acesso a dados não estruturados na forma de arquivos, mas otimizados para os
estilos de dados e acesso a dados exigidos pelo Google (arquivos muito grandes,
por exemplo).
• O Chubby é um serviço multifacetado, suportando, por exemplo, travas distribuí-
das para coordenação no ambiente distribuído e o armazenamento de quantidades
muito pequenas de dados, complementando o armazenamento em larga escala ofe-
recido pelo Google File System.
• A Bigtable dá acesso a dados mais estruturados na forma de tabelas, que podem ser
indexadas de várias maneiras, inclusive por linha ou coluna. Portanto, a Bigtable
é um estilo de banco de dados distribuído, mas, ao contrário de muitos bancos de
dados, não suporta operadores totalmente relacionais (eles são vistos pelo Google
como desnecessariamente complexos e não escaláveis).
Esses três serviços também são interdependentes. Por exemplo, a Bigtable usa o Google
File System para armazenamento e o Chubby, para coordenação.
Examinaremos cada serviço em detalhes a seguir.
21.5.1 O Google File System (GFS)
O Capítulo 12 apresentou um estudo detalhado sobre o tema dos sistemas de arquivos
distribuídos, analisando seus requisitos, sua arquitetura global e examinando dois estu-
dos de caso em detalhes, a saber, NFS e AFS. Esses sistemas de arquivos são sistemas de
arquivos distribuídos de propósito geral que oferecem abstrações de arquivo e diretório
para uma ampla variedade de aplicações dentro e entre organizações. O Google File
System (GFS) também é um sistema de arquivos distribuído; ele oferece abstrações se-
melhantes, mas especializadas para os requisitos específicos do Google, em termos de
armazenamento e acesso a quantidades de dados muito grandes [Ghemawat et al. 2003].
Esses requisitos levaram a decisões de projeto muito diferentes das tomadas no NFS e no
AFS (e, na verdade, em outros sistemas de arquivos distribuídos), conforme veremos a
seguir. Começaremos nossa discussão sobre o GFS examinando os requisitos específicos
identificados pelo Google.
Requisitos do GFS • O objetivo global do GFS é atender às necessidades exigentes e ra-
pidamente crescentes do mecanismo de busca do Google e das diversas outras aplicações
Web oferecidas pela empresa. A partir do entendimento desse domínio de operação em
particular, o Google identificou os seguintes requisitos para o GFS (consulte Ghemawat
et al. [2003]):
• O primeiro requisito é que o GFS deve funcionar de forma confiável na arquitetura
física discutida na Seção 21.3.1 – ou seja, um sistema muito grande, construído a
partir de hardware comum. Os projetistas do GFS começaram com a suposição de
que os componentes falharão (não apenas componentes de hardware, mas também
de software) e de que o projeto deve ser suficientemente tolerante a tais falhas para
Coulouris_21.indd 935
Coulouris_21.indd 935 23/05/13 09:26
23/05/13 09:26
936 Sistemas Distribuídos, Conceitos e Projeto
permitir que serviços em nível de aplicação continuem sua operação diante de qual-
quer combinação provável de condições de falha.
• O GFS é otimizado para os padrões de utilização dentro do Google, tanto em ter-
mos dos tipos de arquivos armazenados como dos padrões de acesso a esses arqui-
vos. O número de arquivos armazenados no GFS não é grande em comparação com
outros sistemas, mas os arquivos tendem a ser pesados. Por exemplo, Ghemawat
et al [2003] relatam a necessidade de talvez um milhão de arquivos tendo em mé-
dia 100 megabytes de tamanho, mas com alguns arquivos na faixa dos gigabytes.
Os padrões de acesso também são atípicos dos sistemas de arquivos em geral. Os
acessos são dominados por leituras sequenciais em arquivos grandes e escritas se-
quenciais que anexam dados em arquivos, e o GFS é muito adequado a esse estilo
de acesso. Pequenas leituras e escritas aleatórias ocorrem (estas últimas muito rara-
mente) e são suportadas, mas o sistema não é otimizado para esses casos. Esses pa-
drões de arquivo são influenciados, por exemplo, pelo armazenamento sequencial
de muitas páginas Web em arquivos únicos, que são examinados por uma variedade
de programas de análise de dados. O nível de acesso concorrente também é alto no
Google, com grandes números de anexações concomitantes sendo particularmente
predominantes, frequentemente acompanhadas de leituras concorrentes.
• O GFS deve satisfazer todos os requisitos da infraestrutura do Google como um
todo; isto é; deve ser flexível (particularmente em termos de volume de dados e nú-
mero de clientes), deve ser confiável, apesar da suposição a respeito das falhas men-
cionada anteriormente, deve funcionar bem e deve ser aberto no sentido de suportar
o desenvolvimento de novas aplicações Web. Em termos de desempenho e dados os
tipos de arquivo de dados armazenados, o sistema é otimizado para rendimento alto
e prolongado na leitura de dados e isso tem prioridade em relação à latência. Não
quer dizer que a latência não seja importante, mas sim que esse componente (o GFS)
em particular precisa ser otimizado para leitura de alto desempenho e anexação de
grandes volumes de dados para a operação correta do sistema como um todo.
Esses requisitos são acentuadamente diferentes dos existentes para o NFS e o AFS (por
exemplo), que devem armazenar grandes números de arquivos frequentemente pequenos
e em que as leituras e escritas aleatórias são comuns. Essas distinções levaram às deci-
sões de projeto muito particulares, discutidas a seguir.
Interface do GFS • O GFS fornece uma interface de sistema de arquivos convencional,
oferecendo um espaço de nomes hierárquico com os arquivos individuais identificados
por nomes de caminho. Embora o sistema de arquivos não ofereça total compatibilidade
com POSIX, muitas das operações são conhecidas dos usuários desses sistemas de arqui-
vos (veja, por exemplo, a Figura 12.4):
create – cria uma nova instância de um arquivo;
delete – exclui uma instância de um arquivo;
open – abre um arquivo nomeado e retorna um identificador (handle);
close – fecha um arquivo especificado por um identificador (handle);
read – lê dados de um arquivo especificado;
write – escreve dados em um arquivo especificado.
Pode-se ver que as principais operações do GFS são muito parecidas com as do serviço
de arquivo plano, descritas no Capítulo 12 (veja a Figura 12.6). Devemos supor que as
Coulouris_21.indd 936
Coulouris_21.indd 936 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 937
operações read e write do GFS recebem um parâmetro especificando um deslocamento
inicial dentro do arquivo, como acontece no serviço de arquivo plano.
A API também oferece duas operações mais especializadas, snapshot e record
append. A primeira operação fornece um mecanismo eficiente para fazer uma cópia de
um arquivo em particular ou da estrutura em árvore do diretório. A última suporta o
padrão de acesso comum mencionado anteriormente, por meio do qual vários clientes
realizam anexações concorrentes em determinado arquivo.
Arquitetura do GFS • A escolha de projeto mais influente no GFS é o armazenamento de
arquivos em trechos de tamanho fixo, em que cada trecho tem 64 megabytes. Isso é muito
grande, comparado aos outros projetos de sistema de arquivos. Em um nível, isso sim-
plesmente reflete o tamanho dos arquivos armazenados no GFS. Em outro nível, essa de-
cisão é fundamental para fornecer leituras sequenciais altamente eficientes e anexações
de grandes volumes de dados. Voltaremos a esse ponto posteriormente, quando tivermos
discutido mais detalhes da arquitetura do GFS.
Dada essa escolha de projeto, a tarefa do GFS é fornecer um mapeamento dos
arquivos em trechos e, então, suportar operações padrão em arquivos, mapeando nas
operações em trechos individuais. Isso é obtido com a arquitetura ilustrada na Figura
21.9, que mostra uma instância de um sistema de arquivos GFS mantida em um cluster
físico. Cada cluster GFS tem um só mestre e vários chunkservers (servidores de trecho)
(normalmente na ordem de centenas) que, juntos, fornecem um serviço de arquivo para
grandes números de clientes que acessam os dados de forma concorrente.
A função do mestre é gerenciar metadados sobre o sistema de arquivos, definindo
o espaço de nomes para arquivos, informações de controle de acesso e o mapeamento
de cada arquivo em particular no conjunto de trechos associado. Além disso, todos os
trechos são replicados (por padrão, em três chunkservers independentes, mas o nível de
replicação pode ser especificado pelo programador). A localização das réplicas é mantida
no mestre. A replicação é importante no GFS, para fornecer a confiabilidade necessária
no caso de falhas (esperadas) de hardware e software. Isso contrasta com o NFS e o AFS,
que não fornecem replicação com atualizações (veja o Capítulo 12).
Os principais metadados são armazenados de forma persistente em um registro
de operação que suporta recuperação em caso de colapsos (novamente, aumentando
a confiabilidade). Em particular, todas as informações mencionadas anteriormente
são registradas, com exceção da localização das réplicas (esta última é recuperada
por eleição de chunkservers e perguntando-se a eles quais réplicas armazenam no
momento).
Biblioteca
de cliente
do GFS
Mestre do GFS
Chunkserver do GFS
trechos de dados
.....
fluxo de controle
fluxo de dados
Cliente
metadados
Chunkserver do GFS
trechos de dados
Figura 21.9 Arquitetura global do GFS.
Coulouris_21.indd 937
Coulouris_21.indd 937 23/05/13 09:26
23/05/13 09:26
938 Sistemas Distribuídos, Conceitos e Projeto
Embora o mestre seja centralizado e, portanto, um ponto único de falha, o registro
de operações é replicado em várias máquinas remotas, de modo que, em caso de falha,
o mestre pode ser prontamente restaurado. A vantagem de se ter um único mestre cen-
tralizado é que ele tem uma visão global do sistema de arquivos e, assim, pode tomar as
melhores decisões de gerenciamento, relacionadas, por exemplo, ao posicionamento de
trechos. Esse esquema também é mais simples de implementar, permitindo ao Google
desenvolver o GFS em um período de tempo relativamente curto. McKusick e Quinlan
[2010] apresentam o fundamento lógico dessa escolha de projeto bastante incomum.
Quando os clientes precisarem acessar dados a partir de um deslocamento de bytes
em particular dentro de um arquivo, a biblioteca de cliente GFS primeiramente transfor-
mará isso em um par nome de arquivo e índice de trecho (facilmente computados, dado o
tamanho fixo dos trechos). Então, isso é enviado para o mestre na forma de uma requisi-
ção RPC (usando buffers de protocolo). O mestre responde com o identificador de trecho
apropriado e a localização das réplicas, e essas informações são colocadas na cache do
cliente e usadas para acessar os dados por invocação RPC direta para um dos chunkser-
vers replicados. Desse modo, o mestre é envolvido no início e depois fica completamente
fora do lago, implementando uma separação de fluxos de controle e de dados – uma se-
paração fundamental para manter o alto desempenho dos acessos a arquivo. Combinado
com o tamanho grande dos trechos, isso significa que, uma vez identificado e localizado
um trecho, os 64 megabytes podem ser lidos tão rapidamente quanto o servidor de ar-
quivos e a rede permitam, sem quaisquer outras interações com o mestre, até que outro
trecho precise ser acessado. Portanto, as interações com o mestre são minimizadas e o de-
sempenho de saída, otimizado. O mesmo argumento se aplica às anexações sequenciais.
Note que outra repercussão do tamanho grande dos trechos é que o GFS mantém
proporcionalmente menos metadados (se fosse adotado um tamanho de trecho de 64
quilobytes, por exemplo, o volume de metadados aumentaria por um fator de 1.000).
Isso, por sua vez, significa que os mestres GFS geralmente podem manter todos os seus
metadados na memória principal (mas veja a seguir), diminuindo significativamente a
latência de operações de controle.
À medida que a utilização do sistema aumenta, têm surgido problemas com o es-
quema do mestre centralizado:
• Apesar da separação entre fluxo de controle e de dados e da otimização do desem-
penho do mestre, isso está aparecendo como um gargalo em seu projeto.
• Apesar do volume de metadados reduzido, decorrente do tamanho grande dos tre-
chos, o volume de metadados armazenados em cada mestre está aumentando a um
nível em que é difícil manter todos os metadados na memória principal.
Por esses motivos, agora o Google está trabalhando em um novo projeto que apre-
senta uma solução de mestre distribuído.
Uso de cache: como vimos no Capítulo 12, o uso de cache frequentemente desempenha
um papel fundamental no desempenho e na escalabilidade de um sistema de arquivos
(veja também a discussão mais geral sobre uso de cache na Seção 2.3.1). É interessante
notar que o GFS não faz muito uso de cache. Conforme mencionado anteriormente, as
informações sobre os locais de trechos são colocadas na cache dos clientes na primeira
vez que são acessadas, para minimizar as interações com o mestre. Fora isso, o cliente
não utiliza a cache. Em particular, os clientes GFS não colocam dados de arquivo na
cache. Como a maioria dos acessos envolve fluxos sequenciais, por exemplo, leitura de
conteúdo Web para produzir o índice invertido exigido, tais caches pouco contribuiriam
Coulouris_21.indd 938
Coulouris_21.indd 938 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 939
para o desempenho do sistema. Além disso, limitando o uso de cache aos clientes, o GFS
também evita a necessidade de protocolos de coerência de cache.
O GFS também não fornece nenhuma estratégia em particular para uso de cache no
lado do servidor (isto é, nos chunkservers), contando com cache de buffer no Linux para
manter dados frequentemente acessados na memória.
Logging: o GFS também é um exemplo importante do uso de logs no Google para su-
portar depuração e análise de desempenho. Em particular, todos os servidores do GFS
mantêm extensivos logs de diagnóstico que armazenam eventos significativos do servi-
dor e todas as requisições e respostas RPC. Esses logs são monitorados continuamente e
usados em caso de problemas no sistema, para identificar as causas subjacentes.
Gerenciando a consistência no GFS • Dado que os trechos são replicados no GFS, é im-
portante manter a consistência das réplicas diante de operações que alteram os dados – ou
seja, as operações write e record append. O GFS fornece uma estratégia para gerencia-
mento de consistência que:
• mantém a separação mencionada anteriormente entre controle e dados e, assim, permi-
te atualizações de alto desempenho nos dados com envolvimento mínimo dos mestres;
• fornece uma forma de consistência relaxada, reconhecendo, por exemplo, a semân-
tica específica oferecida por record append.
A estratégia funciona como segue.
Quando uma mutação (isto é, uma operação write, append ou delete) é requi-
sitada para um trecho, o mestre concede um arrendamento de trecho para uma das
réplicas, a qual é, então, designada como primária. Essa réplica primária é responsável
por fornecer uma ordem serial para todas as mutações concorrentes pendentes para
esse trecho. Assim, uma ordem global é fornecida pela ordenação dos arrendamentos
de trecho, combinados com a ordem determinada por essa primária. Em particular, o
arrendamento permite que a primária faça mutações em suas cópias locais e controle a
ordem das mutações nas cópias secundárias; então, outra primária receberá o arrenda-
mento e assim por diante.
Portanto, as etapas envolvidas nas mutações são as seguintes (ligeiramente sim-
plificadas):
• Ao receber uma requisição de um cliente, o mestre concede um arrendamento para
uma das réplicas (a primária) e retorna a identidade da primária e de outras réplicas
(secundárias) para o cliente.
• O cliente envia todos os dados para as réplicas e isso é armazenado temporariamen-
te em uma cache de buffer e não é escrito até que venham mais instruções (nova-
mente, mantendo a separação do fluxo de controle do fluxo de dados, acoplada a
um regime de controle leve, baseado em arrendamentos).
• Uma vez que todas as réplicas tenham confirmado o recebimento desses dados, o
cliente envia uma requisição de escrita para a primária; então, a primária determina
uma ordem serial para as requisições concorrentes e aplica as atualizações, nessa
ordem, no local onde a primária se encontra.
• A primária solicita que as mesmas mutações, na mesma ordem, sejam realizadas
nas réplicas secundárias, e estas enviam de volta uma confirmação, quando as mu-
tações tiverem ocorrido.
• Se todas as confirmações forem recebidas, a primária relata o sucesso de volta para
o cliente; caso contrário, é informada uma falha, indicando que a mutação ocorreu
Coulouris_21.indd 939
Coulouris_21.indd 939 23/05/13 09:26
23/05/13 09:26
940 Sistemas Distribuídos, Conceitos e Projeto
na primária e em algumas das réplicas, mas não em todas. Isso é tratado como uma
falha e deixa as réplicas em um estado inconsistente. O GFS procura resolver essa
falha tentando fazer as mutações malsucedidas novamente. No pior caso, isso não
terá êxito e, portanto, a consistência não será garantida pela estratégia.
É interessante relacionar esse esquema com as técnicas de replicação discutidas no Ca-
pítulo 18. O GFS adota uma arquitetura de replicação passiva, com uma modificação
importante. Na replicação passiva, as atualizações são enviadas para a réplica primária
e, então, esta fica responsável por enviar as atualizações subsequentes para os servidores
de backup e por garantir que elas sejam coordenadas. No GFS, o cliente envia dados para
todas as réplicas, mas a requisição vai para a primária que, então, fica responsável por
escalonar as mutações reais (a separação entre fluxo de dados e fluxo de controle, men-
cionada anteriormente). Isso permite que a transmissão de grandes quantidades de dados
seja otimizada, independentemente do fluxo de controle.
Nas mutações há uma distinção importante entre as operações write e record
append. A operação write especifica um deslocamento no qual as mutações devem ocor-
rer, enquanto a operação record append não faz isso (as mutações são aplicadas no final
do arquivo, onde quer seja isso em determinado ponto no tempo). No primeiro caso, a lo-
calização é predeterminada, enquanto no último, o sistema decide. Operações write con-
correntes no mesmo ponto não são serializadas e podem resultar em regiões corrompidas
no arquivo. Nas operações record append, o GFS garante que a anexação ocorrerá pelo
menos uma vez e atomicamente (isto é, como uma sequência contínua de bytes); contu-
do, o sistema não garante que todas as cópias do trecho serão idênticas (algumas podem
ter dados duplicados). Novamente, é útil relacionar isso com a matéria do Capítulo 18.
As estratégias de replicação do Capítulo 18 são todas de propósito geral, enquanto esta
estratégia é específica do domínio e flexibiliza as garantias de consistência, sabendo-se
que a semântica resultante pode ser tolerada pelas aplicações e serviços do Google (outro
exemplo de replicação específica do domínio – o algoritmo de replicação de Xu e Liskov
[1989] para espaços de tuplas – pode ser encontrado na Seção 6.5.2).
21.5.2 Chubby
O Chubby [Burrows 2006] é um serviço fundamental da infraestrutura do Google, ofere-
cendo serviços de armazenamento e coordenação para outros serviços da infraestrutura,
incluindo o GFS e a Bigtable. O Chubby é um serviço multifacetado que oferece quatro
recursos distintos:
• Ele fornece travas distribuídas para sincronizar atividades distribuídas no que é um
ambiente assíncrono de larga escala.
• Ele fornece um sistema de arquivos que oferece armazenamento confiável de pe-
quenos arquivos (complementando o serviço oferecido pelo GFS).
• Ele pode ser usado para suportar a eleição da réplica primária em um conjunto de
réplicas (conforme é necessário, por exemplo, pelo GFS, conforme discutido na
Seção 21.5.1).
• Ele é usado como serviço de nomes dentro Google.
À primeira vista, pode parecer que isso contradiz o princípio de projeto global da simpli-
cidade (fazer apenas uma coisa e fazê-la bem). Entretanto, à medida que desvendarmos o
projeto do Chubby, veremos que no centro há um serviço básico que oferece uma solução
para o consenso distribuído e que as outras facetas surgem desse serviço básico, que é
otimizado para o estilo de utilização dentro do Google.
Coulouris_21.indd 940
Coulouris_21.indd 940 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 941
Iniciaremos nosso estudo do Chubby examinando a interface que ele oferece; em
seguida, veremos a arquitetura de um sistema Chubby em detalhes e como isso é mape-
ado na arquitetura física. Concluiremos o exame vendo em detalhes a implementação do
algoritmo de consenso que há no centro do Chubby, o Paxos.
Interface do Chubby • O Chubby fornece uma abstração baseada em um sistema de ar-
quivos, adotando a visão inicialmente promovida no Plan 9 [Pike et al. 1993], de que
todo objeto de dados é um arquivo. Os arquivos são organizados em um espaço de nomes
hierárquico, utilizando estruturas de diretório com os nomes tendo a seguinte forma:
/ls/célula_chubby/nome_diretório/.../nome_arquivo
onde /ls se refere ao serviço de travas, designando que isso faz parte do sistema Chubby,
célula_chubby é o nome de uma instância em particular de um sistema Chubby (o termo
célula é usado no Chubby para denotar uma instância do sistema). Isso é seguido por
uma série de nomes de diretório, culminando em um nome_arquivo. Um nome especial
/ls/local, será solucionado na célula mais local em relação ao aplicativo ou serviço que
fez a chamada.
O Chubby começou sua existência como um serviço de travas e a intenção era que
tudo fosse uma trava no sistema. Entretanto, rapidamente ficou claro que seria útil asso-
ciar quantidades (normalmente pequenas) de dados às entidades do Chubby – veremos
um exemplo disso a seguir, quando examinarmos como o Chubby é usado em eleições
de réplica primária. Assim, no Chubby as entidades compartilham a funcionalidade de
travas e arquivos; elas podem ser usadas exclusivamente como travas, para armazenar
pequenas quantidades de dados ou para associar pequenas quantidades de dados (na ver-
dade, metadados) a operações de trava.
Uma versão ligeiramente simplificada da API oferecida pelo Chubby aparece na
Figura 21.10. Open e Close são operações padrão, com Open recebendo um arquivo ou
diretório nomeado e retornando um identificador Chubby para essa entidade. O cliente
pode especificar vários parâmetros associados a Open, incluindo declarar a utilização
pretendida (por exemplo, leitura, escrita ou trava), e as verificações de permissões são
realizadas nesse estágio, usando listas de controle de acesso. A operação Close simples-
mente abre mão do uso do identificador. A operação Delete é usada para remover o arqui-
vo ou diretório (essa operação falhará se for aplicada a um diretório com filhos).
Na função de sistema de arquivos, o Chubby oferece um pequeno conjunto de ope-
rações para leitura e escrita de arquivos inteiros; são operações simples que retornam os
dados completos do arquivo e escrevem os dados completos no arquivo. Essa estratégia
de arquivo inteiro é adotada para desencorajar a criação de arquivos grandes, pois não é
esse uso pretendido para o Chubby. A primeira operação, GetContentsAndStat, retorna o
conteúdo do arquivo e quaisquer metadados associados ao arquivo (uma operação asso-
ciada, GetStat, retorna apenas os metadados; também é fornecida uma operação ReadDir
para ler nomes e metadados associados aos filhos de um diretório. SetContents escreve o
conteúdo de um arquivo e SetACL fornece uma maneira de configurar os dados da lista
de controle de acesso. A leitura e a escrita de arquivos inteiros são operações atômicas.
Na função de ferramenta de gerenciamento de travas, as principais operações forne-
cidas são Acquire, TryAcquire e Release. Acquire e Release correspondem às operações
de mesmo nome apresentadas na Seção 16.4; TryAcquire é uma variante não bloqueante
de Acquire. Note que, embora as travas sejam consultivas no Chubby, um aplicativo ou
serviço deve passar pelo protocolo correto de adquirir e liberar travas. Os desenvolvedores
do Chubby consideraram uma alternativa de travas obrigatórias, segundo a qual os dados
Coulouris_21.indd 941
Coulouris_21.indd 941 23/05/13 09:26
23/05/13 09:26
942 Sistemas Distribuídos, Conceitos e Projeto
travados ficam inacessíveis para todos os outros usuários e isso é imposto pelo sistema,
mas a flexibilidade extra e resiliência das travas consultivas foram preferidas, deixando
para o programador a responsabilidade pela verificação de conflitos [Burrows 2006].
Se uma aplicação precisa proteger um arquivo contra acesso concorrente, ela pode
usar as duas funções juntas, armazenando dados no arquivo e adquirindo travas antes de
acessar esses dados.
O Chubby também pode ser usado para suportar uma eleição de primária em sis-
temas distribuídos – isto é, a eleição de uma réplica como a primária no gerenciamento
de replicação passiva (consulte as Seções 15.3 e 18.3.1 para discussões sobre algoritmos
de eleição e replicação passiva, respectivamente). Primeiramente, todas as primárias can-
didatas tentam adquirir uma trava associada à eleição. Somente uma terá sucesso. Essa
candidata se torna a primária, com todas as outras candidatas se tornando secundárias. A
primária registra sua vitória escrevendo sua identidade no arquivo associado, e os outros
processos podem então determinar a identidade da primária lendo esses dados. Conforme
mencionado anteriormente, esse é um importante exemplo de combinação das funções
de trava e arquivo para um propósito útil em um sistema distribuído. Isso também mostra
como a eleição de primária pode ser implementada em cima de um serviço de consenso,
como uma alternativa a algoritmos como a estratégia baseada em anel ou o algoritmo
valentão (bully), apresentado na Seção 15.3.
Por fim, o Chubby suporta um mecanismo de evento simples, permitindo aos clien-
tes se registrarem ao abrir um arquivo, para receber mensagens de evento relacionadas
ao arquivo. Mais especificamente, o cliente pode se increver em diversos eventos, como
uma opção na chamada de Open. Então, os eventos associados são entregues de forma
assíncrona, por meio de callbacks. Exemplos de eventos incluem a modificação do con-
teúdo de um arquivo, um identificador se tornando inválido, etc.
Função Operação Efeito
Geral Open Abre um arquivo ou diretório dado e retorna um
identificador
Close Fecha o arquivo associado ao identificador
Delete Exclui o arquivo ou diretório
Arquivo GetContentsAndStat Retorna (atomicamente) o conteúdo do arquivo
inteiro e os metadados associados ao arquivo
GetStat Retorna apenas os metadados
ReadDir Retorna o conteúdo de um diretório – isto é,
os nomes e metadados de quaisquer filhos
SetContents Escreve todo o conteúdo de um arquivo (atomicamente)
SetACL Escreve novas informações na lista de controle de acesso
Trava Acquire Adquire uma trava sobre um arquivo
TryAquire Tenta adquirir uma trava sobre um arquivo
Release Libera a trava
Figura 21.10 API do Chubby.
Coulouris_21.indd 942
Coulouris_21.indd 942 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 943
O Chubby é uma interface de programação de sistema de arquivos reduzida, com-
parada, por exemplo, com o POSIX. O Chubby não apenas exige que as operações de
leitura e atualização sejam aplicadas em arquivos inteiros, como também não suporta
operações para mover arquivos entre diretórios nem vínculos simbólicos (softlinks) ou
restritos (hard links). Além disso, o Chubby mantém apenas metadados limitados (rela-
cionados a controle de acesso, controle de versão e uma soma de verificação para prote-
ger a integridade dos dados).
Arquitetura do Chubby • Conforme mencionado anteriormente, uma única instância de
um sistema Chubby é conhecida como célula; cada célula consiste em um número relati-
vamente pequeno de réplicas (normalmente, cinco), com uma delas designada como mes-
tra. Os aplicativos clientes acessam esse conjunto de réplicas por meio de uma biblioteca
Chubby, a qual se comunica com os servidores remotos usando o serviço RPC descrito na
Seção 21.4.1. As réplicas são colocadas em locais independentes de falha para minimizar
o potencial de falhas correlacionadas – por exemplo, elas não estarão contidas dentro do
mesmo rack. Normalmente, todas as réplicas estariam contidas dentro de determinado
cluster físico, embora isso não seja exigido para o funcionamento correto do protocolo e
tenham sido criadas células experimentais que abrangem os centros de dados do Google.
Cada réplica mantém um pequeno banco de dados, cujos elementos são entidades
no espaço de nomes do Chubby – isto é, diretórios e arquivos/travas. A consistência
do banco de dados replicado é obtida usando-se um protocolo de consenso subjacente
(uma implementação do algoritmo Paxos de Lamport [Lamport 1989, Lamport 1998]),
baseado na manutenção de logs de operação (veremos a implementação desse protoco-
lo, a seguir). Como os logs se tornam muito grandes com o passar do tempo, o Chubby
também suporta a criação de instantâneos – visões completas do estado do sistema em
determinado ponto no tempo. Uma vez tirado um instantâneo, os logs anteriores podem
ser excluídos, com o estado consistente do sistema em qualquer ponto determinado pelo
instantâneo anterior, junto às aplicações do conjunto de operações no log. Essa estrutura
global está mostrada na Figura 21.11.
Uma sessão do Chubby é uma relação entre um cliente e uma célula do Chubby.
Isso é mantido usando-se handshakes KeepAlive entre as duas entidades. Para aumentar
o desempenho, a biblioteca do Chubby implementa cache no cliente, armazenando dados
de arquivo, metadados e informações em tratadores. Em contraste com o GFS (com suas
grandes leituras e anexações sequenciais), a cache no cliente é eficiente no Chubby, com
seus arquivos pequenos que provavelmente serão acessados repetidamente. Por causa des-
se uso de cache, o sistema precisa manter a consistência entre um arquivo e uma cache,
assim como entre as diferentes réplicas do arquivo. A consistência de cache exigida no
Chubby é obtida como segue. Quando uma mutação está para ocorrer, a operação asso-
ciada (por exemplo, SetContents) é bloqueada até que todas as caches associadas sejam
invalidadas (por eficiência, as requisições de invalidação vão “de carona” nas respostas
de KeepAlive da mestra, com as respostas enviadas imediatamente quando ocorre uma
invalidação). Os dados colocados em cache também nunca são atualizados diretamente.
O resultado final é um protocolo de consistência de cache muito simples que apre-
senta semântica determinística para os clientes do Chubby. Compare isso com o regime
de cache no cliente do NFS, por exemplo, no qual as mutações não acarretam a atuali-
zação imediata das cópias colocadas em cache, resultando em versões potencialmente
diferentes de arquivos em diferentes nós clientes. Também é interessante comparar isso
com o protocolo de consistência de cache do AFS, mas deixamos como exercício para o
leitor (veja o Exercício 21.7).
Coulouris_21.indd 943
Coulouris_21.indd 943 23/05/13 09:26
23/05/13 09:26
944 Sistemas Distribuídos, Conceitos e Projeto
Esse determinismo é importante para muitas das aplicações e serviços de cliente que
usam o Chubby (por exemplo, a Bigtable, conforme discutido na Seção 21.5.3) para ar-
mazenar listas de controle de acesso. A Bigtable exige atualização consistente de listas de
controle de acesso, entre todas as réplicas e em termos de cópias colocadas na cache. Note
que foi esse determinismo que levou ao uso do Chubby como servidor de nomes dentro do
Google. Mencionamos, na Seção 13.2.3, que o DNS permite que a atribuição de nomes de
dados se torne inconsistente. Embora isso seja tolerável na Internet, os desenvolvedores
da infraestrutura do Google preferiram a visão mais consistente oferecida pelo Chubby,
usando arquivos Chubby para manter os mapeamentos de nomes para endereços. Burrows
[2006] discute em mais detalhes o uso do Chubby como serviço de nomes.
Implementação do Paxos • Paxos é uma família de protocolos que fornece consenso dis-
tribuído (veja a Seção 15.5 para uma discussão mais ampla sobre protocolos de consenso
distribuído). Os protocolos de consenso operam sobre um conjunto de réplicas com o
objetivo de obter um acordo entre os servidores que gerenciam as réplicas, para atualizá-
-las com um valor comum. Isso é obtido em um ambiente onde:
• Os servidores de réplica podem operar em velocidade arbitrária e podem falhar (e
subsequentemente se recuperar).
• Os servidores de réplica têm acesso a um armazenamento estável e persistente que
sobrevive aos colapsos.
• Mensagens podem ser perdidas, reordenadas ou duplicadas. Elas são entregues sem
corrupção, mas podem demorar um tempo arbitrariamente longo para serem entregues.
Chubby cell
Biblioteca
cliente do
Chubby
Cliente
*
*
Log
Instantâneos
Banco
de dados
local
Log
Instantâneos
Banco
de dados
local
Log
Instantâneos
Banco
de dados
local
denota a mestra atual
•
•
•
Figura 21.11 Arquitetura global do Chubby.
Coulouris_21.indd 944
Coulouris_21.indd 944 23/05/13 09:26
23/05/13 09:26
Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 945
Portanto, o Paxos é fundamentalmente um protocolo de consenso distribuído para siste-
mas assíncronos (veja a Seção 2.4.1) e, de fato, é a oferta dominante nesse universo. Os
desenvolvedores do Chubby enfatizam que as suposições anteriores refletem a verdadeira
natureza dos sistemas baseados na Internet, como o Google, e alertam os profissionais
do setor sobre algoritmos de consenso que fazem suposições mais fortes (por exemplo,
algoritmos para sistemas síncronos) [Burrows 2006].
Lembre-se, do Capítulo 15, de que é impossível garantir a consistência em sis-
temas assíncronos, mas que foram propostas várias técnicas para contornar esse pro-
blema. O Paxos funciona garantindo a exatidão, mas não há garantias de que o Paxos
termine a execução (voltaremos a essa questão, a seguir, quando tivermos visto os de-
talhes do algoritmo).
O algoritmo foi apresentado pela primeira vez por Leslie Lamport, em 1989, em um
artigo chamado The Part-Time Parliament (O parlamento de meio-expediente) [Lamport
1989, Lamport 1998]. Inspirado por sua descrição dos generais bizantinos (conforme
discutido na Seção 15.5.1), ele novamente apresentou o algoritmo fazendo uma analogia,
desta vez se referindo ao comportamento de um parlamento mitológico na ilha grega de
Paxos. Em seu site [research.microsoft.com], Lamport escreve de forma engraçada sobre
a reação a essa apresentação.
No algoritmo, qualquer réplica pode submeter um valor com o objetivo de obter
consenso sobre um valor final. No Chubby, o acordo equivale a todas as réplicas terem
esse valor como a próxima entrada em seus logs de atualização, obtendo, assim, uma visão
consistente dos logs de todos os locais. É garantido que o algoritmo obtenha um consenso,
se a maioria das réplicas executar o bastante, com suficiente estabilidade da rede. Mais
formalmente, Kirsch e Amir [2008] apresentam as seguintes propriedades para o Paxos:
Paxos-L1 (Progresso): se existe uma maioria estável em um conjunto de servido-
res, então, se um servidor do conjunto inicia uma atualização, algum membro do
conjunto executará a atualização.
Paxos-L2 (Replicação Eventual): se um servidor s executa uma atualização e exis-
te um conjunto de servidores contendo s e r, e um tempo após o qual o conjunto não
experimenta falhas de comunicação ou processo, então r executará a atualização.
A intuição aqui diz que o algoritmo não pode garantir que a consistência seja atingida
quando a rede se comporta de forma assíncrona, mas atingirá a consistência quando fo-
rem experimentadas condições mais síncronas (ou estáveis).
O algoritmo Paxos: O algoritmo Paxos funciona como segue:
Etapa 1: o algoritmo conta com a capacidade de eleger um coordenador para
determinada decisão consensual. Reconhecendo que os coordenadores podem fa-
lhar, é adotado um processo de eleição flexível que pode resultar na coexistência
de vários coordenadores, antigos e novos, com o objetivo de reconhecer e rejeitar
mensagens de antigos coordenadores. Para identificar o coordenador correto, os
coordenadores são ordenados por um número sequencial. Cada réplica mantém o
número sequencial mais alto visto até o momento e, se estiver fazendo uma oferta
para ser um coordenador, escolherá um número exclusivo mais alto e divulgará isso
para todas as réplicas em uma mensagem de proposta.
Claramente, é importante que o número sequencial escolhido por um coorde-
nador em potencial seja realmente exclusivo – dois (ou mais) coordenadores não
devem ser capazes de escolher o mesmo valor. Vamos supor que tenhamos n répli-
cas. Um número sequencial exclusivo pode ser garantido se toda réplica receber
Coulouris_21.indd 945
Coulouris_21.indd 945 23/05/13 09:26
23/05/13 09:26
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf
Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf

Mais conteúdo relacionado

Semelhante a Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf

Artc 1249307788 43
Artc 1249307788 43Artc 1249307788 43
Artc 1249307788 43
Bruno Bsantos
 
Arquitetura de Software EXPLICADA
Arquitetura de Software EXPLICADAArquitetura de Software EXPLICADA
Arquitetura de Software EXPLICADA
Fábio Nogueira de Lucena
 
Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...
Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...
Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...
Marcelo Veloso
 
Corbawebserves
CorbawebservesCorbawebserves
Corbawebserves
Portal_do_Estudante_SD
 
O_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdf
O_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdfO_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdf
O_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdf
Athena542429
 
Projeto de Banco de Dados - Capítulo 1
Projeto de Banco de Dados - Capítulo 1Projeto de Banco de Dados - Capítulo 1
Projeto de Banco de Dados - Capítulo 1
Januário Neto
 
Wperformance 2015 (2)
Wperformance   2015 (2)Wperformance   2015 (2)
Wperformance 2015 (2)
Marcelo Iury d
 
Bancos de dados distribuídos
Bancos de dados distribuídosBancos de dados distribuídos
Bancos de dados distribuídos
J Chaves Silva
 
Metodologia de desenvolvimento de sistemas
Metodologia  de desenvolvimento de sistemasMetodologia  de desenvolvimento de sistemas
Metodologia de desenvolvimento de sistemas
Priscila Stuani
 
Do Diagrama de Fluxo de Dados ao Use Case
Do Diagrama de Fluxo de Dados ao Use CaseDo Diagrama de Fluxo de Dados ao Use Case
Do Diagrama de Fluxo de Dados ao Use Case
Robson Silva Espig
 
Indo alem do_mvc_node_js
Indo alem do_mvc_node_jsIndo alem do_mvc_node_js
Indo alem do_mvc_node_js
gustavobeavis
 
VIFinalReport
VIFinalReportVIFinalReport
VIFinalReport
Diogo Nicolau
 
DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...
DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...
DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...
Eduardo Hahn
 
Trabalho individual
Trabalho individualTrabalho individual
Trabalho individual
Alessandra Fraydewoks
 
Visão Geral Arquiteturade Software
Visão Geral Arquiteturade SoftwareVisão Geral Arquiteturade Software
Visão Geral Arquiteturade Software
elliando dias
 
O_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdf
O_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdfO_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdf
O_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdf
BrunaBraga68
 
.NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al...
.NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al....NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al...
.NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al...
Renato Groff
 
SAlmox SIIC 2014
SAlmox SIIC 2014SAlmox SIIC 2014
SAlmox SIIC 2014
Jonas Mayer
 
Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...
Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...
Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...
Lenin Abadie
 
Monografia aplicacoes internet_marcos andre
Monografia aplicacoes internet_marcos andreMonografia aplicacoes internet_marcos andre
Monografia aplicacoes internet_marcos andre
Fernando Palma
 

Semelhante a Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf (20)

Artc 1249307788 43
Artc 1249307788 43Artc 1249307788 43
Artc 1249307788 43
 
Arquitetura de Software EXPLICADA
Arquitetura de Software EXPLICADAArquitetura de Software EXPLICADA
Arquitetura de Software EXPLICADA
 
Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...
Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...
Artigo CONSAD 2013 - Cloud Computing: Necessidade e Benefícios Esperados Com ...
 
Corbawebserves
CorbawebservesCorbawebserves
Corbawebserves
 
O_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdf
O_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdfO_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdf
O_Ciclo_de_Vida_do_Desenvolvimento_de_Sistemas.pdf
 
Projeto de Banco de Dados - Capítulo 1
Projeto de Banco de Dados - Capítulo 1Projeto de Banco de Dados - Capítulo 1
Projeto de Banco de Dados - Capítulo 1
 
Wperformance 2015 (2)
Wperformance   2015 (2)Wperformance   2015 (2)
Wperformance 2015 (2)
 
Bancos de dados distribuídos
Bancos de dados distribuídosBancos de dados distribuídos
Bancos de dados distribuídos
 
Metodologia de desenvolvimento de sistemas
Metodologia  de desenvolvimento de sistemasMetodologia  de desenvolvimento de sistemas
Metodologia de desenvolvimento de sistemas
 
Do Diagrama de Fluxo de Dados ao Use Case
Do Diagrama de Fluxo de Dados ao Use CaseDo Diagrama de Fluxo de Dados ao Use Case
Do Diagrama de Fluxo de Dados ao Use Case
 
Indo alem do_mvc_node_js
Indo alem do_mvc_node_jsIndo alem do_mvc_node_js
Indo alem do_mvc_node_js
 
VIFinalReport
VIFinalReportVIFinalReport
VIFinalReport
 
DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...
DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...
DataOps, Data Mesh e Data Fabric. Melhores práticas para seu projeto de arqui...
 
Trabalho individual
Trabalho individualTrabalho individual
Trabalho individual
 
Visão Geral Arquiteturade Software
Visão Geral Arquiteturade SoftwareVisão Geral Arquiteturade Software
Visão Geral Arquiteturade Software
 
O_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdf
O_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdfO_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdf
O_Emprego_de_Tecnicas_de_IA_no_suporte_a.pdf
 
.NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al...
.NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al....NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al...
.NET Core 3.0 e ASP.NET Core 3.0 : principais novidades - TDC 2019 - Porto Al...
 
SAlmox SIIC 2014
SAlmox SIIC 2014SAlmox SIIC 2014
SAlmox SIIC 2014
 
Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...
Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...
Uma Arquitetura para a Implantação Automática de Serviços em Infraestruturas ...
 
Monografia aplicacoes internet_marcos andre
Monografia aplicacoes internet_marcos andreMonografia aplicacoes internet_marcos andre
Monografia aplicacoes internet_marcos andre
 

Desenvolvimento_Distribuído_Google_Estudo_de_caso.pdf

  • 1. 21.1 Introdução 21.2 Introdução ao estudo de caso: Google 21.3 Arquitetura global e filosofia de projeto 21.4 Paradigmas de comunicação 21.5 Serviços de armazenamento de dados e coordenação 21.6 Serviços de computação distribuída 21.7 Resumo Projeto de Sistemas Distribuídos – Estudo de Caso: Google 21 A capacidade de criar um projeto eficiente é uma habilidade importante em sistemas distribuídos, exigindo o conhecimento das diferentes escolhas tecnológicas apresentadas por todo o livro e um entendimento completo dos requisitos do domínio de aplicação relevante. O objetivo final é propor uma arquitetura de sistema distribuído coerente, que incorpore um conjunto consistente e completo de escolhas de projeto ca- pazes de atender aos requisitos globais. Essa é uma tarefa desafiadora, que exige experiência considerável no desenvolvimento de sistemas distribuídos. Ilustraremos o projeto distribuído por meio de um estudo de caso de peso, examinando em detalhes o projeto da infraestrutura do Google, uma plataforma e middleware associado que suportam a pesquisa no Google e um conjunto de serviços e aplicativos Web associados, incluindo o Google Apps. Isso engloba o estudo de importantes componentes subjacentes, como a infraestrutura física que serve de alicerce para o Google, os paradigmas de comunicação oferecidos pela infraestrutura do Google e os serviços básicos associados para armazenamento e computação. É dada ênfase nos principais princípios de projeto por trás da infraestrutura do Google e em como eles permeiam a arquitetura de sistema global, resultando em um projeto consistente e eficiente. Coulouris_21.indd 915 Coulouris_21.indd 915 23/05/13 09:26 23/05/13 09:26
  • 2. 916 Sistemas Distribuídos, Conceitos e Projeto 21.1 Introdução Este livro abordou os principais conceitos que servem de base para o desenvolvimento de sistemas distribuídos, dando ênfase ao tratamento dos principais desafios dos sistemas distribuídos, incluindo heterogeneidade, abertura, segurança, escalabilidade, tratamento de falhas, concorrência, transparência e qualidade de serviço. O tratamento subsequente inevitavelmente se concentra nas partes que compõem um sistema distribuído, incluin- do paradigmas de comunicação, como a invocação remota e suas alternativas indiretas; as abstrações de programação oferecidas pelos objetos, componentes ou serviços Web; serviços específicos dos sistemas distribuídos para suporte à segurança, atribuição de nomes e sistema de arquivos; e soluções algorítmicas, como coordenação e acordo. Con- tudo, é igualmente importante considerar o projeto global dos sistemas distribuídos e como as partes componentes são reunidas, tratando dos inevitáveis compromissos entre os diferentes desafios para produzir uma arquitetura de sistema global que satisfaça os requisitos de um domínio de aplicação e um ambiente operacional de larga escala. Um tratamento mais completo dos métodos de projeto de sistemas distribuídos necessaria- mente nos levaria para o campo das metodologias de engenharia de software para siste- mas distribuídos. Isso está fora dos objetivos deste livro; os interessados nesse assunto devem consultar o quadro a seguir, que traz alguns tópicos e fontes relevantes. Em vez disso, optamos por dar uma ideia desta área apresentando o estudo de caso de um siste- ma distribuído complexo, destacando as decisões de projeto e compromissos envolvidos nesse projeto. Para motivar os estudos, o Capítulo 1 apresentou, em linhas gerais, três exemplos de importantes domínios de aplicação que representam muitos dos maiores desafios nos sistemas distribuídos: pesquisa na Web, games online para múltiplos jogadores e sis- temas financeiros. Poderíamos ter escolhido qualquer uma dessas áreas e apresentado um estudo de caso atraente e esclarecedor, mas optamos por nos concentrar na primeira delas: pesquisa na Web (e, na verdade, vamos além da pesquisa na Web, examinando o suporte mais geral para serviços em nuvem baseados na Web). Em particular, apresen- tamos neste capítulo um estudo de caso sobre a infraestrutura de sistema distribuído que serve de base para o Google (daqui em diante referida como infraestrutura do Google). O Google é um dos maiores sistemas distribuídos em uso atualmente e sua infraestrutura tem lidado com êxito com uma variedade de requisitos exigentes, conforme discutido a seguir. A arquitetura subjacente e a escolha de conceitos também são muito interessantes, Engenharia de software para sistemas distribuídos Remetemos o leitor aos avanços significativos feitos em áreas como: • projeto orientado a objetos, incluindo o uso de notações de modelagem, como UML [Booch et al. 2005]; • engenharia de software baseada em componentes (CBSE) e sua relação com as arquiteturas empresariais [Szyperski 2002]; • padrões arquitetônicos destinados aos sistemas distribuídos [Bushmann et al. 2007]; • engenharia baseada em modelos, que busca gerar sistemas complexos, incluindo sistemas distribuídos, a partir de abstrações de nível mais alto (modelos) [France e Rumpe 2007]. Coulouris_21.indd 916 Coulouris_21.indd 916 23/05/13 09:26 23/05/13 09:26
  • 3. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 917 reunindo muitos dos tópicos básicos apresentados neste livro. Portanto, um estudo da infraestrutura do Google oferece uma maneira perfeita de encerrar nosso estudo sobre sistemas distribuídos. Note que, além de dar um exemplo de como suportar pesquisa na Web, a infraestrutura do Google também se revelou um exemplo importante de computa- ção em nuvem, conforme ficará claro nas descrições a seguir. A Seção 21.2 apresenta o estudo de caso, fornecendo informações básicas sobre o Google. Em seguida, a Seção 21.3 apresenta o projeto global da infraestrutura do Google, considerando o modelo físico subjacente e a arquitetura de sistema associada. A Seção 21.4 examina o nível mais baixo da arquitetura de sistema, os paradigmas de comunica- ção suportados pela infraestrutura do Google; as duas seções subsequentes, Seções 21.5 e 21.6, discutem os serviços básicos fornecidos pela infraestrutura do Google, apresen- tando os serviços de armazenamento e processamento de grandes volumes de dados. Juntas, as Seções 21.3 a 21.6 descrevem um middleware completo para pesquisa na Web e computação em nuvem. Por fim, a Seção 21.7 resume os principais pontos que surgem de nossa discussão sobre a infraestrutura do Google. Por toda a apresentação, será dada ênfase na identificação e na justificativa das principais decisões de projeto e os compro- missos inerentes associados. 21.2 Introdução ao estudo de caso: Google O Google [www.google.com III] é uma corporação dos Estados Unidos, sediada em Mountain View, Califórnia (a Googleplex), oferecendo pesquisa na Internet e aplica- ções Web mais gerais, obtendo seus lucros principalmente com os anúncios ligados a tais serviços. O nome é um trocadilho com a palavra googol, o número 10 100 (ou 1 seguido por cem zeros), enfatizando a enorme escala das informações disponíveis na Internet atualmente. A missão do Google é dominar esse enorme volume de informa- ções: “organizar as informações do mundo e torná-las universalmente acessíveis e úteis” [www.google.com III]. O Google nasceu de um projeto de pesquisa na Universidade de Stanford, com a empresa sendo inaugurada em 1998. Desde então, ela cresceu até ter uma fatia dominan- te do mercado da pesquisa na Internet, principalmente devido à eficiência do algoritmo de classificação subjacente utilizado em seu mecanismo de busca (discutido com mais detalhes a seguir). De forma significativa, o Google diversificou e, além de fornecer um mecanismo de busca, agora tem uma importante participação na computação em nuvem. Da perspectiva dos sistemas distribuídos, o Google oferece um fascinante estudo de caso, com requisitos extremamente exigentes, particularmente em termos de escala- bilidade, confiabilidade, desempenho e abertura (veja a discussão sobre esses desafios na Seção 1.5). Por exemplo, em termos de pesquisa, vale notar que o sistema subjacente tem se adaptado muito bem ao crescimento da empresa. Desde seu sistema de produção inicial (em 1998), até lidar com mais de 88 bilhões de pesquisas por mês (em 2010), seu principal mecanismo de busca nunca sofreu uma interrupção em todo esse tempo e seus usuários podem esperar resultados de consulta em torno de 0,2 segundos [goo- gleblog.blogspot.com I]. O estudo de caso apresentado aqui examinará as estratégias e decisões de projeto por trás desse sucesso e dará uma ideia do projeto de sistemas distribuídos complexos. Antes de passarmos para o estudo de caso, contudo, é instrutivo ver com mais deta- lhes o mecanismo de busca e também o Google como provedor de nuvem. Coulouris_21.indd 917 Coulouris_21.indd 917 23/05/13 09:26 23/05/13 09:26
  • 4. 918 Sistemas Distribuídos, Conceitos e Projeto O mecanismo de busca do Google • A função do mecanismo de busca do Google, assim como para qualquer mecanismo de pesquisa na Web, é receber determinada consulta e retornar uma lista ordenada com os resultados mais relevantes que satisfazem essa con- sulta, pesquisando o conteúdo da Web. Os desafios derivam do tamanho da Web e de sua taxa de mudança, assim como do requisito de fornecer os resultados mais relevantes do ponto de vista de seus usuários. Fornecemos a seguir uma breve visão geral do funcionamento da pesquisa no Goo- gle; uma descrição mais completa do funcionamento do mecanismo de busca do Goo- gle pode ser encontrado em Langville e Meyer [2006]. Como exemplo, consideraremos como o mecanismo de busca responde à consulta “livro sistemas distribuídos”. O mecanismo de busca consiste em um conjunto de serviços para esquadrinhar a Web e indexar e classificar as páginas descobertas, conforme discutido a seguir. Esquadrinhamento (crawling): a tarefa do crawler é localizar e recuperar o conteúdo da Web e passá-lo para o subsistema de indexação. Isso é realizado por um serviço de soft- ware chamado Googlebot, que lê determinada página Web recursivamente, coletando to- dos os links dessa página Web e programando mais operações de esquadrinhamento para os links coletados (uma técnica conhecida como pesquisa em profundidade, altamente eficiente em buscar praticamente todas as páginas na Web). No passado, devido ao tamanho da Web, o esquadrinhamento geralmente era feito uma vez a cada poucas semanas. Entretanto, para certas páginas Web isso era insuficien- te. Por exemplo, é importante que os mecanismos de busca sejam capazes de informar precisamente sobre notícias de última hora ou mudanças em preços de ações. Portanto, o Googlebot tomava nota do histórico de alterações em páginas Web e revisitava frequen- temente as que mudavam, com um período aproximadamente proporcional à frequência das mudanças. Com a introdução do Caffeine, em 2010 [googleblog.blogspot.com II], o Google mudou de uma estratégia em lotes para um processo mais contínuo de esqua- drinhamento, destinado a oferecer resultados de busca mais atualizados. O Caffeine foi construído usando um novo serviço de infraestrutura, chamado de Percolator, que supor- ta a atualização incremental de grandes conjuntos de dados [Peng e Dabek 2010]. Indexação: embora o esquadrinhamento seja uma função importante em termos de reco- nhecer o conteúdo da Web, ele não nos ajuda na busca de ocorrências de “livro sistemas distribuídos”. Para entendermos como isso é processado, precisamos examinar mais de perto a indexação. A função da indexação é produzir um índice para o conteúdo da Web que seja semelhante a um índice do final de um livro, mas em uma escala muito maior. Mais precisamente, a indexação produz o que conhecido como índice invertido, mapeando as palavras que aparecem em páginas Web e outros recursos Web textuais (incluindo docu- mentos nos formatos .pdf, .doc e outros) nas posições em que ocorrem nos documentos, incluindo a posição exata no documento e outras informações relevantes, como tamanho da fonte e se há uso de letras maiúsculas (que são usadas para determinar a importância, conforme veremos a seguir). O índice também é classificado para suportar consultas efi- cientes de palavras em relação às localizações. Além de manter um índice de palavras, o mecanismo de busca do Google também mantém um índice de links, monitorando quais páginas estão ligadas a determinado site. Isso é usado pelo algoritmo PageRank, conforme discutido a seguir. Vamos voltar ao nosso exemplo de consulta. Esse índice invertido nos permitirá desco- brir páginas Web que incluem os termos de busca “distribuídos”, “sistemas” e “livro” e, por meio de uma análise cuidadosa, poderemos descobrir páginas que incluam todos os termos. Por exemplo, o mecanismo de busca poderá identificar que todos os três termos podem ser Coulouris_21.indd 918 Coulouris_21.indd 918 23/05/13 09:26 23/05/13 09:26
  • 5. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 919 encontrados em amazon.com, www.cdk5.net e em muitos outros sites.Assim, usando o índi- ce é possível reduzir o conjunto de páginas Web candidatas de bilhões para talvez dezenas de milhares, dependendo do nível de diferenciação nas palavras-chave escolhidas. Classificação: o problema da indexação é que ela não fornece nenhuma informação sobre a importância relativa das páginas Web que contêm um conjunto de palavras-chave em parti- cular – apesar de isso ser fundamental para se determinar a relevância em potential de uma página. Portanto, todos os mecanismos de busca modernos dão ênfase significativa a um sistema de classificação por meio do qual uma classificação mais alta seja uma indicação da importância de uma página e seja usada para garantir que a página será retornada mais perto da parte superior da lista de resultados do que as páginas com classificação mais bai- xa. Conforme mencionado anteriormente, grande parte do sucesso do Google pode ser cre- ditado à eficiência de seu algoritmo de classificação, PageRank [Langville e Meyer 2006]. O algoritmo PageRank foi inspirado no sistema de classificação de artigos acadêmi- cos baseado na análise de citações. No mundo acadêmico, um artigo é considerado impor- tante se tem muitas citações feitas por outros acadêmicos da área. Analogamente, no Page- Rank, uma página será considerada importante se for ligada a um grande número de outras páginas (usando os dados de link mencionados anteriormente). O PageRank também vai além de uma simples análise de “citação”, examinando a importância dos sites que contêm links para determinada página. Por exemplo, um link para bbc.co.uk será considerado como mais importante do que um link para a página Web pessoal de Gordon Blair. No Google, a classificação leva diversos outros fatores em conta, incluindo a proxi- midade de palavras-chave em uma página e se estão em uma fonte grande ou se as letras são maiúsculas (com base nas informações armazenadas no índice invertido). Voltando ao nosso exemplo, após fazer uma pesquisa de índice em cada uma das três palavras da consulta, a função de busca classifica todas as referências de página resultantes, de acordo com a importância percebida. Por exemplo, a classificação esco- lheria certas referências de página sob amazon.com e www.cdk5.net por causa do grande número de links para essas páginas em outros sites “importantes”. A classificação dará prioridade às páginas onde os termos “distribuídos”, “sistemas” e “livro” aparecem bem próximos. Analogamente, a classificação extrairia as páginas em que as palavras apare- cem próximas ao início da página ou em letras maiúsculas, talvez indicando uma lista de livros-texto sobre sistemas distribuídos. O resultado final deve ser uma lista classificada de resultados na qual as entradas que estão no início são as mais importantes. Anatomia de um mecanismo de busca: os fundadores do Google, Sergey Brin e Larry Page, escreveram um artigo de referência sobre a “anatomia” do mecanismo de busca do Goo- gle, em 1998 [Brin e Page 1998], fornecendo ideias interessantes sobre como seu meca- nismo de busca foi implementado. A arquitetura global descrita nesse artigo está ilustrada na Figura 21.1, extraída do original. Nesse diagrama, fazemos distinção entre os serviços que suportam pesquisa na Web diretamente, desenhados como elipses, e os componentes da infraestrutura de armazenamento subjacente, ilustrados como retângulos. Embora não seja o objetivo deste capítulo apresentar essa arquitetura em detalhes, uma breve visão geral ajudará na comparação com a infraestrutura do Google mais so- fisticada disponível atualmente. A função básica do esquadrinhamento já foi descrita an- teriormente. Ele recebe como entrada listas de URLs a serem buscados, fornecidos pelo servidor de URL, com as páginas buscadas resultantes colocadas no servidor de armaze- namento. Então, esses dados são compactados e colocados no repositório para mais aná- lise, em particular criando o índice para pesquisa. A função de indexação é executada em dois estágios. Primeiramente, o indexador descompacta os dados do repositório e produz um conjunto de acessos (hits), no qual um hit é representado pelo ID do documento, a Coulouris_21.indd 919 Coulouris_21.indd 919 23/05/13 09:26 23/05/13 09:26
  • 6. 920 Sistemas Distribuídos, Conceitos e Projeto palavra, a posição no documento e outras informações, como o tamanho da palavra e o uso de maiúsculas. Então, esses dados são armazenados em um conjunto de barris, um importante elemento de armazenamento na arquitetura inicial. Essas informações são armazenadas pelo ID do documento. Então, o classificador pega esses dados e os clas- sifica por ID de palavra para produzir o índice invertido necessário (conforme discutido anteriormente). O indexador também executa outras duas funções muito importantes ao analisar os dados: ele extrai informações sobre links em documentos, armazenando essas informações em um arquivo de âncoras, e produz um léxico para os dados analisados (o qual, quando a arquitetura inicial foi usada, consistia em 14 milhões de palavras). O arquivo de âncoras é processado por um solucionador de URL, o qual executa várias funções sobre esses dados, incluindo transformar URLs relativos em URLs absolutos, antes de produzir um banco de dados de links, como uma entrada para os cálculos de Pa- geRank. O solucionador de URL também cria um doc index, o qual fornece entrada para o servidor de URL em termos de mais páginas a esquadrinhar. Por fim, o pesquisador implementa o recurso de pesquisa básico do Google, recebendo entrada do doc index, de PageRank, do índice invertido mantido nos barris e também do léxico. Algo extraordinário em relação a essa arquitetura é que, embora seus detalhes es- pecíficos tenham mudado, os principais serviços que suportam pesquisa na Web – isto é, esquadrinhamento, indexação (incluindo a ordenação), classificação (através de Page- Rank) – permanecem os mesmos. Servidor de URL Crawlers Servidor de armazenagem Repositório Indexador Léxico Âncoras Solucionador de URL Barris de armazenamento Índice de docs. Links PageRank Pesquisador Classificador Figura 21.1 Esboço da arquitetura do mecanismo de busca original do Google [Brin e Page 1998]. Coulouris_21.indd 920 Coulouris_21.indd 920 23/05/13 09:26 23/05/13 09:26
  • 7. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 921 Igualmente notável é que, conforme ficará claro a seguir, a infraestrutura mudou radicalmente, desde as primeiras tentativas de identificar uma arquitetura para pesquisa na Web até o sofisticado suporte para sistemas distribuídos fornecido atualmente, tanto em termos de identificar blocos de construção mais reutilizáveis para comunicação, ar- mazenamento e processamento, como em termos de generalização da arquitetura para além da pesquisa. Google como provedor de nuvem • O Google diversificou significativamente e, agora, além de pesquisa oferece uma ampla variedade de aplicações baseadas na Web, incluin- do o conjunto promovido como Google Apps [www.google.com I]. Mais geralmente, o Google agora é um forte participante na área da computação em nuvem. Lembre-se de que a computação em nuvem foi apresentada no Capítulo 1 e definida como “um conjunto de serviços de aplicativos, armazenamento e computação baseados na Internet, suficientes para suportar as necessidades da maioria dos usuários, permitindo, assim, que eles prescindam em grande medida ou totalmente do software local de armazenamento de dados ou de aplicativo”. É exatamente isso que agora o Google se esforça em oferecer, em particular com produtos significativos nas áreas de software como serviço e plata- forma como serviço (conforme apresentado na Seção 7.7.1). Examinaremos cada uma dessas áreas por sua vez, a seguir. Software como serviço: essa área ocupa-se em oferecer software em nível de aplicação pela Internet, como aplicativos Web. Um exemplo importante é o Google Apps, um con- junto de aplicações baseadas na Web que incluem Gmail, Google Docs, Google Sites, Google Talk e Google Calendar. O objetivo do Google é substituir os tradicionais conjun- tos para escritório por aplicações que suportam preparação compartilhada de documen- tos, calendários online e diversas ferramentas de colaboração que suportam e-mail, wikis, Voice over IP e troca instantânea de mensagens. Recentemente, foram desenvolvidas várias outras aplicações inovadoras baseadas na Web; elas e o Google Apps original estão resumidos na Figura 21.2. Uma das princi- Aplicação Descrição Gmail Sistema de correio com mensagens hospedadas pelo Google, mas com gerenciamento de mensagens do tipo área de trabalho. Google Docs Conjunto de escritório baseado na web, suportando edição compartilhada de documentos mantidos nos servidores do Google. Google Sites Sites no estilo wiki, com recursos de edição compartilhada. Google Talk Suporta troca de mensagens de texto instantâneas e Voice over IP. Google Calendar Calendário baseado na web, com todos os dados hospedados nos servidores do Google. Google Wave Ferramenta de colaboração que integra e-mail, troca de mensagens instantânea, wikis e redes sociais. Google News Site agregador de notícias totalmente automatizado. Google Maps Mapa-múndi baseado na Web, incluindo imagens de alta resolução e sobreposições ilimitadas, geradas pelos usuários. Google Earth Visão do globo terrestre quase tridimensional e escalonável, com sobreposições ilimitadas, geradas pelos usuários. Google App Engine Infraestrutura distribuída do Google, disponibilizada para terceiros como um serviço (plataforma como serviço). Figura 21.2 Exemplo de aplicações do Google. Coulouris_21.indd 921 Coulouris_21.indd 921 23/05/13 09:26 23/05/13 09:26
  • 8. 922 Sistemas Distribuídos, Conceitos e Projeto pais observações para os propósitos deste capítulo é que o Google estimula uma estraté- gia aberta para a inovação dentro da organização e, assim, novas aplicações estão surgin- do o tempo todo. Isso impõe uma demanda específica sobre a infraestrutura de sistemas distribuídos subjacente, um ponto que será revisitado na Seção 21.3.2. Plataforma como serviço: essa área ocupa-se em oferecer APIs de sistema distribuído como serviços pela Internet, sendo essas APIs usadas para suportar o desenvolvimento e a hospedagem de aplicações Web (note que, infelizmente, o uso do termo “plataforma” nesse contexto é incoerente com a maneira como é utilizado em outras partes deste livro, em que se refere ao hardware e ao sistema operacional). Com o lançamento do Google App Engine, o Google foi além do software como serviço e agora oferece sua infraestru- tura de sistemas distribuídos, conforme discutido por todo este capítulo como serviço de nuvem. Mais especificamente, já está previsto que os negócios do Google utilizem essa infraestrutura de nuvem internamente para dar suporte a todas as suas aplicações e servi- ços, incluindo seu mecanismo de pesquisa na Web. Agora, o Google App Engine oferece acesso externo como parte dessa infraestrutura, permitindo que outras organizações exe- cutem suas próprias aplicações Web na plataforma Google. Veremos mais detalhes da infraestrutura do Google no decorrer deste capítulo; para mais detalhes sobre o Google App Engine, consulte o site do Google [code.google.com IV]. 21.3 Arquitetura global e filosofia de projeto Esta seção considera a arquitetura global do sistema Google, examinando: • a arquitetura física adotada pelo Google; • a arquitetura de sistema associada que oferece serviços comuns para o mecanismo de busca na Internet e as muitas aplicações Web oferecidas pelo Google. 21.3.1 Modelo físico A principal filosofia do Google em termos de infraestrutura física é o uso de núme- ros muito grandes de PCs comuns para produzir um ambiente de custo reduzido para armazenamento e computação distribuídos. As decisões de compra são baseadas na obtenção do melhor desempenho por dólar, em vez do desempenho absoluto, com um gasto típico em um único PC girando em torno de US$1.000. Um PC normalmente terá cerca de 2 terabytes de armazenamento em disco, em torno de 16 gigabytes de memória DRAM (Dynamic Random Access Memory – memória de acesso aleatório dinâmico) e executará uma versão reduzida do núcleo Linux. (Essa filosofia de construção de sistemas a partir de PCs comuns reflete os primórdios do projeto de pesquisa original, quando Sergey Brin e Larry Page construíram o primeiro mecanismo de busca do Goo- gle a partir de hardware de refugo, recolhido próximo ao laboratório da Universidade de Stanford.) Optando por tomar o caminho dos PCs comuns, o Google reconhecia que partes de sua infraestrutura falharia e, assim, conforme veremos a seguir, projetou a infraestrutura usando diversas estratégias para tolerar tais falhas. Hennessy e Patterson [2006] relatam as seguintes características de falha do Google: • De longe, a fonte de falha mais comum é em razão do software, com cerca de 20 máquinas precisando ser reinicializadas por dia. (É interessante notar que o proces- so de reinicialização é totalmente manual.) Coulouris_21.indd 922 Coulouris_21.indd 922 23/05/13 09:26 23/05/13 09:26
  • 9. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 923 • As falhas de hardware representam cerca de 1/10 das falhas em razão do software, com cerca de 2 a 3% dos PCs falhando anualmente, devido ao hardware. Dessas, 95% se devem a falhas nos discos ou na memória DRAM. Isso justifica a decisão de adquirir PCs comuns; dado que a ampla maioria das falhas é em razão do software, não vale a pena investir em hardware mais caro e confiável. Outro artigo, de Pinheiro et al. [2007], também relata as características de falha dos discos co- muns utilizados na infraestrutura física do Google, dando uma ideia interessante sobre os padrões de falha de armazenamento em disco em implantações de larga escala. A arquitetura física é construída como segue [Hennessy e Patterson 2006]: • Os PCs são organizados em racks contendo entre 40 e 80 PCs cada um. Os racks têm dois lados, com metade dos PCs em cada um. Cada rack tem um switch Ether- net que fornece conectividade para ele e também para o mundo externo (veja a seguir). Esse switch é modular, organizado como um número de lâminas (blades), com cada lâmina suportando 8 interfaces de rede de 100 Mbps ou uma interface de 1 Gbps. Para 40 PCs, 5 lâminas contendo cada uma oito interfaces de rede são suficientes para garantir a conectividade dentro da prateleira. Mais duas lâminas, cada uma suportando uma interface de rede de 1 Gbps, são usadas para conexão com o mundo externo. • Os racks são organizados em clusters (conforme discutido na Seção 1.3.4), que são uma unidade de gerenciamento importante, determinando, por exemplo, a locali- zação e a replicação de serviços. Normalmente, um cluster consiste em 30 ou mais racks e dois switches de alta largura de banda, fornecendo conectividade para o mundo externo (a Internet e outros centros do Google). Por redundância, cada rack é conectado aos dois switches; além disso, para ter ainda mais redundância, cada switch tem enlaces redundantes para o mundo externo. • Os clusters ficam em centros de dados do Google espalhados pelo mundo. Em 2000, o Google contava com importantes centros de dados no Vale do Silício (dois centros) e na Virgínia, nos Estados Unidos. Quando este livro estava sendo produzi- do, o número de centros de dados tinha aumentado significativamente e agora exis- tem centros em muitos lugares nos Estados Unidos, além de em Dublin (Irlanda), Saint-Ghislain (Bélgica), Zurique (Suiça), Tóquio (Japão) e Pequim (China). Um mapa dos centros de dados conhecidos em 2008 pode ser encontrado em [royal. pingdom.com]. Uma visão simplificada dessa organização global aparece na Figura 21.3. Essa infra- estrutura física proporciona ao Google recursos de armazenamento e computacionais enormes, junto à redundância necessária para a construção de sistemas de larga escala e tolerantes a falhas (note que, para evitar confusão, essa figura mostra apenas as conexões Ethernet de um dos clusters para os enlaces externos). Capacidade de armazenamento: consideremos a capacidade de armazenamento disponível no Google. Se cada PC oferece 2 terabytes de armazenamento, então um rack com 80 PCs fornecerá 160 terabytes, com um cluster de 30 racks oferecendo 4,8 petabytes. Não se sabe exatamente quantas máquinas o Google tem no total, pois a empresa mantém estrito sigilo a respeito desse aspecto de seu negócio, mas pode- mos supor que tenha perto de 200 clusters, oferecendo uma capacidade de armaze- namento total de 960 petabytes ou quase 1 exabyte de armazenamento (10 18 bytes). É provável que esse valor seja conservador, pois a vice-presidente do Google, Ma- rissa Mayer, já fala sobre a explosão de dados à faixa da exaescala [www.parc.com]. Coulouris_21.indd 923 Coulouris_21.indd 923 23/05/13 09:26 23/05/13 09:26
  • 10. 924 Sistemas Distribuídos, Conceitos e Projeto No restante deste capítulo, veremos como o Google utiliza esse recurso de armazena- mento e computacional extensivo e a redundância associada para oferecer serviços básicos. 21.3.2 Arquitetura de sistema global Antes de examinarmos a arquitetura de sistema global, é interessante verificarmos os principais requisitos com mais detalhes: Escalabilidade: o primeiro e mais óbvio requisito para a infraestrutura do Goo- gle é controlar a escalabilidade e, em particular, ter estratégias que se adaptem ao que é um sistema distribuído ULS (Ultra-Large Scale), conforme apresentado no Capítulo 2. Para o mecanismo de busca, o Google vê o problema da escala- bilidade em termos de três dimensões: i) ser capaz de lidar com mais dados (por exemplo, à medida que o volume de informações na Web aumenta por meio de iniciativas como a digitalização de bibliotecas), ii) ser capaz de tratar de mais consultas (à medida que aumenta o número de pessoas que usam o Google em suas casas e locais de trabalho) e iii) procurar resultados melhores (particular- mente importante, pois esse é um fator determinante no funcionamento de um mecanismo de pesquisa na Web). Essa visão do problema da escalabilidade está ilustrada na Figura 21.4. A escalabilidade exige o uso de estratégias (sofisticadas) de sistemas distri- buídos. Vamos ilustrar isso com uma análise simples extraída da ideia básica de Racks ...... Cluster Racks ...... Cluster Racks ...... Cluster Arquitetura do centro de dados Para outros centros de dados e para a Internet X Switches Switches X X X X X X X X X X X X X X X X X X X (Para simplificar o diagrama, é mostrada a conexão Ethernet de um dos clusters com a Internet.) Figura 21.3 Organização da infraestrutura física do Google. Coulouris_21.indd 924 Coulouris_21.indd 924 23/05/13 09:26 23/05/13 09:26
  • 11. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 925 Jeff Dean no PACT’06 [Dean 2006]. Ele presumiu que a Web consiste em cerca de 20 bilhões de páginas com 20 quilobytes cada uma. Isso significa um tamanho total de cerca de 400 terabytes. Examinar esse volume de dados exigiria mais de 4 meses para um único computador, supondo que esse computador possa ler 30 megabytes por segundo. Em contraste, 1.000 máquinas podem ler esse volume de dados em menos de 3 horas. Além disso, conforme vimos na Seção 21.2, pesqui- sar não envolve apenas esquadrinhar. Todas as outras funções, incluindo indexar, classificar e pesquisar, exigem soluções altamente distribuídas para que seja pos- sível fazer a adaptação. Confiabilidade: o Google tem requisitos de confiabilidade rigorosos, especial- mente com relação à disponibilidade de serviços. Isso é particularmente impor- tante para a funcionalidade de pesquisa, em que há necessidade de oferecer dis- ponibilidade 24 horas por dia, sete dias por semana (notando, contudo, que é intrinsecamente fácil mascarar falhas em pesquisas, pois o usuário não tem como saber se todos os resultados foram retornados). Esse requisito também serve para outras aplicações Web e é interessante notar que o Google oferece um acordo de nível de serviço de 99,9% (efetivamente uma garantia de sistema) para clientes que pagam pelo Google Apps, cobrindo o Gmail, o Google Calendar, o Goo- gle Docs, o Google Sites e o Google Talk. A empresa tem um excelente recorde global em termos de disponibilidade de serviços, mas a conhecida interrupção do Gmail em 1º de setembro de 2009 serve como um lembrete dos contínuos desafios nessa área. (Essa interrupção, que durou 100 minutos, foi causada por um problema em cascata de servidores sobrecarregados durante um período de manutenção de rotina). Note que o requisito da confiabilidade deve ser satisfeito no contexto das escolhas de projeto na arquitetura física, o que significa que as falhas (de software e hardware) são antecipadas com frequência razoável. Isso exige detecção de falhas e a adoção de estratégias para mascarar ou tolerar tais falhas. Essas estratégias contam pesadamente com a redundância na arquitetura física subjacente. Veremos exemplos dessas estratégias à medida que os detalhes da arquitetura de sistema surgirem. Desempenho: o desempenho global do sistema é fundamental para o Google, es- pecialmente na obtenção de baixa latência de interações do usuário. Quanto melhor Mais dados Mais consultas Melhores resultados Figura 21.4 O problema da escalabilidade no Google. Coulouris_21.indd 925 Coulouris_21.indd 925 23/05/13 09:26 23/05/13 09:26
  • 12. 926 Sistemas Distribuídos, Conceitos e Projeto o desempenho, mais provável será que um usuário retorne com mais consultas que, por sua vez, aumentam a exposição de anúncios, potencialmente aumentando os lucros. A importância do desempenho é exemplificada, por exemplo, com a meta de concluir operações de pesquisa na Web em 0,2 segundos (conforme menciona- do anteriormente) e obter o desempenho de saída exigido para responder a todas as requisições recebidas, enquanto lida com conjuntos de dados muito grandes. Isso se aplica a uma ampla variedade de funções associadas à operação do Google, incluindo esquadrinhamento da Web, indexação e classificação. Também é impor- tante notar que o desempenho é uma propriedade fim-a-fim, exigindo que todos os recursos associados funcionem juntos, incluindo recursos de rede, armazenamento e computacionais. Abertura: de muitas maneiras, os requisitos anteriores são óbvios para o Google suportar seus serviços e aplicações básicos. Há também um forte requisito de aber- tura, particularmente para suportar mais desenvolvimento na variedade de aplica- ções Web oferecidas. Sabe-se que o Google, como organização, estimula e cultiva a inovação, e isso fica mais evidente no desenvolvimento de novas aplicações Web. Isso só é possível com uma infraestrutura extensível e que dê suporte para o desen- volvimento de novas aplicações. O Google tem respondido a essas necessidades desenvolvendo a arquitetura de sistema global mostrada na Figura 21.5. Essa figura mostra a plataforma de computação na parte inferior (isto é, a arquitetura física descrita anteriormente) e os conhecidos serviços e aplicações do Google na parte superior. A camada do meio define uma infraestrutura distribuída comum que fornece suporte de midd- leware para pesquisa e computação em nuvem. Isso é fundamental para o suces- so do Google. A infraestrutura fornece os serviços de sistema distribuído comuns para os desenvolvedores de serviços e aplicações Google e encapsula as principais estratégias para lidar com escalabilidade, confiabilidade e desempenho. O forne- cimento de uma infraestrutura comum bem projetada como essa pode promover o desenvolvimento de novas aplicações e serviços por meio da reutilização dos serviços de sistema subjacentes e, mais sutilmente, fornece uma coerência global para o crescimento da base de código do Google, impondo estratégias e princípios de projeto comuns. Aplicações e serviços do Google Plataforma do Google Infraestrutura do Google (middleware) Figura 21.5 A arquitetura global de sistemas do Google. Coulouris_21.indd 926 Coulouris_21.indd 926 23/05/13 09:26 23/05/13 09:26
  • 13. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 927 Infraestrutura do Google • O sistema é construído como um conjunto de serviços distri- buídos que oferecem funcionalidade básica para os desenvolvedores (veja a Figura 21.6). Esse conjunto de serviços é naturalmente dividido nos seguintes subconjuntos: • os paradigmas de comunicação subjacentes, incluindo serviços para invocação re- mota e comunicação indireta: – o componente buffers de protocolo oferece um formato de serialização co- mum para o Google, incluindo a serialização de requisições e respostas na invocação remota. – o serviço de publicar-assinar do Google suporta a disseminação eficiente de eventos para números potencialmente grandes de assinantes. • serviços de dados e coordenação, fornecendo abstrações não estruturadas e semies- truturadas para o armazenamento de dados acoplado a serviços para suportar o acesso coordenado aos dados: – O GFS oferece um sistema de arquivos distribuído otimizado para os requisitos específicos de aplicações e serviços do Google (incluindo o armazenamento de arquivos muito grandes). – O Chubby suporta serviços de coordenação e a capacidade de armazenar volu- mes de dados menores. – A Bigtable fornece um banco de dados distribuído que dá acesso a dados semiestruturados. • serviços de computação distribuída, que oferecem meios para executar computação paralela e distribuída na infraestrutura física: – O MapReduce suporta computação distribuída em conjuntos de dados potencial- mente muito grandes (por exemplo, armazenados na Bigtable). Publicar-assinar GFS Chubby Bigtable Sawzall Paradigmas de comunicação Dados e coordenação Computação distribuída MapReduce Buffers de protocolo Figura 21.6 Infraestrutura do Google. Coulouris_21.indd 927 Coulouris_21.indd 927 23/05/13 09:26 23/05/13 09:26
  • 14. 928 Sistemas Distribuídos, Conceitos e Projeto – A Sawzall é uma linguagem de nível mais alto para a execução de tais computa- ções distribuídas. Examinaremos cada um desses componentes por vez, nas Seções 21.4 a 21.6. Primeiro, contudo, é instrutivo refletir sobre os principais princípios de projeto associados à arqui- tetura como um todo. Princípios de projeto • Para se entender completamente o projeto da infraestrutura do Google, é importante entender também as principais filosofias de projeto que permeiam a organização: • O princípio de projeto mais importante por trás do software Google é a simplicida- de: o software deve fazer apenas uma coisa e fazê-la bem, evitando projetos cheios de recursos, quando possível. Por exemplo, Bloch [2006] discute como esse prin- cípio se aplica no projeto da API, implicando que a API deva ser a menor possível (um exemplo da aplicação de Razor de Occam). • Outro importante princípio de projeto é uma forte ênfase no desempenho no desen- volvimento de software de sistemas, capturada na frase “cada milissegundo conta” [www.google.com IV]. Em uma exposição de princípios básicos na LADIS’09, Jeff Dean (membro do Google Systems Infrastructure Group) enfatizou a impor- tância de ser possível estimar o desempenho de um projeto de sistema conhecendo- -se os custos do desempenho de operações primitivas, como acesso à memória e ao disco, envio de pacotes por uma rede, travamento e destravamento de um mu- tex, etc., acoplado ao que ele se referiu como cálculos no “verso do envelope” [www.cs.cornell.edu]. • Um último princípio é defender regimes de teste rigorosos no software, capturado pelo slogan “se não quebrou, você não se esforçou o bastante” [googletesting.blogspot.com]. Isso é complementado por uma forte ênfase no re- gistro e rastreamento para detectar e resolver falhas no sistema. Com essas informações, estamos prontos para examinar as várias partes constituin- tes da infraestrutura do Google, começando com os paradigmas de comunicação sub- jacentes. Para cada área, apresentaremos o projeto global e destacaremos as principais decisões de projeto e compromissos associados. 21.4 Paradigmas de comunicação Recordando os Capítulos 3 a 6, fica claro que a escolha do paradigma (ou paradigmas) de comunicação subjacente é fundamental para o sucesso de um projeto de sistema global. As opções incluem: • usar diretamente um serviço de comunicação entre processos subjacente, como o oferecido pelas abstrações de soquete (descritas no Capítulo 4 e suportadas por todos os sistemas operacionais modernos); • usar um serviço de invocação remota (como um protocolo de requisição-resposta, chamadas de procedimento remoto ou invocação a método remoto, conforme dis- cutido no Capítulo 5), oferecendo suporte para interações cliente-servidor; • usar um paradigma de comunicação indireta, como comunicação em grupo, estraté- gias baseadas em eventos distribuídos, espaços de tupla ou estratégias de memória compartilhada distribuída (conforme discutido no Capítulo 6). Coulouris_21.indd 928 Coulouris_21.indd 928 23/05/13 09:26 23/05/13 09:26
  • 15. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 929 De conformidade com os princípios de projeto identificados na Seção 21.3, o Google adota um serviço de invocação remota simples, mínimo e eficiente que é uma variante de uma estratégia de chamada de procedimento remoto. Os leitores se lembrarão de que a comunicação por chamada de procedimento re- moto exige um componente de serialização para converter os dados da invocação de procedimento (nome do procedimento e parâmetros, possivelmente estruturados) de sua representação binária interna para um formato plano ou serializado neutro quanto ao processador, pronto para transmissão ao parceiro remoto. A serialização para RPC Java foi descrita na Seção 4.3.2. XML surgiu mais recentemente como um formato de dados serializados “universal”, mas sua generalidade apresenta sobrecargas substantiais. Por- tanto, o Google desenvolveu um componente de serialização simplificado e de alto de- sempenho, conhecido como buffers de protocolo, que é usado pela maioria significativa das interações dentro da infraestrutura. Isso pode ser usado em qualquer mecanismo de comunicação subjacente para fornecer um recurso de RPC. Existe uma versão de código- -fonte aberto do componente buffers de protocolo [code.google.com II]. Um serviço de publicar-assinar separado também é usado, reconhecendo a im- portante função que esse paradigma pode oferecer em muitas áreas do projeto de sis- tema distribuído, incluindo a disseminação de eventos eficiente e em tempo real para vários participantes. Em comum com muitas outras plataformas de sistema distribuído, a infraestrutura do Google oferece uma solução mista, permitindo aos desenvolvedores selecionar o melhor paradigma de comunicação para seus requisitos. O protocolo de publicação-assinatura não é uma alternativa ao componente buffers de protocolo na infra- estrutura do Google, mas um acréscimo, oferecendo um serviço de valor agregado onde for mais apropriado. Examinaremos o projeto dessas duas estratégias, a seguir, com ênfase no compo- nente buffers de protocolo (detalhes completos sobre o protocolo de publicar-assinar ain- da não estão publicamente disponíveis). 21.4.1 Invocação remota O componente buffers de protocolo enfatiza a descrição e a subsequente serialização dos dados e, assim, o conceito é mais bem comparado com as alternativas diretas, como XML. O objetivo é fornecer uma maneira, neutra quanto à linguagem e quanto à platafor- ma, de especificar e serializar dados de modo simples, altamente eficiente e extensível; os dados serializados podem, então, ser usados para armazenamento subsequente ou para transmissão, usando um protocolo de comunicação subjacente, ou mesmo para qualquer outro propósito que exija um formato de serialização para dados estruturados. Veremos, posteriormente, como isso pode ser utilizado como base para troca estilo RPC. No componente buffers de protocolo, é fornecida uma linguagem para a especifi- cação de mensagens. Apresentamos os principais recursos dessa linguagem (simples) por meio de um exemplo, com a Figura 21.7 mostrando como uma mensagem Book poderia ser especificada. Como pode ser visto, a mensagem Book consiste em uma série de campos numera- dos exclusivamente, cada um representado por um nome e pelo tipo do valor associado. O tipo pode ser: • um tipo de dados primitivo (incluindo inteiro, ponto flutuante, booleano, string ou bytes brutos); • um tipo enumerado; • uma mensagem aninhada, permitindo uma estruturação de dados hierárquica. Coulouris_21.indd 929 Coulouris_21.indd 929 23/05/13 09:26 23/05/13 09:26
  • 16. 930 Sistemas Distribuídos, Conceitos e Projeto Podemos ver exemplos de cada um na Figura 21.7. Os campos são anotados com um de três rótulos: • os campos required devem estar presentes na mensagem; • os campos optional podem estar presentes na mensagem; • os campos repeated podem existir zero ou mais vezes na mensagem (os desen- volvedores do componente buffers de protocolo veem isso como um tipo de vetor dimensionado dinamicamente). Novamente, podemos ver o uso de cada uma dessas anotações no formato da mensagem Book ilustrados na Figura 21.7. A numeração exclusiva (=1, =2, etc.) representa a marca (tag) que um campo em particular tem na codificação binária da mensagem. Essa especificação está contida em um arquivo .proto e é compilada pela ferramen- ta protoc. A saída dessa ferramenta é código gerado que permite aos programadores ma- nipular o tipo de mensagem específico, em particular atribuir/extrair valores a/de men- sagens. Em mais detalhes, a ferramenta protoc gera uma classe construtor que fornece métodos getter e setter para cada campo, junto a métodos adicionais para testar se um método foi ativado e para limpar um campo com o valor nulo associado. Por exemplo, os seguintes métodos seriam gerados para o campo title: public boolean hasTitle(); public java.lang.String getTitle(); public Builder setTitle(String value); public Builder clearTitle(); A importância da classe construtor é que, embora as mensagens sejam imutáveis no com- ponente buffers de protocolo, os construtores são mutáveis e usados para construir e ma- nipular novas mensagens. Para campos repeated, o código gerado é um pouco mais complicado, com méto- dos fornecidos para retornar uma contagem do número de elementos na lista associada, para obter ou configurar campos específicos na lista, para anexar um novo elemento message Book { required string title = 1; repeated string author = 2; enum Status { IN_PRESS = 0; PUBLISHED = 1; OUT_OF_PRINT = 2; } message BookStats { required int32 sales = 1; optional int32 citations = 2; optional Status bookstatus = 3 [default = PUBLISHED]; } optional BookStats statistics = 3; repeated string keyword = 4; } Figura 21.7 Exemplo de buffers de protocolo. Coulouris_21.indd 930 Coulouris_21.indd 930 23/05/13 09:26 23/05/13 09:26
  • 17. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 931 em uma lista e para adicionar um conjunto de elementos na lista (o método addAll). Ilustramos isso por meio de um exemplo, listando os métodos gerados para o campo keyword: public List<string> getKeywordList(); public int getKeywordCount(); public string getKeyword(int index); public Builder setKeyword(int index, string value); public Builder addKeyword(string value); public Builder addAllKeyword(Iterable<string> value); public Builder clearKeyword(); O código gerado também fornece diversos outros métodos para manipular mensagens, incluindo métodos como toString para fornecer uma representação legível da mensagem (frequentemente usada para depuração, por exemplo) e também uma série de métodos para analisar as mensagens recebidas. Como se pode ver, esse é um formato muito simples, comparado com XML (por exemplo, compare a especificação anterior com as especificações equivalentes em XML, mostradas na Seção 4.3.3), e que seus desenvolvedores dizem ser de 3 a 10 vezes menor do que os equivalentes em XML e de 10 a 100 vezes mais rápido na operação. A interface de programação associada que dá acesso aos dados também é consideravelmente mais simples do que as equivalentes para XML. Note que essa é uma comparação um tanto injusta, por dois motivos. Primeiramen- te, a infraestrutura do Google é um sistema relativamente fechado e, assim, ao contrário de XML, não trata da operação conjunta de sistemas abertos. Em segundo lugar, XML é significativamente mais rica, pois gera mensagens autodescritivas que contêm os dados e os metadados associados descrevendo a estrutura das mensagens (veja a Seção 4.3.3). O componente buffers de protocolo não fornece essa facilidade diretamente (embora seja possível obter esse efeito, conforme descrito nas páginas Web relevantes, em uma seção sobre técnicas [code.google.com II]). Em linhas gerais, isso é obtido pedindo-se para que o compilador protoc gere um FileDescriptorSet contendo autodescrições das mensagens e, então, incluindo-se isso explicitamente nas descrições da mensagem. Contudo, os de- senvolvedores do componente buffers de protocolo enfatizam que isso não é visto como um recurso particularmente útil e que raramente é usado no código da infraestrutura do Google. Suporte para RPC • Conforme mencionado anteriormente, o componente buffers de pro- tocolo é um mecanismo geral que pode ser usado para armazenamento ou comunicação. Contudo, o uso mais comum de buffers de protocolo é na especificação de trocas RPC na rede, e isso é realizado com uma sintaxe extra na linguagem. Novamente, ilustraremos a sintaxe por meio de um exemplo: service SearchService { rpc Search (RequestType) returns (ResponseType); } Esse trecho de código especifica uma interface de serviço chamada SearchService con- tendo uma operação remota, Search, que recebe um parâmetro de tipo RequestType e re- torna um parâmetro de tipo ResponseType. Por exemplo, os tipos poderiam corresponder a uma lista de palavras-chave e uma lista de livros (Books) correspondendo a esse con- Coulouris_21.indd 931 Coulouris_21.indd 931 23/05/13 09:26 23/05/13 09:26
  • 18. 932 Sistemas Distribuídos, Conceitos e Projeto junto de palavras-chave respectivamente. O compilador protoc pega essa especificação e produz uma interface abstrata SearchService e um stub que suporta chamadas no estilo RPC seguras quanto ao tipo para o serviço remoto, usando buffers de protocolo. Além de ser neutro quanto à linguagem e quanto à plataforma, o componente buffers de protocolo também é agnóstico com relação ao protocolo RPC subjacente. Em particular, o stub presume que existem implementações para duas interfaces abs- tratas RpcChannel e RpcController, a primeira oferecendo uma interface comum para as implementações RPC subjacentes e a última oferecendo uma interface de controle comum, por exemplo, para manipular as configurações associadas a essa implementa- ção. O programador deve fornecer implementações dessas interfaces abstratas, efeti- vamente selecionando a implementação de RPC desejada. Por exemplo, isso poderia passar mensagens serializadas usando HTTP ou TCP, ou poderia mapear em uma de várias implementações de RPC de terceiros disponíveis e vinculadas do local do com- ponente buffers de protocolo [code.google.com III]. Note que uma interface de serviço pode suportar várias operações remotas, mas cada operação deve obedecer ao padrão de pegar um único parâmetro e retornar ape- nas um resultado (sendo ambas mensagens de buffer de protocolo). Isso é incomum, comparado aos projetos de sistemas RPC e RMI – como vimos no Capítulo 5 –, pois as invocações remotas podem ter um número arbitrário de parâmetros e, no caso da RMI, os parâmetros ou resultados podem ser objetos ou mesmo referências de objeto (embora deva ser notado que a RPC da Sun, conforme documentado na Seção 5.3.3, adota uma estratégia semelhante ao componente buffers de protocolo). O fundamento lógico para se ter uma requisição e uma resposta é para dar suporte à capacidade de extensão e à evolução do software; embora os estilos mais gerais de interface possam mudar significativamente com o passar do tempo, há uma maior probabilidade de que este estilo mais restrito de interface permaneça constante. Essa estratégia também joga a complexidade para os dados, de uma maneira que lembra a filosofia REST, com seu conjunto de operações restrito e sua ênfase nos recursos de manipulação (veja a Seção 9.2). 21.4.2 Publicar-assinar O componente buffers de protocolo é usado extensivamente, mas não exclusivamente, como paradigma de comunicação na infraestrutura do Google. Para complementar o componente buffers de protocolo, a infraestrutura também suporta um sistema de publi- cação-assinatura destinado a ser usado quando eventos distribuídos precisam ser disse- minados em tempo real e com garantias de confiabilidade para números potencialmente grandes de destinatários. Conforme mencionado anteriormente, o serviço de publicação- -assinatura é acréscimo ao componente buffers de protocolo e, na verdade, utiliza esse componente para sua comunicação subjacente. Um uso importante do sistema de publicar-assinar, por exemplo, é servir de base para o sistema Google Ads, reconhecendo que, no Google, os anúncios têm abragência mundial e que sistemas anunciantes de qualquer lugar na rede precisam saber, em uma fração de segundo, a eligibilidade de certas propagandas que podem ser mostradas em resposta a uma consulta. O sistema RPC descrito anteriormente seria claramente inadequado e altamente ineficiente para esse estilo de interação, especialmente por causa dos números poten- cialmente grandes de assinantes e das garantias exigidas pelas aplicações associadas. Coulouris_21.indd 932 Coulouris_21.indd 932 23/05/13 09:26 23/05/13 09:26
  • 19. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 933 Em particular, o remetente precisaria conhecer a identidade de todos os outros sistemas anunciantes, o que poderia ser muito grande. As RPCs precisariam ser enviadas para todos os sistemas individuais, consumindo muitas conexões e um enorme espaço de buffer associado no remetente, sem mencionar os requisitos de largura de banda para enviar os dados pelos enlaces de rede de longo alcance. Em contraste, uma solução publicar-assinar, com seu inerente desacoplamento temporal e espacial, supera essas dificuldades e também oferece suporte natural para falha e recuperação de assinantes (veja a Seção 6.1). O Google não tornou disponível publicamente os detalhes do sistema de publi- car-assinar. Portanto, restringiremos nossa discussão a alguns recursos de alto nível do sistema. O Google adota um sistema de publicar-assinar baseado em tópicos, fornecendo vários canais para fluxos de evento, com os canais correspondendo a tópicos em particu- lar. Foi escolhido um sistema baseado em tópicos por sua facilidade de implementação e sua relativa previsibilidade em termos de desempenho, em comparação com as estraté- gias baseadas em conteúdo – isto é, a infraestrutura pode ser configurada e personaliza- da para distribuir eventos relacionados a determinado tópico. O inconveniente é a falta de poder expressivo na especificação de eventos de interesse. Como um compromisso, o sistema de publicar-assinar do Google permite assinaturas aprimoradas, definidas não somente pela seleção de um canal, mas também pela seleção de subconjuntos de eventos dentro desse canal. Em particular, um evento consiste em um cabeçalho, um conjunto de palavras-chave associadas e uma carga útil, que é opaca para o programador. As requi- sições de assinatura especificam o canal, junto a um filtro definido sobre o conjunto de palavras-chave. Os canais se destinam a ser usados para fluxos de dados relativamente estáticos e brutos, exigindo alto desempenho de saída de eventos (pelo menos 1 Mbps), de modo que a capacidade adicional de expressar assinaturas refinadas usando filtros ajuda muito. Por exemplo, se um tópico gerar menos do que esse volume de dados, eles serão incluídos dentro de outro tópico, mas poderão ser identificados pela palavra- -chave. O sistema de publicar-assinar é implementado como uma sobreposição de despa- chantes na forma de um conjunto de árvores, onde cada árvore representa um tópico. A raiz da árvore é o publicador e os nós-folha representam os assinantes. Quando filtros são introduzidos, eles são colocados o mais abaixo na árvore possível para minimizar tráfego desnecessário. Ao contrário dos sistemas de publicar-assinar discutidos no Capítulo 6, há uma forte ênfase na entrega confiável e oportuna: • Em termos de confiabilidade, o sistema mantém árvores redundantes; em particu- lar, são mantidas duas sobreposições de árvore separados por canal (tópico) lógico. • Em termos de entrega dentro de prazos, o sistema implementa uma técnica de ge- renciamento de qualidade de serviço para controlar os fluxos de mensagem. Em particular, um esquema de controle de taxa simples é introduzido, com base em um limite de taxa obrigatório, imposto de acordo com o usuário/tópico. Isso substitui uma estratégia mais complexa e gerencia a utilização antecipada de recursos na árvore em termos de memória, CPU e taxas de mensagem e bytes. Inicialmente, as árvores são construídas e constantemente reavaliadas de acordo com um algoritmo de caminho mais curto (veja o Capítulo 3). Coulouris_21.indd 933 Coulouris_21.indd 933 23/05/13 09:26 23/05/13 09:26
  • 20. 934 Sistemas Distribuídos, Conceitos e Projeto 21.4.3 Resumo das principais escolhas de projeto para a comunicação As escolhas de projeto globais relacionadas aos paradigmas de comunicação no Google estão resumidas na Figura 21.8. Essa tabela destaca as decisões mais importantes asso- ciadas ao projeto global e aos elementos constituintes (buffers de protocolo e o sistema de publicar-assinar) e resume o fundamento lógico e os compromissos específicos asso- ciados a cada escolha. No todo, vimos uma estratégia mista que oferece dois paradigmas de comunicação distintos, projetados para suportar diferentes estilos de interação dentro da arquitetura. Isso permite aos desenvolvedores escolher o melhor paradigma para cada domínio de problema em particular. Vamos repetir esse estilo de análise ao final de cada uma das seções a seguir, for- necendo, assim, uma perspectiva global das principais decisões de projeto relacionadas à infraestrutura do Google. Elemento Escolha de projeto Fundamento lógico Compromissos Buffers de protocolo O uso de uma linguagem para especificar formatos de dados Flexível, pois a mesma linguagem pode ser usada para serializar dados para armazena- mento ou comunicação – Simplicidade da linguagem Implementação eficiente Falta de expressividade quando comparado, por exemplo, com XML Suporte para um estilo de RPC (recebendo uma única mensagem como parâmetro e retornando uma única mensagem como resultado) Mais eficiente, extensível e suporta evolução do serviço Falta de expressividade quando comparado com outros pacotes de RPC ou RMI Projeto agnóstico quanto ao protocolo Podem ser usadas diferentes implemen- tações de RPC Nenhuma semântica comum para trocas RPC Publicar-assinar Estratégia baseada em tópicos Suporta implementação eficiente Menos expressiva do que as estratégias baseadas em conteúdo (atenuado pelos recursos de filtragem adicionais) Garantias de tempo real e confiabilidade Suporta a manutenção de modos de exibição consistentes de maneira oportuna Suporte para algoritmo adicional exigido com sobregarga associada Figura 21.8 Resumo das escolhas de projeto relacionadas aos paradigmas de comunicação. Coulouris_21.indd 934 Coulouris_21.indd 934 23/05/13 09:26 23/05/13 09:26
  • 21. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 935 21.5 Serviços de armazenamento de dados e coordenação Apresentaremos agora os três serviços que, juntos, fornecem serviços de dados e coorde- nação para aplicações e serviços de nível mais alto: o Google File System, o Chubby e a Bigtable. São serviços complementares na infraestrutura do Google: • O Google File System é um sistema de arquivos distribuído que oferece servi- ço semelhante ao do NFS e do AFS, conforme discutido no Capítulo 12. Ele dá acesso a dados não estruturados na forma de arquivos, mas otimizados para os estilos de dados e acesso a dados exigidos pelo Google (arquivos muito grandes, por exemplo). • O Chubby é um serviço multifacetado, suportando, por exemplo, travas distribuí- das para coordenação no ambiente distribuído e o armazenamento de quantidades muito pequenas de dados, complementando o armazenamento em larga escala ofe- recido pelo Google File System. • A Bigtable dá acesso a dados mais estruturados na forma de tabelas, que podem ser indexadas de várias maneiras, inclusive por linha ou coluna. Portanto, a Bigtable é um estilo de banco de dados distribuído, mas, ao contrário de muitos bancos de dados, não suporta operadores totalmente relacionais (eles são vistos pelo Google como desnecessariamente complexos e não escaláveis). Esses três serviços também são interdependentes. Por exemplo, a Bigtable usa o Google File System para armazenamento e o Chubby, para coordenação. Examinaremos cada serviço em detalhes a seguir. 21.5.1 O Google File System (GFS) O Capítulo 12 apresentou um estudo detalhado sobre o tema dos sistemas de arquivos distribuídos, analisando seus requisitos, sua arquitetura global e examinando dois estu- dos de caso em detalhes, a saber, NFS e AFS. Esses sistemas de arquivos são sistemas de arquivos distribuídos de propósito geral que oferecem abstrações de arquivo e diretório para uma ampla variedade de aplicações dentro e entre organizações. O Google File System (GFS) também é um sistema de arquivos distribuído; ele oferece abstrações se- melhantes, mas especializadas para os requisitos específicos do Google, em termos de armazenamento e acesso a quantidades de dados muito grandes [Ghemawat et al. 2003]. Esses requisitos levaram a decisões de projeto muito diferentes das tomadas no NFS e no AFS (e, na verdade, em outros sistemas de arquivos distribuídos), conforme veremos a seguir. Começaremos nossa discussão sobre o GFS examinando os requisitos específicos identificados pelo Google. Requisitos do GFS • O objetivo global do GFS é atender às necessidades exigentes e ra- pidamente crescentes do mecanismo de busca do Google e das diversas outras aplicações Web oferecidas pela empresa. A partir do entendimento desse domínio de operação em particular, o Google identificou os seguintes requisitos para o GFS (consulte Ghemawat et al. [2003]): • O primeiro requisito é que o GFS deve funcionar de forma confiável na arquitetura física discutida na Seção 21.3.1 – ou seja, um sistema muito grande, construído a partir de hardware comum. Os projetistas do GFS começaram com a suposição de que os componentes falharão (não apenas componentes de hardware, mas também de software) e de que o projeto deve ser suficientemente tolerante a tais falhas para Coulouris_21.indd 935 Coulouris_21.indd 935 23/05/13 09:26 23/05/13 09:26
  • 22. 936 Sistemas Distribuídos, Conceitos e Projeto permitir que serviços em nível de aplicação continuem sua operação diante de qual- quer combinação provável de condições de falha. • O GFS é otimizado para os padrões de utilização dentro do Google, tanto em ter- mos dos tipos de arquivos armazenados como dos padrões de acesso a esses arqui- vos. O número de arquivos armazenados no GFS não é grande em comparação com outros sistemas, mas os arquivos tendem a ser pesados. Por exemplo, Ghemawat et al [2003] relatam a necessidade de talvez um milhão de arquivos tendo em mé- dia 100 megabytes de tamanho, mas com alguns arquivos na faixa dos gigabytes. Os padrões de acesso também são atípicos dos sistemas de arquivos em geral. Os acessos são dominados por leituras sequenciais em arquivos grandes e escritas se- quenciais que anexam dados em arquivos, e o GFS é muito adequado a esse estilo de acesso. Pequenas leituras e escritas aleatórias ocorrem (estas últimas muito rara- mente) e são suportadas, mas o sistema não é otimizado para esses casos. Esses pa- drões de arquivo são influenciados, por exemplo, pelo armazenamento sequencial de muitas páginas Web em arquivos únicos, que são examinados por uma variedade de programas de análise de dados. O nível de acesso concorrente também é alto no Google, com grandes números de anexações concomitantes sendo particularmente predominantes, frequentemente acompanhadas de leituras concorrentes. • O GFS deve satisfazer todos os requisitos da infraestrutura do Google como um todo; isto é; deve ser flexível (particularmente em termos de volume de dados e nú- mero de clientes), deve ser confiável, apesar da suposição a respeito das falhas men- cionada anteriormente, deve funcionar bem e deve ser aberto no sentido de suportar o desenvolvimento de novas aplicações Web. Em termos de desempenho e dados os tipos de arquivo de dados armazenados, o sistema é otimizado para rendimento alto e prolongado na leitura de dados e isso tem prioridade em relação à latência. Não quer dizer que a latência não seja importante, mas sim que esse componente (o GFS) em particular precisa ser otimizado para leitura de alto desempenho e anexação de grandes volumes de dados para a operação correta do sistema como um todo. Esses requisitos são acentuadamente diferentes dos existentes para o NFS e o AFS (por exemplo), que devem armazenar grandes números de arquivos frequentemente pequenos e em que as leituras e escritas aleatórias são comuns. Essas distinções levaram às deci- sões de projeto muito particulares, discutidas a seguir. Interface do GFS • O GFS fornece uma interface de sistema de arquivos convencional, oferecendo um espaço de nomes hierárquico com os arquivos individuais identificados por nomes de caminho. Embora o sistema de arquivos não ofereça total compatibilidade com POSIX, muitas das operações são conhecidas dos usuários desses sistemas de arqui- vos (veja, por exemplo, a Figura 12.4): create – cria uma nova instância de um arquivo; delete – exclui uma instância de um arquivo; open – abre um arquivo nomeado e retorna um identificador (handle); close – fecha um arquivo especificado por um identificador (handle); read – lê dados de um arquivo especificado; write – escreve dados em um arquivo especificado. Pode-se ver que as principais operações do GFS são muito parecidas com as do serviço de arquivo plano, descritas no Capítulo 12 (veja a Figura 12.6). Devemos supor que as Coulouris_21.indd 936 Coulouris_21.indd 936 23/05/13 09:26 23/05/13 09:26
  • 23. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 937 operações read e write do GFS recebem um parâmetro especificando um deslocamento inicial dentro do arquivo, como acontece no serviço de arquivo plano. A API também oferece duas operações mais especializadas, snapshot e record append. A primeira operação fornece um mecanismo eficiente para fazer uma cópia de um arquivo em particular ou da estrutura em árvore do diretório. A última suporta o padrão de acesso comum mencionado anteriormente, por meio do qual vários clientes realizam anexações concorrentes em determinado arquivo. Arquitetura do GFS • A escolha de projeto mais influente no GFS é o armazenamento de arquivos em trechos de tamanho fixo, em que cada trecho tem 64 megabytes. Isso é muito grande, comparado aos outros projetos de sistema de arquivos. Em um nível, isso sim- plesmente reflete o tamanho dos arquivos armazenados no GFS. Em outro nível, essa de- cisão é fundamental para fornecer leituras sequenciais altamente eficientes e anexações de grandes volumes de dados. Voltaremos a esse ponto posteriormente, quando tivermos discutido mais detalhes da arquitetura do GFS. Dada essa escolha de projeto, a tarefa do GFS é fornecer um mapeamento dos arquivos em trechos e, então, suportar operações padrão em arquivos, mapeando nas operações em trechos individuais. Isso é obtido com a arquitetura ilustrada na Figura 21.9, que mostra uma instância de um sistema de arquivos GFS mantida em um cluster físico. Cada cluster GFS tem um só mestre e vários chunkservers (servidores de trecho) (normalmente na ordem de centenas) que, juntos, fornecem um serviço de arquivo para grandes números de clientes que acessam os dados de forma concorrente. A função do mestre é gerenciar metadados sobre o sistema de arquivos, definindo o espaço de nomes para arquivos, informações de controle de acesso e o mapeamento de cada arquivo em particular no conjunto de trechos associado. Além disso, todos os trechos são replicados (por padrão, em três chunkservers independentes, mas o nível de replicação pode ser especificado pelo programador). A localização das réplicas é mantida no mestre. A replicação é importante no GFS, para fornecer a confiabilidade necessária no caso de falhas (esperadas) de hardware e software. Isso contrasta com o NFS e o AFS, que não fornecem replicação com atualizações (veja o Capítulo 12). Os principais metadados são armazenados de forma persistente em um registro de operação que suporta recuperação em caso de colapsos (novamente, aumentando a confiabilidade). Em particular, todas as informações mencionadas anteriormente são registradas, com exceção da localização das réplicas (esta última é recuperada por eleição de chunkservers e perguntando-se a eles quais réplicas armazenam no momento). Biblioteca de cliente do GFS Mestre do GFS Chunkserver do GFS trechos de dados ..... fluxo de controle fluxo de dados Cliente metadados Chunkserver do GFS trechos de dados Figura 21.9 Arquitetura global do GFS. Coulouris_21.indd 937 Coulouris_21.indd 937 23/05/13 09:26 23/05/13 09:26
  • 24. 938 Sistemas Distribuídos, Conceitos e Projeto Embora o mestre seja centralizado e, portanto, um ponto único de falha, o registro de operações é replicado em várias máquinas remotas, de modo que, em caso de falha, o mestre pode ser prontamente restaurado. A vantagem de se ter um único mestre cen- tralizado é que ele tem uma visão global do sistema de arquivos e, assim, pode tomar as melhores decisões de gerenciamento, relacionadas, por exemplo, ao posicionamento de trechos. Esse esquema também é mais simples de implementar, permitindo ao Google desenvolver o GFS em um período de tempo relativamente curto. McKusick e Quinlan [2010] apresentam o fundamento lógico dessa escolha de projeto bastante incomum. Quando os clientes precisarem acessar dados a partir de um deslocamento de bytes em particular dentro de um arquivo, a biblioteca de cliente GFS primeiramente transfor- mará isso em um par nome de arquivo e índice de trecho (facilmente computados, dado o tamanho fixo dos trechos). Então, isso é enviado para o mestre na forma de uma requisi- ção RPC (usando buffers de protocolo). O mestre responde com o identificador de trecho apropriado e a localização das réplicas, e essas informações são colocadas na cache do cliente e usadas para acessar os dados por invocação RPC direta para um dos chunkser- vers replicados. Desse modo, o mestre é envolvido no início e depois fica completamente fora do lago, implementando uma separação de fluxos de controle e de dados – uma se- paração fundamental para manter o alto desempenho dos acessos a arquivo. Combinado com o tamanho grande dos trechos, isso significa que, uma vez identificado e localizado um trecho, os 64 megabytes podem ser lidos tão rapidamente quanto o servidor de ar- quivos e a rede permitam, sem quaisquer outras interações com o mestre, até que outro trecho precise ser acessado. Portanto, as interações com o mestre são minimizadas e o de- sempenho de saída, otimizado. O mesmo argumento se aplica às anexações sequenciais. Note que outra repercussão do tamanho grande dos trechos é que o GFS mantém proporcionalmente menos metadados (se fosse adotado um tamanho de trecho de 64 quilobytes, por exemplo, o volume de metadados aumentaria por um fator de 1.000). Isso, por sua vez, significa que os mestres GFS geralmente podem manter todos os seus metadados na memória principal (mas veja a seguir), diminuindo significativamente a latência de operações de controle. À medida que a utilização do sistema aumenta, têm surgido problemas com o es- quema do mestre centralizado: • Apesar da separação entre fluxo de controle e de dados e da otimização do desem- penho do mestre, isso está aparecendo como um gargalo em seu projeto. • Apesar do volume de metadados reduzido, decorrente do tamanho grande dos tre- chos, o volume de metadados armazenados em cada mestre está aumentando a um nível em que é difícil manter todos os metadados na memória principal. Por esses motivos, agora o Google está trabalhando em um novo projeto que apre- senta uma solução de mestre distribuído. Uso de cache: como vimos no Capítulo 12, o uso de cache frequentemente desempenha um papel fundamental no desempenho e na escalabilidade de um sistema de arquivos (veja também a discussão mais geral sobre uso de cache na Seção 2.3.1). É interessante notar que o GFS não faz muito uso de cache. Conforme mencionado anteriormente, as informações sobre os locais de trechos são colocadas na cache dos clientes na primeira vez que são acessadas, para minimizar as interações com o mestre. Fora isso, o cliente não utiliza a cache. Em particular, os clientes GFS não colocam dados de arquivo na cache. Como a maioria dos acessos envolve fluxos sequenciais, por exemplo, leitura de conteúdo Web para produzir o índice invertido exigido, tais caches pouco contribuiriam Coulouris_21.indd 938 Coulouris_21.indd 938 23/05/13 09:26 23/05/13 09:26
  • 25. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 939 para o desempenho do sistema. Além disso, limitando o uso de cache aos clientes, o GFS também evita a necessidade de protocolos de coerência de cache. O GFS também não fornece nenhuma estratégia em particular para uso de cache no lado do servidor (isto é, nos chunkservers), contando com cache de buffer no Linux para manter dados frequentemente acessados na memória. Logging: o GFS também é um exemplo importante do uso de logs no Google para su- portar depuração e análise de desempenho. Em particular, todos os servidores do GFS mantêm extensivos logs de diagnóstico que armazenam eventos significativos do servi- dor e todas as requisições e respostas RPC. Esses logs são monitorados continuamente e usados em caso de problemas no sistema, para identificar as causas subjacentes. Gerenciando a consistência no GFS • Dado que os trechos são replicados no GFS, é im- portante manter a consistência das réplicas diante de operações que alteram os dados – ou seja, as operações write e record append. O GFS fornece uma estratégia para gerencia- mento de consistência que: • mantém a separação mencionada anteriormente entre controle e dados e, assim, permi- te atualizações de alto desempenho nos dados com envolvimento mínimo dos mestres; • fornece uma forma de consistência relaxada, reconhecendo, por exemplo, a semân- tica específica oferecida por record append. A estratégia funciona como segue. Quando uma mutação (isto é, uma operação write, append ou delete) é requi- sitada para um trecho, o mestre concede um arrendamento de trecho para uma das réplicas, a qual é, então, designada como primária. Essa réplica primária é responsável por fornecer uma ordem serial para todas as mutações concorrentes pendentes para esse trecho. Assim, uma ordem global é fornecida pela ordenação dos arrendamentos de trecho, combinados com a ordem determinada por essa primária. Em particular, o arrendamento permite que a primária faça mutações em suas cópias locais e controle a ordem das mutações nas cópias secundárias; então, outra primária receberá o arrenda- mento e assim por diante. Portanto, as etapas envolvidas nas mutações são as seguintes (ligeiramente sim- plificadas): • Ao receber uma requisição de um cliente, o mestre concede um arrendamento para uma das réplicas (a primária) e retorna a identidade da primária e de outras réplicas (secundárias) para o cliente. • O cliente envia todos os dados para as réplicas e isso é armazenado temporariamen- te em uma cache de buffer e não é escrito até que venham mais instruções (nova- mente, mantendo a separação do fluxo de controle do fluxo de dados, acoplada a um regime de controle leve, baseado em arrendamentos). • Uma vez que todas as réplicas tenham confirmado o recebimento desses dados, o cliente envia uma requisição de escrita para a primária; então, a primária determina uma ordem serial para as requisições concorrentes e aplica as atualizações, nessa ordem, no local onde a primária se encontra. • A primária solicita que as mesmas mutações, na mesma ordem, sejam realizadas nas réplicas secundárias, e estas enviam de volta uma confirmação, quando as mu- tações tiverem ocorrido. • Se todas as confirmações forem recebidas, a primária relata o sucesso de volta para o cliente; caso contrário, é informada uma falha, indicando que a mutação ocorreu Coulouris_21.indd 939 Coulouris_21.indd 939 23/05/13 09:26 23/05/13 09:26
  • 26. 940 Sistemas Distribuídos, Conceitos e Projeto na primária e em algumas das réplicas, mas não em todas. Isso é tratado como uma falha e deixa as réplicas em um estado inconsistente. O GFS procura resolver essa falha tentando fazer as mutações malsucedidas novamente. No pior caso, isso não terá êxito e, portanto, a consistência não será garantida pela estratégia. É interessante relacionar esse esquema com as técnicas de replicação discutidas no Ca- pítulo 18. O GFS adota uma arquitetura de replicação passiva, com uma modificação importante. Na replicação passiva, as atualizações são enviadas para a réplica primária e, então, esta fica responsável por enviar as atualizações subsequentes para os servidores de backup e por garantir que elas sejam coordenadas. No GFS, o cliente envia dados para todas as réplicas, mas a requisição vai para a primária que, então, fica responsável por escalonar as mutações reais (a separação entre fluxo de dados e fluxo de controle, men- cionada anteriormente). Isso permite que a transmissão de grandes quantidades de dados seja otimizada, independentemente do fluxo de controle. Nas mutações há uma distinção importante entre as operações write e record append. A operação write especifica um deslocamento no qual as mutações devem ocor- rer, enquanto a operação record append não faz isso (as mutações são aplicadas no final do arquivo, onde quer seja isso em determinado ponto no tempo). No primeiro caso, a lo- calização é predeterminada, enquanto no último, o sistema decide. Operações write con- correntes no mesmo ponto não são serializadas e podem resultar em regiões corrompidas no arquivo. Nas operações record append, o GFS garante que a anexação ocorrerá pelo menos uma vez e atomicamente (isto é, como uma sequência contínua de bytes); contu- do, o sistema não garante que todas as cópias do trecho serão idênticas (algumas podem ter dados duplicados). Novamente, é útil relacionar isso com a matéria do Capítulo 18. As estratégias de replicação do Capítulo 18 são todas de propósito geral, enquanto esta estratégia é específica do domínio e flexibiliza as garantias de consistência, sabendo-se que a semântica resultante pode ser tolerada pelas aplicações e serviços do Google (outro exemplo de replicação específica do domínio – o algoritmo de replicação de Xu e Liskov [1989] para espaços de tuplas – pode ser encontrado na Seção 6.5.2). 21.5.2 Chubby O Chubby [Burrows 2006] é um serviço fundamental da infraestrutura do Google, ofere- cendo serviços de armazenamento e coordenação para outros serviços da infraestrutura, incluindo o GFS e a Bigtable. O Chubby é um serviço multifacetado que oferece quatro recursos distintos: • Ele fornece travas distribuídas para sincronizar atividades distribuídas no que é um ambiente assíncrono de larga escala. • Ele fornece um sistema de arquivos que oferece armazenamento confiável de pe- quenos arquivos (complementando o serviço oferecido pelo GFS). • Ele pode ser usado para suportar a eleição da réplica primária em um conjunto de réplicas (conforme é necessário, por exemplo, pelo GFS, conforme discutido na Seção 21.5.1). • Ele é usado como serviço de nomes dentro Google. À primeira vista, pode parecer que isso contradiz o princípio de projeto global da simpli- cidade (fazer apenas uma coisa e fazê-la bem). Entretanto, à medida que desvendarmos o projeto do Chubby, veremos que no centro há um serviço básico que oferece uma solução para o consenso distribuído e que as outras facetas surgem desse serviço básico, que é otimizado para o estilo de utilização dentro do Google. Coulouris_21.indd 940 Coulouris_21.indd 940 23/05/13 09:26 23/05/13 09:26
  • 27. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 941 Iniciaremos nosso estudo do Chubby examinando a interface que ele oferece; em seguida, veremos a arquitetura de um sistema Chubby em detalhes e como isso é mape- ado na arquitetura física. Concluiremos o exame vendo em detalhes a implementação do algoritmo de consenso que há no centro do Chubby, o Paxos. Interface do Chubby • O Chubby fornece uma abstração baseada em um sistema de ar- quivos, adotando a visão inicialmente promovida no Plan 9 [Pike et al. 1993], de que todo objeto de dados é um arquivo. Os arquivos são organizados em um espaço de nomes hierárquico, utilizando estruturas de diretório com os nomes tendo a seguinte forma: /ls/célula_chubby/nome_diretório/.../nome_arquivo onde /ls se refere ao serviço de travas, designando que isso faz parte do sistema Chubby, célula_chubby é o nome de uma instância em particular de um sistema Chubby (o termo célula é usado no Chubby para denotar uma instância do sistema). Isso é seguido por uma série de nomes de diretório, culminando em um nome_arquivo. Um nome especial /ls/local, será solucionado na célula mais local em relação ao aplicativo ou serviço que fez a chamada. O Chubby começou sua existência como um serviço de travas e a intenção era que tudo fosse uma trava no sistema. Entretanto, rapidamente ficou claro que seria útil asso- ciar quantidades (normalmente pequenas) de dados às entidades do Chubby – veremos um exemplo disso a seguir, quando examinarmos como o Chubby é usado em eleições de réplica primária. Assim, no Chubby as entidades compartilham a funcionalidade de travas e arquivos; elas podem ser usadas exclusivamente como travas, para armazenar pequenas quantidades de dados ou para associar pequenas quantidades de dados (na ver- dade, metadados) a operações de trava. Uma versão ligeiramente simplificada da API oferecida pelo Chubby aparece na Figura 21.10. Open e Close são operações padrão, com Open recebendo um arquivo ou diretório nomeado e retornando um identificador Chubby para essa entidade. O cliente pode especificar vários parâmetros associados a Open, incluindo declarar a utilização pretendida (por exemplo, leitura, escrita ou trava), e as verificações de permissões são realizadas nesse estágio, usando listas de controle de acesso. A operação Close simples- mente abre mão do uso do identificador. A operação Delete é usada para remover o arqui- vo ou diretório (essa operação falhará se for aplicada a um diretório com filhos). Na função de sistema de arquivos, o Chubby oferece um pequeno conjunto de ope- rações para leitura e escrita de arquivos inteiros; são operações simples que retornam os dados completos do arquivo e escrevem os dados completos no arquivo. Essa estratégia de arquivo inteiro é adotada para desencorajar a criação de arquivos grandes, pois não é esse uso pretendido para o Chubby. A primeira operação, GetContentsAndStat, retorna o conteúdo do arquivo e quaisquer metadados associados ao arquivo (uma operação asso- ciada, GetStat, retorna apenas os metadados; também é fornecida uma operação ReadDir para ler nomes e metadados associados aos filhos de um diretório. SetContents escreve o conteúdo de um arquivo e SetACL fornece uma maneira de configurar os dados da lista de controle de acesso. A leitura e a escrita de arquivos inteiros são operações atômicas. Na função de ferramenta de gerenciamento de travas, as principais operações forne- cidas são Acquire, TryAcquire e Release. Acquire e Release correspondem às operações de mesmo nome apresentadas na Seção 16.4; TryAcquire é uma variante não bloqueante de Acquire. Note que, embora as travas sejam consultivas no Chubby, um aplicativo ou serviço deve passar pelo protocolo correto de adquirir e liberar travas. Os desenvolvedores do Chubby consideraram uma alternativa de travas obrigatórias, segundo a qual os dados Coulouris_21.indd 941 Coulouris_21.indd 941 23/05/13 09:26 23/05/13 09:26
  • 28. 942 Sistemas Distribuídos, Conceitos e Projeto travados ficam inacessíveis para todos os outros usuários e isso é imposto pelo sistema, mas a flexibilidade extra e resiliência das travas consultivas foram preferidas, deixando para o programador a responsabilidade pela verificação de conflitos [Burrows 2006]. Se uma aplicação precisa proteger um arquivo contra acesso concorrente, ela pode usar as duas funções juntas, armazenando dados no arquivo e adquirindo travas antes de acessar esses dados. O Chubby também pode ser usado para suportar uma eleição de primária em sis- temas distribuídos – isto é, a eleição de uma réplica como a primária no gerenciamento de replicação passiva (consulte as Seções 15.3 e 18.3.1 para discussões sobre algoritmos de eleição e replicação passiva, respectivamente). Primeiramente, todas as primárias can- didatas tentam adquirir uma trava associada à eleição. Somente uma terá sucesso. Essa candidata se torna a primária, com todas as outras candidatas se tornando secundárias. A primária registra sua vitória escrevendo sua identidade no arquivo associado, e os outros processos podem então determinar a identidade da primária lendo esses dados. Conforme mencionado anteriormente, esse é um importante exemplo de combinação das funções de trava e arquivo para um propósito útil em um sistema distribuído. Isso também mostra como a eleição de primária pode ser implementada em cima de um serviço de consenso, como uma alternativa a algoritmos como a estratégia baseada em anel ou o algoritmo valentão (bully), apresentado na Seção 15.3. Por fim, o Chubby suporta um mecanismo de evento simples, permitindo aos clien- tes se registrarem ao abrir um arquivo, para receber mensagens de evento relacionadas ao arquivo. Mais especificamente, o cliente pode se increver em diversos eventos, como uma opção na chamada de Open. Então, os eventos associados são entregues de forma assíncrona, por meio de callbacks. Exemplos de eventos incluem a modificação do con- teúdo de um arquivo, um identificador se tornando inválido, etc. Função Operação Efeito Geral Open Abre um arquivo ou diretório dado e retorna um identificador Close Fecha o arquivo associado ao identificador Delete Exclui o arquivo ou diretório Arquivo GetContentsAndStat Retorna (atomicamente) o conteúdo do arquivo inteiro e os metadados associados ao arquivo GetStat Retorna apenas os metadados ReadDir Retorna o conteúdo de um diretório – isto é, os nomes e metadados de quaisquer filhos SetContents Escreve todo o conteúdo de um arquivo (atomicamente) SetACL Escreve novas informações na lista de controle de acesso Trava Acquire Adquire uma trava sobre um arquivo TryAquire Tenta adquirir uma trava sobre um arquivo Release Libera a trava Figura 21.10 API do Chubby. Coulouris_21.indd 942 Coulouris_21.indd 942 23/05/13 09:26 23/05/13 09:26
  • 29. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 943 O Chubby é uma interface de programação de sistema de arquivos reduzida, com- parada, por exemplo, com o POSIX. O Chubby não apenas exige que as operações de leitura e atualização sejam aplicadas em arquivos inteiros, como também não suporta operações para mover arquivos entre diretórios nem vínculos simbólicos (softlinks) ou restritos (hard links). Além disso, o Chubby mantém apenas metadados limitados (rela- cionados a controle de acesso, controle de versão e uma soma de verificação para prote- ger a integridade dos dados). Arquitetura do Chubby • Conforme mencionado anteriormente, uma única instância de um sistema Chubby é conhecida como célula; cada célula consiste em um número relati- vamente pequeno de réplicas (normalmente, cinco), com uma delas designada como mes- tra. Os aplicativos clientes acessam esse conjunto de réplicas por meio de uma biblioteca Chubby, a qual se comunica com os servidores remotos usando o serviço RPC descrito na Seção 21.4.1. As réplicas são colocadas em locais independentes de falha para minimizar o potencial de falhas correlacionadas – por exemplo, elas não estarão contidas dentro do mesmo rack. Normalmente, todas as réplicas estariam contidas dentro de determinado cluster físico, embora isso não seja exigido para o funcionamento correto do protocolo e tenham sido criadas células experimentais que abrangem os centros de dados do Google. Cada réplica mantém um pequeno banco de dados, cujos elementos são entidades no espaço de nomes do Chubby – isto é, diretórios e arquivos/travas. A consistência do banco de dados replicado é obtida usando-se um protocolo de consenso subjacente (uma implementação do algoritmo Paxos de Lamport [Lamport 1989, Lamport 1998]), baseado na manutenção de logs de operação (veremos a implementação desse protoco- lo, a seguir). Como os logs se tornam muito grandes com o passar do tempo, o Chubby também suporta a criação de instantâneos – visões completas do estado do sistema em determinado ponto no tempo. Uma vez tirado um instantâneo, os logs anteriores podem ser excluídos, com o estado consistente do sistema em qualquer ponto determinado pelo instantâneo anterior, junto às aplicações do conjunto de operações no log. Essa estrutura global está mostrada na Figura 21.11. Uma sessão do Chubby é uma relação entre um cliente e uma célula do Chubby. Isso é mantido usando-se handshakes KeepAlive entre as duas entidades. Para aumentar o desempenho, a biblioteca do Chubby implementa cache no cliente, armazenando dados de arquivo, metadados e informações em tratadores. Em contraste com o GFS (com suas grandes leituras e anexações sequenciais), a cache no cliente é eficiente no Chubby, com seus arquivos pequenos que provavelmente serão acessados repetidamente. Por causa des- se uso de cache, o sistema precisa manter a consistência entre um arquivo e uma cache, assim como entre as diferentes réplicas do arquivo. A consistência de cache exigida no Chubby é obtida como segue. Quando uma mutação está para ocorrer, a operação asso- ciada (por exemplo, SetContents) é bloqueada até que todas as caches associadas sejam invalidadas (por eficiência, as requisições de invalidação vão “de carona” nas respostas de KeepAlive da mestra, com as respostas enviadas imediatamente quando ocorre uma invalidação). Os dados colocados em cache também nunca são atualizados diretamente. O resultado final é um protocolo de consistência de cache muito simples que apre- senta semântica determinística para os clientes do Chubby. Compare isso com o regime de cache no cliente do NFS, por exemplo, no qual as mutações não acarretam a atuali- zação imediata das cópias colocadas em cache, resultando em versões potencialmente diferentes de arquivos em diferentes nós clientes. Também é interessante comparar isso com o protocolo de consistência de cache do AFS, mas deixamos como exercício para o leitor (veja o Exercício 21.7). Coulouris_21.indd 943 Coulouris_21.indd 943 23/05/13 09:26 23/05/13 09:26
  • 30. 944 Sistemas Distribuídos, Conceitos e Projeto Esse determinismo é importante para muitas das aplicações e serviços de cliente que usam o Chubby (por exemplo, a Bigtable, conforme discutido na Seção 21.5.3) para ar- mazenar listas de controle de acesso. A Bigtable exige atualização consistente de listas de controle de acesso, entre todas as réplicas e em termos de cópias colocadas na cache. Note que foi esse determinismo que levou ao uso do Chubby como servidor de nomes dentro do Google. Mencionamos, na Seção 13.2.3, que o DNS permite que a atribuição de nomes de dados se torne inconsistente. Embora isso seja tolerável na Internet, os desenvolvedores da infraestrutura do Google preferiram a visão mais consistente oferecida pelo Chubby, usando arquivos Chubby para manter os mapeamentos de nomes para endereços. Burrows [2006] discute em mais detalhes o uso do Chubby como serviço de nomes. Implementação do Paxos • Paxos é uma família de protocolos que fornece consenso dis- tribuído (veja a Seção 15.5 para uma discussão mais ampla sobre protocolos de consenso distribuído). Os protocolos de consenso operam sobre um conjunto de réplicas com o objetivo de obter um acordo entre os servidores que gerenciam as réplicas, para atualizá- -las com um valor comum. Isso é obtido em um ambiente onde: • Os servidores de réplica podem operar em velocidade arbitrária e podem falhar (e subsequentemente se recuperar). • Os servidores de réplica têm acesso a um armazenamento estável e persistente que sobrevive aos colapsos. • Mensagens podem ser perdidas, reordenadas ou duplicadas. Elas são entregues sem corrupção, mas podem demorar um tempo arbitrariamente longo para serem entregues. Chubby cell Biblioteca cliente do Chubby Cliente * * Log Instantâneos Banco de dados local Log Instantâneos Banco de dados local Log Instantâneos Banco de dados local denota a mestra atual • • • Figura 21.11 Arquitetura global do Chubby. Coulouris_21.indd 944 Coulouris_21.indd 944 23/05/13 09:26 23/05/13 09:26
  • 31. Capítulo 21 Projeto de Sistemas Distribuídos – Estudo de Caso: Google 945 Portanto, o Paxos é fundamentalmente um protocolo de consenso distribuído para siste- mas assíncronos (veja a Seção 2.4.1) e, de fato, é a oferta dominante nesse universo. Os desenvolvedores do Chubby enfatizam que as suposições anteriores refletem a verdadeira natureza dos sistemas baseados na Internet, como o Google, e alertam os profissionais do setor sobre algoritmos de consenso que fazem suposições mais fortes (por exemplo, algoritmos para sistemas síncronos) [Burrows 2006]. Lembre-se, do Capítulo 15, de que é impossível garantir a consistência em sis- temas assíncronos, mas que foram propostas várias técnicas para contornar esse pro- blema. O Paxos funciona garantindo a exatidão, mas não há garantias de que o Paxos termine a execução (voltaremos a essa questão, a seguir, quando tivermos visto os de- talhes do algoritmo). O algoritmo foi apresentado pela primeira vez por Leslie Lamport, em 1989, em um artigo chamado The Part-Time Parliament (O parlamento de meio-expediente) [Lamport 1989, Lamport 1998]. Inspirado por sua descrição dos generais bizantinos (conforme discutido na Seção 15.5.1), ele novamente apresentou o algoritmo fazendo uma analogia, desta vez se referindo ao comportamento de um parlamento mitológico na ilha grega de Paxos. Em seu site [research.microsoft.com], Lamport escreve de forma engraçada sobre a reação a essa apresentação. No algoritmo, qualquer réplica pode submeter um valor com o objetivo de obter consenso sobre um valor final. No Chubby, o acordo equivale a todas as réplicas terem esse valor como a próxima entrada em seus logs de atualização, obtendo, assim, uma visão consistente dos logs de todos os locais. É garantido que o algoritmo obtenha um consenso, se a maioria das réplicas executar o bastante, com suficiente estabilidade da rede. Mais formalmente, Kirsch e Amir [2008] apresentam as seguintes propriedades para o Paxos: Paxos-L1 (Progresso): se existe uma maioria estável em um conjunto de servido- res, então, se um servidor do conjunto inicia uma atualização, algum membro do conjunto executará a atualização. Paxos-L2 (Replicação Eventual): se um servidor s executa uma atualização e exis- te um conjunto de servidores contendo s e r, e um tempo após o qual o conjunto não experimenta falhas de comunicação ou processo, então r executará a atualização. A intuição aqui diz que o algoritmo não pode garantir que a consistência seja atingida quando a rede se comporta de forma assíncrona, mas atingirá a consistência quando fo- rem experimentadas condições mais síncronas (ou estáveis). O algoritmo Paxos: O algoritmo Paxos funciona como segue: Etapa 1: o algoritmo conta com a capacidade de eleger um coordenador para determinada decisão consensual. Reconhecendo que os coordenadores podem fa- lhar, é adotado um processo de eleição flexível que pode resultar na coexistência de vários coordenadores, antigos e novos, com o objetivo de reconhecer e rejeitar mensagens de antigos coordenadores. Para identificar o coordenador correto, os coordenadores são ordenados por um número sequencial. Cada réplica mantém o número sequencial mais alto visto até o momento e, se estiver fazendo uma oferta para ser um coordenador, escolherá um número exclusivo mais alto e divulgará isso para todas as réplicas em uma mensagem de proposta. Claramente, é importante que o número sequencial escolhido por um coorde- nador em potencial seja realmente exclusivo – dois (ou mais) coordenadores não devem ser capazes de escolher o mesmo valor. Vamos supor que tenhamos n répli- cas. Um número sequencial exclusivo pode ser garantido se toda réplica receber Coulouris_21.indd 945 Coulouris_21.indd 945 23/05/13 09:26 23/05/13 09:26