Análise de desempenho em servidores Linux

Autores: Albino Laginski Junior e Rogério Neves Batata

1. INTRODUÇÃO

O conceito de software de código aberto, isto é, cujo código e distribuição aderem a licenças como a GPL (General Public License), veio fazer frente ao modelo de distribuição de software vigente, onde o código é proprietário, e sua utilização e distribuição são regidas por contratos fortemente favoráveis aos produtores do software. O representante do software de código aberto que tem recebido maior destaque é o sistema operacional Linux. Assim, muitos ambientes computacionais estão sendo construídos utilizando-se de servidores e estações de trabalho equipados com estes programas.

O modelo cliente-servidor é definido por um servidor que oferece recursos ou dados para um conjunto de clientes que utilizam ou requisitam estes recursos ou dados. Como um exemplo, podemos tomar a infra-estrutura de e-mail: existe um servidor que cuida do envio e recepção das mensagens e um servidor que cuida da entrega destas mensagens aos usuários. Os usuários, por sua vez, utilizam diversos programas diferentes para ter acesso e enviar as suas mensagens. Nesta linha, podemos ter servidores de banco de dados, de processamento e de arquivos, entre outros.

Assim, este trabalho visa fornecer base para a análise de desempenho destes ambientes. O acompanhamento do desempenho é tarefa fundamental para a gerência de um sistema, provendo informações sobre o desempenho do conjunto e a sua utilização, e também subsídios para decisões relacionadas à atualização, ampliação e dimensionamento do sistema, em função do crescimento da carga, do seu comportamento temporal e da otimização do uso dos recursos disponíveis.

Esta sistemática traz melhores resultados quando se faz um acompanhamento de longo prazo, de forma contínua, pois com base em um histórico de dados relativos à utilização do sistema sob diversos aspectos, pode-se fazer projeções de crescimento de demanda, favorecendo o planejamento de investimentos em expansão dos recursos atuais de forma a manter ou elevar o nível de qualidade do sistema.

2. CONCEITOS EM AVALIAÇÃO DE DESEMPENHO

2.1. Conceitos e Importância

A avaliação de desempenho de sistemas computacionais consiste em um conjunto de técnicas e metodologias que permitem responder à questão de como se obter o melhor desempenho de um sistema computacional a um dado custo. A atividade de avaliação de desempenho compreende:

- Seleção de técnicas de avaliação, métricas de desempenho e cargas de trabalho;

- A correta condução das medidas de desempenho e das simulações;

- A utilização de técnicas estatísticas apropriadas para comparar as diversas alternativas;

- O desenvolvimento dos experimentos de medição e simulação visando prover a maior quantidade de informação com o menor esforço;

- A utilização de modelos de filas para analisar o desempenho dos sistemas.

Contrário ao pensamento comum, a avaliação de desempenho não pode ser realizada de forma automatizada. Cada avaliação exige um conhecimento profundo dos sistemas a serem modelados e uma cuidadosa seleção da metodologia, carga de trabalho e ferramentas. Definir o problema real e convertê-lo em uma forma em que ferramentas e técnicas usuais podem ser utilizadas é a parte subjetiva do trabalho.

2.2. Monitoração de Desempenho

As técnicas de avaliação de desempenho podem ser divididas em três grupos principais: modelos analíticos, simulação e medição de desempenho [7]. Cada uma destas técnicas é apresentada nas seções subseqüentes.

2.2.1. Os Modelos Analíticos

Um modelo analítico é uma construção matemática que representa aspectos-chave de um sistema computacional. Estes modelos são uma ferramenta excelente para uma rápida avaliação de um produto novo ou modificado. Também são adequados para comparar o desempenho entre várias alternativas de projetos. As técnicas de modelagem analítica que são úteis para a análise de desempenho de sistemas, são as que seguem:

Modelo de Fila

Um modelo de fila representa um sistema como um conjunto de centros de serviço que processam requisições de clientes, denominadas tarefas, transações ou chegadas. Os centros de serviços podem ser qualquer recurso ativo como a CPU, o disco ou a conexão de rede. Os modelos de fila podem prever a latência, a vazão e a utilização do sistema e seus componentes.

Modelo Assintótico

É a aplicação mais simples de redes de filas. São utilizados para prever o melhor e o pior caso de latência e vazão de um único centro de serviços. Um uso típico é examinar o comportamento do ponto de contenção de um conjunto de recursos sob diferentes cargas.

Modelo de Rede Aberta

Neste modelo, os clientes passam através do sistema uma única vez. Por exemplo, um dispositivo de rede processando um fluxo de pacotes pode ser modelado com um sistema aberto. O número de clientes do sistema é calculado pela taxa de chegada de clientes e as características do centro de serviço. Se existirem tipos diferentes de clientes, um modelo aberto de múltiplas classes poderá ser utilizado.

Modelo de Rede Fechada

Neste caso, o número de clientes é fixo. O exemplo clássico é o sistema computacional de tempo compartilhado com um número fixo de terminais de usuário. Neste modelo, o número de clientes é conhecido e a vazão é calculada. Um método interativo conhecido como Análise do Valor Médio (Mean Value Analysis ou MVA) é usado para calcular vazão e latência. A exemplo dos modelos abertos, os modelos fechados podem ser de classe única ou de múltiplas classes. Existem duas variações do algoritmo MVA: solução exata e solução aproximada.

Limitação dos modelos de Redes de Filas

Todas as técnicas de solução requerem que o modelo atinja certas condições que o faça um modelo particionável; em alguns casos isso pode fazer o modelo desviar significativamente do sistema real. Também os modelos de fila não são adequados para modelar recursos passivos como, por exemplo, buffers.

Cadeias de Markov

São usadas para modelar sistemas como um conjunto finito de estados com uma taxa conhecida de transições entre os estados. Este modelo é adequado para prever a disponibilidade de um sistema, dadas as taxas de falha de um componente e as taxas de recuperação. Também podem ser usadas para modelar buffers de filas que armazenam um pequeno número de itens idênticos.

2.2.2. Simulação

Conceitualmente, a simulação modela um sistema do mundo real como um programa de computador. A simulação permite que um sistema seja modelado em qualquer nível de detalhe: de uma tradução direta de um modelo de redes de filas à captura de todo aspecto do comportamento do sistema. A simulação suporta qualquer coleção de métricas de desempenho que possam ser definidas.

Arquitetura da simulação

Simulações de sistemas de computadores escritas para o propósito de análise de desempenho são, em geral, simulações de eventos discretos, isto é, a representação do tempo é discretizada e ocorrem mudanças de estado somente quando ocorre um evento. Por comparação, uma simulação contínua modela o tempo como uma progressão contínua.

A simulação de eventos discretos pode ser classificada em dirigida por eventos ou baseada em ciclo. Uma simulação dirigida por eventos modela a atividade do sistema como uma série de eventos que ocorrem assincronamente e em intervalos irregulares. Por exemplo, a simulação de um servidor de arquivos de rede deve incluir eventos como a chegada de um pacote ethernet ou a finalização da escrita em disco. Este tipo de simulação modela uma grande variedade de sistemas. Na simulação baseada em ciclos, todas as mudanças no sistema são síncronas, isto é, a simulação é, em essência, uma grande máquina de estados que muda de estado a cada ciclo.

Este tipo de simulação é tipicamente utilizado para modelar núcleos de processador ou outra lógica digital com uma única frequência de clock. Note, porém, que as duas abordagens podem ser combinadas em uma simulação que inclua eventos síncronos e assíncronos.

Existem três técnicas básicas para gerar cargas de trabalho para realizar simulações: estocástica, rastreamento (trace-driven) e baseada em execução.

A simulação estocástica descreve a chegada de padrões de clientes e outros aspectos da carga por amostragem a partir de uma distribuição probabilística. Muitas cargas podem ser descritas precisamente pelo uso de uma distribuição apropriada. As cargas estocásticas são uma boa escolha quando a informação detalhada sobre a carga não está disponível ou quando existe necessidade de variar as características da carga. A geração de carga é eficiente e não necessita de grandes arquivos de dados.

A simulação por rastreamento representa a carga como uma sequência de operações ou requisições. Por exemplo, para a simulação de um servidor Web, uma sequência de requisições http deve ser rastreada, enquanto na simulação de uma CPU, as operações do micro-código devem ser rastreadas. Se dados de rastreamento que representam corretamente a carga estão disponíveis, obteremos bons resultados de simulação, sendo desnecessário escrever o código que modela a carga. A desvantagem desta técnica é que montar uma coleção de rastreamentos é um esforço não trivial e o tamanho dos arquivos de dados é muito grande.

A simulação baseada em execução é utilizada para modelar processadores em detalhes. A entrada de uma simulação baseada em execução é o mesmo código executável que seria processado no sistema real.

A principal desvantagem de utilizar qualquer técnica de simulação é o esforço necessário para escrever e validar o programa de simulação e os consideráveis requisitos de processamento (tempo de CPU para todas as simulações e espaço em disco para rastreamentos). Em geral, a simulação é significativamente mais lenta do que um sistema real: uma hora de simulação pode significar alguns poucos segundos do tempo real, mas pode ocorrer o contrário.

2.2.3. Medição de Desempenho

Devemos considerar, ao planejar uma medição de desempenho, o propósito da medição, a seleção da carga de trabalho e sua implementação, os dados a serem coletados, a instrumentação utilizada na coleta destes dados e a forma de validação dos resultados.

Todos os experimentos de medição de desempenho requerem três elementos básicos: o sistema sob teste, os geradores de carga de trabalho e a instrumentação que irá coletar os dados de desempenho.

Selecionando uma Carga de Trabalho

O desempenho de um sistema pode ser medido em qualquer tempo com qualquer carga de trabalho. Alguns administradores de sistemas coletam regularmente dados de desempenho como parte do monitoramento do estado geral do sistema. As medidas de desempenho e análises baseadas em sistemas e cargas reais parecem atrativas num primeiro momento, mas possuem diversas limitações. A carga aplicada a um sistema pode variar muito de dia para dia ou até mesmo de minuto a minuto, e existe a dificuldade, senão a impossibilidade, de executar a carga de um dia em particular em uma data posterior. Entretanto, a maioria das medidas de desempenho baseia-se em uma carga sintética, que possui características similares a uma carga real, mas é definida e implementada de maneira a ser reproduzida. Em muitos casos, a carga é descrita através de alguns parâmetros-chave, e o objetivo da medição é avaliar como as mudanças nos parâmetros de carga afetam o desempenho do sistema.

Benchmarks são uma categoria importante de cargas sintéticas, definindo não somente a carga de trabalho, mas as métricas de desempenho a serem coletadas e relatadas. Algumas organizações de desenvolvimento podem e fazem definições de benchmarks para uso interno, mas benchmarks desenvolvidos independentemente são sempre preferidos porque permitem aos clientes compararem resultados de múltiplos fornecedores.

Instrumentação

O sistema sob teste pode ser instrumentado para coletar uma variedade de métricas. Muitos benchmarks simplesmente medem a latência e a taxa de serviço. Entretanto, a informação sobre a utilização do processador e de outros recursos é muito útil na identificação de pontos de contenção no sistema ou para futuros esforços de modelagem. Existem contadores implementados tanto em software quanto em hardware que fornecem informação útil de desempenho. Por exemplo, falhas de página podem ser gravadas em um contador na CPU, no kernel do sistema operacional ou em ambos. Rastreamento das operações ou eventos também podem ser coletados.

Os benchmarks cujos resultados são os mais utilizados pela indústria são aqueles mantidos pelo Transaction Processing Performance Council, conhecido como TPC, que têm como missão a definição de bancos de dados e benchmarks de processamento de transações.

O Standard Performance Evaluation Corporation, conhecido como SPEC, busca estabelecer, manter e endossar um conjunto padrão relevante de benchmarks e métricas de avaliação de desempenho.

2.3. Métricas de Desempenho

Todas as métricas de desempenho baseiam-se no comportamento do sistema ao longo do tempo. As três classes principais de métricas que podem ser observadas por um usuário ou uma outra entidade externa ao sistema são:

- Latência ou Tempo de Resposta - que mede o atraso entre a requisição de alguma ação e a obtenção do resultado;

- Taxa de serviço - que mede quantidade de trabalho realizado por unidade de tempo ou a taxa em que novos resultados são obtidos;

- Disponibilidade - que mede quanto tempo o sistema está disponível para operação normal.

A quarta classe de métrica, que seria a métrica de utilização, só pode ser observada de dentro do sistema. A informação de utilização é vital para entender e prever o desempenho do sistema.É importante ressaltar que há dezenas de métricas, dependendo do ambiente. Por exemplo, perda de pacotes em redes ou tempo de consulta em um banco de dados.

2.3.1. Latência

A latência ou tempo de resposta é medida em unidades de tempo decorrido. Por definição, a métrica de latência deve especificar um evento de início e um evento de término, ou seja, quando começar a medição do atraso e quando terminá-la. Por exemplo:

- O tempo decorrido entre digitar um novo endereço em um navegador Web e a página ser completamente exibida.

- O tempo que um pacote é mantido por um roteador até que seja retransmitido.

- O tempo decorrido entre receber o pedido de um item em uma loja on-line e a atualização da “quantidade em estoque” que é reportado ao cliente.

Na maioria dos casos, a latência é relatada ou especificada como uma distribuição estatística. Por exemplo, pode-se exigir que uma estação base de telefonia celular complete 99,5% de todas as chamadas em um segundo.

2.3.2. Taxa de Serviço

A Taxa de serviço é medida em unidades de tarefas executadas em um intervalo de tempo, e é inversamente proporcional ao tempo de resposta por tarefa. Por exemplo, número de transações completas por minuto, gigabytes de dados escritos em fita por hora, número de acessos à memória por segundo, quantidade de megabits transmitidos por segundo.

O termo largura de banda é normalmente usado para descrever a vazão máxima teórica de um fluxo de dados ou de outro componente. Por exemplo, o barramento de dados de 32 bits de largura, operando a um clock de 100 MHz, tem uma largura aproximada de banda de 3,2 bilhões de bits por segundo. Uma vez que os componentes impõem uma sobrecarga em termos de cabeçalhos de pacotes, os atrasos entre transporte dos blocos de dados, ou ainda, os protocolos de controle, a vazão útil é sempre menor que a largura de banda. A eficiência é definida como a razão entre a vazão útil e a largura de banda.

Para algumas aplicações, a métrica de vazão pode ser normalizada sobre alguma outra característica do sistema como, por exemplo, custo ou consumo de energia. É prática comum especificar a vazão considerando as restrições de latência, e vice-versa.

2.3.3. Disponibilidade e Confiabilidade

Disponibilidade é a fração de tempo em que o sistema está disponível. Por exemplo, se um banco de dados deixa de operar uma hora por dia, a sua disponibilidade é cerca de 0,96. Entretanto, sozinha, a métrica disponibilidade não é completa. Por exemplo, se o mesmo banco de dados deixa de operar por 10 milissegundos a cada segundo, a sua disponibilidade é de 0,99, mas provavelmente será inútil para propósitos práticos. Por isso, a métrica confiabilidade é usada para relatar o tempo médio entre falhas (Mean Time Between Failures ou MTBF), que indica na média o período em que um sistema é utilizável. Uma outra métrica relacionada é o tempo médio para reparos (Mean Time To Repair ou MTTR), que quantifica o tempo necessário para recuperar o sistema de uma falha.

2.3.4. Utilização

Utilização é a fração de tempo em que um componente do sistema, por exemplo, a CPU, o disco ou a rede realizou serviço, em relação a um período de tempo observado. Segue dessa definição que os valores de utilização estão entre 0 e 1. Teoricamente, a vazão máxima de um sistema é atingida quando o mais utilizado dos dispositivos atinge a utilização igual a 1. Na prática, o tempo de resposta aumenta rapidamente quando a utilização atinge o máximo. Desta forma, muitos sistemas são projetados para manter uma utilização abaixo da capacidade máxima, em geral entre 60% e 80%.

2.4. Metodologia para Planejamento de Capacidade

Na figura abaixo, temos um fluxograma que representa a metodologia para planejamento de capacidade de sistemas computacionais. O processo de planejamento baseia-se em três pontos: Modelo de Carga, Modelo de Desempenho e Modelo de Custo.

Figura 1. Metodologia para Planejamento de Capacidade

O modelo de custo é representado em termos monetários, onde se avalia o custo do sistema atual (aquisição e manutenção). Ele é utilizado para avaliar o custo/benefício de uma possível atualização do sistema, para definir se é viável ou não, financeiramente. Por se tratar de uma visão mais gerencial do processo de decisão, não entraremos em detalhes aqui.

Já o modelo de carga é baseado na utilização dos recursos do sistema levando em conta a quantidade de recursos e suas respectivas taxas de utilização. Os modelos de carga são fortemente apoiados em modelos matemáticos, para fazer uma representação o mais fiel possível do ambiente real, para que o processo de avaliação de desempenho seja válido.

O modelo de desempenho trata de avaliar a situação atual do sistema, confrontando os recursos disponíveis e a sua utilização pelos usuários. O modelo é baseado em observações sobre o comportamento do sistema, por um período de tempo, de forma a caracterizar um padrão de utilização, para que se possa ter uma base de comparação que seria utilizada como referência em um cenário de planejamento de capacidade.

3. FERRAMENTAS PARA MEDIÇÃO NO AMBIENTE GNU/LINUX

Neste capítulo descreveremos ferramentas padrão do ambiente GNU/Linux comumente utilizadas para acompanhamento de desempenho do sistema.

Para aumentar a abrangência da aplicação, concentramos-nos em ferramentas que são encontradas em praticamente todas as distribuições Linux. As ferramentas são parte do projeto GNU [3].

3.1. Uptime

O comando uptime é utilizado, inicialmente, para mostrar a quanto tempo o sistema está em operação ininterruptamente. Além disso, também mostra mais algumas informações interessantes: número de usuários logados no momento, e as médias de cargas para os últimos 1, 5 e 15 minutos. Um exemplo de saída do uptime é:

Este exemplo nos diz que a máquina está em operação há 23 dias, oito horas e 45 minutos. Existem 9 usuários logados no sistema e as médias de carga do sistema nos últimos 1, 5 e 15 minutos são 0,17, 0,05 e 0,01, respectivamente.

3.2. Free

O comando free mostra estatísticas de utilização de memória. Além do total de memória disponível, o comando mostra quanto de memória está sendo utilizado, quanto está livre e quanto está sendo usado para buffer/cache. O comando mostra também estatísticas de utilização de swap. Um exemplo de saída do free é:

No exemplo, os dados impressos mostram que o sistema tem 2060704K bytes de memória total, dos quais 1933992K estão sendo utilizados, 126712K estão livres e 1424720K em cache.

3.3. Top

O comando top apresenta diversas informações sobre os processos que mais consomem recursos na máquina. Os processos podem ser ordenados por diversos critérios (uso de CPU, de memória, maior tempo de processamento utilizado, idade ou número do processo). À parte destas informações, o top mostra também estatísticas sobre o número de processos em execução na máquina (quantidade/estado), sobre a utilização do processador, além das informações do uptime e também do free (com outra formatação).

Neste exemplo podemos observar que a primeira linha da saída é idêntica à saída do comando uptime. As duas linhas subseqüentes sumarizam a contabilização dos processos e o estado de utilização da CPU. As linhas iniciadas por “Mem:” e “Swap:” são referentes à utilização e são similares à saída do comando free. No segundo bloco de informações, temos dados sobre os processos que estão em execução (status R) e parados ou traced (status S). A primeira coluna apresenta o número do processo, na segunda temos o usuário a quem pertence este processo. As colunas “PRI” e “NI” são a prioridade e o parâmetro do comando nice especificado para o processo, respectivamente. As três colunas seguintes, “SIZE”, “RSS” e “SHARE”, dizem respeito à utilização de memória pelo processo. “SIZE” é o espaço total de memória utilizada pelo processo. “RSS” é o espaço de memória física utilizada e “SHARE” é a quantidade de memória compartilhada pelo processo, por exemplo, com bibliotecas de vínculo dinâmico. A coluna “STAT” apresenta o status do processo: R para processos em execução, T para processos parados. O N, na mesma coluna, indica um valor de nice positivo. Em “%CPU” e “%MEM” temos o percentual de utilização de CPU e Memória, respectivamente. “Time” informa quanto tempo de CPU o processo já utilizou e “COMMAND” é o nome do programa em execução.

3.4. VMSAT

O comando vmstat mostra estatísticas de uso de memória, paginação, entrada/saída de blocos, interrupções, processos e atividade do processador. As informações são baseadas em amostragens feitas durante um intervalo determinado.

A saída do vmstat é dividida em blocos, referentes a alguns aspectos do sistema, sendo eles Processos, Memória, Swap, Entrada/Saída, Sistema e CPU. Dentro dos processos, temos o número de processos esperando por execução (r) e processos zombie (b). Na parte de memória, temos a quantidade de memória virtual utilizada (swpd), quantidade de memória livre (free) e a quantidade de memória em cache (cache). O conceito de buffers neste tipo de informação não é mais utilizado, e o resultado da coluna aparece todo zerado (buff). Nas informações relativas à memória virtual, temos a quantidade de memória lida (si) e escrita (so) em disco. Neste exemplo, vazio, pois o sistema não utiliza memória virtual. Na parte de Entrada/Saída (io) temos as quantidades de blocos lidos (bi) e escritos (bo) de um dispositivo. Em Sistema (system) temos o número de interrupções por segundo (in) e número de trocas de contexto por segundo (cs). As informações de CPU são o percentual de tempo gastos executando código de usuário (us), código do sistema (sy) e em inatividade (idle). A coluna wa só é utilizada para versões mais novas do kernel.

3.5. O pacote SYSSTAT

O pacote sysstat engloba os comandos iostat, mpstat e sar. O comando iostat mostra estatísticas de utilização de dispositivos de armazenamento. O comando produz uma saída informando o número de blocos lidos e escritos, bem como a taxa de leituras/escritas por segundo e um indicador de número de tps.

Neste caso, o comando está mostrando os percentuais de utilização de CPU por tipo de processos e, logo abaixo, as informações sobre entradas/saídas dos dispositivos de bloco. No exemplo há apenas um disco (dev3-0), que tem no momento uma média de execução de 29,62 transações por segundo, com médias de 535,18 blocos lidos por segundo, 121,55 blocos escritos por segundo, 423520 blocos lidos e 96188 escritos.

O comando mpstat retorna estatísticas relacionadas a utilização da CPU. Além das estatísticas de porcentagem de tempo de processamento utilizadas por usuários, pelo sistema, em nice e sem utilização, mostra também a taxa de interrupções que o sistema recebe.

O comando sar engloba a saída dos comandos iostat e mpstat, além de diversas outras informações, como informação sobre utilização de memória, swap, tráfego de rede por interface, utilização por terminais virtuais ou por processos (opcionais), entre diversas outras informações.

Além das ferramentas, o pacote contém alguns scripts para automatizar a coleta de dados no sistema, podendo recuperar posteriormente todas as informações.

3.6. Outras ferramentas

Além das já citadas, existem ainda algumas ferramentas como o xosview e o tload. Estas ferramentas apresentam, de forma gráfica ou em modo texto, os dados. São frameworks para as outras ferramentas.

Convém observar que devido ao projeto do kernel do Linux, todas as informações relativas ao estado do sistema estão localizadas dentro do diretório /proc, sendo este um local excelente para pesquisar-se informações associadas diretamente ao funcionamento do sistema. A maioria das ferramentas já mencionadas fazem coleta e tratamento de informações ali contidas e apresentam-se em uma forma mais inteligível para o usuário.

4. CONCLUSÕES

A análise de desempenho de um sistema computacional pode ser considerada uma arte [5], pois é necessário o domínio de algumas técnicas e também um senso apurado e vivência por parte do analista de desempenho para obter respostas a partir das informações coletadas e de como coletá-las.

Não devemos procurar por respostas imediatas, em uma única operação. A análise de desempenho é baseada no conceito de prever o futuro de um sistema, observando-se seu comportamento passado e presente. Logo, deve-se considerar a formação de uma base de conhecimentos relativos às diversas situações em que o sistema foi submetido e, a partir desta, subsidiar as tomadas de decisão envolvidas.

Como visto anteriormente, o planejamento de capacidade é baseado em três modelos distintos, para uma avaliação completa. Com a aplicação deste modelo em avaliações futuras, será possível fazer um planejamento não empírico, mas científico da evolução da carga do sistema.

Tratando-se de sistemas abertos, não é necessário o uso de ferramentas não disponíveis em uma configuração típica. Isto facilita a operação de coleta de dados, já que esta pode ser feita sem a necessidade de direitos especiais sobre o sistema e com o auxílio de scripts relativamente fáceis de serem elaborados.

5. REFERÊNCIAS

1. COULOURIS, G. ; DOLLIMORE, J. ; KINDBERG, T. Distributed systems: concepts and design. New York: A. Wesley, 1994.

2. FINK, J. R. ; SHERER, M. D. Linux performance tunning and capacity planning. Indianapolis: Sams Publishing, 2002.

3. GNU’s not UNIX! Disponível em: <http://www.gnu.org>. Acesso em: 03 dez. 2003.

4. HENNESSY, J. L. ; PATTERSON, D. A. Computer architeture: a quantitative approach. São Francisco: M. Kaufmann, 1996.

5. JAIN, R. The art of computer systems performance analysis. New York: J. Wiley & Sons, 1991.

6. MENASCÉ, D. A. ; ALMEIDA, V. A. F. ; DOWDY, L. W. Capacity planning for web peformance: metrics, models & methods. New Jersey: Prentice Hall, 1998.

7. MENASCÉ, D. A. ; ALMEIDA, V. A. F. ; DOWDY, L. W. Capacity planning and performance modeling: from mainframes to client-server systems. New Jersey: Prentice Hall, 1994.

8. SILBERSCHATZ, A. ; GALVIN, P. B. Sistemas operacionais: conceitos. New Jersey: Prentice Hall, 2000.