A ferramenta de software livre memcached é um cache para
armazenar informações frequentemente usadas para evitar o carregamento
(e processamento) de informações de origens mais lentas, como discos ou
um banco de dados. Ela pode ser implementada em uma situação dedicada ou
como um método para usar memória sobressalente em um ambiente
existente. Apesar da simplicidade do memcached, ele é algumas vezes
usado incorretamente ou usado como uma solução no tipo errado de
ambiente. Aprenda onde é melhor tirar vantagem do uso do memcached.
Introdução
O memcached é usado para acelerar processos de aplicativos e, aqui,
teremos como foco as melhores práticas para sua implementação dentro de
seus aplicativos e ambientes. Isto inclui o que deveria e o que não
deveria ser armazenado, como tratar a distribuição flexível de dados e
como regular o método para atualizar o memcached e versões armazenadas
dos dados. Também será coberto o suporte a soluções de alta
disponibilidade, incluindo o IBM WebSphere eXtreme Scale.
Todos os aplicativos, especialmente muitos aplicativos web, precisam
otimizar a velocidade com que acessam e retornam informações para o
cliente. Frequentemente, no entanto, as mesmas informações são
retornadas. Carregar os dados de sua origem de dados (banco de dados ou
sistema de arquivos) é ineficiente, especialmente se forem executadas as
mesmas consultas toda vez que quiser acessar as informações.
Apesar de vários servidores web poderem ser configurados para usar um
cache para retornar informações, isto não funciona com a natureza
dinâmica da maioria dos aplicativos. É aqui que o
memcached pode ajudar. Ele fornece um armazenamento generalizado em
memória que pode conter qualquer coisa, incluindo objetivos nativos de
linguagens, permitindo o armazenamento de uma variedade de informações e
acessá-las de muitos aplicativos e ambientes.
Os fundamentos
O memcached é um projeto de software livre projetado para fazer uso
da RAM sobressalente em muitos servidores para agir como um cache de
memória para informações acessadas com frequência. O elemento chave é o
uso da palavra cache: o memcached fornece armazenamento temporário, em memória, das informações que podem ser carregadas de outro local.
Por exemplo, considere um aplicativo típico baseado em web. Mesmo um
web site servido dinamicamente provavelmente tem alguns componentes de
informações constantes durante a vida da página.
Dentro de um blog, é
improvável que a lista de categorias para os tópicos individuais do blog
altere regularmente entre visualizações de páginas. Carregar estas
informações toda vez durante uma consulta ao banco de dados é
comparativamente caro, especialmente quando os dados não alteraram. É
possível ver na Figura 1 alguns dos fragmentos de página dentro de um
blog que poderiam ser armazenadas em cache.
Figura 1. Elementos que poderiam ser colocados em cache em uma página de blog típica
Extrapole esta estrutura para outros elementos do blog, informações
da pessoa que o publicou, comentários
mesmo os tópicos do blog em si e é possível identificar 10-20
consultas ao banco de dados e formatações que ocorrem somente para
exibir o conteúdo da página principal. Repita isto para centenas, ou
mesmo milhares de visualizações de páginas a cada dia, e seus servidores
e aplicativos estarão executando muito mais consultas do que o
necessário para exibir o conteúdo da página.
Usando o memcached, é possível armazenar as informações formatadas
carregadas do banco de dados em um formulário pronto para ser usado
diretamente na página web. E como as informações estão sendo carregadas
da RAM, e não do disco por meio de um banco de dados e outros
processamentos, o acesso às informações é quase instantâneo.
Para reiterar, o memcached é um cache para armazenar informações
usadas frequentemente para evitar o carregamento e o processamento de
informações de origens mais lentas, como discos ou um banco de dados.
A interface para o memcached é fornecida por meio de uma conexão à
rede. Isto significa que é possível compartilhar um único servidor do
memcached (ou vários servidores, como será demonstrado posteriormente
neste artigo) com vários clientes. A interface de rede é rápida e, para
melhorar o desempenho, o servidor deliberadamente não suporta
autenticação ou comunicação segura.
Mas isto não deveria limitar as
opções de implementação. O servidor do memcached deverá existir na parte
interna de sua rede. A praticidade da interface de rede e a
facilidade com que é possível implementar várias instâncias do memcached
permitem o uso de RAM sobressalente em várias máquinas e aumentar o tamanho geral de seu cache.
O método de armazenamento com o memcached é um par simples de
palavra-chave/valor, similar ao hash ou matriz associativa disponível em
várias linguagens. As informações são armazenadas no memcached
fornecendo a chave e o valor, e recuperadas solicitando as informações
pela chave especificada.
As informações são retidas no cache indefinidamente, a não ser que um dos seguintes ocorra:
- A memória alocada para o cache foi esgotada Neste
caso,
o memcached usa o método least-recently used (LRU) para remover
itens do cache. Itens que não tenham sido usados recentemente são
excluídos do cache, primeiro as com acesso mais antigo. - O item é especificamente excluído É sempre possível excluir um item do cache.
- O item expirou Itens individuais podem ter uma
expiração para permitir que sejam retirados do cache quando as
informações armazenadas com relação à chave são provavelmente muito
antigas.
Essas situações podem ser usadas em combinação com a lógica de seu
aplicativo para garantir que as informações no cache estejam
atualizadas. Com isso em mente, vamos examinar o quão melhor é usar o
memcached em seus aplicativos.
Quando usar o memcached
Há uma série de processos e etapas chave que podem ser modificados ao usar o memcached para melhorar o desempenho do aplicativo.
Ao carregar informações, o cenário típico é o mostrado na Figura 2.
Figura 2. Sequência típica para carregar informações para exibição

Em termos gerais, as etapas são:
- Executar uma ou mais consultas para carregar as informações do banco de dados
- Formatar as informações adequadas para exibição (ou processamento adicional)
- Usar ou exibir os dados formatados
Ao usar o memcached, a lógica do aplicativo é ligeiramente alterada para acomodar o cache:
- Tentar carregar as informações do cache
- Se elas existirem, usar a versão em cache das informações
- Se não existirem:
- Executar uma ou mais consultas para carregar as informações do banco de dados
- Formatar as informações adequadas para exibição ou processamento adicional
- Armazenar as informações no cache
- Usar os dados formatados
Isto é resumido na Figura 3.
Figura 3. Carregando informações para exibição ao usar o memcached

O carregamento dos dados, então, se torna um processo de no máximo
três estágios, carregando os dados do cache ou do banco de dados e
armazenando no cache, se adequado.
Na primeira vez que este processo ocorre, os dados serão carregados
do banco de dados ou outra origem, como normalmente, e, a seguir,
armazenados no memcached. Da próxima vez que as informações forem
armazenadas, elas serão retiradas do memcached, em vez de serem
carregadas do banco de dados, economizando tempo e ciclos de CPU.
O outro lado da equação é garantir que, se as informações que possam
ser armazenadas dentro do memcached forem alteradas, a versão do
memcached é atualizada ao mesmo tempo em que são atualizadas as
informações no backend. Isto modifica a sequência típica daquela
mostrada na Figura 4 para a ligeira modificação na Figura 5.
Figura 4. Atualizando ou armazenando dados em um aplicativo típico
A Figura 5 mostra a sequência modificada usando o memcached.
Figura 5. Atualizando ou armazenando dados ao usar o memcached

Por exemplo, usando o blog como base, quando o sistema do blog
atualiza a lista de categorias no banco de dados, a atualização deverá
seguir esta sequência:
- Atualizar a lista de categorias no banco de dados
- Formatar as informações
- Armazenar as informações no memcached
- Retornar as informações para o cliente
Operações de armazenamento dentro do memcached são atômicas, portanto
as informações serão atualizadas sem que os clientes recebam somente
dados parciais; eles receberão a versão antiga ou a versão nova.
Para a maioria dos aplicativos, estas são as duas únicas operações
com as quais você precisa se preocupar. Quando você acessar dados que as
pessoas usam, eles são automaticamente adicionados ao cache
e alterações àqueles dados são automaticamente atualizadas no cache.
Chaves, espaços de nome e valores
Uma consideração importante com o memcached é como organizar e nomear
os dados armazenados dentro do cache. Dos exemplos anteriores do blog,
deveria estar claro que é preciso usar uma estrutura de nomeação
consistente, para que possa carregar categorias, histórico e outras
informações do blog e, a seguir, usar isto ao carregar informações (e
atualizar o cache) ou ao atualizar os dados (e, novamente, atualizar o
cache).
O sistema exato de nomenclatura que você usar é específico do
aplicativo, mas normalmente é possível usar uma estrutura similar a seu
aplicativo existente, que provavelmente será baseado em algum tipo de
identificador exclusivo. Isto ocorre ao retirar informações do banco de
dados ou ao examinar uma coleção de informações.
Usando o exemplo de tópico do blog, é possível armazenar a lista de categorias em uma entrada com a chave category-list. Os valores associados com um único tópico com relação ao ID do tópico, como blogpost-29, poderiam ser usados, enquanto que comentários com relação à entrada poderiam ser armazenados em blogcomments-29, onde 29
é o ID do tópico do blog. Desta forma, é possível armazenar uma grande
variedade de informações no cache usando diferentes prefixos para
identificar as informações.
A simplicidade do armazenamento de chave/valor do memcached (e a
falta de segurança) significa que, se quiser dar suporte a vários
aplicativos usando o mesmo servidor do memcached ao mesmo tempo, talvez
seja melhor considerar alguma outra forma de quantificador para
identificar os dados como pertencentes a um aplicativo específico. Por
exemplo, é possível adicionar um prefixo do aplicativo como
blogapp:blogpost-29. As chaves têm forma livre, portanto é possível usar qualquer cadeia de caractere que quiser como nome da chave.
Em termos de armazenar valores, é preciso assegurar que as
informações armazenadas no cache sejam adequadas para seu aplicativo.
Por exemplo, com o sistema do blog, talvez você queira armazenar o
objeto usado pelo aplicativo do blog para formatar as informações do
tópico, em vez de HTML bruto. Isto pode ser mais prático se a mesma
estrutura básica for usada em vários locais dentro de seu aplicativo.
A maioria das interfaces de linguagem, incluindo Java, Perl, PHP e
muitas outras, podem serializar objetos de linguagem para armazenamento
com o memcached. Isto permite armazenar e, posteriormente, recuperar
objetos inteiros do cache de memória, em vez de reconstruí-los
manualmente dentro de seu aplicativo.
Muitos objetos, ou as estruturas
que eles usam, são baseados em algum tipo de hash ou estrutura de
matriz. Para ambientes entre linguagens, como quando você deseja
compartilhar as mesmas informações entre seu ambiente JSP e um ambiente
JavaScript, é possível usar o formato independente de arquitetura, como o
JavaScript Object Notation (JSON) ou mesmo XML.
Preenchendo e usando o memcached
Como um produto de software livre, e um originalmente desenvolvido
para trabalhar dentro de um ambiente existente de software livre, o
memcached é suportado por uma ampla gama de ambientes e plataformas. As
interfaces para comunicação com um servidor do memcached são várias,
frequentemente com várias implementações para todas as linguagens.
Consulte Recursos ao final do artigo para obter bibliotecas e kits de ferramentas comuns.
Seria impossível listar todas as interfaces suportadas e ambientes
oferecidos, mas todos suportam a API básica fornecida pelo protocolo do
memcached. Essas descrições foram simplificadas e deverão ser
interpretadas dentro do contexto de diferentes linguagens, onde os erros
podem ser indicados usando diferentes valores. As funções principais
são:
- get(key) Obtém as informações do memcached armazenadas com a chave especificada. Retorna um erro se a chave não existir.
- set(key, value [, expiry]) Armazena o valor
especificado usando a chave do Identificador no cache. Se a chave já
existir, ela será atualizada. O tempo de expiração é em segundos e é
considerado como um tempo relativo se o valor for menor do que 30 dias
(30*24*60*60) ou um tempo absoluto (época) se for maior do que este
valor. - add(key, value [, expiry]) Adiciona a chave ao cache
se ela não existir ou retorna um erro se a chave já existir. Isto pode
ser útil se quiser adicionar explicitamente uma nova chave sem
atualizá-la, se já existir. - replace(key, value [, expiry]) Atualiza o valor da chave especificada, retornando um erro se a chave não existir.
- delete(key [, time]) Exclui o par chave/valor do
cache. Se for fornecido um tempo, adicionar um novo valor com esta chave
será bloqueado pelo período especificado. O tempo limite permite
garantir que o valor seja sempre lido novamente de sua origem de dados. - incr(key [, value]) Incrementa a chave especificada com um ou com o valor especificado. Só funciona com valores numéricos.
- decr(key [, value]) Decrementa a chave especificada com um ou com o valor especificado. Só funciona com valores numéricos.
- flush_all Invalida (ou expira) todos os itens atuais no cache.
Por exemplo, dentro do Perl, uma operação básica de conjunto seria tratada como mostra a Listagem 1.
Listagem 1. Operação básica de conjunto dentro do Perl
use Cache::Memcached;
my $cache = new Cache::Memcached {
'servers' => [
'localhost:11211',
],
};
$cache->set('mykey', 'myvalue');
A mesma operação básica no Ruby é mostrada na Listagem 2.
Listagem 2. Operação básica de conjunto dentro do Ruby
require 'memcache'
memc = MemCache::new '192.168.0.100:11211'
memc["mykey"] = "myvalue"
É possível ver em ambos os exemplos a mesma estrutura básica: definir o
servidor do memcached e, a seguir, atribuir ou definir o valor. Estão
disponíveis outras interfaces, incluindo aquelas que funcionam dentro da
tecnologia Java, permitindo usar o memcached dentro de seus aplicativos
WebSphere.
A classe da interface do memcached permite serializar
objetos Java
diretamente dentro do memcached para poder armazenar e carregar
estruturas complexas. Ao implementar dentro de um ambiente como o
WebSphere, duas coisas são realmente importantes: a resiliência do
serviço (e o que fazer se o memcached não estiver disponível) e como
aumentar seu armazenamento em cache para melhorar seu desempenho ao usar
vários servidores de aplicativo, ou ambientes como o WebSphere eXtreme
Scale. A seguir, veremos estas duas questões.
Resiliência e disponibilidade
Uma das perguntas mais comuns sobre o memcached é “O que acontece
quando o cache está indisponível?” Como deveria estar claro das seções
anteriores, as informações no cache nunca deverão ser a única origem das
informações. É preciso ser capaz de carregar os dados armazenados no
cache a partir de algum outro local.
Apesar de a praticidade ser de que não ser capaz de acessar
informações do cache reduzirá o desempenho de seu aplicativo, ela não
deverá impedir que o aplicativo continue funcionando. Existem alguns
cenários que poderão ocorrer:
- Se o serviço do memcached sair do ar, seu aplicativo deverá voltar a
carregar informações da origem de dados original e formatá-la conforme
necessário para exibição. O aplicativo também deverá continuar a tentar
carregar e armazenar as informações no memcached. - Quando o servidor do memcached estiver disponível novamente, seu
aplicativo deverá automaticamente tentar armazenar os dados. Não há
necessidade de recarregar forçosamente os dados armazenados em cache, é
possível usar o acesso padrão para carregar e popular o cache com
informações. Eventualmente, o cache será preenchido novamente com os
dados usados mais comumente.
Para reiterar, o memcached é um cache de informações, e não a única
origem. Perder seu servidor do
memcached não deverá ser o fim de seu aplicativo, apesar de que poderá
implicar em uma redução no desempenho até que o servidor do memcached
esteja disponível novamente. Na prática, o servidor do memcached é
relativamente simples e, apesar de não estar livre de problemas, a
simplicidade leva a menos erros.
Distribuindo seu cache
O servidor do memcached é somente um cache armazenando valores com
relação a chaves em uma rede. Se houver várias máquinas, a tentação é
definir uma instância do memcached em todas as suas máquinas
sobressalentes para fornecer uma grande quantidade de armazenamento de
cache em RAM na rede.
Ao encarar esta ideia, a tentação é presumir que é necessário algum
tipo de mecanismo de distribuição ou replicação que copiará os pares
chave/valor entre as máquinas. O problema com esta abordagem é que você
está, na verdade, diminuindo seu cache disponível em RAM, e não
aumentando. Se observar a Figura 6, você verá que existem três
servidores de aplicativo, cada um com acesso a uma instância do
memcached.
Figura 6. uso incorreto de várias instâncias do memcached

Apesar de cada instância do memcached ter 1 GB de tamanho (dando 3 GB
de cache de RAM), se cada servidor de aplicativo tiver somente seu
próprio
cache (ou houve uma replicação de dados entre as instâncias do
memcached), toda sua instalação ainda teria somente 1 GB de cache
duplicado em cada instância.
Como o memcached fornece suas informações sobre uma interface de
rede, um único cliente pode acessar os dados de qualquer instância do
memcached ao qual tenha acesso. Se os dados não forem copiados ou
duplicados em cada instância, o que você terá é 3 GB de cache de RAM
disponível para cada servidor de aplicativos, como mostra a Figura 7.
Figura 7. Uso correto de várias instâncias do memcached
O problema com esta abordagem é escolher qual servidor armazenará seu
par chave/valor e como determinar qual servidor do memcached acessar
quando quiser recuperar um valor. A solução é ignorar complexidades como
tabelas de consulta ou esperar que o servidor do memcached trate o
processo para você. Em vez disso, os clientes do memcached deverão
pensar de forma simples.
Em vez de ter que determinar estas informações, os clientes do
memcached usam um algoritmo de
hashing simples na chave que for especificada ao armazenar a
informação. Ao armazenar ou obter informações de uma lista de servidores
do
memcached, o cliente do memcached deriva um valor numérico da chave
usando um algoritmo de
hashing consistente.
Para dar um exemplo, a chave
mykey é convertida para o valor 23875. Não
importa se você está armazenando ou obtendo informações, sempre usará a
mesma chave como identificador exclusivo para carregar do servidor do
memcached, portanto “mykey” sempre obterá o hash com um valor de 23875, pelo menos neste exemplo.
Se houver dois servidores, o cliente do memcached obtém este valor
numérico e realiza um cálculo simples nele (por exemplo, módulo) para
determinar se deveria armazenar o valor na primeira ou na segunda
instância configurada do memcached.
Ao armazenar um valor, o cliente determina o valor do hash a partir
da chave e o servidor usado para armazená-lo. Ao obter um valor, o
cliente determina o mesmo valor do hash a partir da chave e escolhe o
mesmo servidor para obter as informações.
Se você usar a mesma lista de servidores (e na mesma ordem) em cada
servidor de aplicativos, cada servidor de aplicativos escolherá o mesmo
servidor quando solicitado a armazenar ou recuperar a mesma chave. Agora
você está compartilhando 3 GB de espaço de memcached, em vez de
duplicar o mesmo
1 GB de espaço, dando mais cache para usar e, provavelmente, melhorando o
desempenho de seu aplicativo para ainda mais usuários.
Existem complexidades neste processo (como o que acontece quando um
servidor está indisponível), mas a documentação oferece mais informações
(consulte detalhes Recursos).
Como não usar o memcached
Apesar da simplicidade do memcached, a tentação é usar a instância do
memcached em algumas formas inesperadas e, algumas vezes, infelizes.
-
O memcached não é um banco de dados
Provavelmente o uso incorreto mais comum do memcached é o uso deste
para armazenamento de dados, e não como um cache. A finalidade principal
do memcached é melhorar os tempos de resposta para dados que, de outra
forma, podem ser construídos ou recuperados de alguma outra origem.
Um
exemplo é a recuperação de informações de um banco de dados,
particularmente se houver alguma formatação ou manipulação das
informações antes que sejam exibidas ao usuário. O memcached foi
projetado para armazenar estas informações em memória para evitar a
realização repetida daquela tarefa cada vez que os dados forem
recuperados.
O memcached nunca deverá ser usado como a única origem de dados de
que necessita para executar seu aplicativo; os dados sempre deverão ser
deriváveis de alguma outra origem. Além disso, tenha em mente que o
memcached é somente um armazenamento de chave/valor.
Não é possível
realizar uma consulta sobre os dados ou realizar uma iteração no
conteúdo para extrair informações. Ele deverá ser usado para armazenar
blocos ou objetos de dados que você precisa usar em estilo de atacado.
-
Não armazene em cache linhas de banco de dados ou arquivos
Apesar de ser possível usar o memcached para armazenar as linhas de
dados como carregadas de um banco de dados, isto é na verdade
armazenamento em cache de consultas, e a maioria dos bancos de dados
fornecem seus próprios mecanismos de armazenamento de consultas em
cache. O mesmo pode ser dito para outros objetos, como imagens ou
arquivos do sistema de arquivos. Muitos aplicativos e servidores web já
têm soluções bem otimizadas para este tipo de trabalho.
Você ganhará mais melhorias de utilidade e desempenho do memcached se
usá-lo para armazenar blocos inteiros de informações depois do
carregamento e da formatação. Usando nosso exemplo do blog, o melhor
ponto para armazenar informações é depois que tiver formatado as
categorias do blog como um objeto, ou mesmo depois de formatar em HTML.
A
construção da página do blog pode, então, ser alcançada carregando os
componentes (tópicos do blog, lista de categorias, histórico de tópicos
etc.) a partir do memcached e gravando o HTML completo de volta para o
cliente.
-
O memcached não é seguro
Para garantir o desempenho máximo, o memcached não fornece nenhum
tipo de segurança, seja autenticação ou criptografia. Isto significa que
o acesso a seus servidores do memcached deverão ser tratados
colocando-os na mesma zona privada que seu ambiente de implementação do
aplicativo ou, se a segurança for fundamental, use os soquetes do UNIX e
permita que somente aplicativos no mesmo host atual acessem o servidor
do memcached.
Isto remove parte da flexibilidade e resiliência e sua capacidade de
compartilhar um cache de RAM entre várias máquinas pela rede, mas é a
única solução para implementar segurança em seus dados do memcached
nesta situação.
Não se limite
Apesar das coisas para as quais você não deveria usar suas instâncias
do memcached, a flexibilidade do memcached não deve ser ignorada. Como o
memcached está no mesmo nível de arquitetura que seu aplicativo, ele é
fácil de integrar e conectar. E alterar seu aplicativo para tirar
vantagem do memcached não é complicado.
Além disso, como o memcached é
somente um cache, ele não deverá interromper a execução de seu
aplicativo no caso de um problema. O que ele faz, se usado corretamente,
é diminuir a carga no resto da infraestrutura do servidor (reduz
leituras de bancos de dados e origens de dados), e isto significa
suportar mais clientes sem a necessidade de mais hardware.
Mas lembre-se, é só cache!
Resumo
Neste artigo, abordamos o memcached e como usá-lo da melhor forma. Em
particular, vimos como as informações são armazenadas, como escolher
chaves razoáveis e como escolher as informações a serem armazenadas.
Também vimos alguns problemas chave da implementação pelos quais todos
os usuários do memcached passam, incluindo o uso de vários servidores, o
que fazer quando uma instância do memcached fica indisponível e, talvez
o aspecto mais importante, como não usar o memcached.
Como um aplicativo de software livre, e um que tem um objetivo bem
simples e direto, o poder e a utilidade do memcached advêm dessa
simplicidade. Ao fornecer um grande armazenamento em RAM para
informações, tornando-as disponíveis na rede e, a seguir, acessíveis por
meio de tal imensa gama de diferentes interfaces e linguagens, é
possível integrar o memcached em uma enorme variedade de instalações.
Recursos
Aprender
- A documentação do MySQL memcached fornece várias informações sobre como usar o memcached dentro de um ambiente típico de implementação de banco de dados.
- Conheça a solução comercial de armazenamento em cache da IBM,
o solidDB®, verificando a família de produtos IBM
solidDB. - Para ouvir entrevistas e discussões interessantes para desenvolvedores de software, confira developerWorks podcasts.
-
Visite a Zona de software livre
do developerWorks para obter extensas informações de instruções,
ferramentas e atualizações de projetos para ajudá-lo a desenvolver com
tecnologias de software livre e usá-las com produtos da IBM, bem como
nossos artigos e tutoriais mais populares. - Acompanhe e aprenda sobre a IBM e tecnologias de software livre e funções de produtos com os demos gratuitos On demand do developerWorks.
Obter produtos e tecnologias
- memcached.org fornece informações sobre o memcached, como efetuar seu download e instalá-lo.
- A Cache::Memcached interface for Perl fornece uma interface extensiva.
- Para a tecnologia Java, a classe com.danga.MemCached pode ser usada e fornece algumas extensões adicionais de failover e várias instâncias.
- Inove em seu próximo projeto de desenvolvimento em software livre com software de avaliação da IBM, disponível para download ou em DVD.
- Efetue o download
de versões de avaliação de produtos IBM
ou explore
as avaliações on-line no IBM SOA Sandbox e pratique em ferramentas de desenvolvimento de aplicativos e produtos de middleware do
DB2, Lotus, Rational, Tivoli e WebSphere.
artigo publicado originalmente no developerWorks Brasil, por Martin Brown
Martin Brown é um escritor profissional há mais de sete anos. Ele é o
autor de vários livros e artigos sobre uma série de tópicos. Seu
conhecimento passa por muitas linguagens de desenvolvimento e
plataformas – Perl, Python, Java, JavaScript, Basic, Pascal, Modula-2, C, C++, Rebol, Gawk,
Shellscript, Windows, Solaris, Linux , BeOS, Mac OS/X e mais – bem
como programação em Web, gerenciamento de sistemas e integração. Martin é
um Subject Matter Expert (SME) da Microsoft e contribuidor regular do
ServerWatch.com, LinuxToday.com e IBM developerWorks. Ele também é um
blogger regular em Computerworld, The Apple Blog e outros sites. É
possível entrar em contato com ele em seu Web site em:
http://www.mcslp.com
.



