Lucas do R. B. Brasilino da Silva. Aceleração HTTP: Um comparativo de performance entre as soluções Squid e Varnish - PDF
Lucas do R. B. Brasilino da Silva. Aceleração HTTP: Um comparativo de performance entre as soluções Squid e Varnish
Download "Lucas do R. B. Brasilino da Silva. Aceleração HTTP: Um comparativo de performance entre as soluções Squid e Varnish"
Ana Júlia Paiva Salgado
1 Lucas do R. B. Brasilino da Silva Aceleração HTTP: Um comparativo de performance entre as soluções Squid e Varnish Monografia de Pós-Graduação Lato Sensu apresentada ao Departamento de Ciência da Computação para obtenção do título de Especialista em Administração em Redes Linux Orientador Prof. MSc. Joaquim Quinteiro Uchôa Lavras Minas Gerais - Brasil 2009
3 Lucas do R. B. Brasilino da Silva Aceleração HTTP: Um comparativo de performance entre as soluções Squid e Varnish Monografia de Pós-Graduação Lato Sensu apresentada ao Departamento de Ciência da Computação para obtenção do título de Especialista em Administração em Redes Linux Aprovada em Novembro de 2009 Prof. Marluce Rodrigues Pereira Prof. Sandro Melo Prof. MSc. Joaquim Quinteiro Uchôa (Orientador) Lavras Minas Gerais - Brasil 2009
5 Esse trabalho é dedicado a todos que contribuíram e contribuem para que a World Wide Web seja um vetor democrático de desenvolvimento social, econômico e cultural. É especialmente dedicado ao físico inglês Tim Berners-Lee, que há décadas vislumbrou um mundo sem barreiras geográficas.
7 Agradecimentos Agradeço ao Professor Joaquim Quinteiro Uchôa por ter acolhido com entusiasmo essa monografia e por sua dedicação em orientá-la. Agradeço à minha esposa Simone pelo apoio e incentivo constantes, pela preocupação no andamento dessa monografia, pelas revisões gramaticais e pelos mimos diários. Agradeço aos colegas da Procuradoria Geral da República e da 4Linux pelas oportunidades de desenvolver trabalhos em áreas as quais me permitem crescer como profissonal.
8 Sumário 1 Introdução 1 2 Aceleração HTTP Servidor proxy/cache Servidor proxy/cache reverso Hyper Text Transfer Protocol (HTTP) Uniform Resource Locator - URL Requisição e resposta Headers HTTP que implementam caching Header Expires Header Cache-Control Header Last-Modified Header If-Modified-Since Mecanismos de caching do HTTP Modelo baseado em expiração Modelo baseado em validação Heurística de caching Mecanismos de caching aplicados ao acelerador HTTP i
9 3 Principais Aplicativos para Aceleração HTTP Squid Varnish Outros aplicativos Apache Cherokee Lighttpd Metodologia Utilizada Hardware Hardware cliente Hardware servidor Rede de interconexão Sistema Operacional Parametrizações Fila de conexões pendentes Tempo de espera para fechamento de conexão Portas TCP locais disponíveis Máximo de descritores de arquivos por processo Sumário de parametrizações Ferramenta de medição de performance Medição baseada em sessões Preparação do ambiente de ensaios de carga Servidor Web Instalação do Apache Página Web de prova ii
10 Configuração do Apache Acelerador HTTP Instalação do Varnish Configuração do Varnish Instalação do Squid Configuração do Squid Ferramenta de medição Arquivo de workload de sessões Sistemática dos ensaios de carga Modos de operação do Apache Resultados e Discussão Pré-testes Largura de banda da rede de interconexão Performance do Apache sem acelerador Resultados dos ensaios do Squid e Varnish Respostas HTTP por segundo Tempo médio de conclusão de respostas Modo CACHE_TOTAL Modo CACHE_PARCIAL Modo SEM_CACHE Discussão Conclusão Outros critérios de escolha Trabalhos Futuros iii
11 A Arquivos de configuração 61 A.1 Arquivo /etc/sysctl.conf A.2 Arquivo httpd.conf A.3 Arquivo varnish.vcl A.4 Arquivo squid.conf iv
12 Lista de Figuras 2.1 Disposição de um proxy/cache Disposição de um proxy/cache reverso Disposição de um acelerador HTTP Exemplo de URL Formato de URL para schema http Exemplo de requisição HTTP Formato de uma requisição HTTP Exemplo de resposta HTTP Header Expires Header Cache-Control Header If-Modified-Since Conversão de respostas por segundo para largura de banda Arranjo para ensaios de carga Saída do comando mii-tool Consulta ao número máximo de descritores Exemplo de saída do httperf Exemplo de arquivo de sessão Página Web de prova v
13 4.8 Arquivo de workload utilizado nos ensaios Inicialização do Apache no modo CACHE_TOTAL Respostas por segundo do Apache Respostas por segundo: Squid e Varnish Tempo médio no modo CACHE_TOTAL Tempo médio no modo CACHE_PARCIAL Tempo médio no modo SEM_CACHE vi
14 Lista de Tabelas 2.1 Categorias de código de resposta Código de repostas mais comuns Diretivas do Cache-Control Versões do Squid Características do kernel quanto à operação em rede Sumário de parametrizações Arquivos que compõem a página Web de prova vii
16 Resumo A utilização da World Wide Web cresce a cada dia. Com isso, a demanda de acesso a servidores de aplicação Web cresce em uma razão muito maior. Uma das formas de amenizar a carga sobre tais servidores é incluir uma camada de caching. Esse trabalho discute inicialmente como o protocolo HTTP suporta Web caching e como se comportam, em termos de performance, duas das soluções mais usadas de aceleração HTTP cujas licenças são aprovadas pela Open Source Initiative: Squid e Varnish. Palavras-Chave: Hyper Text Transfer Protocol; HTTP; World Wide Web; Web; Performance; Proxy; Cache; Caching; Surrogate Server ix
17 Capítulo 1 Introdução A World Wide Web desempenha um papel central na Internet. Esse é um fato natural pois ela impulsionou e difundiu o uso da grande rede entre os usuários não-técnicos. Estudos recentes demonstram que os protocolos de rede que dão sustentação à World Wide Web, ou Web como é mais conhecida, são responsáveis por mais de 70% do tráfego global da Internet (RABINOVICH; SPATSCHEK, 2002). Esse percentual certamente aumenta diariamente ao se firmar a tendência do uso de aplicativos e sistemas baseados na Web, bem como no aparecimento de novos serviços neste ambiente. A versão 2.0 da Web consolidou a Internet como uma plataforma, não mais apenas como um meio de comunicação. Desta forma, tornou-se base para novos tipos de interação entre pessoas: redes sociais, compartilhamento de áudio e vídeo, weblogs (blogs), wikis e tagging colaborativo. Estabeleceu-se um nível de interatividade nunca antes experimentado: Web sites como Orkut, Facebook, Del.icio.us, Twitter, Youtube e Last.fm, entre outros, demonstram esta tendência. Um ponto crucial quanto à usabilidade da Web é a latência, que pode ser definida como o tempo entre a solicitação de uma página e sua total renderização no navegador e apresentação ao usuário (SIEMINSKI, 2005). Nesse tempo estão incluídas a busca e a transferência de objetos (páginas HTML, figuras, folhas de estilo, etc) através do protocolo HTTP - Hyper Text Transfer Protocol. Para minimizar esse tempo, o protocolo HTTP provê mecanismos de caching. Estudos sobre o comportamento humano indicam que o homem executa, em média, 6 operações elementares por minuto. Pode-se inferir que uma latência 1
18 acima de 10 segundos rompe com essa média e pode causar sensação de desconforto e desinteresse (SIEMINSKI, 2005). Outros estudos, focados no comportamento durante o uso da Web, indicam que a latência máxima tolerável é de 8 segundos (ZONA RESEARCH, 1999) e quanto mais experiente menos paciente é o usuário. Existem várias tecnologias envolvidas em minimizar a latência experimentada pelo usuário. Dentre elas, podem-se destacar servidores proxy/cache e servidores surrogate (ou proxy/cache reverso) (RABINOVICH; SPATSCHEK, 2002). Um acelerador HTTP é um caso particular desse último. Dentre as soluções de aceleração HTTP distribuídas sob uma licença aprovada pela Open Source Initiative, certamente a mais conhecida e utilizada é o Squid. Por estar sendo desenvolvido há mais de uma década, ele detém uma grande base de usuários, além de ser disponível virtualmente em todos os sistemas operacionais Unix-like (Linux, Solaris, BSD s, etc) e foi, há alguns anos, portado para o kernel do Windows NT. Grandes sites, como Wikipedia, implementam-o como acelerador HTTP com sucesso. Em 2006 foi lançada uma nova solução chamada Varnish. Afirmando que o Squid tem um design antigo e que foi adaptado para ser um proxy/cache reverso, o Varnish foi pensado desde o início para ser um acelerador HTTP e para usar ao máximo recursos otimizados presentes nos S.O s Unix-like modernos. Portanto, os desenvolvedores do Varnish alegam que sua performance é muito superior à do Squid. Este trabalho tem como objetivo o estudo comparativo em termos de performance entre o Squid e o Varnish como aceleradores HTTP. O Capítulo 2 é dedicado a uma revisão do protocolo HTTP e suas funcionalidades de caching. O Capítulo 3 apresenta os principais aplicativos que provêem funcionalidades de aceleração HTTP, com ênfase no Squid e Varnish. O Capítulo 4 discorre sobre a metodologia e ferramentas utilizadas na produção dos dados comparativos entre as soluções que são tema deste trabalho. O Capítulo 5 demonstra os resultados experimentais. O Capítulo 6 apresenta as conclusões do trabalho e propõe trabalhos futuros. 2
19 Capítulo 2 Aceleração HTTP A aceleração HTTP é provida por um ou vários servidores proxy/cache implementados como proxy/cache reverso (servidor surrogate) com a característica de estar no mesmo hardware servidor ou na mesma LAN que o servidor Web de origem Servidor proxy/cache Proxy/cache é o servidor que busca nos servidores Web de origem (ou em outros proxy/caches) os objetos como se fossem requisitados pelos clientes. Tipicamente está próximo, na mesma LAN ou a poucos hop s, dos requisitantes. É também conhecido como forward proxy/cache (NAGARAJ, 2004). A Figura 2.1 ilustra sua implementação. Normalmente, os clientes HTTP necessitam ser configurados para utilizarem o servidor proxy/cache. Alternativamente há a possibilidade da implantação no modo interception proxy (RABINOVICH; SPATSCHEK, 2002). Nessa modalidade, um equipamento de rede (roteador, firewall, etc) intercepta os pacotes TCP cuja porta de destino seja 80 e os divergem para o proxy/cache. Em linhas gerais, se adequadamente configurado, o proxy/cache melhora a performance: Web. 1 Servidor de origem é o termo aplicado aos servidores que mantém a cópia original do objeto 3
20 Proxy/Cache Internet Primergy Servidor Web LAN Cliente Web Figura 2.1: Disposição de um proxy/cache Reduzindo a latência percebida pelo usuário ao acessar conteúdos Web. Esta redução se dá proporcionalmente ao hit rate 2 ; Racionalizando o uso da banda passante na rede, pois os objetos servidos pelo proxy/cache atravessa uma pequena parte da rede; Minimizando a demanda de serviço ao servidor Web de origem, diminuindo sua carga de processamento; Funcionando como um cache de conexões TCP. 2.2 Servidor proxy/cache reverso O servidor proxy/cache reverso pode ser entendido como uma variante da implementação descrita na Seção 2.1. Nessa modalidade o servidor está próximo à origem do conteúdo e não à sua destinação, conforme Figura 2.2. Um acelerador HTTP é um caso particular de proxy/cache reverso, onde se encontra diretamente conectado através de uma rede de banda idealmente infinita ao servidor Web de origem. A Figura 2.3 ilustra-o. 2 Taxa definida pela quantidade de objetos servidos pelo proxy/cache sobre o total requisitado 4
21 Primergy Proxy/Cache Reverso Internet Client Web Ambiente Corporativo WAN Servidor Web Figura 2.2: Disposição de um proxy/cache reverso As vantagens do uso de um acelerador HTTP são as mesmas já citadas na seção anterior, acrescentando-se: Mimetiza o comportamento da origem do conteúdo; Configura os headers HTTP de forma conveniente nas respostas dos objetos servidos a partir do cache; Mantém uma forte consistência em seu cache local; Pode ser usado como um gateway de conexões não-persistentes para persistentes, diminuindo o número de conexões abertas ao servidor Web de origem; Pode ser usado como um tradutor de versões de protocolos. (Ex: HTTP/1.0 HTTP/1.1). 5
22 Primergy Proxy/Cache Reverso Client Web Internet Acelerador HTTP LAN Ambiente Corporativo Servidor Web Figura 2.3: Disposição de um acelerador HTTP 2.3 Hyper Text Transfer Protocol (HTTP) O HTTP é um protocolo baseado em requisição e resposta. Foi inicialmente definido como HTTP/0.9 (BERNERS-LEE, 1994). A versão HTTP/1.0 foi então definida pela RFC 1945 (BERNERS-LEE; FIELDING; FRYSTYK, 1996) para expandir suas possibilidades. Nessa versão foram introduzidas informações que permitiam caching de conteúdo Web. Com o passar do tempo e com o uso, tais informações mostraram-se limitadas. Em junho de 1999, foi publicada a RFC 2616 (FIELDING et al., 1999) que define o HTTP/1.1. Essa nova versão em muito ampliou as funcionalidades do protocolo. Um capítulo foi dedicado a web caching, introduzindo a idéia de mecanismos baseados em expiração e em validação. A partir deste ponto do texto será abordado a versão 1.1 do protocolo HTTP Uniform Resource Locator - URL Uniform Resource Locator (BERNERS-LEE; MASINTER; MCCAHILL, 1994) é um conceito fundamental na Web. Sua função é endereçar cada objeto disponível 6
23 na Internet em uma relação de N para 1: o mesmo objeto pode ser localizado por URL s diferentes (RABINOVICH; SPATSCHEK, 2002). Na Figura 2.4 tem-se um exemplo. Basicamente uma URL é definida na forma: <scheme>:<scheme-specific-part> O scheme que se aplica a este texto é o http (Figura 2.5), que é dividido em: host: Nome do servidor ou endereço IP onde encontra-se o objeto; port: Porta TCP utilizada para conexão. Se omitida deve-se utilizar as portas-padrão 80 para schema http e 443 para a variante segura https; path: Caminho no servidor, a partir de um raiz, que o objeto deve ser buscado; searchpart: Uma sequencia pré-determinada de valores para serem referenciadas como argumentos. Também conhecida como query string. É opcional. Normalmente, o servidor proxy/cache utiliza a URL como argumento principal de consulta para determinar se o objeto já foi armazenado localmente em sua área de caching. Muitos utilizam uma técnica de hashing para que a localização seja eficiente. Pode-se deduzir que, como um objeto por ser referenciado por várias URL s, o proxy/cache armazene cópias idênticas desperdiçando espaço. Porém, como o tamanho médio de um objeto é de 4Kb, o armazenamento de algumas cópias não chega a ser preocupante, dado que é comum áreas de armazenamento de centenas de Megabytes a alguns Gigabytes. Figura 2.4: Exemplo de URL Figura 2.5: Formato de URL para schema http 7
24 GET /files/arl_logo.gif HTTP/1.1 Host: arl.ginux.ufla.br User-Agent: BrasilinoBrowser/1.0 Accept: text/html, image/* Connection: close Figura 2.6: Exemplo de requisição HTTP Requisição e resposta Requisição é a ação promovida por um cliente Web para buscar um conteúdo (objeto) disponível em um servidor. Como seu nome sugere, o protocolo HTTP preocupa-se com transferência dos dados que compõem o objeto, tanto na direção cliente servidor quanto na direção servidor cliente. Uma categoria de clientes conhecida como navegadores gráficos também acumulam a função de renderizar o objeto ao usuário. Um cliente, ao solicitar a busca do objeto identificado pela URL ilustrada na Figura 2.4, efetuará a resolução DNS para determinar o IP do servidor arl.ginux.ufla.br (a parte host da URL), se conectará à porta 80 desse e efetuará a requisição conforme Figura 2.6. Essa requisição segue o formato padrão ilustrado na Figura 2.7. A primeira linha é a request line (linha de requisição), que contém o método, a parte path da URL e a versão do protocolo. Os métodos são GET, HEAD, OPTIONS, POST, PUT, DELETE e TRACE. O método GET é o método mais comum e responsável por mais de 97% das requisições. É usado para buscar o objeto especificado na parte path. Na linha de requisição GET /files/arl_logo.gif HTTP/1.1 o arquivo GIF arl_logo.gif será buscado. As linhas subsequentes são os headers, ou cabeçalhos. Eles qualificam a requisição e a resposta provendo informações necessárias como qual codificação e/ou língua é aceita pelo cliente, quais objetos são aceitos para transferência, dados sobre autenticação, sobre caching, entre outros. Os headers são divididos em: 8
25 Request Line Headers CRLF Entity Body Figura 2.7: Formato de uma requisição HTTP General headers: São aplicáveis tanto em requisições quanto em respostas; Request headers: São aplicáveis apenas em requisições; Response headers: São aplicáveis apenas em respostas; Entity headers: Descreve os dados contidos na requisição ou na resposta. Na requisição exemplificada na Figura 2.6, o Host, User-Agent e Accept são request headers. O Connection é um general header. Para efeito de simplificação, todos os headers de uma requisição são chamados de request headers. Após os headers, seguem-se dois caracteres que sinalizam o fim da parte inicial da requisição: carriage return (CR) e line feed (LF), cujos códigos ASCII são respectivamente 13 e 10. Entity body compreende os dados do objeto que está sendo transferido. O método POST é a única requisição que envia dados ao servidor. Nesse caso, o entity body é preenchido com os dados a serem enviados. Na requisição exemplificada não há entity headers, uma vez que não há entity body. A resposta HTTP tem um formato similar à requisição. A diferença básica é que na primeira linha é colocada uma status line, ou linha de status. Na Figura 2.8 demonstra a resposta do servidor Web arl.ginux.ufla.br quando da requisição do arquivo arl_logo.gif conforme Figura 2.6. A status line é formada pela versão do protocolo utilizado na resposta, um código numérico do status (status code) e sua descrição textual. O código numérico é 9
26 HTTP/ OK Date: Sat, 14 Feb :35:05 GMT Server: Apache Last-Modified: Tue, 27 Nov :35:25 GMT ETag: "40d56-129f-43fef05453d40" Accept-Ranges: bytes Content-Length: 4767 Cache-Control: max-age= Expires: Sat, 28 Feb :35:05 GMT Connection: close Content-Type: image/gif GIF89a Figura 2.8: Exemplo de resposta HTTP agrupado em 5 categorias separadas pelas centenas conforme Tabela 2.1, enquanto os códigos mais usuais estão sumarizados na Tabela 2.2. Nessa resposta, os headers Date, Cache-Control e Connection são general headers, os Server e ETag são response headers e por fim Last-Modified, Content-Length, Expires e Content-Type são entity headers. Coloquialmente todos os headers contidos em uma resposta são chamados de response headers. A partir da linha em branco gerada pelos dois caracteres CR e LF, iniciase a transferência dos bytes referente ao arquivo solicitado que, por economia de espaço, apenas os primeiros estão demonstrados na Figura 2.8. Tabela 2.1: Categorias de código de resposta Código do status 1xx 2xx 3xx 4xx 5xx Categoria de resposta Informação Sucesso Redirecionamento Erro do cliente Erro do servidor 10
27 Tabela 2.2: Código de repostas mais comuns Código de status Descrição textual 200 OK 206 Partial Content 301 Moved Permanently 302 Found 304 Not Modified 400 Bad Request 401 Unauthorized 403 Forbidden 404 Not Found 500 Internal Server Error 503 Service Unaviable Um cliente HTTP de posse destas informações salva o arquivo arl_logo.gif em um diretório local. Caso seja gráfico, renderiza-o ao cliente. Esse texto foca no uso dos headers Expires, Cache-Control, Last-Modified e If-Modified-Since. Os dois primeiros são os mais importantes pois implementam os mecanismos de caching do HTTP. 2.4 Headers HTTP que implementam caching Header Expires Expires é um response header que foi introduzido na versão 1.0 do protocolo HTTP (BERNERS-LEE; FIELDING; FRYSTYK, 1996) como um primeiro esforço para estabelecer a funcionalidade de caching. Seu valor deve ser a data de expiração do objeto, ou seja, até quando ele é válido. Portanto, Expires define o tempo absoluto da expiração. No exemplo ilustrado na Figura 2.9 o objeto foi buscado no dia 27 de fevereiro de 2009, uma sexta feira, às 21:13 no horário de Greenwich (header Date) porém será válido até 17 de janeiro de 2038 às 19:14 também no horário de Greenwich. Até essa data, o servidor proxy/cache servirá o objeto diretamente ao cliente, não buscando-o no servidor Web de origem. Um tempo no passado informa que o objeto já está expirado, necessitando que seja requisitado novamente em um novo acesso. Essa é uma forma que os servidores Web de origem usam para forçar que um objeto não seja cacheado. 11
28 HTTP/ OK Server: Apache Content-Type: image/gif Date: Fri, 27 Feb :13:45 GMT Last-Modified: Wed, 07 Jun :50:30 GMT Expires: Sun, 17 Jan :14:07 GMT Connection: Keep-Alive Figura 2.9: Header Expires HTTP/ OK Server: Apache Content-Type: image/gif Date: Fri, 27 Feb :13:45 GMT Cache-Control: max-age=3600, public Last-Modified: Wed, 07 Jun :50:30 GMT Connection: Keep-Alive Figura 2.10: Header Cache-Control Header Cache-Control Para aumentar a flexibilidade nos mecanismos de caching foi introduzido, no HTTP versão 1.1, o header Cache-Control. Esse header é mais completo e mais complexo. Por ser um general header, ele pode ser usado tanto em uma requisição quanto em uma resposta. Porém este texto trata-o apenas quanto ao uso em uma resposta. O valor pode ser uma ou mais diretivas separadas por vírgula, como exemplificado na Figura A Tabela 2.3 sumariza as diretivas desse header. A diretiva max-age define o tempo relativo em segundos da expiração tendo como base o momento (data e hora) da requisição. A resposta presente na Figura 2.10 está definindo que a expiração do objeto acontecerá em 3600 segundos. 12
29 Em uma resposta que estejam presentes tanto o Expires quanto o Cache-Control, esse último prevalecerá. Tabela 2.3: Diretivas do Cache-Control Diretiva Valor Significado no-cache nenhum A resposta não pode ser cacheada no-store nenhum A resposta não pode ser armazenada no cliente (proxy/cache ou navegador) private nenhum A resposta só poderá ser reutilizada pelo cliente que o requisitou inicialmente public nenhum A resposta poderá ser cacheada e compartilhada entre clientes diferentes must-revalidade nenhum A resposta deverá sempre ser validada, geralmente através de uma requisição condicional proxy-revalidation nenhum O mesmo que must-revalidade porém aplica-se apenas a proxy/caches max-age segundos A resposta será válida durante este tempo s-maxage segundos O mesmo que max-age porém aplica-se apenas a proxy/caches no-transform nenhum A resposta deverá ser idêntica à fornecida pelo servidor de origem Header Last-Modified Last-Modified é um entity header que indica a data da última modificação do objeto. Os objetos cujas repostas estão ilustradas nas Figuras 2.9 e 2.10 tiveram sua última modificação (de conteúdo) datada de 7 de junho de 2006 às 19:50, horário de Greenwich Header If-Modified-Since If-Modified-Since é um request header utilizado para questionar ao servidor, tanto Web de origem quanto proxy/cache, se o objeto foi modificado desde uma data específica. Essa data é explicitada no valor do header. 13
30 A Figura 2.11 é igual à requisição da Figura 2.6, porém adicionando-se o questionamento através do If-Modified-Since. GET /files/arl_logo.gif HTTP/1.1 Host: arl.ginux.ufla.br User-Agent: BrasilinoBrowser/1.0 If-Modified-Since: Fri, 27 Feb :00:00 GMT Accept: text/html, image/* Connection: close Figura 2.11: Header If-Modified-Since 2.5 Mecanismos de caching do HTTP Caching não teria utilidade se não melhorasse de forma significativa a performance minimizando a latência experimentada pelo usuário. Seu objetivo é, em alguns casos, eliminar a necessidade do envio de requisições e, em outros, eliminar a necessidade do objeto Web ser transferido por completo (NAGARAJ, 2004). O protocolo HTTP baseia-se no conceito de time to live (TTL). Time to live, ou tempo de vida, indica a duração tempo que um objeto é válido. Quando um objeto está cacheado por um tempo maior que seu TTL ele é dito inválido. O termo não-expirado também é empregado como sinônimo de válido, enquanto o termo expirado é empregado como sinônimo de inválido. Esse conceito também é utilizado em outras tecnologias: DNS por exemplo. As requisições a um objeto válido são satisfeitas pelo proxy/cache. Quando o objeto tornar-se inválido, o proxy/cache deverá ou buscá-lo novamente ou revalidálo através de uma requisição condicional (RABINOVICH; SPATSCHEK, 2002). Em uma requisição condicional, o cliente HTTP especifica certas condições através de seus request headers. O servidor, tanto um proxy/server quanto um Web de origem, avalia a condição e se ela for verdadeira responderá com 200 OK acrescido do conteúdo do objeto no corpo da resposta, ou seja, uma resposta como se a requisição não fosse condicional. Caso a condição seja falsa, o servidor responde com uma status line 304 Not Modified. 14
31 O comportamento de um proxy/cache, quanto ao objeto inválido, depende do modelo de caching aplicado pelo servidor Web de origem. Esses modelos são definidos na RFC2616 (FIELDING et al., 1999) como modelo baseado em expiração e modelo baseado em validação Modelo baseado em expiração O modelo de caching baseado em expiração tem como objetivo evitar requisições ao servidor Web de origem, diminuindo sua carga de processamento e a latência da rede (FIELDING et al., 1999). Utilizando-se o header Expires com uma data no futuro ou o Cache-Control com a diretiva max-age, o servidor Web de origem sinaliza ao proxy/cache que um dado objeto é válido por um determinado período de tempo, ou seja, informa seu TTL. Esse modelo é muito aplicado em conteúdos estáticos como figuras, vídeos, arquivos em geral (PDF, ODP, ODT, etc), folhas de estilos (CSS), código javascripts, páginas HTML estáticas, etc. Pode ser também aplicado a conteúdos que tendam a ser dinâmicos, como uma página com sumário de notícias, desde que o tempo de expiração seja curto, tipicamente na ordem de minutos Modelo baseado em validação Esse modelo baseia-se na possibilidade de se efetuar uma requisição condicional ao servidor e tem como objetivo minimizar a largura de banda de rede a ser utilizada na busca de um objeto (FIELDING et al., 1999). Quando o proxy/cache tem armazenado um objeto inválido ele realiza uma requisição condicional adicionando o header If-Modified-Since com a data recebida através do header Last-Modified de quando o objeto foi buscado inicialmente. Existem duas possibilidades de resposta: 1. Se a condição for verdadeira, ou seja, o objeto foi modificado desde a data e hora indicadas no If-Modified-Since, o servidor Web de origem: (a) responde com a linha de status 200 OK ; (b) acrescenta o header Last-Modified atualizando no proxy/cache o tempo da última modificação; 15
32 (c) possivelmente informa uma nova data de expiração (ou seja, um novo TTL), através do header Expires ou Cache-Control. 2. Se a condição for falsa, ou seja, o objeto não foi modificado desde a data e hora indicadas no If-Modified-Since, o servidor Web de origem: (a) responde com a linha de status 304 Not Modified ; (b) possivelmente adiciona uma nova data de expiração. Se ocorrer a segunda possibilidade, o objeto será revalidado pelo proxy/cache. Como não haverá a transferência integral do objeto, consequentemente haverá uma economia significativa na largura de banda da rede. É possível forçar que o objeto sempre seja revalidado. Basta o servidor Web de origem adicionar Cache-Control: max-age=0, must-revalidade em sua resposta. O modelo de validação é muito utilizado em informações onde há a necessidade tempestiva de se acessar a última versão do conteúdo disponível, como por exemplo: notícias de última hora, valores de ações, placares de jogos, páginas HTML dinâmicas, etc Heurística de caching Como os servidores Web de origem nem sempre provêem informações que possam sugerir o uso de algum modelo de caching, os proxy/caches aplicam algoritmos para determinar se um objeto é válido ou não. Tais algoritmos não são padronizados pela RFC2616 e dependem da implementação de cada proxy/cache. Geralmente objetos serão considerados não-cacheáveis se em suas respectivas URL s (RABINOVICH; SPATSCHEK, 2002): Contiverem o caracter?, onde presume-se que também contenham uma searchpart; Contiverem cgi-bin como parte de seu path; Não utilizarem os métodos GET e HEAD; Contiverem alguns headers como o Authorization; 16
33 Contiverem o header Cookie em sua requisição ou Set-Cookie em sua resposta. Se a resposta de um objeto contiver apenas o header Last-Modified, o proxy/cache calcula a idade do objeto pela equação: age = Date - (Last-Modified) E considera o objeto válido por uma fração do valor calculado em age. No Squid (THE SQUID TEAM, 2009), por exemplo, esta fração por padrão é de 20%. 2.6 Mecanismos de caching aplicados ao acelerador HTTP Conforme visto na Figura 2.3 e definido na Seção 2.2, o acelerador HTTP é um servidor proxy/cache reverso que está próximo ao servidor Web de origem, geralmente conectado por uma LAN ou sendo executado no mesmo hardware. É importante frisar que, normalmente, os servidores Web de origem são servidores de aplicação em geral conectados a servidores de banco de dados e outros recursos. Tais servidores, ao serem muito requisitados, necessitam de grande poder computacional. A economia de largura de banda propiciada pelo modelo baseado em validação não é impactante nem deve ser levada em consideração 3. Por outro lado, a diminuição da carga e o número de requisições propiciados pelo modelo baseado em expiração é considerável. Portanto, uma política plausível de implantação de um acelerador HTTP é a de escolher o mecanismo de caching baseado em expiração onde conteúdos estáticos podem ser cacheados por dias, enquanto os que mudam com frequência podem expirar em poucos segundos. Com isso, o acelerador terá uma rápida inconsistência em seu cache. Outra política muito comum é a de se usar o modelo baseado em validação apenas nos conteúdos dinâmicos para que, ao mudarem, sejam imediatamente buscados, enquanto aos conteúdos estáticos é aplicado o modelo baseado em expiração. Dessa forma, o acelerador terá uma forte consistência em seu cache, visto que fará mais requisições condicionais ao servidor Web de origem. 3 Atualmente as LAN s são implantadas com no mínimo 100Mb/s de largura de banda 17
35 Capítulo 3 Principais Aplicativos para Aceleração HTTP 3.1 Squid Em 1994, o Internet Research Task Force on Resource Discovery (IRTF-RD) iniciou um projeto para o desenvolvimento de uma ferramenta integrada para buscar, extrair, organizar, pesquisar, cachear e replicar informações baseadas em tecnologia Web. Esse projeto foi batizado de Harvest (WESSELS, 2004). Seu módulo de caching tornou-se bastante popular. No início de 1996, após vários pesquisadores saírem do IRTF-RD, um deles, Duane Wessels, integrou o National Laboratory for Applied Network Research (NLANR). Tendo em mãos o código do módulo de caching do Harvest, ele o renomeou para Squid e o disponibilizou sob licença GNU General Public License (GPL). Em 2000 o NLANR deixou de custear seu desenvolvimento e, desde então, um grupo de voluntários continua a liberar novas versões sempre adicionando funcionalidades (WESSELS, 2004). O Squid (THE SQUID TEAM, 2009) é um servidor proxy/cache estável, rápido e flexível. Possui grande número de usuários ao redor do mundo. Conta com vasta documentação disponível na Internet formada de tutoriais nas mais diversas línguas e um site bem estruturado contendo, entre vários recursos, um wiki 1 muito detalhado
36 Além de ser um forward proxy/cache, topologia discutida na Seção 2.1, o Squid foi adaptado e melhorado para ser um proxy/cache reverso, topologia discutida na Seção 2.2. Existem duas famílias de versões paralelas do Squid: versão 2 e versão 3. A versão 2 (Squid-2) é a continuação do desenvolvimento da versão 1. Já a versão 3 (Squid-3) é uma reorganização e reescrita total do código-fonte, além da adição de suporte a alguns protocolos como o Edge Side Includes (ESI) (TSIMELZON, 2001) e o Internet Content Adaptation Protocol (ICAP) (ELSON; CERPA, 2003). Na Tabela 3.1 estão as versões disponíveis no tempo da elaboração deste trabalho. Tabela 3.1: Versões do Squid Família de versões Squid-2 Squid-3 Última versão disponível 2.7.STABLE7 3.0.STABLE18 Este trabalho utiliza a versão 2.7.STABLE7. O Squid suporta algumas funcionalidades que podem ser utilizadas quando está operando como um acelerador HTTP a fim de ampliar as possibilidades de sua implantação. Destacam-se: Internet Cache Protocol (ICP): Alguns servidores Web de origem, por exemplo o Zope, suportam ICP. Apesar de ser um protocolo simples e não confiável, caso seja implementado com cuidado pode ser útil. Hyper Text Caching Protocol (HTCP): É uma versão melhorada do ICP. Balanceamento de carga: Distribui a carga de requisições não satisfeitas pelo proxy/cache a um conjunto (pool) de servidores Web. A escolha de um servidor entre o conjunto é feita através de round-robin com possibilidade de definição de servidor preferencial. Cache Array Routing Protocol (CARP): É outra forma de distribuição de carga. Baseia-se na escolha de um servidor 20
37 Web dentre os vários através de um hash da URL requisitada. Assim, a requisição de um objeto sempre será repassada ao mesmo servidor Web de origem. Redirecionadores externos: Suportam o uso de programa externo para reescrita de URL. Estatísticas em tempo real: Através do utilitário de linha de comando squidclient é possível obter diversas informações em tempo real. A implementação na prática de ICP e HTCP tem-se mostrado ineficiente. É quase nulo o número de servidores Web de origem que suportam esses protocolos. Por serem baseados em pergunta e resposta podem inserir tempos de espera da resposta HTTP, o que certamente acarretará aumento da latência. 3.2 Varnish O Varnish (KAMP, 2009) é um daemon servidor rico em funcionalidades e que foi desenvolvido a partir do zero com o objetivo claro de ser um poderoso proxy/cache reverso. A primeira versão estável foi liberada em 2006 e nomeada de 1.0. Seu arquiteto e principal desenvolvedor, Poul-Henning Kamp, é há muito tempo parte integrante do grupo de desenvolvedores do kernel do FreeBSD. De posse de seus conhecimentos intrísecos ao núcleo de sistemas operacionais Unixlike modernos, ele identificou que o design do Squid é antigo. Ao iniciar a escrita do Varnish, preocupou-se em utilizar de forma otimizada os recursos dos S.O s modernos, como memory mapped file e comunicação entre processos shared memory. O Website do projeto é organizado na forma de um site trac 2, contendo alguns tutoriais, documentações, lista de perguntas frequêntes, um timeline das modificações realizadas no código-fonte e uma interface Web para o Subversion, sendo possível o acesso ao código-fonte em desenvolvimento. Em 15 de outubro de 2008, foi lançada a versão 2.0 incorporando várias modificações e aperfeiçoamentos, principalmente quanto à estabilidade. No tempo da escrita deste trabalho a versão disponível é a
38 Entre as funcionalidades disponíveis no Varnish, destacam-se: Varnish Configuration Language (VCL): É uma linguagem de domínio específico (DSL - Domain Specific Language) utilizada para configurar o Varnish. Tem a sintaxe similar ao Perl ou C e é extremamente flexível. Permite a definição do comportamento desde a requisição do objeto até sua entrega ao cliente. A VCL permite uma sub-funcionalidade: a introdução de códigos em C para uma customização granular. Edge Side Includes (ESI): O protocolo ESI permite a separação de uma página Web em pequenos pedaços, que podem ser armazenados em cache individualmente. Reescrita e redirecionamento de URL: Ao contrário do Squid que precisa de um código externo para a reescrita da URL, o próprio Varnish efetua este procedimento através de funções disponíveis na VCL. Gerência em tempo real: Através de uma porta TCP é possível a realização de gerência em tempo real. A conexão à essa porta é via utilitário telnet. Estatísticas e registros em tempo real: Através de uma comunicação entre processos shared memory, os utilitários varnishlog e varnishhist registram os logs de acesso e geram estatísticas, respectivamente. Balanceamento de carga: Atualmente são suportados dois algoritmos: round-robin e random. Utilitário Web para administração: Está em desenvolvimento o suporte a um utilitário baseado na Web para administração e configuração em tempo real do daemon. Contudo, o Varnish implementa poucos aspectos da RFC O próprio autor afirma que o Varnish não é um cache nos termos dessa RFC. Ele prefere pensá-lo como um servidor web que obtém seus conteúdos através de HTTP 3. Porém, as funcionalidades não implementadas por padrão podem ser incluídas através de um arquivo VCL
39 3.3 Outros aplicativos Existem algumas outras soluções que podem ser utilizadas com o objetivo de acelerar o acesso a um site ou aplicação Web, porém, nem todos são classificados como aceleradores HTTP Apache Apache (THE APACHE SOFTWARE FOUNDATION, 2009) é um servidor Web bastante popular. Segundo o site Netcraft (NETCRAFT, 2009), de acordo com a pesquisa realizada em fevereiro de 2009, ele é utilizado cerca de 50% dos sites ao redor do mundo. Um dos fatores que promoveram o uso do Apache foi sua estrutura modularizada: vários módulos com os mais diversos propósitos foram escritos. Dentre eles, existem três que combinados podem agregar a funcionalidade de proxy/cache reverso: mod_proxy, mod_cache e mod_disk_cache. Os módulos de caching foram declarados estáveis e funcionais com o advento da versão 2.2 do Apache. Porém, o autor desse trabalho teve experiências anteriores negativas na implementação dos módulos acima listados em ambiente de produção. Pode ser citado, a fim de exemplificação, a impossibilidade de ser invalidado (excluído) um objeto em cache Cherokee Cherokee (ORTEGA, 2009) é um servidor com um design moderno e eficiente. Seu objetivo é obter o máximo em performance do hardware através de multithreading. Benchmarks iniciais pontam que ele chega a ser 20 vezes mais rápido que o Apache. Segundo avaliações realizadas por seu autor 4, o Cherokee é o servidor Web mais rápido disponível sob uma licença aprovada pela Open Source Initiative. Um dos grandes atrativos deste servidor é sua forma de configuração. O cherokee-admin é um aplicativo Web que configura todo e qualquer funcionamento do Cherokee, de forma simples e centralizada
40 O handler HTTP reverse proxy faz com que o Cherokee atue como um proxy reverso com suporte a balanceamento de carga. Porém o mesmo não atua como cache Lighttpd O Lighttpd (THE LIGHTTPD TEAM, 2009) disputa junto ao Cherokee o título de servidor Web mais rápido do mundo. É mais estável que seu competidor e portanto pode ser usado em ambiente de produção. A página Web do projeto afirma que ele é utilizado por vários sites como Youtube, Wikipedia e Meebo. Também dispõe de suporte a proxy reverso e a caching, ambos através de módulos. Porém, conforme a própria página de documentação do módulo de caching, essa implementação visa armazenar em cache os objetos que seriam servidos pelo próprio Lighttpd e não os provenientes de um outro servidor Web. 24
41 Capítulo 4 Metodologia Utilizada Existem algumas métricas que possibilitam investigar se um software utiliza recursos, funcionalidades e algoritmos de forma otimizada. Por exemplo, o número necessário de pulsos de clock para o processador finalizar uma tarefa pode ser usado como uma métrica. Outro exemplo: o número de trocas de modo entre user mode e kernel mode pode também ser utilizado como métrica. Nesse trabalho, as métricas aplicadas aos aceleradores HTTP são o número de respostas HTTP por segundo e o tempo médio de conclusão de respostas. A primeira métrica é importante para avaliar a taxa de respostas HTTP que o acelerador consegue manter. Essa taxa é normalmente igual ao número de requisições por segundo suportada pelo acelerador, definindo o throughput do mesmo (WESSELS, 2001). Normalmente, o throughput é apresentado como largura de banda, geralmente em megabits por segundo (Mb/s). Para realizar a conversão de respostas HTTP por segundo para largura de banda aplica-se a equação da Figura 4.1, onde tamanho medio é o tamanho médio das requisições em kilobytes (KB). largura_de_banda = respostas_por_segundo tamanho_medio 1024 [em Mb/s] Figura 4.1: Conversão de respostas por segundo para largura de banda 25
42 Cliente Web Acelerador + Servidor Web httperf HTTP/1.1 Rede Ethernet Squid/Varnish Hardware cliente Apache Paginas Web Hardware servidor Figura 4.2: Arranjo para ensaios de carga A segunda métrica - tempo de conclusão de respostas - sugere a capacidade de redução da latência experimentada pelo usuário. Esse tempo tende a aumentar com o aumento do número de requisições HTTP por segundo sobre o acelerador (WESSELS, 2001). O método utilizado nesse trabalho foi idealizado de forma a mimetizar um ambiente Web real. Uma página Web de prova é servida pelo Servidor Web Apache. Entre a ferramenta de medição de performance e o Apache está o acelerador HTTP, em um arranjo ilustrado na Figura 4.2. O hardware cliente executa a ferramenta de medição de performance Web httpef (Seção 4.4), responsável por gerar o workload e coletar dados estatísticos. O hardware servidor executa o acelerador HTTP, atendendo às requisições do cliente, ao mesmo tempo que executa o Apache como servidor Web de origem e armazena a página Web de prova (Seção 4.5). 4.1 Hardware Hardware cliente Por ser responsável apenas pela execução da ferramenta de medição de performance Web, o hardware cliente não necessita ser uma máquina de última geração. Foi adotado um computador com as seguintes características: 26
43 Processador Intel Celeron M 1,50Ghz Memória RAM de 2GB Disco rígido IDE de 120Gb Placa de rede fast ethernet Broadcom BCM Hardware servidor Como processa toda a carga de requisições proveniente do cliente, o hardware servidor é mais robusto. Esse computador tem as seguintes características: Processador Intel Core 2 Duo de 1,80GHz Memória RAM de 4Gb Disco rígido SATA de 250Gb Placa de rede gigabit ethernet Realtek RTL8168B 4.2 Rede de interconexão A interconexão entre o hardware cliente e servidor é realizada através de uma rede ethernet. É natural a utilização desse protocolo uma vez que é de-facto padrão universal. Ao invés de ser disposto um hardware de rede 1 entre os computadores envolvidos no ensaio, foi instalado um cross-cable conectando diretamente às placas de rede do hardware cliente e servidor. Evitam-se, assim, possíveis latências e minimiza-se a possibilidade de colisão de frames ethernet durante as simulações. A Figura 4.3 demonstra que o link ethernet foi negociado entre os computadores a 100 Mb/s full-duplex. Por fim, o hardware servidor é configurado com o IP e o cliente com o IP , ambos com máscara switches, hubs, roteadores, etc. 27
44 # mii-tool eth0 eth0: negotiated 100baseTx-FD flow-control, link ok Figura 4.3: Saída do comando mii-tool Tabela 4.1: Características do kernel quanto à operação em rede Chave do sysctl Valor padrão Descrição fs.file-max Máximo descritores em todo S.O. fs.nr_open Máximo de descritores por processo net.ipv4.tcp_max_syn_backlog 1024 Fila de conexões pendentes net.ipv4.ip_local_port_range a Portas TCP locais disponíveis net.ipv4.tcp_fin_timeout 60 Tempo de espera para fechamento de conexão 4.3 Sistema Operacional O sistema operacional presente em ambos os hardwares, cliente e servidor, é o Debian GNU/Linux 5.0 Lenny cujo kernel instalado é o bigmem. Esse kernel é relativamente novo e de estabilidade e performance comprovadas. As principais características quanto ao seu comportamento em rede também foram pesquisadas através do utilitário sysctl, conforme Tabela 4.1. Fizeram-se necessárias modificações de certos parâmetros para garantir que as aplicações envolvidas (ferramenta de medição, acelerador HTTP e servidor Web) não sofressem com a exaustão de alguns recursos. Tais modificações são detalhadas na Seção Para evitar uso desnecessário de recursos dos computadores envolvidos no ensaio, vários outros processos foram finalizados: interface gráfica, daemons servidores diversos, etc. O único serviço em execução é o ntpd Parametrizações O processo de inicialização e estabelecimento de um grande número de conexões TCP consome recursos como portas locais e descritores de arquivos em um grau mais elevado que uma utilização corriqueira do sistema operacional. 28
45 Os kernels empacotados na maioria das distribuições GNU/Linux têm valores modestos na configuração de sua pilha TCP/IP. Dessa forma, alguns valores default precisam ser parametrizados visando prover os recursos necessários para as ferramentas de medição Fila de conexões pendentes O kernel mantém uma fila de conexões pendentes onde pacotes TCP com a flag SYN habilitada foram recebidos, porém, pacotes correspondentes com as flags SYN e ACK ainda não foram enviados. Em outras palavras, o three-way handshake ainda não foi estabelecido (STEVENS, 1994). O kernel inicia o three-way handshake assim que a chamada de sistema accept() 2 é executada pela aplicação 3. Se o número de pacotes na fila de conexões pendentes for maior que seu comprimento, conexões serão perdidas. Portanto, é indicado aumentar seu tamanho. A chave net.ipv4.tcp_max_syn_backlog 4 define o comprimento da fila de conexões pendentes. Nesse trabalho seu valor é configurado para Tempo de espera para fechamento de conexão Sempre que uma aplicação fecha uma conexão, através da chamada de sistema close() 5, seu estado é mudado para TIME_WAIT durante um tempo de 2 vezes o maximum segment lifetime (MSL) antes de ser realmente fechada. MSL é o tempo que um pacote é válido em um segmento de rede. Essa forma de término de conexão é denominada active close (STEVENS, 1994). Como efeito colateral, a porta local associada à conexão não pode ser reutilizada durante o tempo em que seu estado é TIME_WAIT. O kernel, por padrão, mantém esse tempo de espera em 60 segundos, ou seja, o MSL é de 30 segundos. Conforme a Tabela 4.1, a faixa de portas locais que podem ser utilizadas para iniciar uma conexão é de a Essa faixa resulta em portas disponíveis. Se o tempo em TIME_WAIT é de 60 segundos, então é possível manter no máximo uma taxa de 470 conexões por segundo Após o recebimento de um pacote TCP de início de conexão (SYN) 4 Do utilitário sysctl
46 Frente a este fato limitador, nesse trabalho o tempo de espera para fechamento de conexão é definido em 10 segundos. Dessa forma, o MSL é de 5 segundos: tempo suficiente em uma rede com baixa taxa de colisão. A chave net.ipv4.tcp_fin_timeout configura o tempo em questão. Se a faixa de portas locais disponíveis não fosse alterada, então, ao diminuir o tempo em TIME_WAIT para 10 segundos, conclui-se que é possível manter uma taxa de 2823 conexões por segundo: um ganho expressivo. Na Seção é discutido o aumento na faixa de portas locais Portas TCP locais disponíveis Cada conexão TCP é definida por um par de sockets compreendendo um endereço IP e uma porta do cliente e um endereço IP e uma porta do servidor. Considerando cliente e servidor dotados de apenas um endereço IP cada um e que a porta 6 do servidor é fixa, o único recurso que muda entre várias conexões cliente servidor é a porta do cliente. Ao serem geradas várias conexões simultâneas, portas locais no cliente são alocadas. Durante o ensaio de carga existe a possibilidade do número de portas disponíveis no cliente se esgotar conforme discutido na Seção Nesse trabalho, a faixa de portas locais disponíveis, configurada através da chave net.ipv4.ip_local_port_range, é definida de 1025 a 65535, o que disponibiliza portas locais. Considerando o tempo de espera de fechamento de conexões de 10 segundos (Seção ), há a possibilidade teórica de se manter uma taxa de 6451 conexões por segundo Máximo de descritores de arquivos por processo A Tabela 4.1 demonstra que na configuração do kernel o limite de descritores de arquivos por processo é suficiente para se atingir as 6451 conexões por segundo. Porém, o Linux implementa POSIX Capabilities, que limita o número de descritores em A Figura 4.4 ilustra a consulta a este valor. Nesse trabalho aplica-se o valor 8192 para o número máximo de descritores por processo, seja ele cliente ou servidor, através do comando ulimit. 6 A porta do servidor está em estado LISTEN 30
Oficina Escalabilidade e performance da infraestrutura Plone/Zope com CacheFU e Varnish
Consegi 2010 Oficina Escalabilidade e performance da infraestrutura Plone/Zope com CacheFU e Varnish Lucas Brasilino Sobre o instrutor Servidor do MPF, lotado na PGR; Integrante
Adequação do servidor Proxy/Cache Squid a redes de extrema carga. Lucas Brasilino <lucas.brasilino@gmail.com> Procuradoria Geral da República MPF