Added methodology and context.
[mymsc.git] / mscMonografia.tex
blobd2a15bc90b9fa2fe9a065390c137aafe02d01db3
1 \documentclass[10pt]{article}
3 \usepackage[top=3cm, bottom=3cm, left=3cm, right=3cm]{geometry}
4 \usepackage{todonotes}
5 \usepackage{times}
6 \usepackage[brazil]{babel}
7 \usepackage[utf8]{inputenc}
8 \usepackage{graphicx}
9 \usepackage{url}
10 \usepackage{paralist}
11 \usepackage{hyperref}
12 \usepackage{amssymb}
13 \usepackage{setspace}
14 \usepackage{paralist}
16 \newcommand{\mytitle}{Impacto do armazenamento remoto de estados na
17 recuperação de replicas} %PT
18 \newcommand{\f}{$\blacksquare$}
20 \hypersetup{
21 pdftitle={\mytitle},
22 pdfauthor={Rodrigo Eduardo Lazo Paz},
23 pdfdisplaydoctitle=true,
24 pdfborder=0 0 0
27 \title{\mytitle}
29 \author{
30 Rodrigo Eduardo Lazo Paz\\%\thanks{Grants.} \\
31 IC, Unicamp \\
32 Campinas, Brasil \\
33 {\small \url{rodrigo.lazo@students.ic.unicamp.br}} \\
34 \and
35 Luiz E. Buzato \\ %\thanks{Identificação de projetos aqui.}\\
36 IC, Unicamp \\ Campinas, Brasil \\ {\small
37 \url{buzato@ic.unicamp.br}}
40 \hyphenation{par-ti-cu-lar-men-te}
41 \hyphenation{su-fi-ci-en-tes}
43 \begin{document}
44 \doublespacing
46 \maketitle
48 \begin{abstract}
49 \noindent Nos sistemas distribuídos replicados, a queda de um, ou
50 vários processos durante a execução, produz uma degradação no
51 desempenho devido à re-distribuição de trabalho. Além de possíveis
52 perdas de informação, a carga adicional poderia ultra-passar a
53 capacidade dos componentes disponíveis. É, portanto, fundamental
54 reduzir ao mínimo o tempo de recuperação dos processos. Um dos
55 procedimentos que contribui a este é a leitura dos dados necessários
56 para voltar ao estado prévio à queda. Nós propomos a avaliação
57 minuciosa de múltiplas configurações de sistemas distribuídos
58 replicados com armazenamento híbrido, combinando memoria estável
59 local e repositórios remotos, tal que se minimize o uso de
60 dispositivos de alta latência durante a recuperação sem sacrificar a
61 consistência. Adicionalmente, o projecto contempla a implementação de
62 detetores de falhas mais acordes ao modelo de falha-e-recuperação,
63 como os propostos por Aguilera et al.\, devido à possibilidade de
64 queda dos repositórios remotos e a necessidade de tomar previsões
65 nesse cenário. Os resultados serão aplicados na melhora da
66 biblioteca Tréplica para a construção de aplicações de alta
67 disponibilidade, desenvolvida no Laboratório de Sistemas
68 Distribuídos do Instituto de Computação da Universidade Estadual de
69 Campinas.
70 \end{abstract}
73 \newpage
75 \section{Introdução}
76 \label{sec:introduction}
78 Algoritmos distribuídos são aqueles desenhados para executar se em
79 sistemas compostos por um conjunto interconectado de processos
80 autônomos que intercambiam informação. O progresso do algoritmo
81 depende de dois elementos: o progresso individual de cada um dos
82 processos, e a troca de informação entre eles. Os distintos modelos,
83 i.e.\ presunções, que descrevem características específicas desses
84 elementos no sistema são:
86 \begin{itemize}
87 \item \textit{Modelo de intercomunicação dos processos}, admite duas
88 possibilidades: a troca de mensagens (enviando mensagens
89 ponto-a-ponto ou um-para-varios; mantendo o ordem de envio na
90 recepção ou não), ou a leitura e escrita de variáveis comuns na
91 memoria compartilhada.
92 \item \textit{Modelo temporal}, distingue três possibilidades:
93 \begin{inparaenum} [\itshape a\upshape)]
94 \item \textit{sistemas síncronos}: todos os processos executam cada
95 passo do algoritmo simultaneamente e o tempo de demora é
96 conhecido;
97 \item \textit{sistemas assíncronos}: cada processo pode tomar uma
98 quantidade indeterminada de tempo para executar cada passo do
99 algoritmo;
100 \item \textit{sistemas parcialmente síncronos}, algumas presunções
101 sobre o tempo de demora de algumas operações são possíveis, mas
102 não se garante que os processos executem simultaneamente os passos
103 do algoritmo.
104 \end{inparaenum}
105 \item \textit{Modelo de falhas}, classifica o comportamento dos
106 processos na presencia de falhas em: \textit{falha-e-para}: o
107 processo falha e deixa de participar do sistema;
108 \textit{falha-e-recuperação}: o processo falha, mas, em algum
109 momento no futuro, volta ao sistema; \textit{falha de omissão}: o
110 processo não realiza algumas ações arbitrariamente, e.g.\ enviar uma
111 mensagem; e \textit{falha bizantina}: o comportamento do processo é
112 aleatório. Além dos processos, os canais de comunicação também podem
113 apresentar falhas; por exemplo, no caso da comunicação por troca de
114 mensagens, perder, duplicar ou corromper as mensagens.
115 \end{itemize}
117 É claro que, as distintas combinações dos modelos apresentados, dão
118 lugar a uma multiplicidade de ambientes muito amplia e, portanto, não
119 é possível, ou ao menos prático, desenhar algoritmos distribuídos que
120 sejam capazes de executar se em qualquer modelo; é por isso que
121 somente pode avaliar se a correção dos algoritmos se suas presunções
122 sobre o sistema são válidas. Por exemplo, um algoritmo desenhado para um
123 sistema de memoria compartilhada, síncrono e sem falhas não vai
124 funcionar, mesmo seja correto, se o sistema é assíncrono, utiliza
125 troca de mensagens ponto-a-ponto é apresenta falhas bizantinas.
127 Os modelos supostos pelo algoritmo vão definir as caraterísticas do
128 sistema, portanto, se são muito restritivos, a aplicabilidade do
129 algoritmo é menor. Aqueles mais estritos fazem o desenvolvimento, e as
130 provas de correção, mais simples, já que garantem comportamentos mais
131 previsíveis; porém, construir um sistema que cumpra aquelas condições
132 fortes é muito complexo ou altamente custoso, além de não ser sempre
133 possível. Portanto, a eleição de modelos mais relaxados é preferível,
134 embora introduzam uma maior complexidade, apresentam condições mais
135 próximas das alcançáveis na realidade.
137 Os algoritmos no modelo temporal assíncrono não dependem do tempo para
138 seu correção e, portanto, são preferíveis, uma vez que esta
139 caraterística temporal é introduzida pelas variações no desempenho do
140 sistema~\cite{Chandra:1996:WFD:234533.234549}. Além da assincronia, a
141 tolerância a falhas é outra caraterística importante, já que, seja por
142 erros no software ou por falhas do hardware, elas vão acontecer. A
143 desvantagem da assincronia com falhas de processo é que existem
144 problemas solucionáveis em outros modelos que não são resolvíveis,
145 e.g.\ consenso no modelo
146 síncrono~\cite{Dwork:1988:CPP:42282.42283}. Nestos casos, uma solução
147 pode-se alcançar só se os requerimentos de correção são debilitados, o
148 modelo fortalecido, ou ambos~\cite{Lynch:1996:DA:525656}.
150 Os detetores de falhas são, informalmente, módulos distribuídos que
151 fornecem informação (não necessariamente correta) sobre o estado atual
152 dos processos no sistema, i.e.\ quais são suspeitos de estar
153 inativos. Os detetores acrescentam o modelo assíncrono, possibilitando
154 a solução de problemas como o problema de consenso
155 distribuído~\cite{Chandra:1996:UFD:226643.226647}.
157 No modelo de \textit{falha-e-recuperação}, os processos podem voltar ao
158 sistema e, portanto, precisam de armazenar, com segurança, suficiente
159 informação para voltar a seu estado anterior se uma falha acontecer;
160 no caso contrario, i.e.\ se fossem amnésicos, pode-se argumentar que um
161 processo em recuperação é indistinguível de um processo novo,
162 i.e.\ \textit{falha-e-para}.
164 Os processos só podem armazenar de maneira persistente os dados
165 necessários para recuperar se em dois lugares: localmente, em sua
166 memoria estável, ou remotamente, em outro processo. No primeiro caso, o
167 custo é determinado pela latência do disco; no segundo caso, é
168 determinado pela latência da rede mais o custo do aceso à informação,
169 i.e.\ memoria volátil ou memoria estável. Neste contexto, a nossa
170 questão de pequisa é a seguente:
172 \begin{quotation}
173 \noindent \textit{Qual é o método, ou combinação deles, de
174 armazenamento e obtenção da informação necessária para a
175 recuperação de processos após falhas com melhor desempenho e menor
176 impacto no sistema?}\todo{pergunta correta?}
177 \end{quotation}
179 A recuperação é um procedimento que volta o estado de um processo em
180 recuperação, a um estado anterior à falha. Os dados que permitem
181 aquela operação, normalmente uma copia do estado anterior, são
182 chamados de
183 \textit{checkpoints}~\cite{Randell:1978:RIC:356725.356729}, os quais
184 têm que ser gerados periodicamente e armazenados
185 persistentemente. Portanto, o custo da solução escolhida, tem um
186 impacto no sistema ainda durante os períodos sem falhas. Além disso,
187 tem que se considerar a robustez: se a informação é armazenada em na
188 memoria volátil, não se pode suportar uma falha massiva dos
189 processos. Por conseguente, a adequação da escolha depende dos
190 cenários supostos.
192 O restante do projeto é organizado da seguinte forma. A próxima seção
193 contextualiza este projeto dentro da pesquisa já realizada no
194 Laboratório de Sistemas Distribuídos sobre replicação ativa. A
195 seção~\ref{sec:teoria} apresenta os fundamentos sobre modelos
196 computacionais no cenário de falha-e-recuperação para algoritmos
197 distribuídos que se comunicam através de \textit{broadcast} de ordem
198 total. A seção~\ref{sec:treplica} apresenta a plataforma Treplica,
199 empregada para os testes e a avaliação de nossa projeto. Na
200 seção~\ref{sec:proposta} são discutidos, ainda em caráter inicial, os
201 argumentos que dão sustentação ao nosso projeto, assim como os modelos
202 que podem ser empregados para ajudar na resposta da nossa pergunta de
203 pesquisa. Finalmente, a seção~\ref{sec:metodologia} apresenta
204 concisamente a metodologia de pesquisa, as etapas a serem cumpridas no
205 projeto e o seu respectivo cronograma.
207 \section{Contexto da Pesquisa}
208 \label{sec:contexto}
209 Esta seção sumariza o contexto dentro do qual este projeto será
210 desenvolvido. Nestos últimos quatro anos o Prof. Buzato trabalhou em
211 replicação ativa com o seu aluno de Doutorado, Gustavo M. D. Vieira e
212 com o Prof. Willy Zwaenepoel, EPFL. O trabalho com o Prof. Zwaenepoel
213 foi desenvolvido durante a licença sabática do Prof. Buzato,
214 realizada durante 2008 no Instituto de Comunicação e Computação da
215 EPFL, Lausanne, Suiça. Os seguintes trabalhos são o resultado desse
216 período de pesquisa:
218 \begin{description}
219 \item \textsl{Treplica: Ubiquitous
220 replication}~\cite{vieira08:_trepl}, publicado em 2008 , apresenta
221 detalhadamente a conceição e implementação de Treplica.
223 \item \textsl{Dynamic Content Web Applications: Crash, Failover, and
224 Recovery Analysis}~\cite{buzato09}, mostra o efeito das falhas e
225 recuperações no desempenho de um aplicação Web implementada com
226 Treplica. Neste artigo, a medição do desempenho é baseada no
227 \emph{benchmark} TPC-W aumentado com medidas de disponibilidade. Os
228 resultados mostraram bom desempenho, excelente escalabilidade e
229 disponibilidade ininterrupta. Este artigo foi publicado nos anais
230 da \textsl{39th International Conference on Dependable Systems and
231 Networks (DSN 2009)}, Estoril, Portugal
232 (doi:10.1109/DSN.2009.5270331).
234 \item \textsl{The Performance of Paxos and Fast
235 Paxos}~\cite{vieira09}, caracteriza e compara, em execuções com e
236 sim presencia de falhas, o desempenho dos algoritmos de consenso
237 Paxos e Fast Paxos. Os resultados mostraram que no ambiente LAN
238 Paxos teve um melhor desempenho que Fast Paxos; isto devido às
239 violações de temporização deste último e não, como se poderia
240 intuir, à suposição otimista deste. Esse é o primeiro indício de que
241 é possível considerar modelos parcialmente síncronos para produzir
242 uma versão de Fast Paxos com desempenho melhor. Este artigo foi
243 publicado nos anais do 27º Simpósio Brasileiro de Redes de
244 Computadores e Sistemas Distribuídos (SBRC 2009), Recife, Brasil.
246 \item \textsl{On the Coordinator's Rule for Fast
247 Paxos}~\cite{vieira08b}, mostra uma análise da implementação da
248 regra de consistência do algoritmo Fast Paxos como implementada pelo
249 processo coordenador em função do número de processos no quórum. Com
250 base nesta análise, os autores propuseram uma regra simplificada de
251 consistência interessante para implementação. Este artigo foi
252 publicado no periódico \textsl{Information Processing Letters},
253 volume 107, 2008.
255 \item \textsl{A Recovery Efficient Solution for the Replacement of
256 Paxos Coordinators}~\cite{vieira-tr10a}, mostra uma otimização do
257 procedimento de substituição de um coordenador no algoritmo
258 Paxos. Devido à importancia deste, o processo de substituição pode
259 deter. Mostro-se um procedimento que provoca o mínimo de
260 perturbação. Uma observação interessante é que em sistemas
261 sobrecarregados, ainda na ausência de falhas de processos, a
262 coordenação troca constantemente.
263 \end{description}
265 Os resultados de pesquisa obtidos nos trabalhos listados aqui
266 constituem o contexto que nos motivou à formulação da nossa questão de
267 pesquisa: Qual é o método, ou combinação deles, de armazenamento e
268 obtenção da informação necessária para a recuperação de processos após
269 falhas com melhor desempenho e menor impacto no
270 sistema?. \todo{pregunta de pesquisa repetida}
272 \section{Fundamentação Teórica}
273 \label{sec:teoria}
274 Fornecer um serviço altamente disponível empregando múltiplos
275 processos replicados é uma técnica bem
276 conhecida~\cite{Schneider:1990:IFS:98163.98167}. Existem duas formas
277 de replicação: a ativa ou de máquina de
278 estados~\cite{lamport1978implementation}, se todos os processos
279 recebem e executam as mesmas requisições, no mesmo ordem; e a passiva,
280 se um único processo recebe todas as requisições, as aplica
281 localmente, e depois seu estado é copiado pelas demais réplicas. Na
282 replicação ativa, um dos métodos mais utilizados em sua implementação
283 são os algoritmos de consenso~\cite{Lamport:1998:PP:279227.279229,
284 Schneider:1990:IFS:98163.98167,Oki:1988:VRN:62546.62549} e o
285 \textit{broadcast} de ordem total~\cite{vieira10:implementing-tr}.
287 Nesta seção discute-se a fundamentação teórica da solução de
288 replicação ativa, no modelo assíncrono com falha-e-recuperação,
289 utilizada nossa nossa proposta de pesquisa. Na
290 seção~\ref{sec:notacao}, nos definiremos a notação utilizado ao longo
291 do texto além dos modelos supostos. A seção~\ref{sec:consenso}
292 descreve o problema do consenso e sua solução utilizando o algoritmo
293 Paxos. Na seção~\ref{sec:broadcast}, o \textit{broadcast} de ordem
294 total é definido, e suas caraterísticas detalhadas. Finalmente, na
295 seção~\ref{sec:detetores}, os detetores de falhas propostos por
296 Chandra e Toueg~\cite{Chandra:1996:UFD:226643.226647} são descritos,
297 incluindo as melhoras para sua adequação ao modelo de
298 falha-e-recuperação, introduzidas por Aguilera et
299 al.~\cite{springerlink:aguilera98}.
301 \subsection{Modelo do sistema e notação}
302 \label{sec:notacao}
303 O modelo suposto neste trabalho é assíncrono, portanto, não existe
304 presunção nenhuma acerca do tempo de demora da comunicação ou do
305 processamento. Todos os processos no sistema estão conectados, e a
306 comunicação é através da troca de mensagens, as quais se podem perder
307 durante a transmissão. Os processos podem falhar e voltar ao
308 sistema. Após falhar, os processos perdem seu estado atual, mas, têm a
309 possibilidade de armazenar, de maneira persistente, informação
310 suficiente para a recuperação de algum estado anterior.
312 % \begin{table}[h]
313 % \small
314 % \centering
315 % \begin{tabular}{|l|p{5cm}|l|p{5.4cm}|}
316 % \hline
317 % \(\Pi\) & Conjunto de processos. &
318 % \(\mathcal{M}\) & Conjunto de mensagens. \\
319 % \(sender(m)\) & Processo remitente de \(m\). &
320 % \(Dest(m)\) & Conjunto destinatário de \(m\). \\
321 % \(\Pi_{sender}\) & Conjunto de processos que podem enviar mensagens. &
322 % \(\Pi_{dest}\) & Conjunto de processos que podem receber mensagens. \\
323 % \(\mathcal{T}\) & Relógio global. &
324 % \(F(t)\) & Conjunto de processos caídos no tempo \(t\). \\
325 % \(Bom(F)\) & Conjunto de processos bons (em F). &
326 % \(Ruim(F)\) & Conjunto de processos ruins (em F). \\
327 % \textit{Instável}\((F)\) & Conjunto de processos instáveis (em F).& & \\
328 % \hline
329 % \end{tabular}
330 % \caption{Notação}
331 % \label{tab:notacao}
332 % \end{table}
334 % Neste trabalho vamos a seguir a notação utilizada por Défago, Schiper
335 % e Úrban~\cite{Defago:2004}, resumida na tabela~\ref{tab:notacao}. Seja
336 % \(\Pi = \{P_1, \ldots, P_n\}\) um conjunto de \(n\) processos que
337 % conformam o sistema. A comunicação é baseada no envio de mensagens,
338 % tal que \(\mathcal{M}\) é o conjunto de mensagens válidos. Seja \(m
339 % \in \mathcal{M}\) uma mensagem válida em \(\mathcal{M}\), \(sender(m)
340 % \in \Pi \) designa o processo originador da mensagem \(m\), e
341 % \(Dest(m) \subseteq \Pi \) é o conjunto não vazio de processos aos
342 % quais a mensagem \(m\) foi enviada. Além disso, seja \(\Pi_{sender}\)
343 % o conjunto de todos os processos que podem enviar mensagens válidas, e
344 % seja \(\Pi_{dest} \stackrel{\mathrm{def}}{=} \bigcup_{m \in
345 % \mathcal{M}} Dest(m)\) o conjunto de destinos possíveis das
346 % mensagens válidas.
348 Neste trabalho vamos a seguir a notação utilizada por Défago, Schiper
349 e Úrban~\cite{Defago:2004}. Seja \(\Pi = \{P_1, \ldots, P_n\}\) um
350 conjunto de \(n\) processos que conformam o sistema. A comunicação é
351 baseada no envio de mensagens, tal que \(\mathcal{M}\) é o conjunto de
352 mensagens válidos. Seja \(m \in \mathcal{M}\) uma mensagem válida em
353 \(\mathcal{M}\), \(sender(m) \in \Pi \) designa o processo originador
354 da mensagem \(m\), e \(Dest(m) \subseteq \Pi \) é o conjunto não vazio
355 de processos aos quais a mensagem \(m\) foi enviada. Além disso, seja
356 \(\Pi_{sender}\) o conjunto de todos os processos que podem enviar
357 mensagens válidas, e seja \(\Pi_{dest} \stackrel{\mathrm{def}}{=}
358 \bigcup_{m \in \mathcal{M}} Dest(m)\) o conjunto de destinos possíveis
359 das mensagens válidas.
361 Para simplificar a apresentação do modelo, suponha-se a existência de um
362 relógio discreto global \(\mathcal{T}\) com rango de valores dos
363 números naturais; os processos não têm conhecimento ou contato como
364 ele.
366 A seguinte classificação dos processos em função a seu comportamento
367 de falhas é tomada de Aguilera, Chen e
368 Toueg~\cite{springerlink:aguilera98}. Seja o padrão de falhas \(F\)
369 uma função de \(\mathcal{T}\) a \(2^\Pi\), tal que \(F(t)\) representa
370 o conjunto dos processos que não estão presentes no sistema no tempo
371 \(t\). Um processo está \textit{ativo no tempo} \(t\) (em \(F\)) se
372 \(p \in F(t)\), e está \textit{inativo no tempo} \(t\) (em \(F\)) no
373 caso contrario. Um processo \textit{cai} no tempo \(t\) se está ativo
374 no tempo \(t-1\) e inativo no tempo \(t\)\footnote{Um processo
375 \textit{cai} no tempo \(t=0\) se está inativo no tempo \(t=0\) }. Um
376 processo se \textit{recupera} no tempo \(t\) se está inativo no tempo
377 \(t-1\) e está ativo no tempo \(t\). Os processos, em função a seu
378 comportamento, podem se classificar como:
380 \begin{itemize}
381 \item \textit{Sempre Ativo}: O processo \(p\) nunca cai.
382 \item \textit{Eventualmente Ativo}: O processo caiu pelo menos uma
383 vez, mas, após algum momento \(t\), o processo mantém-se ativo.
384 \item \textit{Eventualmente Inativo}: O processo caiu pelo menos uma
385 vez, e, após algum momento \(t\), o processo não volta à atividade.
386 \item \textit{Instável}: O processo cai e volta um número infinito de
387 vezes.
388 \end{itemize}
390 Um processo é \textit{bom} (em \(F\)) se é sempre ativo ou
391 eventualmente ativo. Um processo é \textit{ruim} (em \(F\)) se é
392 eventualmente inativo ou instável. Denota-se \(Bom(F)\), \(Ruim(F)\) e
393 \textit{Instável}\((F)\) aos conjuntos de processos (em \(F\)) bons,
394 ruins e instáveis, respetivamente.
396 \subsection{Consenso}
397 \label{sec:consenso}
398 O problema do consenso~\cite{Pease:1980:RAP:322186.322188} é um dos
399 mais fundamentais da área dos algoritmos distribuídos. Considere um
400 conjunto \(\Pi = \{p_1,\ldots,p_n\}\) de \(n\) processos; seja \(V =
401 \{v_1^0, \ldots, v_n^0\}\) o conjunto de estados inicias dos
402 processos, tal que \(v_i^0\) é o valor inicial do processo
403 \(p_i\). Eventualmente cada processo \(p_i\) tem que \textit{decidir}
404 um valor \(decide(p_i) = v_i\), tal que todos os processos corretos
405 concordem neste, e as seguintes propriedades forem
406 satisfeitas~\cite{springerlink:aguilera98}:
408 \begin{description}
409 \item[Validade uniforme] se um processo decide $v$, então algum
410 processo o propôs, i.e.\ \(\forall p \in \Pi(decide(p) \in V)\).
411 \item[Consenso] Todos os processos \textit{bons} decidem o mesmo
412 valor, i.e.\ \(\exists ! v \in V \forall p \in Bom(F) (decide(p_i) = v)\).
413 \item[Terminação] Se todos os processos \textit{bons} propõem um
414 valor, eventualmente um daqueles é escolhido, i.e.\ \(\exists ! v
415 \in V~\forall p \in Bom(F)~\exists T \in \mathcal{T}~\forall t > T
416 (v^0_p \in V \Rightarrow decide(p) = v)\).
417 \end{description}
419 Existe uma variação mais estrita, o consenso
420 uniforme~\cite{Neiger:1990:AIF:83334.83337}, que impõe restrições às
421 escolhas dos processos \textit{ruins}:
423 \begin{description}
424 \item[Consenso uniforme] Os processos não \textit{decidem} valores
425 distintos, i.e.\ \(\exists ! v \in V~\forall p \in \Pi (decide(p_i) = v)\).
426 \end{description}
428 No caso síncrono sem falhas, o problema é facilmente
429 resolúvel~\cite{Lynch:1996:DA:525656}, porém, o resultado de
430 impossibilidade obtido por Fischer, Lynch e Patterson~\cite{fischer85}
431 mostra que o problema não se pode resolver de maneira determinista num
432 sistema distribuído assíncrono com apenas um processo falho. Existem
433 distintas soluções propostas: o uso de randomização~\cite{Chor89},
434 definição de problemas mais débeis e suas soluções~\cite{dolev87},
435 detetores de falhas não
436 confiáveis~\cite{Chandra:1996:WFD:234533.234549,
437 Chandra:1996:UFD:226643.226647}, etc.
439 \paragraph{Algoritmo de consenso Paxos}
440 O algoritmo de consenso Paxos, originalmente proposto por
441 Lamport~\cite{Lamport:1998:PP:279227.279229}, é um dos mais utilizados
442 na prática~\cite{Burrows:2006:CLS:1298455.1298487,
443 Camargos:2007:SMH:1272998.1273036,
444 MacCormick:2004:BAF:1251254.1251262,
445 Saito:2004:FBD:1024393.1024400}. Neste algoritmo, os processos
446 assomem pelo menos um dos seguintes papéis:
447 \begin{inparaenum}[\itshape a\upshape)]
448 \item \textit{proponente}, que propõe valores;
449 \item \textit{receptor}, que escolhe um único valor; e
450 \item \textit{aprendiz}, que aprende o valor escolhido.
451 \end{inparaenum}
452 O algoritmo pode precisar uma ou varias rodadas para alcançar o
453 consenso, cada uma identificada por um número de rodada \(r\). No
454 começo de cada rodada os proponentes eligem um coordenador, quem
455 avalia se a maioria \(\lfloor n/2 \rfloor +1\) dos \(n\) receptores
456 participou da rodada anterior \(r-1\), e, portanto, o consenso foi
457 alcançado. No caso contrario, o algoritmo continua em duas fases com
458 dois passos cada uma:
460 \begin{itemize}
461 \item \textit{Fase 1a}, o coordenador invita aos receptores a
462 participar da rodada \(r\), os quais aceitam somente se não
463 participam de uma rodada \(r' \geq r\). A partir desse momento, os
464 receptores que aceitaram o convite \textit{prometem} não participar
465 em outra rodada, \(r'' < r\).
466 \item \textit{Fase 1b}, os receptores que aceitaram o convite enviam
467 ao coordenador o valor da última proposta que votaram e o número de
468 rodada na qual aquilo aconteceu, ou \textit{nulo} no caso contrario.
469 \item \textit{Fase 2a}, se suficientes respostas forem recebidas pelo
470 coordenador, \(\lfloor n/2 \rfloor +1\), ele escolhe dentro dos
471 valores retornados aquele que poderia ter sido \textit{decidido} em uma
472 rodada \(r' < r\), ou no caso seja \textit{nulo}, escolhe a
473 proposta feita pelos proponentes. Logo, ele pede aos receptores que
474 votem na proposta escolhida.
475 \item \textit{Fase 2b}, após receber o pedido de votar do coordenador,
476 e sempre que não houveram \textit{prometido} participar na rodada
477 \(r\), os receptores votam enviando o número de rodada \(r\) e o
478 valor decidido aos aprendizes.
479 \item O consenso é alcançado no momento que suficientes receptores,
480 \(\lfloor n/2 \rfloor +1\), votam na fase 2b.
481 \end{itemize}
483 \todo[noline]{Multipaxos? Fast Paxos? devo incluir?}Uma caraterística
484 interessante do Paxos é que sua tolerância a falhas fundamenta-se no
485 uso de \textit{quorum} de processos, e não no conhecimento do estado
486 atual deles, como os detetores de falhas. O algoritmo garante que se
487 um valor é eleito, a escolha não muda, portanto um processo que caiu e
488 volta, pode aprendê-lo. Para que isso aconteça, cada participante do
489 algoritmo tem que armazenar persistentemente as rodadas nas quais ele
490 participou e os valores que votou.
492 \subsection{Broadcast de ordem total}
493 \label{sec:broadcast}
494 % seção muito longa?
495 O \textit{broadcast} de ordem total, ou atômico, é uma primitiva de
496 comunicação assíncrona de alto nível que garanta que as mensagens
497 enviadas a um conjunto de processos sejam recebidas, no mesmo ordem,
498 por todos os membros~\cite{Defago:2004}. O problema é definido
499 formalmente em função de duas primitivas, \textit{TO-broadcast}\((m)\)
500 e \textit{TO-deliver}\((m)\), onde \(m \in \mathcal{M}\) e uma
501 mensagem válida. Quando um processo \(p \in \Pi\) executa
502 \textit{TO-broadcast}\((m)\) (respectivamente,
503 \textit{TO-deliver}\((m)\)) diz-se que o processo \(p\)
504 \textit{TO-broadcasts} \(m\) (respectivamente, \textit{TO-delivers}
505 \(m\)). Todas as mensagens têm identificadores únicos, e levam consigo
506 a identidade de seu remetente, denotado \textit{sender}\((m)\). Além
507 disso, supomos que para qualquer mensagem \(m\), e em quaisquer
508 execução, a chamada \textit{TO-broadcasts}\((m)\) é feita uma vez
509 só. Neste contexto, o \textit{broadcast} de ordem total é definido
510 pelas seguintes
511 propriedades~\cite{Chandra:1996:WFD:234533.234549,hadzilacos94}:
513 \begin{itemize}
514 \item \textit{Validade}, se um processo bom \textit{TO-broadcasts} a
515 mensagem \(m\), então ele eventualmente \textit{TO-delivers} \(m\).
516 \item \textit{Acordo uniforme}, se um processo \textit{TO-delivers} uma
517 mensagem \(m\), então todos os processos bons eventualmente
518 \textit{TO-deliver} \(m\).
519 \item \textit{Integridade uniforme}, para qualquer mensagem \(m\),
520 cada processo \textit{TO-delivers} \(m\) no máximo uma vez, se
521 somente se \(m\) foi \textit{TO-broadcast} por
522 \textit{sender}\((m)\) anteriormente.
523 \item \textit{Ordem total uniforme}, se os processos \(p\) e \(q\)
524 \textit{TO-deliver} as mensagens \(m\) e \(m'\), então \(p\)
525 \textit{TO-delivers} \(m\) antes de \(m'\), se somente se \(q\)
526 \textit{TO-delivers} \(m\) antes de \(m'\).
527 \end{itemize}
529 Se a primitiva de comunicação satisfaz todas as propriedades exceto
530 ordem total uniforme é chamada \textit{broadcast} confiável. No caso a
531 primitiva cumpra todas as propriedades prévias, é chamada uniforme,
532 porque impõe restrições ao comportamento de todos dos processos. O
533 broadcast não uniforme só se aplica aos processos bons (propriedades
534 de acordo e integridade não uniformes).
536 % Não gosto do paragrafo, é uma simples enumeração, não é muito
537 % legível.
538 A relação entre o conjunto destino das mensagense, o conjunto de
539 processos do sistema e a presença do remetente como destinatario da
540 mensagem gera a seguinte classificação:
541 \begin{inparaenum}[\itshape a\upshape)]
542 \item Se ambos são iguais, i.e \(\forall m \in \mathcal{M} (Dest(m) =
543 \Pi)\), a primitiva é \textit{broadcast};
544 \item Se o conjunto destino é um subconjunto dos processos, e
545 distintas mensagens têm distintos conjuntos destinos e os remetentes
546 podem não ser destinatários, i.e.\ \(\exists m \in \mathcal{M}
547 (sender(m) \notin Dest(m)) \wedge \exists m_i,m_j \in \mathcal{M}
548 (Dest(m_i) \neq Dest(m_j))\), a primitiva é multicast.
549 \item Se o remitente é membro dos destinatários, i.e.\ \(\forall m \in
550 \mathcal{M} (sender(m) \in Dest(m))\), o grupo é \textit{fechado};
551 \item Se o remitente não precisa pertencer ao grupo destino, i.e.\
552 \(\exists m \in \mathcal{M}(sender(m) \notin Dest(m))\), o grupo e
553 \textit{aberto}.
554 \end{inparaenum}
556 A conformação do conjunto de processos do sistema não precisa ser
557 fixa. Se os processos podem entrar, sair e ser removidos dele, o grupo
558 é \textit{dinâmico}, contraposto ao grupo \textit{estático}, que não
559 permite a mudanca de membros durante a execução. Às distintas
560 configurações ao longo do tempo são
561 \textit{vistas}~\cite{Chockler:2001:GCS:503112.503113}. A primitiva de
562 comunicação equivalente ao \textit{broadcast} confiável nos grupos
563 dinâmicos é a \textit{sincronia de vista}, que cumpre as mesmas regras
564 de validade, integridade uniforme e uma versão de acordo relaxada aos
565 membros atuais. Uma sincronia de vista que cumpre adicionalmente a
566 propriedade de ordem total é o equivalente ao \textit{broadcast} de
567 ordem total nos grupos estáticos.
569 Existem diversos mecanismos pelos quais se pode definir a ordem de
570 entrega das mensagens~\cite{Defago:2004}, porém, em todos são
571 distinguíveis três papéis: remetente (i.e.\ \(p \in \Pi_{sender}\)),
572 destinatário (i.e.\ \(p \in \Pi_{dest}\)) e o sequenciador que define
573 o ordem de entrega das mensagens. Existem as seguintes cinco classes:
575 \begin{itemize}
576 \item \textit{Sequenciador fixo} (e.g.\ Garcia-Molina e
577 Spauster~\cite{garcia2002message}). Um único sequenciador é
578 escolhido. Possui três variantes:
579 \begin{inparaenum}[\itshape a\upshape)]
580 \item \textit{unicast-broadcast}, se o remetente envia as mensagens
581 ao sequenciador, e ele se responsabiliza pela entrega ordenada;
582 \item \textit{broadcast-broadcast}, se o remetente envia as
583 mensagens diretamente aos destinatários e ao sequenciador, e logo
584 este envia a ordem de entrega;
585 \item \textit{unicast-unicast-broadcast}, se o remetente envia as
586 mensagens ao sequenciador, logo este retorna os identificadores de
587 sequencia das mensagens, e finalmente o remetente envia
588 diretamente as mensagens.
589 \end{inparaenum}
590 \item \textit{Sequenciador móvel} (e.g.\
591 Pinwheel~\cite{cristian97:high_performance}). É muito similar ao
592 sequenciador fixo, mas o papel de sequenciador é transferível entre
593 um conjunto de processos. Na literatura, o principio utilizado pelos
594 sequenciadores móveis é equivalente ao \textit{broadcast-broadcast}
595 dos sequenciadores fixos~\cite{Defago:2004}.
596 \item \textit{Baseados em privilégios} (e.g.\ Gopal e
597 Toueg~\cite{Gopal:1989:RBS:645946.675018}). A diferença das classes
598 anteriores, os papéis do sequenciador e do remetente são
599 desenvolvidos pelo mesmo processo. O principio é que só o processo
600 que possui o privilegio, e.g.\ token, pode enviar mensagens, mas
601 este privilegio é circulado entre os remetentes.
602 \item \textit{Baseados na historia da comunicação}(e.g.\
603 Atom~\cite{Bar-Joseph:2002:EDA:645959.676132}). São os destinatários
604 os que definem a ordem de entrega das mensagens baseando-se na
605 historia deles, i.e.\ os destinatários são os sequenciadores. Os
606 dois métodos utilizados são:
607 \begin{inparaenum}[\itshape a\upshape)]
608 \item \textit{historia causal}, onde algoritmos de ordem causal
609 parcial~\cite{Lamport:1978_clocks} são aumentados com políticas
610 comuns para a ordenação de mensagens concorrentes, e o ordem
611 total resultante é utilizado para ordenação das mensagens;
612 \item \textit{união determinista}, onde não existe uma ordenação
613 causal das mensagens, senão uma política determinista de união dos
614 fluxos de mensagens de cada remetente.
615 \end{inparaenum}
616 \item \textit{Acordo dos destinatários}(e.g.\ Chandra e
617 Toueg~\cite{Chandra:1996:UFD:226643.226647}). Como o nome o indica,
618 os destinatários acordam a ordem das mensagens a ser entregues. As
619 variantes são:
620 \begin{inparaenum}[\itshape a\upshape)]
621 \item \textit{acordo na sequencia de mensagens}, cada destinatário
622 assina uma \textit{timestamp} local a mensagem, logo a maior
623 destas é escolhida como a \textit{timestamp} global e é utilizada
624 para ordenar a entrega;
625 \item \textit{acordo no conjunto de mensagens}, algoritmos de
626 consenso são utilizados para determinar um subconjunto de
627 mensagens a ser entregues simultaneamente por todos os processos
628 (a ordenação no subconjunto é definida por algum parâmetro
629 predefinido);
630 \item \textit{acordo na aceitação de ordens propostas}, um processo
631 propõe uma ordem das mensagens e os demais destinatários acordam
632 se é aceitado o não, utilizando algum protocolo de \textit{commit}
633 atômico.
634 \end{inparaenum}
635 \end{itemize}
637 Foi mostrado por Chandra e Toueg~\cite{Chandra:1996:UFD:226643.226647}
638 que o problema do consenso uniforme e o \textit{broadcast} de ordem
639 total em sistemas assíncronos com falhas de parada são equivalentes,
640 i.e.\ qualquer algoritmo que possa resolver um deles também se pode
641 adaptar para resolver o outro. Portanto, o \textit{broadcast} de ordem
642 total é sujeito ao mesmo resultado de impossibilidade de Fischer,
643 Lynch e Patterson.
645 Existem múltiplos mecanismos pelos quais se pode prover alguma
646 tolerância a falhas ao \textit{broadcast} de ordem total. Na prática, os
647 algoritmos implementam vários mecanismos simultaneamente. Os mecanismos
648 são:
650 \begin{itemize}
651 \item \textit{Detecção de falhas} Baseados nos detetores de falhas não
652 confiáveis propostos inicialmente por Chandra e
653 Toueg~\cite{Chandra:1996:UFD:226643.226647}, os quais são discutidos
654 com detalhe na seção~\ref{sec:detetores}
655 \item \textit{Serviço de configuração do grupo}, profundamente
656 relacionado com os grupos dinâmicos. No evento de um processo cai, o
657 serviço gera uma nova vista do grupo e a envia aos processos ativos,
658 portanto, eles podem assumir que na vista atual todos os processos
659 estão ativos. Se um processo foi excluído erroneamente, é forçado a
660 cair para manter a correção. A diferença dos detetores de falhas,
661 provê notificações de falhas consistentes.
662 \item \textit{Patrões de comunicação resistentes}, são aqueles patrões
663 que consideram, dentro do número \(n\) total de processos, um número
664 \(f\) máximo de processos que podem falhar, e trabalham sob o
665 pressuposto que sempre vão receber pelo menos \(n-f\) mensagens de
666 resposta.
667 \item \textit{Estabilidade das mensagens}. Além da possibilidade que
668 um processo fique bloqueado esperando a resposta de outro que caiu,
669 tem que se considerar a estabilidade das mensagens. Uma mensagem
670 \(m\) é \(k\)-estável se \(m\) e recebida por \(k\) processos. Se
671 num sistema podem cair ao mais \(f\) processos, é importante detetar
672 que as mensagens são \(f+1\)-estáveis, também chamadas estáveis, já
673 que permite aos algoritmos garantir que, eventualmente, as mensagens
674 são recebidas por todos os processos bons.
675 \item \textit{Consenso} O \textit{broadcast} de ordem total pode
676 reduzir se a uma série de execuções do problema do consenso,
677 portanto é possível delegar toda a responsabilidade da tolerância a
678 falhas ao algoritmo de consenso.
679 \end{itemize}
681 \subsection{Detetores de falhas }
682 \label{sec:detetores}
683 Os detetores de falhas não confiáveis, propostos inicialmente por
684 Chandra e Toueg~\cite{Chandra:1996:WFD:234533.234549,
685 Chandra:1996:UFD:226643.226647}, são, informalmente, um conjunto de
686 módulos distribuídos, um por processo, que possuem uma visão do
687 sistema, i.e.\ uma listagem dos processos que são suspeitos de estar
688 inativos, mas não precisasse garantir a correção desta, e.g.\ pode-se
689 incluir na listagem processos ativos.
691 Formalmente, a \textit{historia de um detetor de falhas} \(H\) é uma
692 função de \(\Pi \times \mathcal{T}\) a \(2^\Pi\), onde \(H(p,t)\) é o
693 valor do detetor de falhas do processo \(p\) ao tempo \(t\). Se o
694 processo \(q \in H(p,t)\) diz-se que o processo \(p\) suspeita \(q\)
695 ao tempo \(t\). Já que os detetores não são confiáveis, e possível que
696 dois processos distintos \(p \neq q\) possuam informação distinta,
697 i.e.\ \(H(p,t) \neq H(q,t)\). Um detetor de falhas \(\mathcal{D}\) é
698 uma função que mapeia cada padrão de falhas \(F\) a um conjunto de
699 historias de detetores de falhas \(D(F)\), sendo este o conjunto de
700 todas as historias do detetor de falhas \(D\) que podem acontecer em
701 execuções com o padrão de falhas \(F\).
703 Na proposta original de Chandra e
704 Toueg~\cite{Chandra:1996:UFD:226643.226647,
705 Chandra:1996:WFD:234533.234549}, definem se duas propriedades de
706 completude e quatro de precisão que podiam cumprir os detetores de
707 falhas:
708 \begin{inparaenum}[\itshape a\upshape)]
709 \item \textit{completude forte}, eventualmente todo processo que caiu é
710 suspeito permanentemente por \textit{todos} os processos bons;
711 \item \textit{completude fraca}, eventualmente todo processo que caiu
712 é suspeito permanentemente por \textit{alguns} processos bons;
713 \item \textit{precisão forte}, nenhum processo é suspeito antes de cair;
714 \item \textit{precisão débil}, alguns processos bons não são
715 suspeitos nunca;
716 \item \textit{precisão forte eventual}, após algum tempo \(t \in
717 \mathcal{T}\), nenhum processo bom é suspeito por nenhum outro
718 processo bom.
719 \item \textit{precisão franca eventual}, após algum tempo \(t \in
720 \mathcal{T}\), alguns processos bons não são suspeitos por nenhum
721 outro processo bom.
722 \end{inparaenum}
723 Das possíveis oito classes de detetores de falhas que se podem criar
724 baseando-se nas combinações daquelas propriedades, os autores mostram
725 que são \textit{reduzíveis} só a quatro, onde \(\mathcal{D'}\) e
726 reduzível a \(\mathcal{D}\) se existe um algoritmo distribuído que
727 possa transformar \(D\) em \(D'\). Eles mostram que é possível
728 resolver o problema do consenso com cada uma das classes de detetores
729 de falhas resultantes: perfeito \(\mathcal{P}\) (completude forte,
730 precisão forte), forte \(\mathcal{S}\) (completude forte, precisão
731 fraca), eventualmente perfeito \(\diamond \mathcal{P}\) (completude
732 forte, precisão forte eventual), e eventualmente forte \(\diamond
733 \mathcal{S}\) (completude forte, precisão fraca).
735 O modelo de falhas utilizado por Chandra e Toueg não permite a
736 recuperação dos processos, portanto, a diferença da definição da
737 seção~\ref{sec:notacao}, os processos bons eram aqueles que nunca
738 falhavam e os ruins aqueles que caiam e não voltavam. Oliveira et
739 al.~\cite{oliveira97:consensus} e Hurfin et
740 al.~\cite{Hurfin:1998:CAS:829523.830974} apresentaram soluções para o
741 modelo de falha e recuperação, mas Aguilera et
742 al.~\cite{springerlink:aguilera98} mostraram que a propriedade de
743 completude forte das que elas dependiam, pode gerar comportamento
744 indesejável para satisfazer aquela propriedade, forçando aos detetores
745 de falhas a suspeitar de processos bons eventualmente para sempre. A
746 raiz deste comportamento é o fato que a abordagem tradicional tenta
747 pronosticar se um processo que caiu e volto, vai volver a cair ou
748 não. Este comportamento não impede que o algoritmo progresse, mas pode
749 ter um efeito negativo em seu desempenho.
751 Aguilera et al.~\cite{springerlink:aguilera98} propõem um novo tipo de
752 detetores de falhas que não exibem este comportamento e, portanto, são
753 mais apropriados ao modelo de falha e recuperação. Cada detetor produz
754 como saída dois elementos \(\langle trustlist, epoch \rangle\):
755 \(trustlist\) é um conjunto de processos, onde \(q \in trustlist\) se
756 \(p\) suspeita que \(q\) está ativo, e \(epoch\) é um vector de
757 inteiros indexado pelos elementos de \(trustlist\), onde \(epoch[q]\)
758 é o estimado de \(p\) do número de vezes que \(q\) caiu e
759 voltou. Existem duas classes de detetores de falhas descritas por
760 Aguilera et al.\
761 \begin{itemize}
762 \item \(\diamond S_e\), caraterizada pelas seguintes propriedades de:
763 \begin{inparaenum}[\itshape a\upshape)]
764 \item \textit{monotonicidade}, os valores de \(epoch\) produzidos
765 pelos detetores dos processos \textit{bons} são eventualmente no
766 decrescentes;
767 \item \textit{completude}, por cada processo ruim \(r\), e por cada
768 processo bom \(b\), ou eventualmente \(b\) suspeita
769 permanentemente de \(r\) ou o \(epoch\) de \(b\) aumenta sem
770 limites.
771 \item \textit{precisão}, algum processo bom \(K\) e cada processo
772 bom \(b\), eventualmente \(g\) permanentemente confia em \(K\) e o
773 valor \(epoch\) de \(K\) em \(g\) para de cambiar.
774 \end{inparaenum}
775 \item \(\diamond S_u\), que aumenta a classe \(\diamond S_e\) com a
776 propriedade de precisão forte que inclui processos instáveis e
777 permite-lhes suspeitar de todos os processos bons: \textit{precisão
778 forte}, seja algum processo bom \(K\):
779 \begin{inparaenum}[\itshape a\upshape)]
780 \item por cada processo bom \(g\), eventualmente \(g\) confia
781 permanentemente de \(K\) e o \(epoch\) de \(K\) em \(g\) para de
782 cambiar; e
783 \item por cada processo instável \(u\), eventualmente quando \(u\)
784 está ativo, \(u\) confia em \(K\) e o \(epoch\) de \(K\) em \(u\)
785 para de cambiar.
786 \end{inparaenum}
787 \end{itemize}
789 \section{Treplica}
790 \label{sec:treplica}
791 Esta seção sumariza a plataforma Treplica, sobre a qual este projeto
792 será desenvolvido. Treplica é uma biblioteca desenhada para suportar a
793 construção de aplicações replicadas altamente disponíveis no modelo de
794 falha e recuperação~\cite{vieira08:_trepl,vieira10:implementing-tr}. O
795 objetivo da ferramenta é garantir consistência e persistência de dados
796 através de abstrações de programação simples e descomplicadas.
798 Na raiz da biblioteca estão as colas assíncronas persistentes, que são
799 canais de comunicação em grupo com as seguintes propriedades:
800 \begin{inparaenum}[\itshape a\upshape)]
801 \item as mensagens são entregues no mesmo ordem;
802 \item todos os processos, ainda aqueles que caem e voltam ao sistema,
803 recebem todas as mensagens; e
804 \item a persistência das mensagens é garantida.
805 \end{inparaenum}
806 A similaridade com o \textit{broadcast} de ordem total com sincronia
807 de vista (seção~\ref{sec:broadcast}) e
808 clara~\cite{Birman:1987:EVS:41457.37515}, mas a entrega das mensagens
809 é restrito ao estado da aplicação, não à vista atual. Porém, pode-se
810 implementar as colas persistentes utilizando \textit{broadcast} de
811 ordem total uniforme. Em Treplica, cada cola tem um identificador
812 único chamado \textit{queue id}. Os processos que participam da
813 comunicação criam pontos de conexão exclusivos chamados \textit{queue
814 endpoints}, um por cada cola que utilizam. As primitivas das colas
815 são simples:
817 \begin{itemize}
818 \item \texttt{create(queueId)}, gera um ponto de conexão associado à
819 cola.
820 \item \texttt{getProcessId()}, retorna o identificador do processo
821 associado ao ponto de conexão.
822 \item \texttt{put(message)}, envia uma mensagem aos participantes da cola.
823 \item \texttt{get()}, recebe a próxima mensagem na cola.
824 \end{itemize}
826 A persistência das mensagens é garantida pela cola e o ponto de
827 conexão que registra as mensagens já entregues. Portanto, no evento de
828 geração de um novo ponto de conexão, o processo vai receber todas as
829 mensagens enviadas pela cola. Esta propriedade, atrativa para o
830 desenvolvedor de aplicações, não se pode implementar efetivamente na
831 prática. Treplica suporta aplicações de grupos estáticos, nos quais os
832 participantes, i.e.\ pontos de conexão, são conhecidos desde o inicio
833 da aplicação e não mudam, mas podem cair e voltar ao sistema,
834 obrigarando o armazenamento permanente de toda a historia das
835 mensagens. A solução é o uso de persistência baseada na
836 cola~\cite{vieira10:implementing-tr} que armazena periodicamente de
837 maneira persistente uma copia do estado atual da aplicação e da cola,
838 i.e.\ \textit{snapshot} e o historial das mensagens já entregues
839 limpado. Este procedimento precisa suporte de parte da aplicação, a
840 qual deve delegar o controle de seu estado à cola através das
841 seguintes duas primitivas adicionais:
843 \begin{itemize}
844 \item \texttt{bind(stateHolder)}, cria uma relação entre o ponto de
845 conexão e o processos, através do \textit{stateHolder}, um
846 componente da aplicação que implementa os métodos
847 \texttt{getState()} e \texttt{setState(state)}.
848 \item \texttt{checkpoint()}, solicita a geração do \textit{snapshot}
849 do estado da aplicação e da cola.
850 \end{itemize}
852 É garantido que os \textit{snapshot} com a seguinte mensagem a ser
853 entregue. No caso que o processo falhe e quede atrasado no progresso
854 do sistema, a copia do estado de outra réplica pode-se utilizar para
855 sua atualização. Ainda em casos que o processo não falha mas fica
856 retrasado, é possível que seu estado seja trocado pelo estado de um
857 processo atualizado. Isto permite, e exige, que a aplicação seja
858 \textit{stateless}.
860 A implementação das colas assíncronas persistentes de Treplica utiliza
861 um algoritmo de \textit{broadcast} de ordem total uniforme baseado em
862 consenso, especificamente Paxos (ver seção~\ref{sec:consenso}) e Fast
863 Paxos~\cite{lamport06a}, uma variante que reduz uma das rondas de
864 comunicação, já que assume que as mensagens são ordenadas naturalmente
865 pelo canal de comunicação. A transição entre ambos algoritmos é
866 transparente ao usuário: em uma configuração de \(N\) réplicas, se
867 pelo menos \(\lceil 3N/4 \rceil\) estão disponíveis, Fast Paxos é
868 utilizado, no caso que pelo menos \(\lfloor 2N/1 \rfloor + 1\) estão
869 disponíveis, o algoritmo escolhido é Paxos; se nenhuma das dois
870 condições é cumprida o sistema é bloqueado até que suficientes
871 processos se recuperem.
873 \section{Proposta de pesquisa}
874 \label{sec:proposta}
875 Pesquisas anteriores~\cite{gray07:empirical,
876 Schroeder:2007:DFR:1267903.1267904, 10.1109/SRDS.2008.9,
877 Pinheiro:2007:FTL:1267903.1267905} mostraram que, na prática, as
878 falhas dos componentes de hardware dos sistemas distribuídos de
879 produção são maiores às reportadas pelos fabricantes; além disso,
880 erros no software também causam quedas nos processos, portanto, a
881 tolerância a falhas é vital.
883 A proposta de pesquisa vai-se focar nos sistemas distribuídos de
884 replicação ativa no modelo de máquina de
885 estados~\cite{Schneider:1990:IFS:98163.98167}, com \textit{broadcast}
886 de ordem total uniforme. Os processos têm as seguintes caraterísticas:
887 \begin{inparaenum}[\itshape a\upshape)]
888 \item aceso a memória estável e a memória volátil;
889 \item participação no \textit{broadcast} como remetentes e
890 destinatários, i.e.\ \(\forall p,j \in \Pi~\exists m \in \mathcal{M}
891 (sender(m) = p \wedge j \in Dest(m))\);
892 \item suscetibilidade às falhas de software ou hardware, as quais
893 causam que os processos percam o conteúdo de sua memória volátil e
894 não participem do sistema por um tempo limitado mas desconhecido,
895 depois \textit{recuperam}-se e voltam à atividade.
896 \end{inparaenum}
897 As propriedades da comunicação pelo \textit{broadcast} uniforme,
898 definidas na seção~\ref{sec:broadcast}, que caracterizam o modelo são:
899 \begin{inparaenum}[\itshape a\upshape)]
900 \item o grupo de processos é fechado e estático;
901 \item a sequencia das mensagens é decidida por acordo dos
902 destinatários, utilizando o algoritmo de consenso Paxos.
903 \end{inparaenum}
905 O mecanismo de tolerância a falhas do sistema é fornecido pelo
906 \textit{broadcast} de ordem total uniforme que garanta a entrega
907 ordenada das mensagens, ainda aos processos com falhas. É possível,
908 porém não prático, que sejam armazenadas todas as mensagens enviadas
909 pelo \textit{broadcast} e, no caso de falhas, estas sejam entregues
910 novamente ao processo recuperado. Ao invés, cada nó vai armazenar
911 \textit{checkpoints} em períodos regulais. Não precisasse utilizar
912 protocolos de \textit{checkpoint} distribuídos tais como os
913 apresentados em~\cite{Chandy:1985:DSD:214451.214456,
914 Koo:1986:CRD:324493.325074} já que, a principal motivação do uso
915 deles, é garantir a consistência dos estados armazenados através do
916 sistema, mas neste caso não precisa; o \textit{broadcast} garanta a
917 consistência das mensagens entregues às replicas, e o algoritmo de
918 consenso fornece o mecanismo de coordenação e sincronização dos
919 estados.
921 % \begin{table}[h]
922 % \small
923 % \centering
924 % \begin{tabular}{|l|p{5cm}|l|p{5cm}|}
925 % \hline
926 % \(\Pi\) & Conjunto de processos do sistema. &
927 % \(\Pi_{local}\) & Conjunto de processos que armazenam localmente seus \textit{checkpoints}. \\
928 % \(\Pi_{remote}\) & Conjunto de processos que armazenam remotamente seus \textit{checkpoints}. &
929 % \(\Pi_{storage}\) & Conjunto de processos que armazenam localmente \textit{checkpoints} remotos, além dos próprios. \\
930 % \(\Pi'_{storage}\) & Conjunto de processos externos que armazenam localmente \textit{checkpoints} remotos. &
931 % \(P_{storage}\) & \(\Pi_{storage} \cup \Pi'_{storage}\). \\
932 % \(States_i\) & Conjunto de estados do processo \(p_i\). &
933 % \(S_i(t)\) & Estado do processo \(p_i\) no tempo \(t\). \\
934 % \(\mathcal{M}_b\) & Conjunto das mensagens dos algoritmos (\textit{broadcast} e consenso). &
935 % \(\mathcal{M}_s\) & Conjunto das mensagens de armazenamento dos \textit{checkpoints}. \\
936 % \hline
937 % \end{tabular}
938 % \caption{Notação adicional.}
939 % \label{tab:notacion_proposta}
940 % \end{table}
942 % Vamos definir mais formalmente o sistema; a
943 % tabela~\ref{tab:notacion_proposta} contém o resumo da notação
944 % utilizada adicional à já definida na tabela~\ref{tab:notacao}. Seja
945 % \(\Pi = \{p_1, \ldots, p_n\}\) um conjunto de \(n\) processos que
946 % conformam o sistema, i.e.\ participam do \textit{broadcast} de ordem
947 % total. Cada processo do sistema é modelado como uma máquina de
948 % estados, onde \(States_i\) é o conjunto (não necessariamente finito)
949 % de estados do processo \(p_i\). Seja \(S_i\) uma função de
950 % \(\mathcal{T}\) a \(States_i\), tal que \(S_i(t)\) representa o estado
951 % do processo \(i\) ao tempo \(t\); o estado especial \(\bot\)
952 % representa inatividade, e.g.\ \(S_i(t) = \bot \iff p_i \in F(t)\). Os
953 % processos só mudam de estado pelo intercambio de mensagens \(m \in
954 % \mathcal{M}\), ou pelos eventos de falha e recuperação.
956 Vamos definir mais formalmente o sistema;. Seja \(\Pi = \{p_1, \ldots,
957 p_n\}\) um conjunto de \(n\) processos que conformam o sistema, i.e.\
958 participam do \textit{broadcast} de ordem total. Cada processo do
959 sistema é modelado como uma máquina de estados, onde \(States_i\) é o
960 conjunto (não necessariamente finito) de estados do processo
961 \(p_i\). Seja \(S_i\) uma função de \(\mathcal{T}\) a \(States_i\),
962 tal que \(S_i(t)\) representa o estado do processo \(i\) ao tempo
963 \(t\); o estado especial \(\bot\) representa inatividade, e.g.\
964 \(S_i(t) = \bot \iff p_i \in F(t)\). Os processos só mudam de estado
965 pelo intercambio de mensagens \(m \in \mathcal{M}\), ou pelos eventos
966 de falha e recuperação.
968 O \textit{checkpoint} do processo \(p_i\) no tempo \(t\) é definido
969 como a copia não modificável do estado \(S_i(t)\). A operação que os
970 gera é atômica~\cite{Randell:1978:RIC:356725.356729} e só pode-se
971 executar no tempo \(t\) se \(S_i(t) \neq \bot\). Formalmente, a
972 recuperação, ou reconstrução~\cite{Okun:2002:NSR:829526.831119}, no
973 tempo \(t'\) do processo \(p_i\) é uma operação especial, executável
974 se \(p_i \in F(t')\), que transforma do estado inicial \(S_i(0)\) ao
975 estado \(S_i(t)\) armazenado pelo \textit{checkpoint} gerado no tempo
976 \(t\), tal que \(t'> t\). O procedimento descrito só volta o processo
977 a seu último estado armazenado; a responsabilidade da atualização
978 deste até o estado atual das demais réplicas é delegada ao algoritmo
979 de consenso. Os \textit{checkpoints} são gerados em intervalos
980 regulais.
982 Sejam \(\Pi_{local}\), \(\Pi_{remote}\) e \(\Pi_{storage}\), três
983 subconjuntos disjuntos do \(\Pi\) tais que sua união é igual a
984 este. Se \(p \in \Pi_{local}\), o processo \(p\) armazena seus
985 \textit{checkpoints} em sua memoria estável local. Se \(p \in
986 \Pi_{remote}\), o processo \(p\) delega a responsabilidade do
987 armazenamento a outros processos, enviando-lhes os
988 \textit{checkpoints}. Se \(p \in \Pi_{storage}\), o processo \(p\)
989 armazena seus \textit{checkpoints} em sua memoria estável local, além
990 de armazenar \textit{checkpoints} de processos remotos em suas duas
991 memórias: a estável e a volátil. Além dos processos já definidos,
992 existem um conjunto de processos \(\Pi'_{storage}\) que não participam
993 do \textit{broadcast} de ordem total, e portanto não são replicas do
994 sistema, i.e.\ \(\Pi_{storage} \cap \Pi = \emptyset\): se \(p \in
995 \Pi'_{storage}\), o processo \(p\) é um repositório, e tem a única
996 função de armazenar \textit{checkpoints} de processos remotos em suas
997 duas memorias: a estável é a volátil. Existe uma relação entre os
998 processos que delegam o armazenamento de seus \textit{checkpoints},
999 \(\Pi_{remote}\), e aqueles que assumem a responsabilidade,
1000 representados pelo conjunto de processos \(P_{storage} = \Pi_{storage}
1001 \cup \Pi'_{storage}\)~: seja \(Store\) uma relação de \(\Pi_{remote}\)
1002 a \(2^{P_{storage}}\), tal que \(Store(p)\) representa o conjunto de
1003 processos em \(P_{storage}\) que armazenam os \textit{checkpoints} de
1004 \(p\); diz-se que \(j\) é um \textit{store} de \(p\) se somente se \(j
1005 \in Store(p)\). Todos os processos de armazenamento devem de ser o
1006 \textit{store} de pelo menos um processo remoto, i.e.\ \(\forall j \in
1007 P_{storage} \exists p \in \Pi_{remote} (j \in Store(p))\), e todo
1008 processo remoto tem que armazenar seus \textit{checkpoints} em pelo
1009 menos um \textit{store}, i.e.\ \(\forall p \in \Pi_{remote} (Store(p)
1010 \neq \emptyset)\).
1012 As mensagens válidas são de dois classes: sejam \(\mathcal{M}_b\) e
1013 \(\mathcal{M}_s\) dois subconjuntos disjuntos de \(\mathcal{M}\), tais
1014 que \(\mathcal{M}_b \cap \mathcal{M}_s = \emptyset \wedge
1015 \mathcal{M}_b \cup \mathcal{M}_s = \mathcal{M}\). \(\mathcal{M}_b\) é
1016 o conjunto de todas as mensagens válidas do sistema que estão
1017 relacionadas com o progresso dos algoritmos de consenso e de
1018 \textit{broadcast} de ordem total uniforme; os remetentes e
1019 destinatários destas mensagens são processos que participam do
1020 consenso, i.e.\ \(\forall m \in \mathcal{M}_b (sender(m) \in \Pi \wedge
1021 Dest(m) \subseteq \Pi)\). \(\mathcal{M}_s\) é o conjunto de todas as
1022 mensagens válidas do sistema que transmitem valores de
1023 \textit{checkpoint} entre os processos que participam do armazenamento
1024 remoto de dados, i.e.\ \(\forall m \in \mathcal{M}_s(sender(m) \in
1025 (\Pi_{remote} \cup P_{storage}) \wedge Dest(m) \in (\Pi_{remote} \cup
1026 P_{storage}))\).
1028 \begin{figure}[h]
1029 \centering
1030 \includegraphics[width=120mm]{images/system_arch}
1031 \caption{Arquitetura do sistema}
1032 \label{fig:arquitetura}
1033 \end{figure}
1035 O objetivo desta pesquisa é encontrar a melhor configuração em termos
1036 de desempenho num sistema com as caraterísticas descritas na
1037 figura~\ref{fig:arquitetura}. As medidas de desempenho utilizadas são:
1038 \begin{inparaenum}[\itshape a\upshape)]
1039 \item \textit{disponibilidade}, ratio entre o tempo que a aplicação
1040 está operacional e o tempo total de execução;
1041 \item \textit{perfomability}, é o ratio entre o desempenho promédio da
1042 aplicação (AWIPS) durante o período sem falhas e o desempenho
1043 promédio durante o período de recuperação; está medida quantifica o
1044 impacto das falhas no desempenho da aplicação;
1045 \item \textit{precisão}, ratio entre o número de requisições com erro
1046 e o total destas durante a execução;
1047 \item \textit{autonomia}, ratio entre o número de intervenções humanas
1048 precisadas para o reinicio das replicas e o número de falhas no
1049 sistema.
1050 \end{inparaenum}
1051 \todo{Os parâmetros de desempenho supostos são os mesmos que no
1052 trabalho de tréplica do 2009\cite{buzato09}}
1054 As possíveis configurações do sistema são:
1056 \begin{itemize}
1057 \item \(\Pi_{local} = \Pi\), está é a configuração atual de
1058 Treplica. Todos os processo armazenam seus \textit{checkpoints},
1059 portanto o custo de recuperação do estado é dominado pela latência
1060 da memoria estável, e o procedimento não gera tráfego de rede ou
1061 carga adicional aos nós vizinhos\footnote{É claro que a falha de um
1062 processo vai gerar uma carga de trabalho adicional aos demais
1063 membro do sistema, devido à redistribuição de tarefas, mas é
1064 considerado um custo inerente ao modelo e portanto não considerado
1065 nos cálculos.}
1066 \item \(\Pi_{local} \neq \emptyset \wedge \Pi_{remoto} \neq \emptyset
1067 \wedge \Pi_{storage} \neq \emptyset \wedge \Pi'_{storage} =
1068 \emptyset \), alguns processos armazenam seus estados em processos
1069 remotos que participam do \textit{broadcast}, portanto o custo de recuperação
1070 desses processos é dominado pela latência de rede, e o procedimento
1071 gera tráfego de rede e carga adicional aos vizinhos, mas é uma
1072 quantidade limitada aos processos que utilizam armazenamento remoto.
1073 \item \(\Pi_{local} \neq \emptyset \wedge \Pi_{remoto} \neq \emptyset
1074 \wedge \Pi_{storage} \neq \emptyset \wedge \Pi'_{storage} \neq
1075 \emptyset \), alguns processos armazenam seus estados em processos
1076 remotos que participam ou não do \textit{broadcast}, portanto o custo de
1077 recuperação desses processos é dominado pela latência de rede, e o
1078 procedimento gera tráfego de rede e carga adicional aos vizinhos,
1079 mas é uma quantidade menor à opção anterior, já que o tráfego e a
1080 carga gerados aos nós repositório não tem impacto sobre o desempenho do
1081 sistema.
1082 \item \(\Pi_{local} \neq \emptyset \wedge \Pi_{remoto} \neq \emptyset
1083 \wedge \Pi_{storage} = \emptyset \wedge \Pi'_{storage} \neq
1084 \emptyset \), alguns processos armazenam seus estados em processos remotos
1085 que não participam do \textit{broadcast}, portanto o custo de recuperação
1086 desses processos é dominado pela latência de rede, e o procedimento
1087 não gera tráfego de rede ou carga adicional aos vizinhos.
1088 \item \(\Pi_{local} = \emptyset \wedge \Pi_{remoto} \neq \emptyset
1089 \wedge \Pi_{storage} \neq \emptyset \wedge \Pi'_{storage} =
1090 \emptyset \), todos os processos armazenam seus estados em processos
1091 remotos que participam do \textit{broadcast}, portanto o custo de recuperação
1092 está dominado pela latência de rede, e o procedimento gera tráfego
1093 de rede e carga adicional aos vizinhos.
1094 \item \(\Pi_{local} = \emptyset \wedge \Pi_{remoto} \neq \emptyset
1095 \wedge \Pi_{storage} \neq \emptyset \wedge \Pi'_{storage} \neq
1096 \emptyset \), todos os processos armazenam seus estados em processos
1097 remotos que participam ou não do \textit{broadcast}, portanto o
1098 custo de recuperação está dominado pela latência de rede, e o
1099 procedimento gera tráfego de rede e carga adicional aos vizinhos,
1100 mas é uma quantidade menor à proposta anterior.
1101 \item \(\Pi_{local} = \emptyset \wedge \Pi_{remoto} \neq \emptyset
1102 \wedge \Pi_{storage} = \emptyset \wedge \Pi'_{storage} \neq
1103 \emptyset \), todos os processos armazenam seus estados em processos
1104 remotos que não participam do \textit{broadcast}, portanto o custo
1105 de recuperação está dominado pela latência de rede, e o procedimento
1106 não gera tráfego de rede ou carga adicional aos vizinhos.
1107 \end{itemize}
1109 A avaliação das opções tem que considerar não só a melhor opção, senão
1110 qual é a proporção de cada conjunto de processo que gera o resulta
1111 mais ótimo. Um aspecto importante a considerar se é o desempenho das
1112 soluções sobre as distintas classes de processos em relação as falhas:
1113 ativo, eventualmente ativo, eventualmente inativo e intestável (ver
1114 seção~\ref{sec:notacao}). Portanto, além de implementar os mecanismos
1115 necessários para dar suporte às distintas classes de processos, é
1116 preciso a implementação de detetores de falhas no modelo proposto por
1117 Aguilera et al.~\cite{springerlink:aguilera98} (ver
1118 seção~\ref{sec:detetores}), que possam fornecer melhor informação
1119 sobre os processos bons, ruins é instáveis.
1121 % LAS TECNICAS PROPUESTAS TAMBIEN HAN SIDO HECHAS PARA EL AMBIENTE
1122 % HPC. [ver paper de Bautista Gomez] REVISAR ARTICULO DE ISLENE
1124 % As alternativas a avaliar são as seguintes:
1126 % % hay que tener en consideracion que en este caso no se asume las
1127 % % fallas de disco dentro de la evaluacion. El metodo necesario para
1128 % % soportar esa situacion seria, por ejemplo, el uso de un sistema de
1129 % % archivos distribuido con replicacion, como hdfs. Aunque el impacto
1130 % % sobre el desempenho del sistema no es, necesariamente, despreciable,
1131 % % puede asumirse que afecta de manera uniforme a todos los nodos del
1132 % % sistema que utilizan la memoria estable.
1135 \section{Metodologia Científica}
1136 \label{sec:metodologia}
1137 O trabalho divide-se em duas fases. Na primeira, sob o método de
1138 comparação (formal), será realizada uma evaluação de distintas
1139 soluções a problemas similares propostas na literatura, por exemplo no
1140 trabalho de Menderico e Garcia~\cite{10.1109/SRDS.2010.17}, tomando em
1141 conta as caraterísticas proprias de um sistema de replicação ativa com
1142 comunicação de \textit{broadcast} de ordem total, no qual não é
1143 necessario um protocolo distribuído de \textit{checkpoint}.
1145 Na segunda fase, codificaremos o sub-sistema de armazenamento remoto
1146 compararemos experimentalmente o seu desempenho em distintas
1147 configurações. Durante essa fase os experimentos serão realizados com
1148 o mesmo método experimental e com as duas aplicações já implementadas
1149 para testar Treplica: um benchmark TPC-W e um hash
1150 replicado~\cite{buzato09}. As medidas de interesse são
1151 disponibilidade, desempenho e tempo de recuperação~\cite{buzato09}.
1153 \subsection{Tarefas e cronograma}
1154 \label{sec:planodetrabalho}
1156 Esta seção detalha as tarefas planejadas para o desenvolvimento do
1157 Mestrado e o cronograma proposto (Tabela~\ref{projtimetable}):
1159 \begin{enumerate}
1160 \addtolength{\itemsep}{-0.35\baselineskip}
1162 % Ago-Julho 2010
1163 \item \label{t1} Créditos em disciplinas
1165 % Abril-Julho 2010
1166 \item \label{t2} Revisão bibliográfica
1168 % Maio-Ago 2010
1169 \item \label{t3} Estudo dirigido
1171 % Jul-Ago 2010
1172 \item \label{t4} Elaboração do projeto de mestrado
1174 % Ago 2010 - Jul 2011
1175 \item \label{t5} Estudo comparativo de algoritmos
1177 % Jan 2011 - Dez 2011
1178 \item \label{t6} Proposta, análise e prova de algoritmos.
1180 % Dez 2011 - Dez 2011
1181 \item \label{t7} Implementação da solução sobre a plataforma
1182 Tréplica~\cite{vieira08:_trepl}. Testes de desempenho da solução com
1183 diversas cargas de trabalho, tanto na presença como na ausência de
1184 falhas de processos.
1186 % Mai 2011 - Jan 2012
1187 \item \label{t8} Escrita da Dissertação de Mestrado
1189 % Fev 2012 - Mar 2012
1190 \item \label{t9} Defesa da Dissertação de Mestrado
1192 % Dez 2010 - Mar 2012
1193 \item \label{t10} Escrita e submissão de artigos para publicação
1195 \end{enumerate}
1197 \begin{table}[h]
1198 \begin{center}
1199 \setlength{\tabcolsep}{1.5pt}
1200 \begin{tabular}{|l|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|} \hline
1201 & \multicolumn{5}{c|}{\scriptsize 2010} & \multicolumn{12}{c|}{\scriptsize 2011} & \multicolumn{7}{c|}{\scriptsize 2012} \\ \cline{2-25}
1202 {\small Tarefas } &
1203 \rotatebox{90}{\scriptsize ago } &
1204 \rotatebox{90}{\scriptsize set } &
1205 \rotatebox{90}{\scriptsize out } &
1206 \rotatebox{90}{\scriptsize nov } &
1207 \rotatebox{90}{\scriptsize dez } &
1208 \rotatebox{90}{\scriptsize jan } &
1209 \rotatebox{90}{\scriptsize fev } &
1210 \rotatebox{90}{\scriptsize mar } &
1211 \rotatebox{90}{\scriptsize abr } &
1212 \rotatebox{90}{\scriptsize mai } &
1213 \rotatebox{90}{\scriptsize jun } &
1214 \rotatebox{90}{\scriptsize jul } &
1215 \rotatebox{90}{\scriptsize ago } &
1216 \rotatebox{90}{\scriptsize set } &
1217 \rotatebox{90}{\scriptsize out } &
1218 \rotatebox{90}{\scriptsize nov } &
1219 \rotatebox{90}{\scriptsize dez } &
1220 \rotatebox{90}{\scriptsize jan } &
1221 \rotatebox{90}{\scriptsize fev } &
1222 \rotatebox{90}{\scriptsize mar } &
1223 \rotatebox{90}{\scriptsize abr } &
1224 \rotatebox{90}{\scriptsize mai } &
1225 \rotatebox{90}{\scriptsize jun } &
1226 \rotatebox{90}{\scriptsize jul } \\ \hline
1228 \quad\ref{t1} & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & & & & & & & & & & & & & \\ \hline
1229 \quad\ref{t2} & & \f & \f & \f & \f & \f & \f & & & & & & & & & & & & & & & & & \\ \hline
1230 \quad\ref{t3} & & & & \f & \f & \f & \f & & & & & & & & & & & & & & & & & \\ \hline
1231 \quad\ref{t4} & & & & \f & \f & \f & \f & & & & & & & & & & & & & & & & & \\ \hline
1232 \quad\ref{t5} & & & & & & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & & & & & & & \\ \hline
1233 \quad\ref{t6} & & & & & & & & & & & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & & \\ \hline
1234 \quad\ref{t7} & & & & & & & & & & & & & & & & & \f & \f & \f & \f & \f & \f & & \\ \hline
1235 \quad\ref{t8} & & & & & & & & & & & & & & & \f & \f & \f & \f & \f & \f & \f & \f & \f & \\ \hline
1236 \quad\ref{t9} & & & & & & & & & & & & & & & & & & & & & & & \f & \f \\ \hline
1237 \quad\ref{t10} & & & & & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f & \f \\ \hline
1238 \end{tabular}
1239 \caption{Cronograma do projeto}
1240 \label{projtimetable}
1241 \end{center}
1242 \end{table}
1245 \begin{small}
1246 \phantomsection
1247 \addcontentsline{toc}{section}{\bibname}
1248 \bibliographystyle{plain}
1249 \bibliography{mscMonografia,bibliography}
1250 \end{small}
1252 \end{document}