Post on 17-Apr-2015
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