U NIVERSIDADE DE L ISBOA
Faculdade de Ciências
Departamento de Informática
SUBSTRATO DE ARMAZENAMENTO PARA
SISTEMAS DE FICHEIROS SEGUROS PARA
CLOUDS-OF-CLOUDS
Tiago Moreno Oliveira
DISSERTAÇÃO
MESTRADO EM ENGENHARIA INFORMÁTICA
Especialização em Arquitectura, Sistemas e Redes de Computadores
2012
U NIVERSIDADE DE L ISBOA
Faculdade de Ciências
Departamento de Informática
SUBSTRATO DE ARMAZENAMENTO PARA
SISTEMAS DE FICHEIROS SEGUROS PARA
CLOUDS-OF-CLOUDS
Tiago Moreno Oliveira
DISSERTAÇÃO
Dissertação orientada pelo Prof. Doutor Alysson Neves Bessani
e co-orientada pelo Prof. Doutor Marcelo Pasin
MESTRADO EM ENGENHARIA INFORMÁTICA
Especialização em Arquitectura, Sistemas e Redes de Computadores
2012
Agradecimentos
Em primeiro lugar quero agradecer a toda a minha famı́lia. Em especial aos meus pais
por toda a educação, dedicação, valores e amor que me deram durante toda a minha vida.
Sem o vosso apoio não tinha chegado onde cheguei. São os melhores pais do mundo.
Aos meus maninhos mais novos, que eu sei que me adoram. Dava tudo por eles e sei que
eles davam tudo por mim. Tenho muito orgulho em vocês. Ao meu tio Luı́s, um muito
obrigado pelas palavras e apoio que sempre me deste. À minha avó Quim, por todas as
orações que eu sei que ela rezou e reza por mim. Quero também agradecer a duas pessoas
muito especiais que nunca deixaram e nunca deixarão de estar presentes na minha vida, à
minha avó Ana e ao meu tio Dimas. Obrigado famı́lia.
Em segundo lugar quero agradecer à minha namorada, Patrı́cia. A sua compreensão,
motivação, amor e amizade foram muito importantes para mim. Em todos os momentos,
bons ou menos bons, tu sempre me deste coragem. Obrigado por estares sempre presente
e por seres quem és.
Quero também deixar uma palavra de agradecimento a todos os meus amigos. Em
especial a todos os meus companheiros de casa, com quem eu partilhei momentos de
risada total, o Zabibu, o Fernandinho, o Veiga, e em especial o Tozé. Ao pessoal de
Ficalho, que quando nos encontramos é para a desgraça, o Rato, o Manel, a Filipa, o Zé
Gato, o Mikel, a Inês, o Varela, o Alacrau ,o Zé Francisco e a Mónica. Ao pessoal que me
acompanhou na minha vida académica, o Ricardo, o Guns, o Marcos, o Jonny, o Reis, o
Diogo, o Teixeira, o Gordo, o Panka, e o Chico. Com eles passei os momentos mais duros
e mais alucinantes que a faculdade nos proporcionou. Um obrigado especial ao Ricardo,
que foi a pessoa com quem mais horas passei nestes últimos 5 anos, por toda a ajuda e
companheirismo. Sei que posso contar com todos vocês para qualquer coisa. Obrigado
por toda a força e amizade.
Deixo também um obrigado muito especial para o meu orientador, Professor Alysson
Bessani, e co-orientador, Professor Marcelo Pasin, pela orientação e ajuda que me deram
neste projecto. O “à vontade” com que me deixaram, a forma aberta como trocámos
ideias, e todo o bom ambiente que me foi concedido foram fundamentais para o meu
empenho, motivação e boa disposição. Com vocês aprendi muito. Muito obrigado.
Um sincero obrigado a todos aqueles que influenciaram, de uma forma ou de outra, o
meu crescimento como pessoa e como profissional.
iii
Às boas memórias.
Resumo
O armazenamento de dados em provedores de clouds tem vindo a tornar-se bastante
comum entre empresas, programadores e utilizadores. Porém existem ainda algumas dificuldades de acessos aos mesmos. Estas dificuldades têm vindo a ser mitigadas pelo uso
de sistemas de ficheiros que armazenam os dados, de uma forma transparente, nas clouds.
Contudo, nestes sistemas, a disponibilidade dos dados é comprometida, pois estes dependem da disponibilidade do provedor de armazenamento em uso. O DepSky é um serviço
de armazenamento tolerante a faltas bizantinas que melhorar a disponibilidade dos dados armazenados nas clouds através da replicação dos dados por um conjunto destas, ao
mesmo tempo que garante a integridade e confidencialidade dos mesmos. Ao conceito de
armazenar os dados em várias clouds foi dado o nome cloud-of-clouds.
Assim nasce o C2FS, um sistema de ficheiros seguro e fiável para cloud-of-clouds,
que vem cobrir estas limitações pois, ao mesmo tempo que fornece uma interface do estilo
POSIX, armazena os dados em múltiplas clouds através do DepSky. Este projecto apresenta o serviço de armazenamento construı́do para o C2FS que visa melhorar a utilização
do Depsky através do uso intensivo de dois nı́veis de cache, o de memória e o de disco.
Este serviço suporta também dois modelos de envio de dados para as clouds, podendo este
ser sı́ncrono ou assı́ncrono. O nı́vel de consistência fornecido pelo C2FS é influenciado
pelo cliente aquando da configuração do nı́vel de cache e do modelo de envio de dados.
Neste projecto é também apresentada uma avaliação experimental que mostra o desempenho do serviço de armazenamento de dados com diferentes configurações. Os resultados obtidos mostram que, ao mesmo tempo que as diversas limitações mencionadas
são ultrapassadas, é fornecido um desempenho muito satisfatório.
Palavras-chave: sistemas de ficheiros, armazenamento em clouds, computação em
clouds, tolerância a faltas, cache
vii
Abstract
Storing data in the cloud is becoming quite common today. However, there are still
some difficulties related with how to access and manage this data. These difficulties are
been mitigated by the use of cloud-backed file systems that store data, in a transparent
manner, in the cloud. Nevertheless, with these systems, data availability is directly tied
with the availability of the storage provider being used. Recently, the problem of cloud
unavailability was addressed through the use multiple cloud providers (cloud-of-clouds).
DepSky is a Byzantine fault-tolerant storage service, which has improved the availability
of data stored in clouds through replication of data by a set of clouds, while ensuring the
integrity and confidentiality.
The project described in this thesis contributes to C2FS, a secure and dependable
cloud-backed file system that addresses the mentioned limitations by providing a familiar
file system interface and, at the same time, storing the data in cloud-of-clouds using DepSky. More specifically, it presents the C2FS storage service that aims improve the use os
DepSky through intensive use of two cache levels: memory and disk. This service also
supports two cloud data transfer models, which can be synchronous or asynchronous. The
level of consistency provided by this service is controlled by the level of cache and data
sending model parameters, as configured by the user.
This thesis also presents an experimental evaluation that shows the performance of the
storage service with different settings. The results show that, while the various mentioned
limitations are overcomed, the system provides a very satisfactory performance.
Keywords: file systems, cloud storage, clouds computing, Byzantine fault tolerance,
cache
ix
Conteúdo
Lista de Figuras
xiii
Lista de Tabelas
xv
1
2
Introdução
1.1 Motivação . . . . . . .
1.2 Objectivos . . . . . . .
1.3 Contribuições . . . . .
1.4 Publicações . . . . . .
1.5 Planeamento . . . . . .
1.6 Estrutura do documento
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Trabalho relacionado
2.1 Serviços de Armazenamento . . .
2.1.1 Petal . . . . . . . . . . .
2.1.2 OceanStore . . . . . . . .
2.1.3 Ursa Minor . . . . . . . .
2.1.4 DepSky . . . . . . . . . .
2.1.5 Considerações Finais . . .
2.2 Sistemas de Ficheiros Distribuı́dos
2.2.1 Andrew File System . . .
2.2.2 Ceph . . . . . . . . . . .
2.2.3 CODA . . . . . . . . . .
2.2.4 Frangipani . . . . . . . .
2.2.5 Considerações Finais . . .
2.3 Sistemas de Ficheiros para Clouds
2.3.1 S3FS . . . . . . . . . . .
2.3.2 S3QL . . . . . . . . . . .
2.3.3 BlueSky . . . . . . . . . .
2.3.4 Frugal cloud File System .
2.3.5 Cumulus . . . . . . . . .
xi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
3
3
4
4
5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
7
7
8
9
10
12
12
12
14
15
17
18
18
19
20
20
21
22
2.4
3
4
5
6
2.3.6 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . .
Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Armazenamento de Dados do C2FS
3.1 C2FS . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Arquitectura . . . . . . . . . . . . . . . .
3.1.2 Modelo do Sistema . . . . . . . . . . . . .
3.2 FUSE . . . . . . . . . . . . . . . . . . . . . . . .
3.3 DepSky . . . . . . . . . . . . . . . . . . . . . . .
3.4 Serviço de Armazenamento . . . . . . . . . . . . .
3.4.1 Visão Geral da Gestão do Armazenamento
3.4.2 Algoritmos de Gestão de Armazenamento .
3.4.3 Modelo de Envio de Dados . . . . . . . . .
3.4.4 Durabilidade dos Dados . . . . . . . . . .
3.4.5 Colector de Lixo . . . . . . . . . . . . . .
3.5 Considerações Finais . . . . . . . . . . . . . . . .
23
23
.
.
.
.
.
.
.
.
.
.
.
.
25
25
25
26
27
28
31
32
34
43
44
45
47
.
.
.
.
49
49
50
55
57
.
.
.
.
.
59
59
60
61
63
65
Conclusão
6.1 Trabalho Futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67
67
Concretização do Serviço de Armazenamento
4.1 Diagrama de Classes . . . . . . . . . . .
4.2 Diagramas de Sequência . . . . . . . . .
4.3 Agente C2FS . . . . . . . . . . . . . . .
4.4 Considerações Finais . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Avaliação
5.1 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Latência das Escritas e Leituras de Dados . . . . . . . . . . . . . .
5.3 Desempenho do Serviço de Armazenamento do C2FS . . . . . . . .
5.4 Comparação do C2FS com outros Sistemas de Ficheiros para Cloud
5.5 Considerações Finais . . . . . . . . . . . . . . . . . . . . . . . . .
Bibliografia
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
72
xii
Lista de Figuras
2.1
2.2
2.3
2.4
2.5
2.6
2.7
Arquitectura do Petal [29]. . . . . . . . . . . . . .
Arquitectura do Ursa Minor [18]. . . . . . . . . . .
Arquitectura do DepSky [19]. . . . . . . . . . . . .
Arquitectura do Andrew File System. . . . . . . .
Arquitectura do Ceph [47]. . . . . . . . . . . . . .
Arquitectura do Frangipani [43]. . . . . . . . . . .
Arquitectura de Sistemas de Ficheiros para clouds.
.
.
.
.
.
.
.
8
10
11
13
14
17
19
3.1
3.2
3.3
3.4
Arquitectura do C2FS. . . . . . . . . . . . . . . . . . . . . . . . . . . .
Caminho percorrido por cada chamada ao sistema. . . . . . . . . . . . .
Fluxo dos dados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Desencadeamento das chamadas ao sistema no serviço de armazenamento.
26
28
33
43
4.1
4.2
4.3
4.4
Modelo de classes do sistema. . .
Operação de leitura das clouds. . .
Operação de escrita em cache. . .
Operação de escrita para as clouds.
.
.
.
.
51
54
55
56
5.1
5.2
Latência das escritas e leituras (em segundos) para a cloud-of-clouds . . .
Tempo de execução (em segundos) do IOzone e PostMark para escritas
sı́ncronas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tempo de execução (em segundos) do IOzone e PostMark para escritas
assı́ncronas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Latência e throughput das operações de escrita e leitura não sequenciais.
Valores medidos através da execução do workload randomrw do Filebench
61
5.3
5.4
.
.
.
.
xiii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
62
62
63
Lista de Tabelas
3.1
3.2
Operações FUSE-J. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Durabilidade dos dados. . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
44
4.1
Linhas de código das classes do serviço de armazenamento . . . . . . . .
52
5.1
5.2
Comparação dos tempos de execução (em segundos) com o S3FS. . . . .
Comparação dos tempos de execução (em segundos) com o S3QL. . . . .
64
65
xv
Capı́tulo 1
Introdução
Nos dias de hoje, os utilizadores normais de computadores e internet, os programadores
ou até mesmo empresas têm vindo a fazer cada vez mais uso dos diversos provedores
de armazenamento baseados nas clouds (cloud storage), para armazenar os seus dados.
A crescente popularização destes serviços deve-se à necessidade e/ou vontade que os
utilizadores têm em exteriorizar os seus dados tanto para fins de backup e facilidade de
acesso aos mesmos, como para a partilha de ficheiros. Alguns exemplos destes serviços
são o iCloud [5], a Amazon S3 [4] e o Google Storage [9].
Com este aumento de utilização das clouds para armazenar dados, nasce a necessidade
de estudar as abstracções necessárias para que os programadores possam fazer as suas
aplicações acederem às clouds. O modelo mais utilizado hoje em dia para tal finalidade
é a disponibilização de web services por parte das clouds que podem ser acedidos via
REST, SOAP ou XML-RPC. Este modelo não é nada mais que uma instância do modelo
clássico de chamada remota a procedimentos (RPC) que, apesar de ser muito bom para a
troca directa de mensagens, é muito mais orientado para controlo que para os dados.
Um modelo de acesso bem mais atraente aos olhos dos utilizadores é a gestão de
ficheiros na cloud através de um sistema de ficheiros. Esta abstracção fornece aos utilizadores uma forma muito mais simples e familiar para a gestão de dados nos provedores
de armazenamento. Esta ideia já tem sido suportada por alguns sistemas de ficheiros que
armazenam os dados em clouds como o S3FS [16] e o BlueSky[45]. Porém, todos estes
sistemas mostram algumas limitações devido ao facto de armazenarem os dados num só
provedor de armazenamento, dependendo assim da disponibilidade, da polı́tica de acesso
e dos custos oferecidos por este.
A equipa de investigação Navigators têm estado a trabalhar num projecto financiado
pela Comissão Europeia chamado TClouds [14] que tem como principal objectivo eliminar essas limitações. Este objectivo é alcançado através do uso de vários provedores em
nuvem ao invés de um só. Este colectivo de clouds é denominado de cloud-of-clouds.
Neste contexto, nasce a ideia de concretizar um sistema de ficheiros que, ao mesmo
tempo que fornece uma semântica bem conhecida aos utilizadores, semântica essa sim1
Capı́tulo 1. Introdução
2
ilar à definida pelo padrão POSIX (concretizado pelos sistemas Unix) [13], elimina as
limitações que os sistemas existentes apresentam. Um dos principais objectivos é tornar
a gestão de dados na cloud-of-clouds tão simples quanto a gestão de dados num sistema
de ficheiros local. A este sistema de ficheiros foi dado o nome de C2FS (Cloud-of-Clouds
File System).
Com esta finalidade, surge este Projecto de Engenharia Informática (PEI) que se foca
assim no desenho do substracto de armazenamento para este sistema de ficheiros e tem
como objectivos fundamentais a construção da abstracção de discos virtuais onde os blocos de dados serão armazenados e a sua integração numa interface de sistema de ficheiros
do estilo POSIX.
1.1
Motivação
Como já mencionado, existem alguns sistemas de ficheiros exploraram a ideia de armazenar os seus dados em serviços de armazenamento como as clouds. O uso destes
serviços para armazenar dados apresenta algumas vantagens como a facilidade de acesso
que os utilizadores têm para aceder aos dados, o seu baixo custo e o seu modelo de pagamento conforme o uso, que não necessita investimento inicial. Contudo, o uso de uma
só cloud por estes sistemas de ficheiros para o armazenamento dos dados acarreta algumas desvantagens que podem ser bastante problemáticas em condições adversas. A
primeira desvantagem prende-se no facto da disponibilidade dos dados ser directamente
afectada pela disponibilidade do provedor utilizado, isto é, se o provedor sofrer qualquer
tipo de problema ou se a ligação até ele mostrar alguma deficiência os dados tornam-se
inacessı́veis. Outra desvantagem prende-se com o acesso não controlado do provedor
aos dados por ele armazenados, o que levanta algumas preocupações quando se quer armazenar informação crı́tica. Outro possı́vel perigo está relacionado com o facto de o
provedor poder corromper os dados devido a faltas (maliciosas ou não) na sua infraestrutura. A última limitação a apontar diz respeito ao possı́vel aumento do preço por parte do
provedor de armazenamento, que pode impedir os utilizadores de remover de lá os seus
dados. Este acontecimento é conhecido por vendor lock-in [23].
Recentemente, foi provado pelo serviço de armazenamento DepSky [19] que estas
limitações podem ser ultrapassadas se aliarmos o uso de provedores independentes a
técnicas de tolerância a faltas e a criptografia. Este sistema armazena os blocos de dados
numa cloud-of-clouds para que estes se mantenham confidenciais e disponı́veis mesmo
que uma fracção dos provedores sejam faltosos, tolerando assim faltas bizantinas (isto é,
quando apresentam um comportamento arbitrário fora da sua especificação). Contudo,
a interface disponibilizada pelo DepSky é de baixo nı́vel pois assemelha-se a um disco
virtual onde os blocos de dados são armazenados. O uso deste tipo de interface é bastante
complicado para programadores que têm intenção de construir aplicações que armazenam
Capı́tulo 1. Introdução
3
os dados nas clouds, e ainda mais complicado para utilizadores que apenas desejam armazenar os seus ficheiros na cloud-of-clouds e que não têm nenhum conhecimento e
experiência sobre como usar este tipo de interface.
Como referido na secção anterior, uma abstracção muito mais familiar aos utilizadores
e/ou programadores são os sistemas de ficheiros. Constitui assim um desafio interessante
implementar um sistema de ficheiros que armazene os seus dados numa cloud-of-clouds
através do DepSky. A concretização deste sistema de ficheiros consegue assim unir todas
as garantias fornecidas pelo DepSky a uma interface bem conhecida.
1.2
Objectivos
Para a construção do C2FS é necessário a integração de uma série de serviços distintos: o DepSpace, o DepSky e o FUSE. O DepSpace [20] é um sistema de coordenação
tolerantes a faltas bizantinas. A utilização deste serviço no C2FS tem como principais objectivos fornecer o serviço de directorias para a gestão dos metadados e o serviço de locks
para coordenar escritas concorrentes sobre o mesmo ficheiro. O desenvolvimento destes
dois serviços e a sua integração no C2FS foi efectuado em outro Projecto de Engenharia
Informática [32]. Este PEI foca-se no uso do FUSE [7] e do DepSky para contrução de
um serviço de armazenamento para o C2FS. Assim, os objectivos especı́ficos deste PEI
são:
• Estudar os serviços de armazenamento e sistemas de ficheiros existentes, principalmente os que armazenam dados nas clouds.
• Estudar e implementar uma interface de sistemas de ficheiros.
• Estudar e modificar a implementação do DepSky de modo a este responder o melhor
possı́vel às necessidades do C2FS.
• Concretizar um serviço de armazenamento cliente do DepSky e integrá-lo na interface de sistemas de ficheiros disponibilizada pelo FUSE.
• Avaliar este serviço para mostrar que ao mesmo tempo que fornece mais garantias,
tem um desempenho similar aos dos sistemas existentes que armazenam dados nas
clouds.
1.3
Contribuições
Este projecto contribuiu com alguns pontos essenciais para o desenho do C2FS. Uma
das contribuições foi a disponibilização da interface de sistemas de ficheiros para o C2FS
através do módulo FUSE. Este é um serviço que nos permite implementar sistemas de
Capı́tulo 1. Introdução
4
ficheiros a nı́vel do utilizador, não sendo assim necessário quaisquer alterações a nı́vel
do kernel. Outra contribuição foi a introdução de novas técnicas do DepSky. Outra
contribuição importante foi a concretização do serviço de armazenamento de dados que
usa os discos virtuais do DepSky para armazenar os dados na cloud-of-clouds. Este
serviço fornece dois nı́veis diferentes de cache (cache em disco e cache em memória) e
duas formas distintas de enviar os dados para as clouds sendo elas sı́ncrona e assı́ncrona.
Os utilizadores podem escolher qual o nı́vel de cache pretendido e qual a forma de envio a
utilizar de modo a preencher as suas necessidades. Por fim, foi concretizado um colector
de lixo para eliminar todos os dados dispensáveis ainda armazenados na cloud-of-clouds.
1.4
Publicações
O trabalho descrito nesta dissertação foi contribuiu para a publicação de um artigo
cientı́fico no INForum 2012, na track “Computação Paralela, Distribuı́da e de Larga Escala” [33].
1.5
Planeamento
No inı́cio o plano de trabalho para este PEI consistia em:
• Tarefa 1 (Setembro e Outubro 2011): Revisão bibliográfica e estudo das tecnologias
envolvidas (acesso aos provedores de armazenamento em cloud e construção de
sistemas de ficheiro em espaço de utilizador).
• Tarefa 2 (Novembro 2011): Desenho da abstracção de disco virtual e sua integração
no sistema de ficheiros como um todo (tarefa a ser realizada em conjunto com outros
membros do Navigators que estejam a trabalhar no sistema de ficheiro).
• Tarefa 3 (Dezembro 2011): Evolução do DepSky visando robustez e facilidade de
utilização.
• Tarefa 4 (Janeiro e Fevereiro 2012): Concretização de um cliente FUSE para o
disco virtual baseado no DepSky.
• Tarefa 5 (Março 2012): Integração do trabalho realizado com os outros mecanismos do sistema de ficheiro (nomeadamente a coordenação e serviço de nomes e
directorias).
• Tarefa 6 (Abril 2012): Avaliação do sistema através de benchmarks de sistemas de
ficheiros utilizados na indústria.
• Tarefa 7 (Maio 2012): Escrita da tese e, idealmente, de um artigo cientifico para
workshop ou conferência de médio porte.
Capı́tulo 1. Introdução
5
A ordem de trabalho que foi desenvolvida neste projecto seguiu este planeamento até
a tarefa 4. A tarefa 5, 6 e 7 sofreram alguns atrasos devido a optimizações que foram
efectuadas no serviço de armazenamento.
1.6
Estrutura do documento
Esta dissertação está organizada da seguinte forma:
• Capı́tulo 2 - Este capı́tulo apresenta o estudo realizado sobre o trabalho relacionado
com o sistema de ficheiros que se pretendia desenvolver. Aqui são descritas as
caracterı́sticas dos serviços de armazenamento, de alguns sistemas de ficheiros distribuı́dos, e dos sistemas de ficheiros para clouds existentes.
• Capı́tulo 3 - Neste capı́tulo é primeiramente apresentada a arquitectura do C2FS.
Posteriormente é apresentada a interface de sistemas de ficheiros implementada e
são explicadas as modificações mais relevantes efectuadas a nı́vel do Depsky. Por
último é descrito em pormenor o serviço de armazenamento concretizado.
• Capı́tulo 4 - Aqui são apresentados alguns detalhes de concretização do serviço de
armazenamento.
• Capı́tulo 5 - Este capı́tulo apresenta uma avaliação preliminar do C2FS, efectuada
essencialmente sobre as operações de escrita e leitura de dados, focando-nos assim mais no desempenho do serviço de armazenamento concretizado. É também
efectuada uma comparação entre o C2FS e outros dois sistemas de ficheiros para
clouds, sendo eles o S3FS [16] e o S3QL [17].
• Capı́tulo 6 - Este último capı́tulo descreve as conclusões a retirar do trabalho desenvolvido e são introduzidas abordagens a seguir no futuro de forma a aumentar o
desempenho do C2FS.
Capı́tulo 1. Introdução
6
Capı́tulo 2
Trabalho relacionado
Nesta capı́tulo são primeiro apresentados, na secção 2.1, alguns dos serviço de armazenamento representativos. Posteriormente, na secção 2.2, são apresentados alguns sistemas ficheiros distribuı́dos tradicionais que foram concretizados sobre o modelo clienteservidor. Por fim, na secção 2.3, são descritos os sistemas de ficheiros que utilizam clouds
para armazenar os dados.
2.1
Serviços de Armazenamento
Nesta secção são introduzidos alguns serviços de armazenamento estudados. Estes
serviços diferem da abstracção de sistemas de ficheiros por duas principais razões: primeiro
não permitem a criação de directorias e da estrutura em árvore que os sistemas de ficheiros
usualmente têm; em segundo não implementam uma interface de sistemas de ficheiros,
fornecendo só uma pequena lista de operações para a leitura e escrita de dados. Contudo,
alguns dos sistemas de ficheiros existentes utilizam estes tipos de serviços para armazenar
os seus dados.
2.1.1
Petal
Petal [29] é um sistema de armazenamento distribuı́do fácil de gerir, que fornece
aos seus clientes (sistemas de ficheiros e bases de dados) uma total abstracção da sua
visualização fı́sica, mostrando-lhes uma colecção de discos virtuais que podem ser acedidos através de uma interface de chamada remota de procedimentos (RPC). Cada disco
virtual fornece um espaço de 264 bytes para armazenamento, onde cada leitura ou escrita
é feita em blocos de tamanho variável. A sua arquitectura fı́sica baseia-se num conjunto de servidores de armazenamento distribuı́dos que cooperam entre si como mostra a
figura 2.1.
O sistema replica cada bloco de dados por cada par de servidores vizinhos, isto significa, que são mantidas para cada bloco de dados duas réplicas. Assim mesmo que um
servidor falhe, os pedidos que a este são efectuados podem ser respondidos pelo servidor
7
Capı́tulo 2. Trabalho relacionado
8
Figura 2.1: Arquitectura do Petal [29].
vizinho que mantenha a outra réplica. Devido a este mecanismo de replicação, o Petal
faz também balanceamento de carga pelos diferentes servidores. Algoritmos distribuı́dos
asseguram que todos os servidores têm a mesma carga e obtêm informação acerca de
qualquer falha existente no sistema.
Um dos serviços prestado pelo Petal é a possibilidade de efectuar snapshots. Estas
snapshots são imagens consistentes dos discos fı́sicos que permitem aos clientes fazerem
backup do sistema. Para a criação destas snapshots é necessário uma pausa do sistema
por um perı́odo de tempo, o que pode prejudicar a disponibilidade do mesmo. Outra
importante funcionalidade é o facto de os servidores poderem recuperar depois de uma
eventual falha devido a manutenção de um log com os seus blocos de dados.
O sistema permite a adição e remoção de discos fı́sicos com uma simples operação de
reconfiguração.
2.1.2
OceanStore
O OceanStore [28] é uma arquitectura para um sistema de armazenamento persistente
à escala global. Ele consiste num conjunto de servidores altamente conectados espalhados
pelo mundo, a que os clientes se podem conectar (podem estar conectados a mais que um
servidor e estão ligados aos servidores geograficamente mais perto). Este sistema permite
uma adaptação transparente e automática aquando da adição ou remoção de servidores.
Os seus principais objectivos é permitir dados nómadas (dados que podem ser guardados em qualquer lugar a qualquer instante) e construir um sistema que corra sobre servidores não confiáveis suportando faltas bizantinas. Como os dados podem fluir pela internet de um servidor para outro, são necessários algoritmos que encontrem onde os dados
estão guardados a um qualquer instante. Para tal são usados dois algoritmos distintos.
Primeiro é executado uma algoritmo probabilı́stico baseando-se no facto de os dados
poderem estar no servidor vizinho (i.e., mais próximo) da localização do cliente. Este
Capı́tulo 2. Trabalho relacionado
9
algoritmo é bastante rápido, mas só se os dados estiverem na vizinhança do cliente. Caso
este falhe, é executado um algoritmo global que é mais lento, mas mais confiável. Este
localiza os dados que não podem ser encontrados localmente através de uma estrutura de
dados hierárquica de larga escala ao estilo ds difinida por Plaxton et al [35].
Cada objecto do sistema é identificado por um identificador único que é um resumo
criptográfico (criado com a técnica SHA-1) gerado sobre a chave privada do cliente juntamente com informação introduzida por este. Para fornecer disponibilidade, os objectos
são replicados e guardados em múltiplos servidores geograficamente distribuı́dos. Existem duas camadas de réplicas para fazer actualizações (mudança nos dados guardados)
sem ocorrer conflitos: a primária e a secundária. A camada primária decide se uma
actualização pode ser efectuada ou deve ser abortada através do protocolo de acordo
bizantino [21]. Quando a camada primária toma uma decisão, faz multicast do resultado
para as réplicas da camada secundária para estas procederem à actualização. Os objectos são representados em duas formas: activa e arquivada. Todas as actualizações são
efectuadas sobre objectos na forma activa enquanto que objectos arquivados representam
uma versão permanente só de leitura. Os objectos são armazenados utilizando códigos de
apagamento. Para assegurar a integridade de cada fragmento produzido pelos códigos de
apagamento aquando da sua recuperação é utilizado um método de resumo criptográfico
hierárquico para verificá-los.
2.1.3
Ursa Minor
Ursa Minor [18] é um sistema de armazenamento versátil baseado em clusters que
fornece aos seus clientes a oportunidade de escolher o modo de armazenamento (códigos
de apagamento ou replicação), o tamanho dos blocos, a localização dos dados, o modelo
de falha dos servidores de armazenamento (paragem ou bizantino), número de falhas a
tolerar e o modelo de tempo (assı́ncrono ou sı́ncrono). Este sistema permite também a
reconfiguração de alguns destes parâmetros (e.g., modelo de tempo e tamanho dos blocos) para dados on-line. Parâmetros como o modelo de tempo e modelo de falha para os
clientes e servidores compromete a performance, a disponibilidade e fiabilidade dos dados. Este sistema assume armazenamento baseado em objectos. O armazenamento destes
objectos é feito seguindo o padrão de OSDs (object store devices) [24]. Cada objecto
no Ursa Minor, além de ter os dados associados, guarda também informação acerca do
tamanho dos blocos, ACLs e outros parâmetros.
A figura 2.2 mostra a arquitectura do sistema. Os clientes para acederem aos objectos
armazenado nos servidores de armazenamento acedem primeiro ao Object manager para
obterem os metadados, isto é, a localização do objecto e a autorização para acede-lo.
Como mencionado, existem duas formas de armazenar os dados nos nós de armazenamento: com replicação ou usando códigos de apagamento. O uso de códigos de apagamento melhora a performance do sistema. Para tal é utilizado um esquema de códigos
Capı́tulo 2. Trabalho relacionado
10
Figura 2.2: Arquitectura do Ursa Minor [18].
de apagamento [34] em que primeiro, o bloco de dados é dividido em m fragmentos
(stripe-fragments), e em segundo, estes fragmentos são utilizados para criar c (c é igual n
menos m, em que n é número de servidores para replicar os objecto) fragmentos codificados (code-fragments) que fornecem a redundância necessária. Quaisquer m fragmentos
podem reconstruir o bloco de dados original. Note-se que se m for igual a 1 é usado
replicação. Para assegurar a integridade dos dados armazenados nos nós de armazenamento é computado um resumo criptográfico para cada fragmento seguindo o conceito de
checksums cruzados [38] onde cada checksum cruzado é concatenado a cada fragmento.
Aquando de uma operação de escrita, antes do envio dos dados para cada nó de armazenamento, cada fragmento é marcado com um timestamp único. Assim, na operação
de leitura, os clientes têm que obter os blocos de dados dos servidores de armazenamento
com o mesmo timestamp para obter os fragmentos do mesmo bloco de dados. É mantido
um colector de lixo pois cada escrita cria uma versão nova dos fragmentos.
Os nós de armazenamento usam uma cache write-back para evitar acessos ao disco
aumentando assim a performance. Esta cache só mantêm fragmentos com o último timestamp.
2.1.4
DepSky
O DepSky [19] é um serviço de armazenamento fiável e seguro que armazena os
dados em múltiplas cloud formando assim uma cloud-of-clouds. Este conceito é introduzido na imagem 2.3 onde são utilizadas quatro diferentes clouds. Este serviço fornece
alta disponibilidade, integridade e confidencialidade dos dados armazenados replicandoos, codificando-os e encriptando-os. Existem dois protocolos disponı́veis para usar este
sistema: DepSky-A e DepSky-CA. DepSky-A fornece disponibilidade e integridade dos
dados enquanto que o DepSky-CA assegura estas duas garantias acrescentado a confiden-
Capı́tulo 2. Trabalho relacionado
11
cialidade dos mesmos.
Figura 2.3: Arquitectura do DepSky [19].
Para suportar falhas bizantinas o DepSky utiliza um protocolo de quóruns (são necessários
3f + 1 servidores para suportar f falhas), efectuando cada operação (escrita ou leitura)
em n − f clouds, onde n é o número total de clouds utilizadas. O DepSky implementa um
registo onde são permitidos a cada instante um escritor e múltiplos leitores, pois os nós
de armazenamento são incapazes de executar código que elimine conflitos entre escritas
concorrentes.
Os programadores acedem aos seus dados através de uma interface de armazenamento
de objectos. Cada operação (e.g., leitura e escrita) é efectuada usando um objecto denominado data unit. Basicamente, cada data unit corresponde a um contentor em cada cloud.
Cada contentor armazena todas as versões dos dados, pois cada operação de escrita cria
uma nova versão. É também mantido em cada contentor um ficheiro de metadados que
contém o número da versão mais actual armazenada e um resumo criptográfico para assegurar a integridade desta versão. Numa operação de escrita são primeiro escritos os
dados e só depois os metadados. Esta sequência assegura que só irão ser lidos metadados
de dados previamente armazenados no sistema. As versões antigas dos dados podem ser
eliminados utilizando um protocolo para colectar lixo. Este modelo de dados abstrai para
os cliente a heterogeneidade de armazenar dados em diferentes clouds.
Como foi mencionado acima, o DepSky fornece dois protocolos para a manutenção
dos dados na cloud-of-clouds. O DepSky-A garante disponibilidade replicando os dados na cloud-of-clouds usando técnicas de quóruns, e integridade computando um resumo criptográfico como descrito em cima. Apesar de assegurar estas duas garantias, o
DepSky-A mostra-se inútil quando os programados precisam armazenar dados crı́ticos
Capı́tulo 2. Trabalho relacionado
12
e confidenciais, pois os dados são replicados na forma de texto em claro. O protocolo
DepSky-CA cobre esta limitação encriptando os dados com uma chave simétrica. Neste
protocolo, são criados key shares através de um esquema de partilha de segredos e são utilizados códigos de apagamento para codificar os dados encriptados. Assim, é armazenado
em cada cloud um fragmento codificado concatenado um key share (como são usadas 4
clouds, são gerados 4 key shares e 4 fragmentos codificados).
2.1.5
Considerações Finais
Dos serviços de armazenamento descritos nestas secções, podemos verificar que só o
Petal oferece uma interface para o armazenamento de blocos, enquanto que os restantes
oferecem uma interface para o armazenamento de objecto. Ao invés do armazenamento
baseado em blocos, o armazenamento baseado em objectos facilita o agrupamento de
diferentes informações para cada bloco de dados armazenado, como também permite armazenar objectos de tamanho variável. Outra vantagem inerente ao uso de serviços de
armazenamento de objectos refere-se ao facto de não ser necessário manter estruturas
que nos indiquem onde cada bloco está armazenado, bastando utilizar o identificador do
objecto para efectuar operações de escrita ou leitura.
2.2
Sistemas de Ficheiros Distribuı́dos
Nesta secção são descritos alguns dos sistemas de ficheiros distribuı́dos que mais influenciaram alguns dos sistemas de ficheiros de hoje em dia. Um sistema de ficheiros distribuı́do é um sistema que permite aos programadores ou utilizadores armazenar os seus
dados remotamente, ou seja, numa outra localização através da internet, exactamente da
mesma forma que o fazem nos sistemas de ficheiros locais, sendo assim a transparência
uma das principais propriedades destes [22]. Estes foram desenhados seguindo o conhecido modelo cliente-servidor de sistemas distribuı́dos.
2.2.1
Andrew File System
O Andrew File System (AFS) [40] é um sistema de ficheiros antigo que foi desenvolvido para um ambiente de mais ou menos 5000 clientes. A sua arquitectura e design
influenciaram muitos dos sistemas de ficheiros dos dias de hoje. Apesar de a cache ser
o ponto chave do seu design, é dada uma grande atenção à segurança, à transparência da
localização dos dados, à escalabilidade, à mobilidade do utilizador, à heterogeneidade e
à partilha de dados. Existem duas principais entidades na sua arquitectura como mostra a
figura 2.4: Vice e Virtue. A entidade Vice é o conjunto de servidores responsáveis de armazenar os dados que as várias estações de trabalho Virtue querem guardar. É importante
referir que é assumido que o Vice é seguro. Cada estação Virtue foi concretizada em duas
Capı́tulo 2. Trabalho relacionado
13
distintas partes: algumas modificações necessárias a nı́vel do kernel para ser possı́vel interceptar as chamadas ao sistema referentes a ficheiros pertencentes ao AFS, e a entidade
que realmente comunica com o Vice e que gere a cache local denominada Venus.
Figura 2.4: Arquitectura do Andrew File System.
Para obter uma boa performance, mobilidade e escalabilidade, o AFS utiliza uma
cache no lado do cliente e transfere os ficheiros completos para os servidores. A cache,
além de manter os dados actualizados, guarda também informação sobre o seu estado e
sobre a sua custódia. Este sistema de ficheiros só executa operações (escrita e leitura) em
ficheiros que estejam em cache. Se um ficheiro não estiver em cache, então Venus comunica com o servidor Vice que mantem o ficheiro armazenado (os dados são só guardados
num servidor) e transfere-o para a sua cache local. Para garantir que os ficheiros em
cache têm uma vista coerente em diferentes estações de trabalho, o AFS usa um sistema
de validação da cache que necessita alguma computação nos servidores pertencentes ao
Vice. Basicamente, a Virtue notifica o Vice quando um ficheiro em cache é fechado e
o Vice notifica as outras estações de trabalho que partilham o mesmo ficheiro de que o
ficheiro foi modificado. Note-se que são armazenados ficheiros inteiros ao invés de blocos
e que os ficheiros só são armazenados depois do seu fecho. Esta abordagem simplifica a
recuperação de falhas das estações de trabalho. Para melhorar a disponibilidade dos dados
guardados, o Vice replica versões só de leitura de ficheiros que são raramente modificados
e frequentemente acedidos para leitura.
Como é suposto que toda a rede é não confiável, todas as comunicações entre a
Virtue e o Vice iniciam com um protocolo de autenticação que gera uma chave única
para encriptar toda a informação trocada em cada conexão. Esta chave é obtida através
de uma informação especı́fica do utilizador (password). É também na autenticação que é
Capı́tulo 2. Trabalho relacionado
14
fornecido o controlo de acesso usando listas de acesso (ACLs).
2.2.2
Ceph
O Ceph [47] é um sistema de ficheiros distribuı́do desenhado para ser fiável, disponı́vel,
e com um alto desempenho ao mesmo tempo que é altamente escalável. Estas propriedades são alcançadas através das caracterı́sticas de desenho presentes na sua arquitectura onde a principal ideia é separar a gestão dos metadados e dos dados.
O sistema é assim composto por três diferentes componentes como mostra a figura 2.5:
o cluster de OSDs (object store devices) que é responsável por armazenar os dados e
os metadados; o cluster de servidores de metadados (MDS) que concretiza o espaço de
nomes e que coordena a segurança, a consistência e a coerência do sistema; e o cliente
que executa operações de metadados nos MDSs e armazena os dados comunicando directamente com os OSDs.
Figura 2.5: Arquitectura do Ceph [47].
Os OSDs oferecem grande escalabilidade pois disponibilizam uma interface para armazenamento de objectos. Esta permite a escrita e a leitura de intervalos muito maiores,
e com tamanho variáveis, de bytes, do que a tradicional interface ao nı́vel do bloco. Estes
utilizam um sistema de ficheiros local especial para armazenar os dados no disco. O cluster de MDSs baseia-se numa estratégia de partição dinâmica de sub-árvores que distribui
hierarquicamente os metadados pelo diferentes nós MDS, permitindo adaptar-se aos diferentes tipos de carga de trabalho que está presentes nos sistemas de ficheiros. Embora estes
servidores respondam aos clientes maioritariamente usando os metadados em cache, armazenam os seus nós de metadados nos OSDs. Estes servidores são também responsáveis
por efectuar controlo de acesso aos ficheiros. Os clientes efectuam operações de escrita e
leitura no cluster de OSDs e tanto o podem efectuar comunicando directamente com os
Capı́tulo 2. Trabalho relacionado
15
OSDs ou através de um sistema de ficheiros implementado a nı́vel do utilizador através
do FUSE [7].
Os clientes mantém uma cache local para aumentar a performance das operações de
escrita e leitura. Esta cache é invalidade pelos MDSs na existência de múltiplos escritores
ou de um conjunto de escritores e leitores para o mesmo ficheiro. Neste cenário, o cliente
que adquirir o lock do ficheiro é obrigado a efectuar escritas sı́ncronas para os OSDs.
Contudo, os cliente podem também efectuar escritas assı́ncronas se utilizarem um serviço
de locks que os OSDs disponibilizam onde os clientes podem aceder exclusivamente a um
determinado OSD.
O Ceph, para mapear os objectos pelo diferentes OSDs disponı́veis, recorre a uma
função de dados distribuı́da, chamada CRUSH [46], que elimina a preocupação com listas
distribuı́das que mantenham a localização (OSD) dos dados. Os objectos armazenados
pelos diferentes OSDs chamam-se placement groups (PGs), onde cada um é composto por
diferentes blocos de diferentes ficheiros. Estes diferentes blocos de diferentes ficheiros
são mapeados para dentro de cada PGs através uma função de hash.
Para manter os dados sempre disponı́veis, o sistema replica os PGs por uma lista de
n OSDs. A replicação é feita da seguinte forma: os pedidos de escrita são efectuados
ao primeiro OSD disponı́vel da lista (chamado primary); este actualiza a versão do PG
que recebe o novo bloco a escrever, e envia a escrita aos restantes OSDs (replicas) que
mantém este PG. Os clientes recebem um ack quando os dados atingem o buffer de todas
as réplicas (quando fica visı́vel aos outros clientes) e da mesmo forma, um commit quando
a escrita é armazenada em memória estável por todas as réplicas. Na ocorrência do ack
o sistema tolera a falha de um único OSD presente na lista, enquanto que no commit o
cliente tem a garantia que mesmo que todos os OSDs da lista falhem, os dados podem ser
recuperados.
O Ceph mantém também um sistema de detecção de falhas de OSDs que permite
perceber se as listas de OSDs para cada PG está disponı́vel. Quando algum OSD é dado
como não disponı́vel, outro é adicionado à lista para permitir o mesmo nı́vel de replicação.
2.2.3
CODA
O Coda [41] é um sistema de ficheiros cujo objectivo é manter a disponibilidade
mesmo com clientes móveis, isto é, com conexão intermitente. A sua construção foi
baseada no Andrew File System onde as caracterı́sticas que mantém deste são: o modelo, onde servidores confiáveis armazenam dados provenientes de estação de trabalho
Unix não confiáveis; os clientes continuam a fazer cache de ficheiros inteiros e a guardar
informação sobre onde os seus dados estão armazenados; usa também callbacks (promessa
do envio de uma notificação aquando de uma alteração a qualquer ficheiro) para assegurar
a coerência da cache nas diferentes estações, mas de uma forma mais complexa; utiliza
réplicas só de leitura; e para assegurar segurança utiliza um protocolo de autenticação
Capı́tulo 2. Trabalho relacionado
16
baseado em tokens e cifra todas as mensagens trocadas.
Este sistema fornece uma disponibilidade mais alta que o AFS porque lida com falhas
quer dos servidores, como da rede. Para tal são usadas duas estratégias complementares.
A primeira é o facto de replicar os dados por diferentes servidores. A segunda prende-se
na possibilidade que os clientes têm em fazer operações desconectados, ou seja, mesmo
sem acesso à rede, estes podem continuar a operar na cache local. Para tal ser possı́vel,
o Coda lida com falhas na rede usando uma estratégia optimista que assegura que depois
de ocorrer uma partição, todos os conflitos irão ser detectados e resolvidos.
A colecção de servidores que armazenam os dados (a unidade de replicação é chamada
volume e representa um conjuntos de ficheiros e/ou directorias) é denominada de volume
stompe group (VSG). Cada cliente mantém um subconjunto do VSG denominado accessible volume stompe group (AVSG) que são os membros do VSG disponı́veis, isto é,
acessı́veis, no momento. Para replicar os dados é utlizado uma variante da abordagem
read-one, write-all1 . A leitura é efectuada de um servidor previamente marcado como
servidor preferido, contudo, é necessário contactar também os outros servidores do AVSG
para assegurar que o servidor preferido têm a versão mais actual dos dados. Quando
é encontrado um servidor com uma versão mais actual que o servidor preferido, este é
marcado como novo servidor preferido e é estabelecida uma callback com ele. Já na
operação de escrita, depois do ficheiro ser fechado, ele é replicado por todos servidores
pertencentes ao AVSG em paralelo. Para manter a coerência da cache, as estações de
trabalho que executam o sistema de ficheiros têm que detectar 3 tipos de acontecimentos
no máximo t segundos depois de terem ocorrido. Assim, é necessário estar alerta para:
• O aumento do AVSG (quando um servidor inacessı́vel se torna acessı́vel) tentando
contactar os servidores que se encontram inacessı́veis, a cada t segundos. Quando
este acontecimento se verifica, os clientes descartam as callbalcks dos objectos em
cache, pois eles podem já não ser a versão mais actualizada;
• A diminuição do AVSG (quando um servidor acessı́vel se torna inacessı́vel) testando a cada t segundos se todos os membros do AVGS se mantêm acessı́veis. Se o
servidor preferido se tornar inacessı́vel, as callbacks desse servidor são descartadas;
• A perda de callbacks simplesmente esperando callbacks dos servidores.
As operações desconectadas começam assim que todos os membros do VSG se tornam inacessı́veis. A troca do modo de operação normal (replicação) para o modo de
operação desconectado e o contrário é completamente transparente para o cliente excepto quando algum ficheiro em cache é perdido (o que acontece raramente). Obviamente, durante este modo, os clientes armazenam os dados na sua cache local. Quando os
1
Cada operação de escrita é efectuada em todos os servidores e a operação de leitura obtém os dados só
de um.
Capı́tulo 2. Trabalho relacionado
17
clientes conseguem aceder novamente a alguns membros do VSG é iniciado um processo
de reintegração onde são executados um conjunto de actualizações a todos os membros
do AVSG de forma a todas as réplicas ficarem iguais à cache local.
2.2.4
Frangipani
O Frangipani [43] é um sistema de ficheiros distribuı́dos que fornece quase as mesmas
garantias semânticas que os sistemas de ficheiros Unix. A figura 2.6 apresenta a arquitectura do Frangipani. Como podemos ver a sua estrutura é dividida em duas camadas.
A camada de baixo contém dois serviços: o Petal (serviço de armazenamento descrito
anteriormente) e um serviço de lock distribuı́do. O Petal ajuda o Frangipani a fornecer
uma fácil administração, escalabilidade e tolerância a faltas. Estes dois serviços (Petal
e lock) não necessitam estar na mesma máquina, até porque não trocam qualquer tipo
de informação entre si. Na camada de cima encontram-se os clientes e os servidores de
ficheiros Frangipani. Os clientes (programas do utilizador) acedem ao Frangipani através
de uma interface padrão de chamadas ao sistema.
Figura 2.6: Arquitectura do Frangipani [43].
Os servidores de ficheiros Frangipani comunicam com o Petal e com o serviço de
lock. Para comunicar com o Petal, os servidores usam uma driver de dispositivo. Esta
driver vê o Petal como um disco virtual com 264 bytes de espaço e esconde a real natureza
distribuı́da presente na sua arquitectura fı́sica. Neste disco virtual é definido previamente
espaço para logs, para inodes, para blocos pequenos e para blocos grandes.
Capı́tulo 2. Trabalho relacionado
18
O sistema permite a adição e remoção de servidores recorrendo a poucas tarefas de
administração (o sistema adapta-se ao novo número de servidores automaticamente). Para
a recuperação após uma falha de um servidor (fail recovery) é usado write-ahead logging
de metadados no Petal. Como não é feito log dos blocos de dados, os clientes não têm
garantias de consistência depois de uma recuperação.
Para manter sincronização quando diferentes clientes requisitam o mesmo bloco de
dados, o Frangipani utiliza o modelo de lock multi-reader/single-writer. Os locks são
efectuados a ficheiros inteiros ou directorias ao contrário de blocos individuais. A cache
foi implementada seguindo a ideia da cache do AFS, mas neste caso cada servidor Frangipani envia uma notificação aos outros servidores para actualizarem a sua cache. Numa
operação de escrita, só é garantido que os blocos de dados alcancem memória não volátil
quando duas chamadas especı́ficas ao sistema são executadas - fsync ou sync.
Como o Petal, o Frangipani permite também tirar snapshots ao sistema para a manutenção
de backups. Estas snapshots são crash-consistent, o que significa que são uma imagem
coerente do sistema.
2.2.5
Considerações Finais
Desta secção podemos retirar muitas ideias para aplicar na construção do C2FS. Como
podemos verificar, a utilização de cache no lado do cliente é essencial para o bom desempenho de um sistema de ficheiros. Outra interessante estratégia introduzida pelo AFS
[40] é a transferência de ficheiros completos para os servidores de armazenamento. Isto
permite alcançar um bom desempenho do sistema pois elimina a necessidade lidar com
latências inerentes à transferência de blocos de dados individualmente. Por sua vez, o
Ceph [47] utiliza a ideia da separação do tratamento de metadados com o armazenamento
dos dados para o aumento do desempenho e da escalabilidade. Esta ideia é também bastante interessante pois uma vez que os sistema de ficheiros efectuam muito mais operações
nos metadados do que nos dados, e as operações de dados por norma são mais lentas que
as de metadados, a distribuição da carga de trabalho é bem conseguida. Por fim é importante dar ênfase as garantias de consistência de cache expostas pelo AFS e pelo Frangipani
onde só é garantido que os dados sejam devidamente armazenados em memória estável
após o seu fecho ou aquando das operações fsync ou sync.
Contudo, é importante referir que todas as propostas de validação de cache apresentadas por estes necessitam computação nos servidores de armazenamento, o que não se
verifica no C2FS.
2.3
Sistemas de Ficheiros para Clouds
Nesta secção são apresentados alguns dos sistemas de ficheiros que armazenam os seus
dados nos diferentes provedores de armazenamento. A figura 2.7 demonstra a arquitectura
Capı́tulo 2. Trabalho relacionado
19
que estes sistemas de ficheiros adoptam. Alguns destes sistema utilizam uma proxy a que
os clientes se conectam, e esta por sua vez é que contacta a cloud. Note-se que neste
caso, a proxy é um ponto único de falha. Outros são executados directamente na máquina
do cliente, conectando-se assim directamente à cloud. A comunicação existente entre os
clientes e as clouds é efectuado via APIs fornecidas por estas. A utilização de clouds
para armazenar os dados, ao contrário dos sistemas de ficheiros descritos anteriormente,
tem a vantagem de fornecer um espaço de armazenamento quase ilimitado (ou mesmo
ilimitado) enquanto que o custo não é muito elevado.
Figura 2.7: Arquitectura de Sistemas de Ficheiros para clouds.
2.3.1
S3FS
O S3FS [16] é um sistema de ficheiros para sistemas Unix que permite montar um
bucket da Amazon S3 [4] como um sistema de ficheiros local através do FUSE [7]. Este
sistema permite o uso de uma cache local efectuada em disco de forma a aumentar o
desempenho do sistema. Note-se que esta cache só é utilizada se o cliente o indicar.
Quando um ficheiro é aberto, é feita a transferência do ficheiro completo para a cache,
e quando é fechado, é enviado para a cloud, efectuando assim todas as operações de
escrita e leitura localmente. Quando uma transferência para a cloud não é efectuada com
sucesso, o sistema volta a tentar mais 2 vezes antes de abortar a mesma. De forma a
minimizar as transferência de dados da Amazon S3, são usados resumos criptográficos
(computados através da técnica MD5) para validar a cache. Esta cache pode crescer
infinitamente, podendo assim ocupar todo o espaço em disco. Se tal acontecer, é da
responsabilidade do cliente eliminar os ficheiros de forma ao espaço do disco não ficar
todo preenchido. É mantida também uma cache em memória (por omissão 4MB) para
armazenar os metadados dos ficheiros.
Capı́tulo 2. Trabalho relacionado
2.3.2
20
S3QL
O S3QL [17] é um sistema de ficheiro para sistemas operativos tipo Unix que armazena os seus dados em provedores de armazenamento como Google Storage [9], e
Amazon S3 [4]. Este sistema utiliza uma base de dados local que serve de cache tanto
para dados como para metadados. Todas as operações, como a criação de uma directoria, a renomeação de um ficheiro, a alteração de permissões, são efectuadas nesta cache.
Estas alterações são enviadas assincronamente para a cloud. Os ficheiros presentes no sistema de ficheiros são divididos e armazenados em blocos pequenos. Esta opção permite
optimizar o desempenho e o custo associado à transferência dos dados para a cloud pois
só os blocos requisitados/modificados necessitam ser obtidos ou enviados tanto da/para a
cache, como da/para a cloud. Antes da transferência dos dados para a cloud, este passam
primeiro por um mecanismo de compressão (como LZMA ou bzip2) e posteriormente
são cifrados através da técnica AES com um chave de 256 bits. Para manter a integridade
dos dados armazenados nas clouds o serviço armazena também um resumo criptográfico
(usado SHA256 HMAC) para cada bloco de dados transferido.
Uma outra caracterı́stica interessante do S3QL é que ele a geração snapshots de directorias servindo estas para backup.
2.3.3
BlueSky
O BlueSky [45] é um sistema de ficheiros que foi principalmente desenhado para
ser utilizado por clientes dentro de empresas. Para tal, o sistema adopta um arquitectura
baseada no conceito de proxy. Os clientes comunicam assim com a proxy, que por sua vez
interage directamente com a cloud para armazenar os dados. A comunicação feita entre
os clientes e a proxy pode ser efectuada através de dois diferentes protocolos de sistemas
de ficheiros do modelo cliente-servidor: o NFS (versão 3) e o CIFS.
A proxy concretiza uma cache write-back usando o seu disco local, computando assim
quase todos os pedidos localmente. Devido a isto, deve ser instalada na rede dos clientes
para minimizar a latência inerentes aos pedidos. Os pedidos são assim todos satisfeitos
na cache (pedidos de leitura e escrita) com a excepção da eventualidade de um pedido
de leitura ser efectuado sobre um ficheiro que não está em cache. Neste caso o ficheiro
é obtido da cloud e armazenado na cache. Quando a cache está cheia (visto a cloud
ter mais capacidade que o disco local) os ficheiros são substituı́dos através de polı́ticas
LRU (Least Recently Used). Os ficheiros são mantidos em cache divididos em blocos
sequencialmente numerados onde cada bloco tem o tamanho de poucos megabytes. Isto
permite melhorar a performance do sistema, pois só são lidos do disco os blocos referentes
ao offset requisitado.
Todas as escritas para as clouds são efectuadas assincronamente. Inerente a esta
opção, existe o problema da possibilidade da falha do disco local. Se tal acontecer,
Capı́tulo 2. Trabalho relacionado
21
poderão haver dados que serão perdidos, e consequentemente nunca propagados para
a cloud. Para minimizar este risco, o BlueSky envia dados para as clouds a cada cinco
segundos. Note-se que se um envio demorar mais que cinco segundos, o envio posterior
só iniciará quando este terminar.
O sistema adopta uma estrutura baseada em log, sendo este log a unidade de armazenamento utilizada. Cada log armazenado na cloud é composto por vários segmentos de log,
e cada um deste segmentos de log agrega múltiplos objectos. Os logs são construı́dos de
forma a terem um tamanho de aproximadamente 4MB (para esconder a latência inerente
a efectuar escritas para a cloud com um tamanho pequeno). Note-se o sistema permite
efectuar leituras parciais nestes logs armazenados na cloud.
O sistema armazena quatro tipos diferentes de objectos nos logs. Estes objectos representam tando os dados como os metadados e podem ser blocos de dados, inodes, mapas
de inodes e checkpoints. Os blocos de dados representam os próprios dados e cada um
tem o tamanho fixo de 32KB (excepto o último bloco de um ficheiro que pode ser mais
pequeno). Os inodes representam os metadados dos ficheiros contento informações sobre
o dono do ficheiro, listas de controlo de acesso, timestamp e os apontadores para cada
bloco de dados. Os mapas de inodes são utilizados para localizar as versões mais recentes
de cada inode dentro do segmento. Por fim, os checkpoints contêm os apontadores para
a localização do mapas de inodes em uso. Os checkpoints são também utilizados para
manter a integridade do sistema após uma falha da proxy e para fornecer backups por
versão.
Para manter a confidencialidade dos dados, cada objecto é cifrado individualmente
antes do seu envio para a cloud (através da técnica AES) e protegidos com códigos de
autenticação de mensagens (com HMAC-SHA-256).
Para limpar os dados não mais necessários presentes na estrutura em log armazenada
na cloud, o BlueSky implementa um colector de lixo. Este colector de lixo tanto pode ser
executado na proxy como numa instância de computação nas clouds (Amazon EC2 por
exemplo), sendo neste último caso mais eficiente em relação aos custo e a performance.
2.3.4
Frugal cloud File System
O Frugal cloud File System (FCFS) [36] é um sistema de ficheiros que foi concretizado
tendo em conta o objectivo de reduzir ao máximo os custos monetários impostos por estes
serviço relativos ao armazenamento e acesso aos dados.
Para efectuar esta melhoria nos custos necessários para manter os dados nas clouds, o
FCFS baseia-se nas diferentes opções de armazenamento que as algumas clouds fornecem
que diferem não só nos custos, mas também no tempo de resposta aos pedidos. A Amazon por exemplo, fornece três diferentes opções de armazenamento: a Amazon S3 [4],
a Amazon EBS [1] e a Amazon Elasticache [3]. A Amazon S3 fornece baixo custo de
armazenamento, contudo, tem a desvantagem de cada pedido ter um preço associado (es-
Capı́tulo 2. Trabalho relacionado
22
crita ou leitura, e no caso das leituras existe também um preço associado à quantidade de
GB lidos) e as respostas a esses pedidos sofrerem de uma latência maior. Já a Amazon
EBS fornece um custo para escritas e leituras mais baixo, mas o preço de armazenamento
é mais elevado em relação à Amazon S3. A última opção referida, a Amazon Elasticache,
é a que fornece o melhor tempo de resposta (mantém os dados em memória) não cobrando
nada pelos pedidos nem pela quantidade de GB lidos, contudo o preço de armazenar os
dados é muito mais elevado do que nas outras duas opções. Basicamente, quanto maior
for o preço do armazenamento dos dados, menores serão os preços associados aos pedidos e quantidades de bytes transferidos, e menor a latência nos pedidos. Note-se que a
Elasticache e a EBS não podem ser acedidos de foram da Amazon, o que implica que o
FCFS só possa ser executado nas VMs (virtual machines) da Amazon EC2 [2].
O FCFS utiliza assim a Amazon S3 como disco do sistema (onde o armazenamento
dos dados é mais barato) e a Amazon EBS ou Amazon Elasticache como cache (onde
obter os dados é mais barato). Os ficheiros são armazenados em blocos de dados de 4
MB. Estes blocos de dados podem ser obtidos directamente do disco ou da cache. Neste
último caso os blocos de dados têm de ter sido previamente transferidos do disco. Esta
transferência (do disco para a cache) tem um preço associado se as suas bases de dados
(S3 e EBS/Elasticache) estiverem em servidores diferentes. Note-se que quando os blocos
de dados são carregados para a cache não são eliminados do disco devido a motivos de
disponibilidade. Por omissão, os dados são armazenado no disco pelo simples motivo
do preço de armazenamento ser mais baixo. Os blocos de dados, quando armazenados
na cache, são mantidos dentro de volumes de armazenamento que podem ser ajustáveis
a qualquer instante, de modo a terem exactamente a capacidade de armazenar os blocos
que, para esse instante, são precisos manter em cache. A troca de ficheiros em cache é
efectuada através de polı́ticas de substituição de cache do tipo LRU e ARC [31].
2.3.5
Cumulus
O Cumulus [44] é um sistema que permite aos utilizador fazerem backup dos seus
sistemas de ficheiros através de snapshots. Apesar de este sistema não ser um sistema
de ficheiros, está inserido nesta secção porque os backups que este permite efectuar sobre os sistemas de ficheiros são armazenados na cloud. A interface fornecida para os
clientes comunicarem com o servidor consiste em somente 4 operações: get, put, list e
delete. Estas operações operam em ficheiros inteiros. Como os sistemas de ficheiros
têm muitos ficheiros pequenos, e armazená-los individualmente nas clouds trás alguns
problemas como maiores tempos de latência e custos monetários mais elevados devido
aos modelos de custos apresentados pelas clouds, o Cumulus agrupa vários ficheiros pequenos e coloca-os dentro de uma unidade denominada segmentos. Estas unidades são
armazenadas da mesma forma que os ficheiros possuindo também um identificador único.
Capı́tulo 2. Trabalho relacionado
23
Cada snapshot inclui um log de metadados e os próprios dados. O log de metadados
contém entradas para cada ficheiro, onde são guardadas informações sobre as permissões
e custódia do ficheiros, um resumo criptográfico para garantir a integridade dos dados, e os
apontadores para a localização dos dados. Cada snapshot é transformada num segmento,
comprimida e encriptada antes de ser enviada para a cloud.
Os clientes podem fazer uma recuperação completa extraindo todos os ficheiros ou
uma recuperação parcial recuperando só parte deles.
2.3.6
Considerações Finais
Após o estudo destes sistemas de ficheiros para cloud, é importante dar relevância
a três importantes limitações que estes apresentam. A primeira limitação refere-se ao
caso dos sistema que adoptam uma arquitectura baseada em proxy, pois esta é um ponto
único de falha. A segunda relata com o facto de nenhum deles permitir a partilha de
ficheiros controlada por diferentes utilizadores em diferentes localizações (note-se que no
caso de uma arquitectura com proxy é permitida a partilhar de ficheiros entre os clientes
que a estejam conectados à mesma proxy). Por último, estes só confiam unicamente num
provedor de armazenamento dependendo assim deste, não efectuando assim nenhuma
replicação de dados.
Apesar destas limitações, é de notar o mecanismo de validação de cache que alguns
descrevem, em que são comparados resumos criptográficos efectuados para cada versão.
2.4
Considerações Finais
Neste capı́tulo foram introduzidos e descritos alguns dos serviço de armazenamento,
sistemas de ficheiros distribuı́dos e sistemas de ficheiros para clouds estudados que nos
ajudaram a desenhar e concretizar o C2FS. No próximo capı́tulo é introduzida a arquitectura e modelo de sistema do C2FS, e é descrito em pormenor o serviço de armazenamento
concretizado para este.
Capı́tulo 2. Trabalho relacionado
24
Capı́tulo 3
Armazenamento de Dados do C2FS
3.1
C2FS
Conforme já mencionado, o trabalho desenvolvido neste PEI enquadra-se num projecto maior que é um sistema de ficheiros que armazena os seus dados na cloud-of-clouds
chamado C2FS (cloud-of-clouds file system). Assim nesta secção é introduzida a arquitectura e o modelo de sistema do C2FS para melhor se perceber a descrição dos componentes
realizados por este projecto nas secções seguintes.
3.1.1
Arquitectura
A figura 3.1 apresenta a arquitectura do C2FS. Na base na arquitectura está o FUSE-J
[8]. Este é o componente responsável por interceptar as chamadas de sistema para recursos pertencentes ao C2FS. É também devido ao uso deste módulo que o C2FS fornece aos
seus clientes uma interface do estilo POSIX [13]. As chamadas de sistemas interceptadas
são passadas ao agente C2FS pois este implementa uma interface fornecida pelo FUSEJ. O agente C2FS concretiza assim uma lista de operações de sistemas de ficheiros (i.e.,
open, write, etc) onde integra os outros componentes do sistema: o serviço de directorias,
o serviço de locks e o serviço de armazenamento. Note-se que a interacção com estes
sistemas depende da operação recebida pelo agente C2FS, tendo cada operação um comportamento especı́fico. Além desta integração, o agente C2FS é também responsável por
gerar a chave de encriptação para cada ficheiro. Na secção 3.2 é explicado em pormenor
o funcionamento do FUSE-J e as operações de sistemas de ficheiros que este permite
implementar.
O serviço de directorias [32] é o componente responsável por armazenar os metadados
dos recursos do C2FS. Juntamente com os metadados, é também armazenada a chave de
encriptação. Este mecanismo faz também controlo de acesso a ficheiros partilhados. Estas
funções são concretizadas tendo por base um serviço de coordenação distribuı́do chamado
DepSpace [20] que é executado em diferentes provedores de computação, fazendo uso do
conceito cloud-of-clouds, assim como o DepSky. Este componente faz uso de um sistema
25
Capı́tulo 3. Armazenamento de Dados do C2FS
26
de cache para diminuir o número de chamadas ao DepSpace, diminuindo assim também
os custos associados a estas chamadas, e aumentando a performance do sistema.
O serviço de locks [32] tem a tarefa de manter a consistência dos ficheiros controlando
o acesso em simultâneo aos mesmos. Assim, o C2FS garante que enquanto um utilizador
está a escrever num determinado ficheiro, mais nenhum outro pode efectuar esta mesma
operação. Como o serviço de directorias, este serviço também é cliente do DepSpace.
O serviço de armazenamento tem o objectivo de gerir os dados na cloud-of-clouds
através do DepSky. Este componente fornece dois nı́veis distintos de cache. No primeiro
os dados são mantidos no disco local para evitar chamadas às clouds, enquanto que no
segundo, os dados são mantidos em memória de forma a diminuir o tempo de resposta,
aumentando assim o desempenho do sistema. Este serviço permite também duas formas
distintas de escrever os dados nas clouds. No primeiro as escritas são efectuadas de forma
sı́ncrona enquanto que no segundo são efectuadas de forma assı́ncrona. Neste caso é
mantida uma fila de tarefas a correr em background para gerir estas mesmas escritas. Os
dados são encriptados antes do envio para as clouds, ou seja, os dados em cache estão em
claro. Este serviço é descrito em detalhe na secção 3.4.
Figura 3.1: Arquitectura do C2FS.
3.1.2
Modelo do Sistema
Antes de descrevermos o serviço de armazenamento do C2FS em detalhe, explicamos
as hipóteses que o sistema requer para um correcto funcionamento.
Capı́tulo 3. Armazenamento de Dados do C2FS
27
Em primeiro lugar o C2FS tolera um número ilimitado de clientes assumindo que
cada um destes tem um identificador único, e assume que a média do tamanho máximo
por ficheiro é de 50MBs para garantir bom desempenhos.
Em segundo lugar, o modelo de sistema do C2FS herda as propriedades dos modelos
de sistema do DepSky e do DepSpace uma vez que o serviço de armazenamento do C2FS
recorre ao DepSky para armazenar os dados na nuvem composta por uma cloud-of-clouds
enquanto que os serviços de directorias e locks utilizam o DepSpace para armazenar os
metadados.
Cada cloud utilizada pelo DepSky representa um servidor passivo ou seja, que não é
capaz de executar código nenhum da aplicação, fornecendo só uma interface para proceder a operações de escrita ou leitura de dados. Estas operações têm uma semântica de
consistência regular onde uma operação de leitura que seja executada concorrentemente
com uma operação de escrita irá retornar ou os dados que já lá estavam, ou os dados resultante da escrita em processo. Embora, como referido acima, o C2FS tenha a preocupação
de não permitir mais que um escritor para o mesmo ficheiro no mesmo instante, o sistema
não considera escritores maliciosos, pois estes ao terem acesso aos ficheiros, poderiam escrever dados sem sentido do ponto de vista da aplicação. A comunicação existente entre
o DepSky e as clouds é efectuada via o modelo clássico de chamada remota a procedimentos (RPC). Cada operação continua a ser invocada até obter uma resposta da cloud ou
até ser cancelada.
Já a comunicação existente entre os serviço de directorias e locks com os servidores
DepSpace é efectuada através de canais fiáveis autenticados ponto-a-ponto através do uso
de sockets TCP e códigos de autenticação de mensagens (MAC) com chaves de sessão
sobre a assunção que a rede pode perder, corromper ou atrasar mensagens, mas não o
pode fazer infinitamente entre processos correctos. Para garantir que todas os servidores
executam as mesmas operações por ordem, é usada uma primitiva de multicast com ordem
total, baseada no protocolo de consenso Paxos Bizantino [42]. Tal protocolo requer um
modelo de sistema eventualmente sı́ncrono.
Tanto as clouds que são os servidores de armazenamento, como os servidores do
DepSpace que mantem os metadados online, toleram faltas bizantinas [30] utilizando sistemas de quóruns bizantinos onde são requeridos n ≥ 3f + 1 para suportar f servidores
faltosos. Contudo, o sistema tolera um número ilimitado de clientes faltosos.
3.2
FUSE
O FUSE (File system in USEr space) [7] é um módulo para Linux que permite a
construção de sistemas de ficheiros no espaço do utilizador, eliminando assim a necessidade de efectuar modificações a nı́vel do kernel. Isto significa que com a utilização
deste módulo, o sistema de ficheiros não necessita ser executado no kernel pois é ex-
Capı́tulo 3. Armazenamento de Dados do C2FS
28
ecutado a nı́vel do utilizador. Outra vantagem inerente à utilização deste módulo para a
implementação do sistemas de ficheiros é a interface ao estilo POSIX [13] que é oferecida
aos clientes, facilitando assim a gerência de ficheiros na cloud-of-clouds.
A figura 3.2 ilustra como o FUSE interage com a arquitectura dos sistemas de ficheiros
Unix. Quando o VFS (Virtual File System) intercepta uma chamada de sistema a um recurso pertencente ao sistema de ficheiros C2FS, automaticamente chama o módulo FUSE
(FUSE). Este módulo é instalado no Kernel aquando da instalação do FUSE. Este por
sua vez, envia a chamada para a biblioteca do FUSE (libfuse) através de um descritor
de ficheiro especial. Por fim, o processo que concretiza o sistema de ficheiros recebe a
chamada, processa-a, e envia a resposta pelo caminho inverso.
Figura 3.2: Caminho percorrido por cada chamada ao sistema.
Contudo, o FUSE é implementado em C enquanto que os sistemas a integrar no C2FS,
o DepSky e o DepSpace, são implementados em Java, o que dificulta tal integração. É
usado então uma concretização do FUSE em Java chamado FUSE-J [8] para facilitar a
integração dos sistemas existentes. Este fornece uma API Java que usa ligações JNI (Java
Native Interface) para comunicar com a biblioteca do FUSE. O FUSE-J fornece uma
interface para implementar as operações de sistema de ficheiros chamada FileSystem3.
A tabela 3.1 apresenta a lista das operações que esta interface permite implementar e
a função de cada uma delas no sistemas de ficheiros FUSE-J.
3.3
DepSky
Nesta secção são apresentadas as alterações que foram feitas no DepSky de modo a
este responder de uma melhor forma às necessidades do C2FS. Em sumário foram feitas
duas melhorias significativas, sendo elas a adição de um novo protocolo de uso e a adição
de uma nova operação que permite ler versões antigas de uma determinada Data Unit.
Em baixo são descritas estas duas alterações no DepSky.
Capı́tulo 3. Armazenamento de Dados do C2FS
29
Operações
Função
getattr(path, getattrSetter)
retorna os metadados para um determinado recurso.
lista os recursos filhos de uma determinada directoria.
criar uma directoria com as permissões fornecidas.
criar um ficheiro com as permissões fornecidas.
abre o descritor do ficheiro de acordo com o modo
pretendido (e.g., O WRONLY, O RDWR).
lê o número de bytes pedidos a partir do offset pretendido de um ficheiro aberto.
escreve para um ficheiro aberto a partir do offset
fornecido.
renomeia um determinado recurso.
muda as permissões de um determinado recurso.
fecha o descritor de ficheiro assegurando que os
dados em cache estão devidamente armazenados
no disco. Note-se que se um ficheiro tiver mais
que um descriptor associado (e.g., no caso de um
fork), haverá mais que um flush por open.
sincroniza os dados em cache de um determinado
ficheiro aberto com o disco.
cria uma ligação forte (hard link) entre os dois
ficheiros.
liberta um determinado ficheiro quando todos os
descriptores desse ficheiro tiverem sido devidamente fechados (flush).
altera o tamanho de um ficheiro. Pode ser invocada sobre ficheiro abertos ou ficheiros fechados
elimina uma directoria.
obtém informação estatı́sticas sobre o sistema de
ficheiros.
cria uma ligação simbólica para um dado recurso.
lê uma ligação simbólica.
elimina um ficheiro.
muda o tempo de acesso e/ou o tempo de
modificação de um ficheiro.
muda o dono e o grupo do ficheiro.
getdir(path, dirFiller)
mkdir(path, mode)
mknod(path, mode, rdev)
open(path, flags, openSetter)
read(path, fh, buf, offset)
write(path, fh, isWritepage, buf, offset)
rename(from, to)
chmod(path, mode)
flush(path, fh)
fsync(path, fh, isDatasync)
link(from, to)
release(path, fh, flags)
truncate(path, size)
rmdir(path)
statfs(statfsSetter)
symlink(from, to)
readlink(path, link)
unlink(path)
utime(path, atime, mtime)
chown(path, uid, gid)
Tabela 3.1: Operações FUSE-J.
Capı́tulo 3. Armazenamento de Dados do C2FS
30
Modificação 1. Por motivos relacionados com o controlo de acesso sobre ficheiros
partilhados, o serviço de armazenamento (um componente do C2FS descrito na secção
seguinte) cifra os dados antes de os guardar nas clouds (usando o DepSky), sendo a chave
simétrica usada para cifrar/decifrar os dados armazenada no serviço de directorias. Assim, os dados irão ser armazenados no DepSky já previamente cifrados. Como já descrito
anteriormente, o DepSky fornece dois protocolos distintos para os clientes gerirem os
seus dados na cloud-of-clouds: o DepSky-A e o DepSky-CA [19]. Contudo, nenhum
destes protocolos responde devidamente à necessidade do C2FS. O DepSky-A não nos
é útil porque, apesar de garantirmos a confidencialidade dos dados devido à sua cifração
no serviço de armazenamento, se um bloco de dados de tamanho T for replicado em n
clouds, irá ser consumido n × T espaço de armazenamento e os custos irão ser, em média,
n vezes maiores do que se for usado só uma cloud. O DepSky-CA também não se revela
óptimo para o C2FS porque, embora solucione o problema descrito anteriormente através
do uso de códigos de apagamento, cifra também os dados e usa partilha de segredo para
garantir confidencialidade das chaves, o que penaliza a performance uma vez que os dados
são encriptados duas vezes, uma a nı́vel do C2FS, e outra no DepSky.
Foi concretizado então um novo protocolo que não é mais que uma variante do DepSkyCA. A diferença é que não faz uso de técnicas criptográficas nem de partilha de segredos,
mas mantém a disponibilidade e integridade dos dados ao mesmo tempo que reduz os
custos monetários de armazenamento devido à utilização de códigos de apagamento na
replicação dos dados. Assim, em cada operação de escrita, é armazenado em cada cloud
um fragmento codificado (são gerados tantos fragmentos quanto o número de clouds utilizado). Na operação de leitura são necessários f + 1 fragmentos (em que f é o número
de provedores que podem ser faltosos) para obter o bloco de dados inicial1 . Note-se que
mesmo na eventualidade de alguém escutar a rede e obter f +1 fragmentos (isto é, o bloco
inicial), não conseguirá obter os dados em claro pois estes são previamente cifrados pelo
serviço de armazenamento do C2FS.
Modificação 2. O DepSky mantém todas as versões de todas as escritas efectuadas em
cada cloud. Neste cenário foi concretizada uma operação de leitura que permite ler uma
versão antiga de uma unidade de dados do DepSky. A esta nova operação demos o nome
readMatching(Du, h), onde o primeiro argumento é a unidades de dados do DepSky e o
segundo é um resumo criptográfico. Assim o objectivo é ler a primeira versão em que o
seu resumo é igual ao resumo fornecido.
Para a concretização desta operação foram necessárias algumas alterações na operação
de escrita do Depsky. Primeiro têm que ser armazenados todos os metadados referentes a
cada versão escrita, ao invés de armazenar somente os metadados da última versão. Esta
alteração foi efectuada de modo a garantirmos a integridade de todos os blocos de dados
1
Contudo são esperadas n − f respostas devido ao protocolo bizantino utilizado.
Capı́tulo 3. Armazenamento de Dados do C2FS
31
escritos em cada cloud. Outra alteração feita foi a introdução de um novo campo nos
metadados chamado datahash. Este campo armazena um resumo criptográfico efectuado
pelo DepSky sobre cada bloco de dados completo a ser escrito (i.e., antes de passar por
qualquer processo de codificação ou cifração). Por fim, a operação de escrita do DepSky
passa a retornar ao cliente este resumo.
O algoritmo desta nova alteração é bastante simples.
• Primeiro é obtido o ficheiro de metadados referente à unidade de dados fornecida
Du. Neste caso basta obter o ficheiro de metadados de n − f cloud (uma vez que
neste conjunto de clouds existe pelo menos uma com a versão do campo datahash
mais actual).
• Depois são comparados os resumos presentes nos campos datahash com o resumo
fornecido h, iniciando a procura na versão mais recente, até à mais antiga.
• Quando encontrado um resumo igual ao resumo h, é lida das clouds a versão referente a esse resumo encontrado. Esta leitura é realizada seguindo o protocolo normal
de leitura, ou seja, é efectuada num quórum de n − f clouds. Caso nenhum resumo
presente no ficheiro de metadados seja igual ao resumo fornecido, é retornado erro
na operação.
Esta operação foi introduzida para satisfazer um mecanismo explicado na tese [32],
que tem por finalidade minimizar uma importante limitação presente na maioria das
clouds, que é a consistência eventual, fornecendo assim uma consistência regular forte
para os ficheiros armazenados no C2FS.
3.4
Serviço de Armazenamento
Nesta secção é apresentado o serviço de armazenamento concretizado para o C2FS.
Como já referido anteriormente, este serviço utiliza o DepSky modificado descrito na
primeira modificação da secção 3.3 que mantém a integridade e a disponibilidade dos
dados armazenados na cloud-of-clouds. A confidencialidade é fornecidada pelo próprio
serviço de armazenamento que cifra os dados antes do seu envio para as clouds. Cada
ficheiro neste serviço está directamente relacionado com uma unidade de dados do DepSky (Data Unit).
Este serviço dispõe de uma cache local que aumenta o desempenho do sistema de
ficheiros e diminui os custos monetários associados a downloads que, desta forma, são
evitados. Note-se que apesar de este serviço armazenar os dados nas clouds através do
DepSky, é importante referir que só opera em dados que estejam em cache, sendo só
necessário fazer o download dos dados das clouds caso exista uma versão mais recente
destes nas clouds. Isto acontece se o ficheiro for partilhado por diferentes utilizadores
Capı́tulo 3. Armazenamento de Dados do C2FS
32
ou se o mesmo utilizador mantiver o C2FS em diferentes estações de trabalho. Para
dados que não sejam partilhados nunca é necessário efectuar uma leitura das clouds (a
não ser que o mesmo utilizador monte o mesmo o sistema numa máquina diferente onde
a cache não está actualizada), servindo estas só para backup. Isto é muito importante
pois conseguimos poupar dinheiro uma vez que a transferência de dados para dentro da
maioria das clouds não tem nenhum, ou quase nenhum preço associado, sendo apenas as
operações de transferência de dados para fora cobradas.
Por omissão, a cache dos dados é feita no disco local, mas, os utilizadores deste
serviço podem também manter a cache dos dados em memória volátil de forma a diminuir
o tempo de resposta para cada operação de leitura ou escrita. Este serviço disponibiliza
também duas formas de enviar os dados para as clouds, sı́ncrona e assı́ncrona, em que
na sı́ncrona os clientes esperam pela confirmação de que os dados estão devidamente
armazenados, e na assı́ncrona o envio dos dados é feito em background.
Assim, este serviço permite ao C2FS ser configurado de vários formas:
• O nı́vel de cache a utilizar (só em memória fı́sica ou também em memória volátil).
• A forma do envio-o dos dados para as clouds (sı́ncrona ou assı́ncrona).
• Escolher se a operação fsync do agente C2FS sincroniza os dados no disco local ou
na cloud-of-clouds.
Note-se que consoante os parâmetros de configuração escolhidos diferentes nı́veis de
consistência e durabilidade são fornecidos. De seguida serão descritos os algoritmos para
as operações deste serviço, a sua integração no agente C2FS, e os diferentes nı́veis de
consistência consoante os parâmetros de configuração.
3.4.1
Visão Geral da Gestão do Armazenamento
Conforme já mencionado, o serviço de armazenamento concretizado para o C2FS faz
um uso intensivo de cache. Logicamente esta cache ocupa muito espaço no disco local
(que pode vir a ser o disco todo). Poderı́amos evitar isto concretizando um serviço de armazenamento que operasse directamente nos ficheiros armazenados nas clouds sem fazer
cache dos dados. Mas com isto terı́amos muitos mais problemas do que benefı́cios no que
diz respeito ao desempenho do sistema e aos custos associados às transferências de dados
para as clouds. Note-se que, por exemplo, para uma operação de escrita com offset maior
que zero ocorrer com sucesso, iria ser necessário uma leitura no DepSky (que realmente
são duas leituras, uma para os metadados e outra para os dados [19]) para obter os dados,
e depois de o blocos de dados final ser obtido (i.e., com a escrita já efectuada no offset
correcto) iria ser necessário uma escrita no DepSky (que na verdade efectua uma leitura
dos metadados, e duas escritas, uma para os dados, e outras para ou metadados) para armazenar o ficheiro já actualizado. Assim para uma operação de escrita no C2FS terı́amos
Capı́tulo 3. Armazenamento de Dados do C2FS
33
cinco acessos à cloud-of-clouds. Ora, sobre um ficheiro, desde o momento que é aberto
(open) até ao momento que é fechado (close), podem ocorrer inúmeras operações de escrita com offsets diferentes, o que provocaria um desempenho completamente inaceitável
conjugado com preços proibitivos. Assim, a cache que o serviço de armazenamento faz
sobre os ficheiros é um dos pontos cruciais para o bom desempenho do C2FS.
Os ficheiros podem ser mantido em três diferentes localizações: em memória, em
disco, e na cloud-of-clouds. A figura 3.3 ilustra o fluxo que os dados fazem enquanto são
transferidos entre as diferentes localizações. As setas contı́nuas representam as escritas,
enquanto que as setas a tracejado representam as leituras. Como podemos verificar, os
clientes só efectuam leituras e escritas na memória volátil (se esta for utilizada). Da
memória os dados são escritos para o disco, e posteriormente, do disco são escritos para
as clouds. Como mostra a figura, não é permitido que os dados sejam escritos directamente da memória para as clouds. Isto não é permitido para no caso de ocorrer um falha
durante o envio dos dados, estes poderem ser recuperados. Da mesma forma, quando obtidos os dados das clouds, estes são primeiro armazenados em disco, e só posteriormente
em memória. As operações disponibilizadas para os clientes gerirem os dados nestas
diferentes localizações são descritas em baixo.
Figura 3.3: Fluxo dos dados.
Tanto a cache em disco como a cache em memória aplicam politicas LRU (Least
Recently Used) para a substituição de ficheiros quando não existe espaço suficiente para
armazenar novos ficheiros. Basicamente quando é necessário espaço, são eliminados os
ficheiros que há mais tempo não são acedidos. O tamanho máximo da cache em disco
é exactamente o espaço do disco local, já o tamanho máximo da cache em memória é
configurado pelo cliente. Note-se que antes da eliminação de ficheiros da memória, estes
são armazenados devidamente em disco de forma a não se perder a versão mais actual. Os
clientes podem manter os dados na cache em memória durante o tempo que desejarem.
Isto significa que todas as alterações feitas sobre um ficheiro que está em memória não
serão armazenadas em memória estável (disco local ou clouds-of-clouds) até o cliente o
indicar ou até que seja necessária a sua substituição.
Capı́tulo 3. Armazenamento de Dados do C2FS
3.4.2
34
Algoritmos de Gestão de Armazenamento
Nesta secção são apresentadas as caracterı́sticas fundamentais do serviço de armazenamento como as variáveis utilizadaz e os algortimos concretizados.
Para a validação da cache, o serviço de armazenamento mantém armazenados os resumos criptográficos retornados em cada escrita no DepSky (modificação 2 descrita na
secção 3.3). Este resumo é fornecido ao serviço de directorias de forma a ser armazenado
juntamente com os outros metadados do ficheiro. Assim o resumo presente no serviço
de directorias é sempre o mais actual. A validação de cada ficheiro em cache é então
efectuada comparando o resumo fornecido pelo serviço de directorias com o resumo armazenado neste serviço. Estes resumos criptográficos são mantidos e também frequentemente actualizados no disco local para evitar transferências das clouds depois do sistema
ser desligado e ligado novamente. Este serviço mantém também a indicação de quais
os ficheiros que foram alterados e que ainda não foram enviados para as clouds, de formar a efectuar envios desnecessários. Para possibilitar a recuperação após uma falha, ou
seja, para sincronizar ficheiros que foram alterados e não chegaram a ser enviados para as
clouds, esta informação é também mantida no disco local. Por último, é também mantido
o tamanho dos dados de cada ficheiro. Estas informações são carregadas para memória
sempre que o C2FS é montado.
Este serviço foi concretizado também, tendo em conta que um dos objectivos do C2FS
é fornecer um registo em que são aceites um cliente escritor e múltiplos clientes leitores
para o mesmo ficheiro para cada instante. Para o serviço de armazenamento, este modelo obriga que a cada operação de leitura sobre um determinado ficheiro seja verificado
se existe uma nova versão disponı́vel nas clouds, pois a qualquer momento da leitura,
um cliente escritor pode actualizá-los. Já na operação de escrita não é necessária esta
verificação pois o serviço de locks [32] garante que enquanto um cliente escritor efectua
uma escrita, mais nenhum outro o pode fazer.
Em baixo são apresentadas as operações que este serviço disponibiliza para os clientes
gerirem os dados nas três diferentes localizações(memória, disco e cloud-of-clouds) e qual
a funcionalidade de cada uma delas. Note-se que estas operações foram concretizadas
tendo em conta a interface de sistemas de ficheiros que o agente C2FS implementa e o
momento em que cada operação deste serviço é invocada é determinante para o seu bom
funcionamento.
Nos algoritmos em baixo, os resumos criptográficos estão representados na variável
hashs, a informação referente ao ficheiros alterados em cache é armazenado na variável
valueToSend e o tamanho dos dados na variável sizes. As variáveis cacheMemory e
cacheDisk representam os acessos à memória e ao disco respectivamente. Por sua vez, a
variável depsky representa os acessos efectuados ao DepSky.
Capı́tulo 3. Armazenamento de Dados do C2FS
35
Operação Update Cache. Esta operação é responsável por ler os dados da cloud-ofclouds utilizando o DepSky. Como podemos verificar no algoritmo 1, os dados são lidos
das clouds por dois motivos: ou os dados não se encontram em cache, ou os dados em
cache estão desactualizados (linha 2). Os dados em cache não se encontram actualizados
se o resumo fornecido pelo cliente do serviço for diferente do resumo mantido no serviço
de armazenamento. Os dados são então lidos do DepSky usando a operação readMatching (modificação 2 da secção 3.3) como mostra a linha 5, que recebe como argumentos a
unidade de dados referente ao ficheiro requerido (linha 3) e o resumo criptográfico referente à versão a obter. Como podemos ver no algoritmo, caso os dados não consigam ser
obtidos das clouds, isto é, se não houver nenhuma versão nas clouds que diga respeito ao
resumo fornecido, esta operação volta a tentar obter os dados mais três vezes, de cinco
em cinco segundos (linhas 4-8). Isto acontece porque como referido anteriormente, o
resumo fornecido pelo cliente, no caso o agente C2FS, é sempre o mais actual, e por
conseguinte, isto significa que os dados referentes a este resumo já foram escritos para
as clouds (operação Sync W Clouds). Os dados podem não estar logo visı́veis após a sua
escrita nas clouds devido à consistência fraca fornecida por estes2 . Devido a isto, a sua
leitura é tentada três vezes. Note-se que caso os dados não sejam obtidos em nenhuma
das tentativas é retornado erro ao cliente (linhas 9-10). Caso os dados sejam obtidos, são
então decifrados utilizando a chave simétrica fornecida pelo cliente (linha 11) e a cache é
revalidada, isto é, os dados obtidos são colocados em cache a partir do offset 0, e é escrito
em disco o novo resumo, a informação de que o ficheiro neste momento está actualizado e
o tamanho dos dados lidos (linhas 12-16). Posteriormente, caso o cliente esteja a usufruir
da memória volátil, os dados são adicionados a esta (linhas 17-20). Note que no caso de
não ter sido necessário efectuar a leitura das clouds, para escrever os dados em memória,
estes tem que ser obtidos do disco (neste caso a partir do offset 0 e indicando que se quer
ler o ficheiro todo). Esta operação é responsável por esta acção para garantirmos que
sempre que um cliente desejar adicionar um ficheiro a este nı́vel de memória, adiciona a
versão mais actual do ficheiro.
Esta operação é chamada pelo agente C2FS na operação open ao contrário do que seria
suposto. Embora a operação open seja considerada uma operação de metadados, a leitura
dos dados das clouds é feita nesta operação para que todas as operações efectuadas sobre
um ficheiro aberto (write, read, fsync e flush) sejam feitas sobre um ficheiro actualizado.
Operação Write Data. Esta operação tem a função de escrever os dados para o disco local ou para a memória. O algoritmo 2 mostra-nos como a operação é concretizada. Como
podemos ver, caso o serviço de armazenamento esteja a usufruir da cache em memória
volátil (linha 2), a referência dos dados é obtida desta (linha 3). De seguida é verificado
2
[4].
Note-se que no caso da Amazon S3, os dados estão visı́veis num tempo aproximado a cinco segundos
Capı́tulo 3. Armazenamento de Dados do C2FS
36
Algorithm 1: Update Cache
Map h String, byte[] i hashs;
Map h String, boolean i valueToSend;
Map h String, int i sizes;
CacheOnDiskManager cacheDisk;
CacheOnMemoryManager cacheMemory;
DepSky depSky;
1
2
3
4
5
6
7
8
Entrada: name - identificador do ficheiro, key - chave para desencriptar os dados,
hash - resumo criptográfico para verificar se os dados está em cache
estão actualizados
Saı́da: nenhuma
inı́cio
se (name ∈
/ cacheDisk || hash 6= hashs.get(name)) então
dataU nit ←− DataU nit(name);
para (0 ≤ i ≤ 3) faça
cipherdata ←− depsky.readM atching(dataU nit, hash);
se (cipherdata 6= null) então
sai do ciclo;
senão
sleep(5000ms);
se (cipherdata = null) então
retorna f alse;
9
10
data ←− decryptData(cipherdata, key);
cacheDisk.writeData(name, data, 0);
sizes.add(name, data.length);
valueT oSend.add(name, f alse);
hashs.add(name, hash);
write to disk(name, hash, f alse, data.length);
11
12
13
14
15
16
se (cacheM emory 6= null) então
se (data = null) então
data ←− cacheDisk.getData(name, 0, sizes.get(name));
17
18
19
cacheM emory.writeData(name, data, 0);
retorna true;
20
fim
se é necessário redimensionar o tamanho do buffer. Isto acontece se a soma do tamanho
do bloco a escrever com a posição a iniciar a escrita for superior ao tamanho do buffer em
cache (linha 4-5). O buffer é sempre redimensionado para o dobro do tamanho de forma
a não ser necessário redimensionar o buffer e todas as operações de escrita. Por fim o
ficheiro é marcado como alterado (linha 6) e os dados a escrever são colocado no buffer
a partir no offset correcto. No caso de a escrita ser efectuada para disco, o ficheiro é marcado como alterado e esta informação é armazenado em disco (linhas 8-9) no momento
Capı́tulo 3. Armazenamento de Dados do C2FS
37
antes de se proceder à escrita dos dados (linha 10). Esta ordem de operações permite que
todos os ficheiros alterados sejam enviados para as clouds, mesmo na presença de uma
falha após a sua escrita. Por fim é verificado se a escrita (quer em memória ou em disco)
alterou o tamanho dos dados, e caso tenha alterado, é armazenado o novo tamanho (linhas
11-14). O tamanho do ficheiro é então retornado ao cliente.
Logicamente esta operação é chamada pelo agente C2FS aquando de uma chamada
ao sistema write. Esta operação irá escrever sempre sobre a versão mais actual dos dados,
pois a chamada ao sistema write é só invocada sobre ficheiros abertos (isto é, depois de
um open).
Algorithm 2: Write Data
Map h String, boolean i valueToSend;
Map h String, int i sizes;
CacheOnDiskManager cacheDisk;
CacheOnMemoryManager cacheMemory;
1
2
3
4
5
Entrada: name - identificador do ficheiro, value - dados a escrever, offset posição de onde iniciar a escrita
Saı́da: tamanho final dos dados
inı́cio
se (cacheM emory 6= null) então
data ←− cacheM emory.readData(name);
se (value.length + offset > data.length) então
resizeBuf f er(data);
valueT oSend.add(name, true);
memcopy(data, offset, value, 0, value.length);
senão
valueT oSend.add(name, true);
write to disk(name, true);
cacheDisk.writeData(name, value, offset);
6
7
8
9
10
14
se (value.length + offset > sizes.get(name)) então
size ←− value.length + offset;
sizes.add(name, size);
write to disk(name, size);
15
retorna sizes.get(name);
11
12
13
fim
Operação Read Data. Esta operação é usada para ler um determinado ficheiro. Como
podemos ver no algoritmo 3, a primeira preocupação da operação é verificar se os dados
em cache para o ficheiro em questão estão actualizados através da chamada a operação
já descrita em cima Update Cache (linha 2). Esta verificação em cada leitura vêm ao
encontro do modelo de operação requerido pelo C2FS referido em cima (um escritor e
Capı́tulo 3. Armazenamento de Dados do C2FS
38
múltiplos leitores). Se não for possı́vel obter os dados actualizados é retornado erro ao
cliente. Após ter a garantia que os dados em cache estão devidamente actualizados, os
dados são lidos através da memória volátil se esta estiver a ser utilizada e se o ficheiro
estiver presente neste nı́vel, ou caso contrário são obtidos do disco (linhas 3-5). Por fim,
os dados são requeridos são retornados ao cliente.
Esta operação é invocada pelo agente C2FS na operação read.
Algorithm 3: Read Data
Map h String, byte[] i hashs;
CacheOnDiskManager cacheDisk;
CacheOnMemoryManager cacheMemory;
1
2
3
4
5
Entrada: name - identificador do ficheiro, key - chave para desencriptar os dados,
hash - resumo criptográfico para verificar se os dados está em cache
estão actualizados, offset - posição para iniciar a leitura, capacity número de bytes a ler
Saı́da: valor do ficheiro lido
inı́cio
se (U pdate Cache(name, key, hash)) então
se (cacheM emory 6= null && cacheM emory.contains(name)) então
data ←− cacheM emory.readData(name, offset, capacity);
senão
data ←− cacheDisk.readData(name, offset, capacity);
retorna data;
6
retorna null;
7
fim
Operação Trunc Data. Esta operação tem o objectivo de alterar o tamanho de um determinado ficheiro. No algoritmo 4 podemos ver como a operação foi implementada. A
primeira preocupação a ter e conta é a de ler os dados da cloud se os dados em cache não
estiverem actualizados (linha 2). Caso a operação retorne erro, é também retornado erro
ao cliente (linha 3). De seguida, os dados são truncados tanto em disco como em memória,
caso esta esteja a ser utilizada (linhas 4-6). Posteriormente o ficheiro é armazenado tanto
em memória como em disco o novo tamanho do ficheiro e a informação de que o ficheiro
foi alterado. Por último, caso o cliente do serviço o obrigue, o ficheiro é enviado para as
clouds (linhas 10-11).
Esta operação é invocada na operação truncate do agente C2FS. Esta operação apresenta uma semântica diferente das operações anteriores (Write Data e Read Data) devido
à especificação que o FUSE-J dá para esta chamada de sistema: a operação truncate pode
ser invocada sobre um ficheiro fechado. Isto significa que os dados em cache podem
não estar actualizados aquando da sua chamada e que pode não vir a ser invocada nen-
Capı́tulo 3. Armazenamento de Dados do C2FS
39
huma operação de sincronização (fsync ou flush) após a alteração do tamanho do ficheiro.
Dai a necessidade de garantirmos que a alteração é feita em todas as localizações onde
o ficheiro se encontra. Note-se ainda que esta operação não é mais que uma escrita, e
portanto o ficheiro deve ser bloqueado para escrita caso ainda não esteja (no caso do
ficheiro estar fechado). Assim, o cliente do serviço, neste caso o agente C2FS, tem que
ter a preocupação extra de verificar se o ficheiro já está bloqueado para escrita, e caso
não esteja deve bloqueá-lo. Se o ficheiro não estiver bloqueado para escrita deve também
obrigar a operação Trunc-Data a sincronizar os dados com as clouds especificando-o no
argumento da operação toSyncWithClouds.
Algorithm 4: Trunc Data
Map h String, byte[] i hashs;
Map h String, boolean i valueToSend;
Map h String, int i sizes;
CacheOnDiskManager cacheDisk;
CacheOnMemoryManager cacheMemory;
1
2
3
Entrada: name - identificador do ficheiro, key - chave para desencriptar os dados,
hash - resumo criptográfico para verificar se os dados está em cache
estão actualizados, size - novo tamanho do ficheiro,
toSyncW ithClouds - variável que diz à operação se é necessário
sincronizar os dados com as clouds ou não
Saı́da: nenhuma
inı́cio
se (U pdate Cache(name, key, hash)) então
retorna f alse;
cacheDisk.truncateData(name, size);
se (cacheM emory 6= null && cacheM emory.contains(name)) então
cacheM emory.truncateData(name, size);
4
5
6
11
sizes.add(name, size);
valueT oSend.add(name, true);
write to disk(name, true, size);
se (toSyncW ithClouds = true) então
Sync W Clouds(name, key);
12
retorna true;
7
8
9
10
fim
Operação Sync W Disk. Esta operação tem a função de armazenar um determinado
ficheiro presente na memória volátil no disco local. Como mostra o algoritmo 5 o ficheiro
só é armazenado em disco se sofreu alguma alteração desde o momento que foi carregado para memória (linha 2). Caso se verifique isso, o ficheiro é obtido da memória
(linha 3), depois é escrito em disco (linha 4), e por fim, é armazenado também em
Capı́tulo 3. Armazenamento de Dados do C2FS
40
disco a informação de que o ficheiro em disco sofreu alterações de forma a possibilitar a
recuperação após um falha.
Esta operação é invocada pelo agente C2FS na operação fsync se o utilizador do C2FS
apenas de desejar que a sincronização dos dados seja feita no disco local. Sincronizar
os dados apenas no disco nesta chamada ao sistema pode significar um grande aumento
da performance se, durante a abertura e o fecho de um ficheiro, a operação fsync for
invocada muitas vezes. Note-se que se o cliente configurar o sistema para a operação
fsync sincronizar os dados no disco e não estiver a utilizar a memória volátil, os dados já
estarão previamente sincronizados, não sendo assim necessário nenhum acesso ao disco.
Algorithm 5: Sync W Disk
Map h String, int i sizes;
CacheOnDiskManager cacheDisk;
CacheOnMemoryManager cacheMemory;
1
2
3
4
5
Entrada: name - identificador do ficheiro
Saı́da: nenhuma
inı́cio
se (cacheM emory 6= null && cacheM emory.contains(name) &&
valueT oSend.get(name) = true) então
data ←− cacheM emory.readData(name, 0, sizes.get(name));
cacheDisk.writeData(name, data, 0);
write to disk(valueT oSend);
fim
Operação Sync W Clouds. Esta operação é utilizada para sincronizar os dados com a
cloud-of-clouds. O algoritmo 6 começa por efectuar uma chamada à operação Sync W Disk
para garantir que os dados que irão ser armazenados nas clouds estão previamente armazenados no disco local (linha 2). Os dados só são então enviados para as clouds se
sofrerem alguma alteração em cache (linha 6). Se não sofrerem qualquer alteração significa que estão iguais ao último download ou envio efectuado, ou seja, não é necessário
enviá-los para as clouds. Antes de serem enviados, os dados são lidos do disco (linha 7) e
depois são cifrados com a chave simétrica (linha 8) fornecida pelo cliente. Os dados são
então enviados consoante o modelo utilizado (sı́ncrono ou assı́ncrono). Estes diferentes
modelos são explicados em detalhe na secção 3.4.3. Em qualquer dos modelos, assim
que o envio de dados para as clouds terminar é obtido o novo resumo criptográfico dos
dados enviados (linha 6) retornado na operação de escrita do DepSky. O serviço de directorias é então notificado com este novo resumo e com o tamanho dos dados (linha 7).
É necessário esta sincronização entre o serviço de directorias e o serviço de armazenamento para garantir que os metadados só serão actualizados depois dos dados o serem,
de forma a que nunca nenhum cliente leia os metadados de um ficheiro que ainda não
Capı́tulo 3. Armazenamento de Dados do C2FS
41
existe. Embora assim um cliente possa obter metadados de uma versão mais antiga aos
dados que estão nas clouds, é muito menos provável que o contrário descrito em cima,
pois uma escrita nos servidores de metadados [32] é muito mais rápida que uma escrita
nos servidores de armazenamento. Por fim o novo resumo criptográfico é armazenado
substituindo o antigo, o ficheiro é transferido do estado de alterado para actualizado, e as
estas informações são armazenadas em disco (linhas 8-11).
Esta operação é invocada pelo agente C2FS na operação flush garantindo assim que no
fecho de qualquer ficheiro os dados serão actualizados na cloud-of-clouds. Esta operação
pode também ser invocada pelo agente C2FS na operação fsync se o utilizador do C2FS
assim o quiser. Note-se que desde que o ficheiro é aberto até ser fechado, pode ser requerida muitas vezes a sua sincronização (através de chamada ao sistema fsync). Assim,
sincronizar os dados na cloud-of-clouds com a operação fsync, embora ofereça garantias
mais seguras (por exemplo, tolerar a falha do disco), significa uma diminuição na performance do C2FS.
Algorithm 6: Sync W Clouds
Map h String, byte[] i hashs;
Map h String, boolean i valueToSend;
Map h String, int i sizes;
CacheOnDiskManager cacheDisk;
1
2
3
4
5
6
7
8
9
10
Entrada: name - identificador do ficheiro, key - chave para encriptar os dados
Saı́da: nenhuma
inı́cio
se (valueT oSend.get(name) = true) então
Sync W Disk(name);
data ←− cacheDisk.getData(name, 0, sizes.get(name));
cipherData ←− encryptData(key, data);
newHash ←− Send By M odel(name, cipherData);
notif yDirectoryService(name, newHash, data.length);
hashs.add(name, newHash);
valueT oSend.add(name, f alse);
write to disk(name, newHash, f alse);
fim
Operação Delete Data. Esta operação serve para eliminar um ficheiro do disco local.
Os ficheiros não são eliminados das clouds durante esta operação para evitar a diminuição
do desempenho do sistema, uma vez que para um determinado ficheiro não ficar visı́vel
aos clientes após a sua eliminação basta eliminar os metadados a ele referentes. Outro
motivo para não se proceder à eliminação dos dados nas clouds nesta operação deve-se
ao facto da necessidade de concretizar um colector de lixo que elimine as versões antigas
Capı́tulo 3. Armazenamento de Dados do C2FS
42
de ficheiros ainda não eliminados. Assim, faz sentido proceder à eliminação de dados nas
clouds, quer seja de versões antigas ou mesmo de todas as versões de um ficheiro (se já
tiver sido eliminado), no mesmo protocolo (secção 3.4.5). Além de eliminar o ficheiro
do disco, elimina também todas as entradas em todas as estruturas mantidas pelo serviço
de armazenamento referentes a ele, incluindo a estrutura de resumos criptográficos, a
estrutura que mantém os ficheiros que têm que ser enviados para as clouds, a estrutura
que mantém o tamanho dos ficheiros e, se o modelo de envio de dados por assı́ncrono, da
fila de envio (secção 3.4.3).
Esta operação é integrada no agente C2FS na operação unlink.
Operação Release Data. Esta operação tem o objectivo de libertar o ficheiro. Primeiro
o ficheiro deve ser eliminado da memória volátil se esta o contiver. Depois, o lock efectuado sobre o ficheiro deve ser libertado através do serviço de locks [32]. No caso do
modelo de envio ser sı́ncrono, o ficheiro é libertado no instante, pois este não está a ser
enviado. Já no caso de o modelo ser assı́ncrono, se o ficheiro estiver a ser enviado ou
ainda estiver na fila de envio, o ficheiro só é libertado quando o seu envio em background
terminar.
Esta operação é invocada pelo agente C2FS na operação release de forma a libertar
o ficheiro após todos os descriptores associados a este serem fechados. Como já descrito
anteriormente na tabela 3.1, sobre um ficheiro aberto podem existir vários descriptores se
por exemplo a aplicação fizer uso da função fork, e sobre cada um destes descriptores,
que apontam para o mesmo ficheiro, é invocada a operação flush. Já a operação release é
invocada só quando o último descriptor for fechado.
Ilustração do Funcionamento. A fig 3.4 mostra, de uma forma resumida, uma possı́vel
sequência de chamadas ao sistema que uma qualquer aplicação pode exercer, e o que elas
desencadeiam no agente C2FS e, por sua vez, no serviço de armazenamento aquando
do uso da cache em memória. Note-se que nesta imagem está escondida a interacção
existente com os serviços de directorias e locks [32].
A cache em memória permite assim melhorar o desempenho do C2FS (principalmente
quando se opera em ficheiros grandes) aquando de sucessivas operações de escrita ou de
leitura num mesmo conjunto de ficheiros. Isto porque quando um ficheiro é aberto (open),
a operação Update Cache é chamada e o ficheiro é carregado para memória. Depois todas
as escritas e/ou leituras que são efectuadas sobre um ficheiro aberto são efectuadas sobre
a memória volátil. Quando o ficheiro é fechado, é chamada a operação Sync W Clouds
que armazena devidamente as actualizações nas clouds e posteriormente a operação Release Data que liberta o ficheiro da memória.
Capı́tulo 3. Armazenamento de Dados do C2FS
43
Figura 3.4: Desencadeamento das chamadas ao sistema no serviço de armazenamento.
3.4.3
Modelo de Envio de Dados
Como já mencionado nas secções anteriores, o serviço de armazenamento pode ser
configurado para efectuar escritas sı́ncronas ou assı́ncronas de ficheiros para a cloud-ofclouds, tendo esta escolha influência nas garantias de consistência dos dados em cache
fornecidas pelo serviço. Nos pontos seguinte são descritos estes dois modelos.
• No caso de as escritas serem sı́ncronas, o retorno da operação Sync W Clouds
garante que os ficheiros já estão devidamente armazenados na cloud-of-clouds. Esta
garantia deve-se ao facto do cliente ser obrigado a esperar a confirmação da escrita do ficheiro nas clouds, tendo a garantia que, após a conclusão da operação, o
ficheiro está correctamente armazenado. Assim a utilização deste tipo de escritas
fornece tolerância a faltas do disco local uma vez que o cliente tem a garantia que
após o retorno da operação, o disco pode falhar pois os dados podem ser recuperados das clouds.
• No caso de serem utilizadas escritas assı́ncronas, tal não se verifica, pois o cliente
não tem garantias do momento em que o ficheiro irá chegar às clouds. Embora
exista uma diminuição das garantias de consistência da cache, a utilização deste
tipo de escritas representa um significativo aumento do desempenho do sistema. A
concretização deste modelo de envio envolve um sistema de filas onde existe prioridade de envio para os primeiros ficheiros que forem adicionados a esta. O sistema
44
Capı́tulo 3. Armazenamento de Dados do C2FS
mantém assim tarefas em background a enviar dados de ficheiros diferentes em simultâneo de modo a maximizar o desempenho. O número de tarefas a desempenhar
este trabalho é configurado pelo cliente. Sempre que uma das tarefas terminar o envio de um ficheiro, é iniciado outro envio caso existam ficheiros na fila. Note-se
que se não houvesse este sistema de filas e que se sempre que se quisesse enviar um
ficheiro assincronamente para as clouds fosse iniciada uma tarefa em background,
a máquina onde o C2FS estaria a correr ficaria sobrelotada caso estivessem a ser
enviados centenas de ficheiros em simultâneo. Se for adicionado um ficheiro à fila
e este já lá existir, os dados que estavam para enviar são substituı́dos pelos novos
evitando assim o envio de uma versão que já não é a mais actual. Como já descrito
na operação Delete Data se um determinado ficheiro for eliminado enquanto está
na fila, é também eliminado da fila, evitando assim o seu envio. Tanto a substituição
de dados na fila como a sua eliminação representam uma diminuição nos custo relacionados com a transferência de dados para as clouds.
3.4.4
Durabilidade dos Dados
A tabela 3.2 apresenta os diferentes nı́veis em que os dados são mantidos pelo serviço
de armazenamento. O primeiro nı́vel diz respeito aos dados em memória volátil. Como
podemos ver, é o nı́vel em que se verifica o melhor desempenho de sistema, pois cada
operação de escrita ou de leitura é efectuada com uma latência na ordem dos microssegundos. Contudo não fornece nenhuma garantia no que diz respeito à tolerância de faltas.
No segundo nı́vel, que é quando os dados atingem memória estável no disco local, o
serviço de armazenamento suporta a falha da estação de trabalho onde o C2FS está a
correr, podendo recuperar os dados depois do sistema ser reiniciado. No último nı́vel
os dados são mantidos na cloud-of-clouds permitindo assim a partilha de ficheiros entre
diferentes clientes. Como podemos ver na tabela, a partir do momento em que os dados estão armazenados na cloud-of-clouds o sistema suporta tanto a falha do disco local,
como a falha de f clouds num sistema em que são utilizadas n − f [19]. Este é também
o nı́vel em que a latência para as operações de escrita e leitura apresenta valor mais elevados. Este modelo de durabilidade, ou seja, as diferentes localizações em que os dados
se encontram aliado à integração das operação que gerem os dados nestas localizações no
C2FS, permite a este garantir um nı́vel de consistência forte (consistência ao fechar [26]).
Localização dos Dados
memória não estável
disco local
cloud-of-clouds
Latência
microssegundos
milissegundos
segundos
Tolerância a Faltas
nenhuma
crash
falha do disco e do provedor
Tabela 3.2: Durabilidade dos dados.
Partilha
não
não
sim
Capı́tulo 3. Armazenamento de Dados do C2FS
3.4.5
45
Colector de Lixo
Conforme já mencionado anteriormente, cada escrita no DepSky representa uma versão
nova nas clouds. Assim uma preocupação que este serviço tem que ter é a de eliminar
versões antigas de ficheiros que ainda não tenham sido eliminados. Juntamente com o procedimento de eliminar versões antigas de ficheiro, são também eliminados das clouds os
ficheiros que já foram eliminados do sistema de ficheiros mas que ainda estão armazenados nas clouds (operação Delete Data). Para a eliminação de versões antigas, o cliente
do serviço é responsável por fornecer o número de versões que devem ser mantidas nas
clouds (na continuação da descrição deste protocolo, este número é representado por v).
Em ambos os casos, o objectivo principal, além de o de deixar mais espaço disponı́vel, é
o de não obrigar os utilizadores do C2FS a pagar demasiado por dados obsoletos que não
sejam mais necessários. Em baixo é explicado como se procede à eliminação de versões
e à eliminação de ficheiros por completo:
• Para a eliminação de versões que não sejam mais necessárias, o serviço de armazenamento utiliza o protocolo para colectar lixo disponibilizado pelo DepSKy
(garbageColector(unidade de dados, número de versões a manter)). Este protocolo elimina todas as versões excepto as que o cliente especificar que quer manter.
Por exemplo, se uma determinada unidade de dados do DepSky (que referencia um
ficheiro no C2FS) contiver dez versões (sendo a primeira a mais recente) e este protocolo for invocado fornecendo como argumento a unidade de dados e o número
de versões a manter (por exemplo se v tomar valor três), serão eliminadas todas as
versões desde a quarta até à décima.
• Para a eliminação de ficheiros é utilizada a operação deleteContainer(unidade de
dados) disponibilizada pelo DepSky, que dado uma unidade de dados do DepSky
elimina toda a informação a ela referente. Isto significa que em cada cloud são
eliminadas todas as versões referentes a este ficheiro.
Assim, o serviço de armazenamento do C2FS implementa um colector de lixo que
quando activado, é responsável por estas duas acções. A complexidade da formulação
deste protocolo é escolher o momento óptimo para activá-lo, pois para escolher este momento terı́amos que saber exactamente a carga de trabalho que seria exercida sobre o
sistema. É excluı́da a hipótese de se concretizar este protocolo como um serviço externo
ao C2FS onde darı́amos a responsabilidade ao cliente de o executar quando o bem entendesse.
Uma das formas mais lógicas para activar o colector de lixo seria a cada t unidades
de tempo. Contudo, este modelo poderia levantar alguns problemas. Primeiro, se o
valor t tomasse valores pequenos, o cliente poderia ser obrigado a ter custos adicionais
Capı́tulo 3. Armazenamento de Dados do C2FS
46
desnecessários, uma vez que teriam que ser listadas3 frequentemente todas as versões de
todos os ficheiros, que poderiam até não ter nada para eliminar (se tivessem menos versões
que aquelas a manter). Por outro lado, se o valor t tomasse valores grandes e o sistema
sofresse de uma carga de trabalho com muitas escritas, o cliente iria pagar demasiado por
uma grande quantidade de dados.
Para activar o colector de lixo de uma forma o mais perto do óptimo possı́vel, o serviço
de armazenamento oferece uma solução que tem em conta a quantidade total de bytes e
o número total de versões que existem para eliminar, conseguindo assim não ter a necessidade de estudar a carga de trabalho a cada instante. A atenção prestada à totalidade de
bytes transferidos permite accionar o protocolo num perı́odo de tempo razoável na eventualidade do utilizador do C2FS manter ficheiros grandes no sistema. Contudo, assim o
protocolo pode levar muito tempo a ser activado se o utilizador do C2FS mantiver muitas
versões pequenas no sistema. De forma a evitar isso é também dada atenção ao número
de versões que estão para eliminar nas clouds.
Assim, o colector de lixo é activado quando se verificar algum dos seguintes acontecimentos:
• Se o número total de bytes a eliminar transferidos para as clouds for superior a X.
• Se o número total de versões a eliminar presentes nas clouds for superior a Y .
Para X foi escolhido o valor de 1,5 GB (1610612736 bytes). Como mencionado
anteriormente o tamanho máximo por ficheiro para garantir uma boa performance do
C2FS é de 50 MB. Este valor de X permite assim, no pior caso (assumindo 50 MB por
ficheiro), limpar as clouds quando existem aproximadamente 31 versões. Já para Y foi
escolhido o valor de 1500 versões. Note-se que se o valor de X não for atingido, temos
aproximadamente cerca de 1 MB por cada uma desta 400 versões. Estes valores foram
pensados para que o protocolo não demore muito tempo aquando da sua execução para
não penalizar o desempenho do sistema. Contudo, estes valores podem não ser óptimos.
Para encontrarmos os valores óptimos para X e Y terı́amos que efectuar um estudo mais
aprofundado. Note-se que estes valores podem ser facilmente reconfigurados pelo cliente.
Computando X e Y. O serviço de armazenamento faz a contagem do número de versões
e da quantidade de bytes transferidos para as clouds por cada ficheiro. A contagem das
versões é feita da seguinte forma: enquanto um determinado ficheiro estiver no seu tempo
de vida (ainda não foi eliminado) são contadas todas as vezes que este foi transferido
para as clouds. Esta contagem é só iniciada após v transferência (uma vez que enquanto
não for eliminado, queremos lá manter nunca menos que v versões); quando o ficheiro
for eliminado, o número de transferências para este é incrementado em v (uma vez que
3
Note-se que para a listagem de versões nas clouds está associado um preço, dependendo este preço do
provedor.
Capı́tulo 3. Armazenamento de Dados do C2FS
47
na próxima execução do colector de lixo têm que ser eliminadas todas as versões deste).
Assim, a cada instante, o número total de versões que existem para eliminar são a soma
de todas estas contagens para todos os ficheiros mantidos em cache. Para a contagem do
número de bytes, assim como na contagem de versões, são somados para cada ficheiro os
bytes transferidos em cada transferência. No caso de ficheiros já eliminados são contados
os bytes transferidos em todas as escritas efectuadas, já no caso de ficheiros ainda no
activo são contados os bytes transferidos para todas as escritas efectuadas com a excepção
das últimas v escritas, pois estas não necessitam ser eliminadas4 .
Para possibilitar a soma correcta do número de todas as versões a eliminar e do número
total de bytes transferidos a cada instante, mesmo após o sistema ser reiniciado, são mantidas em disco local as estruturas que armazenam os números de versões e o número de
bytes transferidos para cada ficheiro. Estas estruturas são actualizadas durante a execução
do protocolo (depois de um ficheiro ser limpo, são eliminadas as entradas a ele referentes),
para permitir a sua recuperação depois de uma falha. Note-se que não conseguimos contabilizar a totalidade de número de versões e o número de bytes presentes nas clouds para
ficheiros partilhados, uma vez que os outros clientes também podem efectuar escritas
nestes ficheiros. Contudo, assume-se que mais tarde ou mais cedo algum dos clientes irá
limpar o ficheiro, uma vez que cada instância do C2FS executa um protocolo colector de
lixo.
Este colector de dados não funciona correctamente, no que diz respeito a ficheiros
que já foram eliminados do sistema mas que ainda não foram eliminados das clouds, se
o utilizador do C2FS mudar de estação de trabalho, pois perde-se os dados armazenado
no disco local que referenciam esses mesmos ficheiros. Contudo, esta falha poderia ser
facilmente corrigida se as estruturas fossem mantidas nas clouds. Mas devido às muitas
actualizações que estas estruturas sofrem, o custo para o utilizador do C2FS seria muito
excessivo, pois todas as actualização referidas anteriormente feitas no disco teriam que
ser feitas nas clouds.
3.5
Considerações Finais
Neste capı́tulo foi primeiro apresentada a visão geral do C2FS, um sistema de ficheiros
para cloud-of-clouds que ao mesmo tempo que fornece disponibilidade, integridade e confidencialidade dos dados armazenado, permite também a partilha de ficheiros. Posteriormente foi descrito o módulo FUSE, que permite a implementação e execução do C2FS
a nı́vel do utilizador. Foram também introduzidas as alterações feitas a nı́vel do DepSky
de forma a este responder melhor às necessidades do DepSky. Por fim foi apresentado o
4
No entanto são armazenados em disco o número de bytes referentes a escritas recentes para podermos adicionar ao total de bytes transferidos o terceiro valor mais antigo quando uma nova transferência é
efectuada.
Capı́tulo 3. Armazenamento de Dados do C2FS
48
serviço de armazenamento do C2FS. Nesta secção foram descritas as operações que permitem gerir os dados nas três diferentes localizações que estes se podem encontrar sendo
elas a memória, o disco, e a cloud-of-clouds. Por último foi explicado o colector de lixo
que permite a limpeza de dados obsoletos nas clouds.
No próximo capı́tulo são apresentados os detalhes de concretização presentes no serviço
de armazenamento
Capı́tulo 4
Concretização do Serviço de
Armazenamento
Neste capı́tulo são apresentados os aspectos relevantes da concretização do serviço de
armazenamento do C2FS. Primeiro é apresentado o modelo de classes, e posteriormente
alguns diagramas de sequência que mostram a interacção entre estas classes aquando da
invocação das diferentes operações disponibilizadas.
Como já mencionado na secção 3.2, tanto o DepSky [19] como o DepSpace [20] são
concretizados na linguagem Java. Razão essa que levou à utilização do módulo FUSE-J
[8] para a implementação do sistema de ficheiros. O serviço de armazenamento, sendo o
componente com a função de gerir os dados do sistema de ficheiros no DepSky, também
é concretizado na linguagem Java, facilitando a sua integração.
Em relação á cifra dos dados efectuada por este serviço, é utilizada a técnica AES
através das classes do pacote javax.crypto da plataforma Java. Em relação ao resumo
criptográfico computado a nı́vel do DepSky, este é computado através do algortimo SHA1 utilizando a classe fornecida pela API do Java java.security.MessageDigest.
De seguida é primeiramente apresentado o modelo de classes do sistema e posteriormente os diagramas de sequência para as operação de obtenção dos dados das clouds, da
escrita do dados na cache e da escrita dos dados nas clouds.
4.1
Diagrama de Classes
A figura 4.1 apresenta o diagrama de classes do serviço de armazenamento concretizado.
O C2FSAgent é a classe que implementa o agente C2FS, ou seja, é a classe que integra o serviço de armazenamento, assim como os restantes serviços [32], na interface
de sistema de ficheiros (secção 3.2). Esta classe mantém uma instância do objecto StorageService, objecto este que implementa a interface IStorageService. Esta interface foi
pensada para responder da melhor forma possı́vel aos objectivos do C2FS.
O objecto StorageService permite ao agente C2FS gerir os dados nas três diferentes
localizações: memória, disco e cloud-of-clouds. Quando iniciado, este recebe parâmetros
49
Capı́tulo 4. Concretização do Serviço de Armazenamento
50
de configuração, e consoante estes parâmetros, assim são as instâncias que este cria para
gerir os dados.
Por omissão, o objecto do tipo StorageService mantém uma instância do objecto
cacheDiskManager. Este objecto é responsável por efectuar todos os acessos ao disco, e
de aplicar politicas LRU para a substituição de objectos em cache quando necessário. Para
aceder ao disco, é utilizada a classe RandomAccessFile que permite aceder ao ficheiro em
offsets diferentes. Este objecto mantém uma instância do StorageService para no caso da
necessidade de substituir ficheiros em cache, serem invocadas as operações syncWClouds,
para armazenar o ficheiro nas clouds caso seja necessário, e deleteData(containerId), para
se proceder à limpeza de todas as entradas em todas as estruturas referentes ao ficheiro
em cache a substituir .
Contudo, consoante a configuração indicada pelo C2FSAgent, também este pode manter uma instância do objecto CacheMemoryManager. Assim como a classe descrita em
cima, este objecto permite aceder a todos os ficheiros mantidos em memória através das
operações genéricas de acesso à cache (ICacheManager). Este mantém uma instância do
objecto CacheDiskManager de forma a garantir que um determinado ficheiro é devidamente armazenado em memória estável aquando da aplicação de politicas LRU.
O objecto StorageService mantém também uma instância da classe DepSkyAcessor.
Esta é a classe que opera directamente com o DepSky, e é também responsável por cifrar
o ficheiro antes da sua escrita nas clouds, bem como por decifrar aquando da sua leitura.
Se o C2FSAgent configurar o sistema para escrever assincronamente para as clouds, o
objecto StorageService mantém também um objecto do tipo SendingQueue. Esta classe
permite a adição e remoção de ficheiros na fila de envio. O objecto que é mantido na fila é
o ObjectInQueue que armazena a informação necessária para o envio. O envio neste caso
é feito através do objecto DataSync que representa uma thread possibilitando assim o
envio dos dados em background. Neste caso, cada thread de envio mantém uma instância
diferente do DepSkyAcessor para o envio de diferentes ficheiros ser feito em paralelo.
A classe DataStatsManager mantem uma Map de objectos do tipo DataStats. Cada
objecto destes guarda as informações que são necessárias manter em disco sobre cada
ficheiro em cache. A classe é assim responsável por efectuar todas as actualizações nos
objectos DataStats e armazenar estas actualizações em disco. Esta classe tem também um
objecto do tipo GarbageCollectorService onde são armazenadas as informações necessárias
para a activação do colector de lixo (Garbagecollector).
A tabela 4.1 mostra as linhas de código para cada componente do sistema.
4.2
Diagramas de Sequência
Nesta secção são apresentados três diagramas de sequência diferentes presentes nas
figuras 4.2, 4.3 e 4.4. O primeiro representa o fluxo de operações existente no serviço
Capı́tulo 4. Concretização do Serviço de Armazenamento
Figura 4.1: Modelo de classes do sistema.
51
Capı́tulo 4. Concretização do Serviço de Armazenamento
Classe
C2FSAgent
StorageService
DiskCacheManager
MemoryCacheManager
DepSkyAcessor
DataStats
DataStatsManager
SendingQueue
DataSync
GarbageCollector
GarbageCollectorService
52
Número de Linhas de Código
988
322
85
70
75
40
250
85
80
150
40
Tabela 4.1: Linhas de código das classes do serviço de armazenamento
de armazenamento aquando da operação de actualização da cache. O segundo diagrama
é referente à operação de escrita na cache. Por fim, o terceiro, representa a operação
de sincronização dos dados na cloud-of-clouds. No primeiro e no último diagrama é
escondido o retorno da operação (erro ou ok) de forma a simplificá-los.
Leitura das clouds. A figura 4.2 mostra o fluxo presente na operação de actualização
da cache. Em primeiro lugar é obtido o objecto representante do fileId fornecido. No
caso de o ficheiro não existir em cache, é criado um novo objecto DataStats para este
novo ficheiro e este é adicionado à Map que guarda os objectos deste tipo.
Após obtido o hash referente à versão em cache (através do objecto DataStats), é
necessário verificar se este é igual ao hash fornecido pelo agente C2FS, pois se for igual
significa que os dados em cache são os mesmos que os dados presentes nas clouds, não
sendo assim necessário efectuar o download.
Como podemos ver no diagrama, caso o download seja necessário, o objecto StorageService tenta obter no máximo 4 vezes o ficheiro das clouds através do objecto DepSkyAcessor. Este objecto, por sua vez lê os dados usando o DepSky DepSky através
da operação readMatching(Du, hash) e, caso consiga obter os dados correspondentes ao
hash fornecido, decifra-os e retorna os dados em claro, caso contrário retorna null. No
caso de não se conseguir obter os dados em nenhuma das quatro tentativas é retornado
erro ao C2FSAgent.
Se os dados conseguirem ser obtidos, são então colocado na cache em disco através
do objecto DiskCacheManager. Depois o objecto presente na Map de objectos do tipo
DataStats referente a este ficheiro é actualizado com o novo estado (actualizado), com o
novo tamanho e com o novo resumo criptográfico (referente aos dados lidos). Note-se
que o objecto é escrito para disco pelo objecto DataStatsManager só quando o hash é
actualizado.
Capı́tulo 4. Concretização do Serviço de Armazenamento
53
Esta operação escreve ainda os dados em memória através do objecto MemoryCacheManager, quer tenha sido necessário efectuar a leitura das clouds ou não.
Escrita na cache. O diagrama presente na figura 4.3 mostra o fluxo de mensagens efectuado na operação de escrita em cache. Quando o objecto StorageService recebe uma
operação de escrita em cache, este encaminha o pedido de escrita para o local pretendido.
Ou seja, para o objecto MemorycacheManager caso o StorageService esteja configurado
para a utilização de cache em memória, ou para o disco caso contrário. Note-se que
antes de efectuar a escrita, o estado do objecto é alterado para true, definindo assim que
este ficheiro sofreu alterações e necessita ser armazenado em memória estável. No caso
de a escrita ser efectuada para o objecto DiskcacheManager, esta alteração é também
armazenada em disco através do objecto DataStatsManager explicitando-o no terceiro
argumento da operação setState, de forma a possibilitar a recuperação na ocorrência de
uma falha antes do seu envio para as clouds. Por fim, é verificado se a escrita alterou
o tamanho do ficheiro. Caso tenha alterado, o novo tamanho é armazenado no objecto
DataStats referente ao ficheiro escrito e este novo tamanho é retornado ao agente C2FS.
Caso contrário, retorna o tamanho que já existente no objecto DataStats.
Escrita nas clouds. A figura 4.4 apresenta o diagrama de sequência da operação que
escreve os dados presentes em cache na cloud-of-clouds. A primeira preocupação da
operação é a de chamar a operação syncDisk(containerId) de modo que os dados actualizados em memória fiquem armazenados em disco de forma a garantir a coerência da
cache em memória estável com os dados presentes nas clouds.
O próximo passo é obter o estado do ficheiro através do objecto DataStatsManager
que gere a Map de objectos do tipo DataStats. Se o estado estiver a false significa que não
houve alterações no ficheiro (provavelmente ocorreram só operações de leitura) e portanto
não é necessário enviá-lo para as clouds. Caso contrário, este tem que ser enviado. Neste
caso os dados são então obtidos da cache através do objecto DiskCacheManager.
Se o C2FSAgent utilizar escritas assı́ncronas, os dados são adicionados ao objecto
SendingQueue que gere a fila de envio. O fluxo da operação presente aquando da adição
de um novo objecto na fila não está presente de forma a simplificar o diagrama. Já se
o envio for sı́ncrono, o StorageService chama a operação de escrita para o DepSky presente no objecto DepSkyAcessor. Este, antes de escrever no DepSky, cifra os dados com
a chave fornecida. Após a escrita, o objecto DataStats referente ao ficheiro enviado é
actualizado com o estado a false, de forma a não serem enviados os mesmos dados para
as clouds, e o hash que resulta da escrita no DepSky substitui o hash antigo. Aquando
da actualização do hash, o objecto DataStats é armazenado em disco. De seguida o objecto DataStatsManager é também notificado com o número de bytes transferidos para
a cloud. Este por sua vez actualiza esta informação no objecto GarbageCollectorService
Capı́tulo 4. Concretização do Serviço de Armazenamento
Figura 4.2: Operação de leitura das clouds.
54
Capı́tulo 4. Concretização do Serviço de Armazenamento
55
Figura 4.3: Operação de escrita em cache.
para permitir a activação do colector de lixo. Por fim o DirectoryService é notificado com
o novo hash e como o tamanho dos dados escritos e posteriormente é chamada a operação
commitLocalMetadata para proceder ao envio dos metadados para os servidores.
4.3
Agente C2FS
Como já mencionado várias vezes anteriormente, o agente C2FS é o componente que
implementa as operações do sistema de ficheiros e que integra os três diferentes serviços
(armazenamento, directorias e locks) onde, consoante a semântica de cada operação, assim as operações dos diferentes serviços a invocar. Assim como o serviço de armazenamento, este por sua vez também é configurável. Em baixo são listadas os parâmetros de
configuração que os clientes podem utilizar aquando da montagem do sistema de ficheiros
no Linux:
• -use memory cache - indica que o sistema irá usar o serviço de armazenamento
com cache em memória volátil (por omissão só é utilizada cache em disco);
• -assync model - indica que o sistema irá usar o serviço de armazenamento com
escritas assı́ncronas (por omissão utiliza escritas sı́ncronas);
• -max memory size=size - indica o tamanho máximo da cache em memória no serviço
de armazenamento (por omissão size = 1 GB);
Capı́tulo 4. Concretização do Serviço de Armazenamento
Figura 4.4: Operação de escrita para as clouds.
56
Capı́tulo 4. Concretização do Serviço de Armazenamento
57
• -num threads=num - indica o número de threads a enviar dados em background
(por omissão num = 4);
• -mantain old version=num - indica o número de versões a manter para cada ficheiro
aquando da execução do colector de lixo (por omissão num = 3).
• -fsync to clouds - indica que a operação fsync envias os dados para as clouds (por
omissão escreve-os na cache em disco);
• -use non sharing DS - indica que o sistema irá usar o serviço de directorias sem
partilha de ficheiros (por omissão utiliza a partilha de ficheiros);
• -delta=time - indica o tempo de validade dos metadados em cache (por omissão
time = 0).
4.4
Considerações Finais
Neste capı́tulo foram apresentado alguns detalhes de implementação do serviço de armazenamento. Primeiro foi descrito o modelo de classes e como os diferentes componentes interagem entre si. Posteriormente foram ilustrados os modelos de sequência para
as operações de actualização da cache através da leitura dos dados das clouds, de escrita na cache (tanto em memória como em disco) e de escrita dos dados actualizados na
cloud-of-clouds.
No próximo capı́tulo é apresentada uma avaliação experimental do desempenho deste
serviço e do C2FS.
Capı́tulo 4. Concretização do Serviço de Armazenamento
58
Capı́tulo 5
Avaliação
Neste capı́tulo é apresentada uma avaliação do serviço de armazenamento para o
C2FS. Em primeiro lugar serão apresentadas as latências inerentes ao envio de dados para
as clouds para diferentes tamanhos de ficheiros. De seguida serão mostradas medições de
desempenho efectuadas ao C2FS com diferentes configurações.
Por fim, será comparado o desempenho do C2FS ao desempenho de outros dois sistemas de ficheiros para clouds, nomeadamente o S3FS [16] e o S3QL [17].
5.1
Metodologia
As medições apresentadas neste capı́tulo foram obtidas executando três diferentes
benchmarks, sendo eles o Iozone [10], o PostMark [27] e o Filebench [6]. O Iozone
exercita operações de escrita e leitura sequenciais e aleatórias sobre um ficheiro. O
PostMark, embora apresente um comportamento mais adequado para testar a gestão de
metadados (criação e destruição de ficheiros pequenos), pode ser configurado para criar
ficheiros com um tamanho considerável, podendo assim testar o comportamento do serviço
de armazenamento aquando de operações de escritas e leituras em diferentes ficheiros ao
mesmo tempo. Por fim, o Filebench permite testar diferentes tipos de workloads. Neste
caso foi utilizado o workload randomrw que permite exercitar operações de escrita e
leitura aleatórias sobre o mesmo ficheiro.
Os diferentes benchmarks foram configurados da seguinte forma:
• Iozone - Este foi configurado para testar operações de escrita e leitura sequenciais
e não sequenciais para ficheiros com 512 KB, 1, 2, 4, 8, 16 e 32 Mb.
• PostMark - Este, por sua vez, foi configurado para criar e operar sobre 764 ficheiro
com tamanhos aleatórios entre 512 Kb e 2 Mb.
• Worload randomrw - Por fim, este foi configurado para exercer carga de trabalho no
C2FS através de 6 threads diferentes (3 para leituras e 3 para escritas) num único
ficheiro de 50MB.
59
Capı́tulo 5. Avaliação
60
Nestes três benchmarks podemos avaliar o comportamento do serviço de armazenamento para algumas das propriedades descritas no trabalho apresentado em [25] para os
workloads das aplicações de hoje em dia, nomeadamente o acesso a muitos ficheiros
em simultâneo, escritas e leituras aleatórias e acessos efectuados a partir de diferentes
threads.
Todas as medições foram efectuadas num computador com aproximadamente 2 anos,
localizado em Lisboa. Este computador tem como caracterı́sticas principais um processador 2.4 GHz Intel Core 2 Duo, e uma memória de 4GB DDR3. Para efectuar as
medições foi utilizado um serviço de internet com ligação de 23.67 Mbps de download
e 5.06 Mbps de upload. O DepSky [19] foi configurado para replicar os dados por 4
diferentes provedores de armazenamento, sendo eles Amazon S3 [4], RackSpace [15],
Windows Azure [11] e Google Storage [9]. O driver de acesso esta última cloud foi desenvolvido de raiz para estes experimentos já que o DepSky original não suportava este
serviço [19]. É importante referir ainda que os servidores utilizados para a Amazon S3,
RackSpace e Windows Azure estão localizados na Europa, enquanto que o servidor utilizado para armazenar os dados na Google Storage situa-se no Estados Unidos. O serviço
de directorias utilizado para esta avaliação foi uma versão sem partilha de ficheiros, na
qual os metadados não são armazenado no DepSpace [32]. Esta escolha justifica-se com
o objectivo de minimizar a influência deste serviço nos resultados obtidos.
5.2
Latência das Escritas e Leituras de Dados
Na figura 5.1 são apresentadas as latências experienciadas aquando da escrita e da
leitura de dados para as clouds através do DepSky. Estes valores foram obtidos através
da execução do benchmark Iozone. Foram medidas as latências para escritas e leituras de
dados com seis distintos tamanhos, sendo eles 512KB, 1, 2, 4, 8, 16 e 32MB. Para cada
um dos tamanhos dos blocos de dados testados foram executas 100 operações.
Como podemos observar no gráfico 5.1(a), as latências obtidas para as escritas sofrem
uma perda de desempenho mais ou menos proporcional ao tamanho dos dados escritos.
Este aumento proporcional da latência deve-se ao facto de alguns dos provedores de
armazenamento utilizados sofrerem desta propriedade, como é descrito em [37]. No
gráfico 5.1(b) podemos observar que as latências obtidas para as leituras apresentam um
comportamento semelhante ao anterior, com a excepção de que os valores medidos para
os mesmos tamanhos dos dados são muito mais baixos. Os tempos de latência apresentados na figura são superiores aos tempos apresentados no projecto atrás referido. Isto
deve-se ao facto de os testes apresentados em [37] terem sido efectuados na rede do Departamento de Informática, sendo o desempenho desta rede muito superior ao da ligações
da internet utilizada.
61
Capı́tulo 5. Avaliação
(a) Escritas.
(b) Leituras.
Figura 5.1: Latência das escritas e leituras (em segundos) para a cloud-of-clouds
5.3
Desempenho do Serviço de Armazenamento do C2FS
Nesta secção serão medidos os tempos de execução dos benchmarks IOzone e Postmark para as diferentes configurações do serviço de armazenamento do C2FS. Pretende-se
então perceber de que forma é que estas configurações afectam o desempenho do sistema.
Todos os resultados apresentados nesta secção resultam de uma média de 5 execuções de
cada experimento.
Escritas sı́ncronas. A figura 5.2 mostra o desempenho do serviço de armazenamento
quando configurado para efectuar escritas sı́ncronas para as clouds. É comparado o desempenho do sistema quando este utiliza cache em disco ou memória volátil, e ainda com
as duas diferentes configurações da operação fsync (só para disco, ou para cloud-of-clouds
assegurando também que os dados ficam armazenados em disco).
Umas das conclusões a retirar deste gráfico é que, como seria expectável, existe
um ganho muito grande aquando da utilização da cache em memória para efectuar as
operações de escrita e leitura. Como podemos verificar, no caso do IOzone o tempo
médio de execução diminui para cerca de metade. Já no caso do tempo de execução do
PostMark, este diminui para cerca de um terço aquando da utilização de memória para
efectuar operações de E/S.
Como também se pode verificar, as diferentes configurações da operação fsync resultam em alterações marginais no desempenho do sistema para os dois benchmarks utilizados. Isto justifica-se com o facto do IOzone só efectuar a operação referida acima no
momento exacto antes do fecho do ficheiro. Note-se que antes de qualquer envio de dados para as clouds, estes são devidamente armazenados em disco. Assim, visto os dados
serem enviados na operação fsync, não existem alterações em cache que obrigue o envio
dos dados no fecho do ficheiro. No caso do PostMark não é efectuada nenhum fsync.
Capı́tulo 5. Avaliação
62
Figura 5.2: Tempo de execução (em segundos) do IOzone e PostMark para escritas
sı́ncronas.
Escritas assı́ncronas. A figura 5.3 mostra o desempenho do C2FS quando utiliza escritas assı́ncronas para as clouds. Assim como na avaliação efectuada acima, é também
avaliado neste caso o desempenho do sistema quando utiliza a cache em disco e em
memória, assim como com as duas configurações da operação fsync.
Figura 5.3: Tempo de execução (em segundos) do IOzone e PostMark para escritas
assı́ncronas.
Tal como anteriormente referido, também aqui podemos verificar o grande aumento
63
Capı́tulo 5. Avaliação
de desempenho quando o serviço de armazenamento utiliza a cache em memória. Nesta
caso em concreto, podemos verificar a especial utilidade deste nı́vel de cache quando se
opera sobre ficheiros relativamente grandes. Esta conclusão pode retirar-se da figura, na
qual existe um ganho muito significante no caso do IOzone (que opera sobre ficheiros até
32MB), ao contrário do observado no PostMark, que devido à utilização de ficheiros de
(no máximo) 2MB, tem um ganho de desempenho mais modesto.
Pelas mesmas razões apontadas anteriormente, a alteração da forma de funcionamento
da operação fsync não representa alterações relevantes nos tempos de execução dos benchmarks.
5.4
Comparação do C2FS com outros Sistemas de Ficheiros
para Cloud
Nesta secção será comparado o desempenho do C2FS com o S3FS e com o S3QL.
Nos vários experimentos apresentados nesta secção, tanto o S3FS como o S3QL foram
configurados para armazenarem os seus dados na zona de disponibilidade da “Europa” do
Amazon S3 [4].
Débito e Latência das Operações. A figura 5.4 apresenta a latência e débito das operações
de escrita e leitura dos vários sistemas. Os valores apresentados foram obtidos através da
execução do workload randomrw do Filebench, resultando estes da média de 5 execuções
distintas deste experimento. Visto o workload só ter em conta as operações de escrita e
leitura, a única configuração do serviço de armazenamento relevantes para este experimento é o nı́vel de cache a utilizar.
(a) Latência.
(b) Débito.
Figura 5.4: Latência e throughput das operações de escrita e leitura não sequenciais.
Valores medidos através da execução do workload randomrw do Filebench
64
Capı́tulo 5. Avaliação
Como podemos constatar na figura 5.4(a), o único experimento que apresenta uma
latência superior a 1 ms por operação de leitura é o C2FS quando opera sobre os dados
em disco. No entanto, nas escritas, podemos verificar que esta configuração do C2FS
apresenta melhor desempenho que o S3FS. Podemos ainda observar que o experimento
com melhor desempenho para as escritas é o C2FS quando utiliza a cache em memória
principal.
Assim, na figura 5.4(b) é fácil perceber que o C2FS com leituras feitas na cache em
disco apresenta novamente os piores resultados, tendo no entando um desempenho comparável ao S3FS no que diz respeito às operações de escrita. Podemos ainda verificar
que o C2FS quando configurado para operar sobre os dados em memória apresenta pior
débito de leituras, apresentando no entanto o melhor débito de escritas de todos os sistemas avaliados.
A única explicação encontrada para o C2FS ter um menor débito de leituras que o
S3FS e que o S3QL está relacionada com o uso do FUSE-J, uma vez que na prática, uma
leitura no serviço de armazenamento do C2FS requer apenas cópias de bytes de memória
principal para memória principal.
Tempos de Execução. Nas tabelas abaixo são comparados os tempos de execução do
IOzone e do PostMark obtidos pelo S3FS, S3QL e C2FS. Na tabela 5.1 é comparado o
desempenho do C2FS quando configurado para efectuar escritas bloqueantes, e quando
opera tanto na cache em disco como na cache em memória. Esta comparação faz sentido
pois o S3FS efectua todas as escritas para a Amazon S3 sincronamente aquando do fecho
do ficheiro.
IOzone
PostMark
S3FS
2520.67
7737.5
Block + Disk + SyncD
3770.6
8632.25
Block + Memory + SyncD
1836.5
2725.5
Tabela 5.1: Comparação dos tempos de execução (em segundos) com o S3FS.
Como podemos verificar na tabela 5.1, o desempenho do C2FS com cache em disco é
inferior ao desempenho do S3FS em ambos os benchmarks. Contudo, quando é utilizada
a cache em memória para efectuar as operações de escrita e leitura, o C2FS apresenta
um desempenho muito mais satisfatório que o S3FS, ao mesmo tempo que fornece mais
garantias no que diz respeito à disponibilidade dos dados, pois estes, ao contrário do
S3FS, são armazenados na cloud-of-clouds.
Por sua vez, na tabela 5.2 são comparados os tempos de execução, para os mesmo
benchmarks, do S3QL e do C2FS quando efectua escritas assı́ncronas para as clouds.
Esta comparação é efectuada pois o S3QL envia também todos os dados para a cloud
assincronamente.
65
Capı́tulo 5. Avaliação
IOzone
PostMark
S3QL
19.59
3024.5
NonBlock + Disk + SyncD
2391.74
208.8
NonBlock + Memory + SyncD
30.27
153.25
Tabela 5.2: Comparação dos tempos de execução (em segundos) com o S3QL.
No caso da tabela 5.2 podemos verificar que quando testados o S3QL e o C2FS com o
IOzone, o S3QL apresenta o melhor resultado. Contudo, embora no caso do C2FS utilizar
cache em disco obter resultado bastante inferiores ao S3QL, quando configurado para operar com cache em memória, este obtém um resultado comparável. Surpreendentemente,
no que diz respeito aos tempos de execução obtidos através do PostMark, o S3QL apresenta um resultado bastante negativo quando comparado quer com o C2FS com cache em
disco, como com cache em memória. Isto pode dever-se ao facto do S3QL ser lento a
lidar com o metadados.
5.5
Considerações Finais
Neste capı́tulo foi apresentada uma avaliação experimental do desempenho do serviço
de armazenamento do C2FS. Primeiramente foram mostradas as latências observadas no
envio de dados para as clouds aquando da execução dos testes ao sistema. Foi mostrado
também que com a diminuição do nı́vel de tolerância a faltas e consistência, o desempenho
aumenta drasticamente. Por fim foi mostrado que o C2FS, mesmo armazenando os dados
na cloud-of-clouds, consegue em alguns casos obter desempenhos superiores aos sistemas
de ficheiros para clouds comparados na execução de alguns benchmarks populares.
No próximo capı́tulo, para finalizar este relatório, serão apresentadas a conclusão e o
trabalho futuro a realizar.
Capı́tulo 5. Avaliação
66
Capı́tulo 6
Conclusão
Com o crescimento do armazenamento de dados em clouds, veio a necessidade de
estudar técnicas que possam melhorar tanto a fiabilidade dos dados armazenados, como
da forma de os armazenar. A fiabilidade dos dados torna-se um ponto essencial no armazenamento em clouds no sentido em que estes têm o total controlo sobre os mesmos.
A forma disponibilizada para armazenar os dados também se revela um ponto importante
pois tanto os utilizadores comuns como os programadores precisam de um acesso fácil a
estes provedores de armazenamento.
O C2FS, um sistema de ficheiros seguro e fiável para cloud-of-clouds, vem responder
a estas necessidades, pois ao mesmo tempo que mantém os dados disponı́veis e confidencias, disponibiliza uma interface do estilo POSIX facilitando assim o acesso a estes.
Neste trabalho foi apresentado o serviço de armazenamento desenvolvido para o C2FS,
que armazena os dados na cloud-of-clouds recorrendo ao DepSky [19], tirando assim partido das propriedades que este oferece, sendo elas disponibilidade, integridade e confidencialidade dos dados. Este serviço mostra-se configurável, pois são disponibilizados dois
nı́veis distintos de cache e dois modelos de envio de dados para as clouds. Isto é muito
benéfico pois os clientes podem tirar partido do sistema consoante as suas necessidades.
Na avaliação experimental efectuada mostrou-se que o desempenho do C2FS comparável aos sistemas de ficheiros para clouds testados ao mesmo tempo que fornece garantias mais fortes de fiabilidade. Mostrou-se também que, como seria expectável, à medida
que relaxamos o nı́vel de coerência da cache e a tolerância a faltas, o desempenho aumenta
de uma forma muito satisfatória.
6.1
Trabalho Futuro
Para além do trabalho apresentado neste documento, existem ainda algumas tarefas
em aberto que podem melhorar o C2FS como um todo. Um dos trabalhos futuros passa
por estudar se, ao invés de armazenar em cache os dados de um ficheiro num único bloco,
armazená-lo dividindo-o em blocos mais pequenos, irá aumentar o desempenho do C2FS.
67
Capı́tulo 6. Conclusão
68
Uma outra tarefa a executar no futuro consiste em alterar o DepSky. O C2FS, embora
permita a partilha de ficheiros [32], só o permite se os diferentes utilizadores partilharem
a mesma conta. Para tal não ser necessário, é preciso evoluir o DepSky de forma a este
fornecer listas de controlo de acesso aos contentores de dados armazenados nas clouds.
Uma outra optimização futura é estudar uma técnica que permita esconder a latência inerente ao envio de muitos ficheiros pequenos em separado. O que se pretende neste ponto
é descobrir quais as melhores formas de agrupar ficheiros pequenos num único bloco de
dados para enviar para as clouds. Por fim, é necessário também avaliar o comportamento
e desempenho do sistema com workloads de aplicações desktop da actualidade [25].
Bibliografia
[1] Amazon elastic block store. http://aws.amazon.com/ebs/.
[2] Amazon elastic compute cloud. http://aws.amazon.com/ec2/.
[3] Amazon elasticache. http://aws.amazon.com/elasticache/.
[4] Amazon simple storage service. http://aws.amazon.com/s3/.
[5] Apple icloud. http://www.apple.com/icloud/.
[6] Filebench. http://sourceforge.net/apps/mediawiki/filebench.
[7] Fuse. http://fuse.sourceforge.net/.
[8] Fuse-j. http://fuse-j.sourceforge.net/.
[9] Google cloud storage. https://developers.google.com/storage/.
[10] IOzone Filesystem Benchmark. http://www.iozone.org/.
[11] Microsoft Windows Azure. http://www.windowsazure.com/.
[12] Openstack storage. http://www.openstack.org/software/openstack-storage/.
[13] Posix. http://en.wikipedia.org/wiki/POSIX.
[14] Project TCLOUDS - trustworthy clouds - privacy and resilience for internet-scale
critical infrastructure. http://www.tclouds-project.eu/.
[15] Rackspace Cloud Hosting. http://www.rackspace.co.uk/.
[16] S3fs - fuse-based file system backed by amazon s3. http://code.google.com/p/s3fs/.
[17] S3ql - a full-featured
http://code.google.com/p/s3ql/.
file
system
69
for
online
data
storage.
Bibliografia
70
[18] M. Abd-El-Malek, W. Courtright II, C. Cranor, G. Ganger, J. Hendricks, A. Klosterman, M. Mesnier, Prasad M, B. Salmon, R. Sambasivan, S. Sinnamohideen,
J. Strunk, Eno Thereska, M. Wachs, and J. Wylie. Ursa minor: versatile clusterbased sotrage. In Proceedings of the 4th USENIX Conf. on File and Storage Techonogy (FAST’05), December 2005.
[19] Alysson Bessani, Miguel Correia, Bruno Quaresma, Fernando Andre, and Paulo
Sousa. DepSky: Dependable and Secure Storage in cloud-of-clouds. In Proc. of the
3rd ACM European Systems Conference – EuroSys’11, April 2011.
[20] Alysson N. Bessani, Eduardo P. Alchieri, Miguel Correia, and Joni S. Fraga.
DepSpace: a Byzantine fault-tolerant coordination service. In Proc. of the 3rd ACM
European Systems Conference – EuroSys’08, pages 163–176, April 2008.
[21] Miguel Castro and Barbara Liskov. Practical Byzantine fault-tolerance and proactive
recovery. ACM Transactions Computer Systems, 20(4):398–461, November 2002.
[22] George Coulouris, Jean Dollimore, and Tim Kindberg. Distributed Systems - Concepts and Designs, chapter Distributed File Systems, pages 323–364. 2005.
[23] Abu-Libdeh et al. RACS. Redundant array of cloud storage. In ACM SOCC 2010.
[24] Garth Gibson, David Nagle, Khalil Amiri, Jeff Butler, Fay Chang, Howard Gobioff,
Charles Hardin, Erik Riedel, David Rochberg, and Jim Zelenka. A cost-effective,
high-bandwidth storage architecture. In Proc. of the 8th Int. Conference on Architectural Support for Programming Languages and Operating Systems - ASPLOS’98,
pages 92–103, 1998.
[25] Tyler Harter, Chris Dragga, Michael Vaughn, Andrea C. Arpaci-Dusseau, and
Remzi H. Arpaci-Dusseau. A File is Not a File: Understanding the I/O Behavior of apple desktop applications. In Proceedings of the 23rd ACM Symposium on
Operating Systems Principles – SOSP’11, October 2011.
[26] J. H. Howard, M. L. Kazar, Menees S. G., D. N. Nichols, M. Satyanarayanan, R. N.
Sidebotham, and M. J. West. Scale and performance in a distributed file system. In
ACM Trans. Comput. Syst. vol. 6, no. I, February 1988.
[27] Jeffrey Katcher. PostMark: A New File System Benchmark. Technical report,
August 1997.
[28] J. Kubiatowicz, D. Bindel, Yan Chen, S. Czerwinski, P. Eaton, D. Geels, R. Gummadi, S. Rhea, H. Weatherspoon, W. Weimer, C. Wells, and Ben Zhao. Oceanstore:
An architecture for global-scale persistent storage. In Proceedings of the 9th Intl.
Bibliografia
71
Conf. on Architectural Support for Programming Langauges and Operating Systems, November 2000.
[29] Edward L. Lee and Chandramohan A. Thekkath. Petal: Distributed virtual disks.
In Proceedings of the 7th Intl. Conf. on Architectural Support for Programming
Langauges and Operating Systems. pages 84-92, October 1996.
[30] Barbara Liskov. From viewstamped replication to byzantine fault tolerance. In
Replication, LNCS 5959, pages 121-149, 2010.
[31] N. Megiddo and D. Modha. Arc: A self tuning, low overhead replacement cache.
In Proceedings of USENIX Conference on (FAST) File and Storage Technologies,
2003.
[32] R. Mendes. Substrato de coordenação para sistemas de ficheiros para cloud-ofclouds. Relatório do Projecto de Engenharia Informática. DI/FCUL, September
2012.
[33] Ricardo Mendes, Tiago Oliveira, Alysson Bessani, and Marcelo Pasin. C2FS: um
Sistema de Ficheiros Seguro e Fiável para Cloud-of-clouds. In INForum12, September 2012.
[34] David A. Patterson, Garth Gibson, and Randy H. Katz. A case for redundant arrays of inexpensive disks (raid). In Proc. of the 1988 ACM SIGMOD International
Conference on Management of Data, pages 109–116, 1988.
[35] C. Plaxton, R. Rajaraman, and A. Aggarwal. Accessing nearby copies of replicated
objects in a distributed environment. In Proceedings of ACM SPAA, pages 311-320,
Newport, Rhode Island, June 1999.
[36] Krishna P. N. Puttaswamy, Thyaga Nandagopal, and Murali Kodialam. Frugal Storage for Cloud File Systems. In Proc. of the 3rd ACM European Systems Conference
– EuroSys’12, April 2012.
[37] B. Quaresma. Depsky: Sistema de Armazenamento em Clouds Tolerante a Intrusões. Relatório do Projecto de Engenharia Informática. DI/FCUL, Setembro
2010.
[38] R. L. Rivest. International conference on distributed computing systems. In IEEE
Computer Society Press, 1989.
[39] R. L. Rivest. The md5 message-digest algorithm, rfc-1321. In Network Working
Group, IETF, April 1992.
Bibliografia
72
[40] M. Satyanarayanan, J. H. Howard, D. N. Nichols, R. N. Sidebotham, A. Z. Spector,
and M. J. West. The ITC distributed file system: principles and design. In Proceedings of the 10th ACM Symposium Oper. Syst. Principles. Orcas Island, December
1985.
[41] M. Satyanarayanan, P. Kumar, M. Okasaki, E. Siegel, and D. Steere. Coda: A highly
available file system for a distributed workstation environment. In IEEE Trans. on
Comp. 4. 39 (Apr 1990), 447-459.
[42] J. Sousa and A. Bessani. From byzantine consensus to bft state machine replication:
A latency-optimal transformation. In In the Proc. of the 9th European Dependable
Computing Conference, 2012.
[43] C. Thekkath and E. L. T. Mann. Frangipani: A scalable distributed file system. In
In the Proceedings of the 16th SOSP.
[44] Michael Vrable, Stefan Savage, and Geoffrey M. Voelker. Cumulus: Filesystem
backup to the cloud. volume 5, pages 1–28, 2009.
[45] Michael Vrable, Stefan Savage, and Geoffrey M. Voelker. BlueSky: A cloud-backed
file system for the enterprise. In Proc. of the 10th USENIX Conference on File and
Storage Technologies – FAST’12, 2012.
[46] S. A. Weil, S. A. Brandt, E. L. Miller, and C. Maltzahn. CRUSH: Controlled,
scalable, decentralized placement of replicated data. In Proceedings of the 2006
ACM/IEEE Conference on Supercomputing (SC ’06). Tampa, FL, Nov, 2006, ACM.
[47] Sage A. Weil, Scott A. Brandt, Ethan L. Miller, Darrell D. E. Long, and Carlos
Maltzahn. Ceph: A scalable, high-performance distributed file system. In Proc. of
the 7th USENIX Symposium on Operating Systems Design and Implementation –
OSDI 2006, pages 307–320, 2006.
Download

Projecto em Engenharia Informatica