Questões de Implementação


Os servidores de arquivos têm tanta importância e estão hoje em dia tão difundidos que vale a pena tecer comentários sobre a forma como são implementados. A maneira mais simples é organizar o servidor como um proceso isolado, como um loop principal. As solicitações de trabalho que chegam são processadas e os resultados são transmitidos em retorno. O servidor trata um pedido de cada vez. Enquanto está ocupado com o pedido corrente, todos os novos pedidos são simplesmente enfileirados até que o servidor esteja pronto.

A abordagem do loop principal é certamente utilizável, mas tem a desvantagem de que, se o processamento de um pedido exigir vários acessos ao disco (para diretórios e várias tabelas internas), o servidor ficará ocioso enquanto espera que os acessos ao disco se completem. Um projeto mais sofisticado é o servidor de arquivos que está dividido em diversas tarefas que compartilham um espaço de endereço comum. Cada tarefa é uma sequência de controle separada, com seu próprio contador de programa e sua pilha. No entanto, as tarefas compartilham dados globais, como as tabelas e buffers do sistema de arquivos.
Quando uma mensagem de solicitação chega de um cliente, o núcleo a aceita e a entrega à tarefa de despachante, que normalmente está esperando. O despachante examina o pedido e o entrega a uma tarefa trabalhadora ociosa. Como as tarefas despachantes e trabalhadora estão no mesmo espaço de endereço, somente tem de ser passado um ponteiro, e não a mensagem.
Cada tarefa manipula um único pedido de execução. Contudo, se uma tarefa se bloquear enquanto espera pelo disco, outra tarefa pode entrar em execução. Dessa forma, a CPU nunca está ociosa quando existe trabalho a ser feito. Quando termina o serviço que lhe foi designado, o trabalhador atualiza sua entrada na tabela de status principal da maioria global, a fim de que o despachante saiba que ele está disponível para manipular outro pedido.
A maior parte dos servidores são baseados em blocos, ou seja, dividem o disco em blocos e representam arquivos como sequência de blocos. Um mapa de bits ou lista livre controla os blocos não atribuídos a arquivos. Quando um arquivo cresce, um bloco livre é alocado e atribuído ao arquivo. Alguns servidores de arquivos tentam manter todos os blocos de um arquivo em poucos cilindros, a fim de reduzir o movimento do braço do disco, mas geralmente os blocos não são consecutivos.
Uma técnica amplamente utilizada para aumentar o desempenho é fazer como que o servidor mantenha na memória um cache de buffers. O cache de buffers consiste nos n blocos do disco usados mais recentemente. Quando um bloco de disco é lido, ele é colocado no cache e o bloco usado menos recentemente é purgado. Se o cache for grande o suficiente, a taxa de sucesso pode ser de 900% ou mais, eliminando assim grande parte dos acessos ao disco.

Uma abordagem completamente diferente é utilizada no sistema Amoeba. O servidor de arquivos do Amoeba não é baseado em blocos. Em vez disso, ele armazena cada arquivo em posições contíguas no disco. O cache também é organizado dessa maneira, contendo arquivos inteiros, cada arquivo ocupando certo número de bytes consecutivos na memória do servidor. Os arquivos podem ser transferidos entre o disco e a memória em uma única operação de disco. Quando um cliente solicita um arquivo que está no cache, todo o arquivo pode ser transmitido como uma seqüência de pacotes adjacentes. Medições feitas no Amoeba mostraram que o servidor de arquivos pode operar muito próximo da banda passante completa da LAN básica, algo de que os servidores baseados em blocos não podem nem mesmo chegar perto.

Quando são compartilhados arquivos entre múltiplos usuários trabalhando em equipamentos diferentes, o caching nos clientes dá arigem a um serio problema. Suponha que diversas máquinas clientes têm todas elas cópias em cache de um determinado arquivo. Se um usuário em uma dessas máquinas modificar a cópia local, as alterações não serão visíveis para os outros usuários. Assim, a semântica do compartilhamento de arquivos é drasticamente alterada pela permisão de caches locais.


Copyright ©1995, Jorge Juan Zavaleta Gavidia
E-mail : jorgezg@inf.ufrgs.br