Upload
internet
View
108
Download
2
Embed Size (px)
Citation preview
Towards Specification, Modelling and Analysis of Fault Tolerance in Self Managed
Systems
Jeff MageeImperial College London, London, UK
Tom MaibaumMcMaster University, Hamilton, Ontario, Canada
Vinicius Petrucci, IC/UFFjulho, 2006
Introdução
• Modelagem e análise de mecanismos de tolerância a falhas em sistemas auto-gerenciáveis e auto-curáveis
• Especificação baseada em componentes, com mecanismos de coordenação
– Construção de sistemas a partir dos componentes
• MAL (Modal Action Logic) + Operadores Deônticos
– Formalismo para especificar comportamentos normais e anormais
Introdução
• Mecanismos de tolerância a falhas podem ser especificados em termos de:– Tipo de anormalidade encontrada– Caminho de recuperação desejado
• Modelos de programação abstratos– Especificações usando LTSA (ferramenta de
modelagem baseada em álgebra de processo e máquina estados finitos)
– Podem ser sistematicamente construídos a partir de um modelo de mais alto nível
• LTSA => permite verificação de propriedades em modelos (model checking)
Introdução
• Auto-gerenciamento (self management)– Capacidade do sistema/aplicação se
recuperar de um comportamento anormal de forma autônoma, sem a intervenção externa
• Analogia a sistemas tolerantes a falhas– Reconhecer a ocorrência de situações
anômalas (de certas categorias)– Prescrições para recuperação (parcial)
dessas situações
Introdução
• Modelar tolerância a falhas, analisar tais modelos e implementar os modelos (via algoritmos de recuperação)– Ingredientes importantes para o entendimento
de sistemas do tipo auto-gerenciáveis (self management) e auto-curáveis (self healing)
Modelagem
• Elementos chaves para especificação– Comportamento de componentes– Mecanismo de interação entre componentes
(conectores e coordenação)– Configuração dos sistemas a partir de
componentes e conectores– Caracterização de comportamento e estados
considerados anormais
Método de Engenharia
• Passos principais:1. Criar especificação baseada em arquitetura de
software do sistema, baseada em requisitos bem definidos, incluindo mecanismos apropriados de tolerância a falhas (e auto-gerenciamento). Analisar a especificação.
2. Criar modelo LTSA da especificação (ou partes cruciais) como projeto intermediário. Analisar propriedades demonstrando que o modelo está de acordo com a especificação
3. Usar transformações para gerar programas a partir do modelo em alto nível. Analisar se o programa está de acordo com o modelo.
Método de Engenharia
• Muito trabalho ainda a ser feito para tornar essas idéias apropriadas
• Esse método se aplica para todo sistema onde é preciso distinguir entre comportamento normal e anormal
• Uma forma de caracterizar e analisar os mecanismos propostos, junto de possível padronização de implementação, via passos de modelagem e codificação
• Abordagem formal possui limitações práticas – Model checkers, como o LTSA– Provadores de teoremas
Modelo LTSA• Concepção: processos – unidades de execução
sequencial.
• Modelos:
• finite state processes (FSP) => para modelar os
processos como sequências de ações (forma
algébrica).
• labelled transition systems (LTS) => analisar,
visualizar e simular comportamentos (forma
gráfica).
• Prática: Threads Java
Modelo LTSA
• Modelo FSP de um sinal de trânsito:
TRAFFICLIGHT = (red->orange->green->orange -> TRAFFICLIGHT).
• LTS gerado usando a ferramenta LTSA:red orange green
orange
0 1 2 3
Trace:redorangegreenorangeredorangegreen …
Composição paralela
(0,0)
(0,1)
(0,2)
(1,2)
(1,1)
(1,0)
from CONVERSEfrom ITCH
2 states3 states
2 x 3 states
ITCH
scratch
0 1
CONVERSEthink talk
0 1 2
CONVERSE_ITCH
scratch
think
scratch
talk scratch
talk think
0 1 2 3 4 5
Interação - sincronização
MAKE_A = (makeA->ready->used->MAKE_A).MAKE_B = (makeB->ready->used->MAKE_B).ASSEMBLE = (ready->assemble->used->ASSEMBLE).
||FACTORY = (MAKE_A || MAKE_B || ASSEMBLE).
makeA
makeB makeA ready assemble
used
makeB
0 1 2 3 4 5
CLIENT call request SERVERcall
replywait reply servicecontinue
CLIENT = (call->wait->continue->CLIENT).SERVER = (request->service->reply->SERVER).||CLIENT_SERVER = (CLIENT || SERVER)
/{call/request, reply/wait}.
CLIENT_SERVERcall service reply
continue
0 1 2 3
CLIENTcall reply
continue
0 1 2
SERVERcall service
reply
0 1 2
Exemplo
• O servidor principal faz copia de qualquer alteração feita pelo cliente em seu estado interno para o servidor secundário, antes de permitir ser executada qualquer outra operação
• Possível falha do servidor principal é dada por uma operação chamada failover– Tem o efeito de trocar os papeis dos servidores
principal e secundário– Problema: se failover ocorrer depois de um write
pelo principal e antes de um put no secundário
Exemplo
Exemplo
• Abordagem usando MAL– Componente descrito em termos de memória
local (atributos) e operações locais (ações)– Axiomas descrevem propriedades dos
atributos e ações, assim como o efeito de ações sobre os atributos
component ClientAttributes
c_val:int, c_master:{a,b},ready_to_write:bool, error:bool
Actionsc_init, c_write(int,c_master),c_read(int,c_master), switch, abort
Axioms1. [c_init](c_master=a ^ val=0 ^ ready_to_write ^ ¬error)2. (ready_to_write ^ c_master=m ^ ¬error) →
[write(val,m)]¬ready_to_write3. (¬ready_to_write ^ c_master=m ^ ¬error ^ val=x) → [read(y,m)]((x≠y
→ error) ^ (x=y → (ready_to_write ^ val=x+1))) 4. c_master=a → [switch]c_master=b5. c_master=b → [switch]c_master=a6. ¬ready_to_write → [switch](¬normal ^ Obl(abort))7. ¬normal → [abort](ready_to_write ^ normal)
Exemplo
• ready_to_write: marca o fato de que um write ocorreu e um read agora precisa acontecer
• error: marca que um valor que foi lido não foi o último que foi escrito
component {a,b}.Server Attributes
{a,b}.val:int, {a,b}.master:bool, {a,b}.updating:bool
Actions{a,b}.init, {a,b}.write(int), {a,b}.read(int), {a,b}.put(int), {a,b}.get(int), {a,b}.failover
Axioms1. [a.init](a.master ^ ¬a.updating) (and for b.Server:
[b.init](¬b.master ^ ¬b.updating) 2. (a.master ^ ¬a.updating) → [a.write(val)](a.val=x ^ a.updating) 3. (a.master ^ a.updating) → [a.put(val)]¬a.updating 4. a.master → [a.failover]¬a.master 5. ¬a.master → [a.get(x)]a.val=x 6. (For b.Server, we have axioms 2-5 with ‘a’ replaced by ‘b’.)
Exemplo
• updating: se está no meio de uma transação “write-put” (write no servidor principal e put no secundário)
Coordenação
• Mecanismo de coordenação entre os componentes– Ações sincronizadas, como num envio de
mensagens sincronizadas onde um envio feito por um componente é sincronizado com um recebimento em um outro
• Exemplo: ação switch do Cliente é sincronizada com a.failover em a.Server e com b.failover em b.Server
Coordenação
• Ações c_write(x,a) e c_read(x,a) do Cliente são sincronizadas com a.write(x) e a.read(x), respectivamente, em a.Server. – Analogamente para b.Server
• Servidores sincronizam a.put com b.get e vice-versa
Algumas Propriedades
• Se tudo ocorre bem, então normal é sempre verdade em Cliente e não temos um estado de erro (error).
(□ normal) → (□ ¬error)• Se estamos num estado anormal, e nada mais
de ruim acontece, em algum momento do futuro voltamos ao estado normal
¬normal ^ no_further_violation → ◊normal
Modelo LTSA
• LTSA (Labelled Transition System Analyzer)– Ferramenta de modelagem e verificação de
sistemas representados por sistemas de transição
– Sistema é modelado como um conjunto de processos descritos em FSP (Finite State Process), notação de álgebra de processo
– Permite análise através de propriedades especificadas em lógica temporal linear fluente (FLTL)
Modelo LTSAconst False = 0const True = 1range Bool = False..Truerange Int = 0..2SERVER(M=0) = SERVER[M][0][0],SERVER[master:Bool][val:Int][updating:Bool]= ( when (master)
write[v:Int]-> SERVER[master][v][True]| when (master && updating)
put[val]-> SERVER[master][val][False]| when (master && !updating)
read[val]-> SERVER[master][val][updating]| when (!master)
get[u:Int]-> SERVER[master][u][updating]| failover -> SERVER[!master][val][False]
).
Modelo LTSA
CLIENT = ({a,b}.write[v:Int] -> ({a,b}.read[u:Int] ->
if (u != v) then ERROR else CLIENT| abort->ClIENT )).
||SYS = (a:Server(True)
|| b:Server(False)
|| CLIENT
) /{ a.put/b.get, b.put/a.get, failover/{a,b}.failover}.
Verificações
• Ação failover causa uma troca atômica do servidor principal para secundário, causando uma violação de consistência no Cliente
Trace to property violation in CLIENT:
a.write.1
failover
b.read.0
Analysed in: 0ms
Verificações
• Ação failover causa uma troca atômica do servidor principal para secundário, causando uma violação de consistência no Cliente
Trace to property violation in CLIENT:
a.write.1
failover
b.read.0
Analysed in: 0ms
• Como a troca é atômica, o estado como visto pelo cliente não é. Nesse caso, o cliente pode ler o estado do novo servidor principal antes de uma atualização ocorrer
Verificações
• Caracterizando a situação anterior em FLTL
fluent UPDATING =
<{a,b}.write[Int], {{a,b}.put[Int], abort}>
assert BAD = (UPDATING && failover) • UPDATING é verdade entre o ponto que uma ação write
ocorreu mudando o estado do servidor principal e uma ação de put que registra a mudança no secundário– Se é verdade, então o sistema está num estado ¬normal
Verificações
• Proibir o sistema de entrar nesse estado, adicionando a seguinte restriçãoconstraint NO_BAD = []! BAD
||CON_SYS = (SYS || NO_BAD). – O LTSA então gera um autômato para essa
restrição
Verificações
• Uma alternativa é deixar o sistema entrar num estado “ruim” e então realizar alguma ação compensatória antes de o cliente colocar o sistema diretamente em um estado irrecuperável ERROR. constraint REC_BAD = [ ] (BAD -> X abort)
|| REC_SYS = (SYS || REC_BAD). – Se chegarmos ao estado BAD, então devemos imediatamente
(próxima ação) abortar.– O operador Next (X) é usado para expressar a idéia de que uma
ação de “abort” deve ser realizada antes de qualquer coisa
Conclusão
• Abordagem para modelagem e análise de mecanismos de tolerância a falhas (e auto-gerenciamento) em sistemas multicomponentes e distribuídos
• Formalismo de lógica modal de ação + operadores deônticos– Para descrever comportamentos normais e anormais
• Prover um modo sistemático de tornar essas especificações em (aproximados) modelos de programação abstratos