Você parou pra refletir se está preparado pra criar arquiteturas de software emergentes? Arquiteturas estas que devem poder suportar o crescimento e a diminuição da utilização dos recursos (poder computacional) sem a necessidade de mudar os componentes internos do software ou mesmo mudá-los toda vez que novos recursos são adicionados ou removidos na camada de infraestrutura. Vemos a cada dia mais e mais casos onde aplicações para web no estilo do Facebook, Twitter ou Linkedin são cada vez mais comuns, deixando arquitetos e desenvolvedores de software com um problema complexo pra resolver na hora de construir tais softwares. A demanda por softwares que necessitam suportar mais e mais usuários simultâneos e manter o SLA e o tempo de resposta sempre no nível adequado está maior, e isso é um reflexo natural de como as organizações atuais precisam expressar sua competitividade, sua capacidade de dar respostas rápidas a seus clientes e parceiros, bem como a capacidade de atender, de forma exclusiva e dedicada, seus clientes mais importantes e fiéis.Para saber se você está preparado para construir arquiteturas de software emergentes, é necessário que você faça uma reflexão sobre como você lida com a peça fundamental de um sistema baseado em computador: Os dados. O processamento dos dados, termo que não se usa mais hoje em dia mas que ainda cabe e utilização, é o item mais complexo pra se resolver quando se projeta arquiteturas de software que tenham caracteristicas como resiliência, elasticidade, segurança e alta performance. Tudo gira em torno dos dados. Em especial, a análise da quantidade versus o tamanho dos dados trás uma diferença significativa em como seu software irá funcionar.
Quanto de banda de rede terei que ter entre o servidor X e o servidor Y se a quantidade ou o tamanho dos dados aumentar? Qual a capacidade de storage será necessária pra suportar 10 anos de processamento de folhas de pagamento? Quanto de memória terei que ter caso o número de usuários envolvidos num pregão eletrônico e que estejam dando seus lances aumentar? E se a janela de tempo para dar um lance, diminuir de 10 minutos para apenas 1 segundo, quanto lances a mais o software irá ter que suportar? Todas estas perguntas vão remeter você, arquiteto ou desenvolvedor de software num dilema clássico e recorrente: Como faço para processar os dados sem que a infraestrutura tenha que ser previamente definida e sem que as camadas do software e os seus componentes tenham que ser modificados a cada vez que essa infraestrutura ou sua topologia porventura mudem?
Neste artigo, irei mostrar como o conceito de "Elastic Data Caching" pode ser usado para resolver alguns destes problemas, bem como quais alternativas no mercado temos para a implementação deste conceito. Na sequência, irei mostrar na prática, como o Oracle Coherence pode ser usado para a implementação deste conceito, mostrando detalhes deste sua instalação até sua implementação usando a plataforma Java. Em resumo, este artigo abordará os seguintes temas:
- Condutores Arquiteturais para Cache e suas Implicações
- Elastic Data Caching: O que é e por quê é tão importante?
- Principais Ofertas de Elastic Data Caching e seus Players
- Oracle Coherence: Visão Geral da Tecnologia e Aplicações
- Demonstração do Oracle Coherence na prática usando Java
- Aprofundando no Oracle Coherence: Vídeos e Documentação
Condutores Arquiteturais para Cache e suas Implicações
Como é de meu costume, gosto sempre de abordar neste blog tecnologias do ponto de vista de seus condutores arquiteturais. Isso é importante porque somente a partir da avaliação dos condutores arquiteturais é que podemos chegar a uma arquitetura de software que reflita os reais requisitos (ou motivadores) paras as tecnologias que deverão ser utilizadas. Sem isso, você fatalmente vai incorrer seus projetos no que chamamos de arquiteturas acidentais, ou seja, arquiteturas de software que introduzem tecnologias e soluções sem nem ao menos refletirem sobre o real problema ou suas causas. A avaliação dos condutores arquiteturais também ajuda na eleição do melhor estilo arquitetural (ou conjunto de estilos combinados) para o seu projeto. Se você achar interessante a leitura deste artigo e achar relevante o uso de soluções de cache, não esqueça de avaliar se seu projeto realmente demanda um problema que mereça tal solução.
Quando você precisa projetar uma arquitetura de software que tenha como característica o baixo tempo de resposta para o processamento de um ou um conjunto de dados, então você terá seu principal condutor arquitetural para usar um cache. Soluções de cache são interessantes porque ajudam a construir software que possa lidar com a impedância de recursos críticos como redes e acesso ao disco. Se o seu software precisa acessar com frequência recursos que necessitam da rede para acesso, ou que dependam da leitura de um disco e que envolva intenso I/O, então um cache é fundamental para o aumento da performance. Não somente rede e acesso a disco podem ser evitados com o uso de cache, mas também o uso intenso da CPU. Imagine por exemplo uma página web que para ser renderizada (ter seu código HTML gerado) precisa realizar uma série de cálculos e passar por um determinado conjunto de etapas de processamento. Se estes cálculos puderem ser feitos uma única vez e estas etapas de processamento também forem imutáveis, então é interessante colocar esta página num cache deste a primeira vez que alguém a acessa. Da próxima vez que esta página for acessada, os ciclos de uso da CPU necessários para a computação da página serão evitados.
Soluções de cache também podem ser interessantes não só para evitar o uso (ou desperdício) de recursos de infraestrutura, mas também para ajudar no processamento de dados em massa. Aplicações que precisam lidar com fluxos de dados contínuos para análise de identificação de padrões também podem fazer bom uso de soluções de cache. É o caso por exemplo, de aplicações baseadas em CEP (Complex Event Processing) onde uma grande quantidade e contínua de eventos (estruturas de dados) precisam ser avaliadas na procura de padrões temporais ou comportamentais, possibilitando a identificação de situações e a tomada de ações em tempo real. A baixa latência e o fator "tempo real" aqui só serão possíveis se você puder avaliar contínuamente os eventos, e isso se torna mais fácil quando estes eventos estão num cache.
Mas o que implica usar uma solução de cache? Vamos pensar por um instante no tamanho dos dados. Soluções de cache tornam eficiente o acesso aos dados porque na maioria das vezes utilizam a memória como componente de armazenamento. Apesar da memória ser eficiente para a leitura e recuperação rápida dos dados em comparação aos discos, ela é menor e mais limitada. Se porventura você tiver que lidar com volumes de dados grandes ou quantidades pequenas mas que tenham um enorme footprint de armazenamento, então você poderá comprometer sua infraestrutura com esta questão de tamanho. Outra questão importante é a coerência [do inglês, Coherence :D] dos dados. Os dados num cache são porventura atualizados e removidos com frequência pelos diversos usuários conectados na aplicação. Se estes dados são modificados, então é necessário manter a versão única da verdade destes dados independente de onde eles estejam na infraestrutura. Outra questão relevante quanto aos dados armazenados em cache e em memória é quanto a tolerância falhas. Se os dados estão em memória, então eles são voláteis por natureza. E se o servidor sofrer uma falha e tiver que ser desligado? O que irá acontecer com os dados que estavam em cache? Poderão ser recuperados de forma que não comprometam as transações dos usuários conectados?
A avaliação dos fatores que decorrem da utilização de soluções de cache é particularmente importante quanto você precisa adquirir uma solução que ofereça isto. Na grande maioria das vezes, você não irá optar por apenas uma solução de cache, mas sim várias. Cada solução de cache irá cobrir um conjunto de problemas e será aplicado a uma parte ou área de sua arquitetura ou infraestrutura. Um bom exemplo é se você estiver pensando em aplicar cache para sua camada de visão e seus recursos de apresentação como páginas estáticas e arquivos de imagens. Um proxy reverso pode ser uma solução interessante para este caso, mas nem tanto para resolver o problema de cache de segundo nível de suas entidades que são armazenadas num banco de dados. Quanto maior o conjunto de recursos e facilidades encontrados numa solução de cache, aliado a questão de que ela seja ampla o suficiente para acomodar não apenas um, mas diversos tipos de cenários e camadas de sua arquitetura, vai fazê-lo avaliar não diferentes soluções de cache, mas uma única plataforma que ofereça tudo isso e que acomode todas as implicações que discutimos anteriormente. Neste momento, você irá começar a avaliar uma solução de Elastic Data Caching.
Elastic Data Caching: O que é e por quê é tão Importante?
Diferentemente de soluções de cache locais, que residem no mesmo espaço de endereço da aplicação, soluções de Elastic Data Caching (EDC) são implantados em dois ou mais servidores (no caso de aplicações como Facebook ou Amazon em centenas deles), usualmente em um cluster dedicado apenas a cache. Isso faz com que você insira um componente de cache em sua arquitetura de software, situado normalmente antes e depois do seu cluster de servidores de aplicação ou infraestrutura de middleware. De acordo com o Forrester:
Como é de meu costume, gosto sempre de abordar neste blog tecnologias do ponto de vista de seus condutores arquiteturais. Isso é importante porque somente a partir da avaliação dos condutores arquiteturais é que podemos chegar a uma arquitetura de software que reflita os reais requisitos (ou motivadores) paras as tecnologias que deverão ser utilizadas. Sem isso, você fatalmente vai incorrer seus projetos no que chamamos de arquiteturas acidentais, ou seja, arquiteturas de software que introduzem tecnologias e soluções sem nem ao menos refletirem sobre o real problema ou suas causas. A avaliação dos condutores arquiteturais também ajuda na eleição do melhor estilo arquitetural (ou conjunto de estilos combinados) para o seu projeto. Se você achar interessante a leitura deste artigo e achar relevante o uso de soluções de cache, não esqueça de avaliar se seu projeto realmente demanda um problema que mereça tal solução.
Quando você precisa projetar uma arquitetura de software que tenha como característica o baixo tempo de resposta para o processamento de um ou um conjunto de dados, então você terá seu principal condutor arquitetural para usar um cache. Soluções de cache são interessantes porque ajudam a construir software que possa lidar com a impedância de recursos críticos como redes e acesso ao disco. Se o seu software precisa acessar com frequência recursos que necessitam da rede para acesso, ou que dependam da leitura de um disco e que envolva intenso I/O, então um cache é fundamental para o aumento da performance. Não somente rede e acesso a disco podem ser evitados com o uso de cache, mas também o uso intenso da CPU. Imagine por exemplo uma página web que para ser renderizada (ter seu código HTML gerado) precisa realizar uma série de cálculos e passar por um determinado conjunto de etapas de processamento. Se estes cálculos puderem ser feitos uma única vez e estas etapas de processamento também forem imutáveis, então é interessante colocar esta página num cache deste a primeira vez que alguém a acessa. Da próxima vez que esta página for acessada, os ciclos de uso da CPU necessários para a computação da página serão evitados.
Soluções de cache também podem ser interessantes não só para evitar o uso (ou desperdício) de recursos de infraestrutura, mas também para ajudar no processamento de dados em massa. Aplicações que precisam lidar com fluxos de dados contínuos para análise de identificação de padrões também podem fazer bom uso de soluções de cache. É o caso por exemplo, de aplicações baseadas em CEP (Complex Event Processing) onde uma grande quantidade e contínua de eventos (estruturas de dados) precisam ser avaliadas na procura de padrões temporais ou comportamentais, possibilitando a identificação de situações e a tomada de ações em tempo real. A baixa latência e o fator "tempo real" aqui só serão possíveis se você puder avaliar contínuamente os eventos, e isso se torna mais fácil quando estes eventos estão num cache.
Mas o que implica usar uma solução de cache? Vamos pensar por um instante no tamanho dos dados. Soluções de cache tornam eficiente o acesso aos dados porque na maioria das vezes utilizam a memória como componente de armazenamento. Apesar da memória ser eficiente para a leitura e recuperação rápida dos dados em comparação aos discos, ela é menor e mais limitada. Se porventura você tiver que lidar com volumes de dados grandes ou quantidades pequenas mas que tenham um enorme footprint de armazenamento, então você poderá comprometer sua infraestrutura com esta questão de tamanho. Outra questão importante é a coerência [do inglês, Coherence :D] dos dados. Os dados num cache são porventura atualizados e removidos com frequência pelos diversos usuários conectados na aplicação. Se estes dados são modificados, então é necessário manter a versão única da verdade destes dados independente de onde eles estejam na infraestrutura. Outra questão relevante quanto aos dados armazenados em cache e em memória é quanto a tolerância falhas. Se os dados estão em memória, então eles são voláteis por natureza. E se o servidor sofrer uma falha e tiver que ser desligado? O que irá acontecer com os dados que estavam em cache? Poderão ser recuperados de forma que não comprometam as transações dos usuários conectados?
A avaliação dos fatores que decorrem da utilização de soluções de cache é particularmente importante quanto você precisa adquirir uma solução que ofereça isto. Na grande maioria das vezes, você não irá optar por apenas uma solução de cache, mas sim várias. Cada solução de cache irá cobrir um conjunto de problemas e será aplicado a uma parte ou área de sua arquitetura ou infraestrutura. Um bom exemplo é se você estiver pensando em aplicar cache para sua camada de visão e seus recursos de apresentação como páginas estáticas e arquivos de imagens. Um proxy reverso pode ser uma solução interessante para este caso, mas nem tanto para resolver o problema de cache de segundo nível de suas entidades que são armazenadas num banco de dados. Quanto maior o conjunto de recursos e facilidades encontrados numa solução de cache, aliado a questão de que ela seja ampla o suficiente para acomodar não apenas um, mas diversos tipos de cenários e camadas de sua arquitetura, vai fazê-lo avaliar não diferentes soluções de cache, mas uma única plataforma que ofereça tudo isso e que acomode todas as implicações que discutimos anteriormente. Neste momento, você irá começar a avaliar uma solução de Elastic Data Caching.
Elastic Data Caching: O que é e por quê é tão Importante?
Diferentemente de soluções de cache locais, que residem no mesmo espaço de endereço da aplicação, soluções de Elastic Data Caching (EDC) são implantados em dois ou mais servidores (no caso de aplicações como Facebook ou Amazon em centenas deles), usualmente em um cluster dedicado apenas a cache. Isso faz com que você insira um componente de cache em sua arquitetura de software, situado normalmente antes e depois do seu cluster de servidores de aplicação ou infraestrutura de middleware. De acordo com o Forrester:
"Elastic Data Caching is a software infrastructure that provides application developers with data caching services that are distributed across two or more server nodes that 1) consistently perform as volumes grow; 2) can be scaled without downtime; and 3) provide a range of fault-tolerance levels"
As vantagens do uso de EDC são inúmeras, mas todas estas vantagens giram em torno de uma única palavra: elasticidade. A capacidade de ser elástico quer dizer que a infraestrutura de cache pode aumentar e principalmente diminuir sob demanda, sem causar mudanças ou redesenho nas aplicações que fazem uso dos serviços de cache. Essa característica torna soluções de EDC extremamente atraente, uma vez que a exata previsão sobre capacidade da infraestrutura não deve ser facilmente determinada, e mesmo que fosse, ela jamais seria estática. Como as aplicações atuais precisam lidar com a sazonalidade do número dos usuários, em especial se tais aplicações forem baseadas na web, então o crescimento não preditivo e exponencial do número dos usuários vai ocorrer. Sua infraestutura de cache precisa estar preparada para a inserção de mais servidores no cluster de cache. E da mesma forma que a inserção de mais servidores no cluster de cache não deverá acarretar mudanças nas aplicações, a remoção de tais servidores quando estes não forem mais tão necessários devido a diminuição da demanda, também não deverá acarretar em mudanças ou impactos nas aplicações. Isso é elasticidade. Poder aumentar e diminuir quando necessário, e quantas vezes for necessário.
Mas porque a capacidade de diminuir os recursos é mais importante do que a de aumento destes? A um tempo atrás, as aplicações eram projetadas para poderem oferecer transparência de localização, de forma que quando novos servidores fossem inseridos num cluster, a aplicação pudesse ser executada independente de onde estes servidores estiverem. Isso é interessante e poderoso, mas nos dias de hoje, isso não deve ser a unica preocupação. Inserir novos servidores em um cluster remete as organizações a investiram capital em hardware e máquinas, e isso do ponto de vista contábil não é nada interessante, pois, contabilmente falando, manter um servidor na organização é um custo contínuo e que sempre deprecia, tornando-o menos valioso ao longo do tempo. Se a organização que mantêm esse custo contínuo não for uma organização cujo fim é TI ou serviços de TI, então o problema se torna maior ainda, pois qualquer valor de capital investido em servidores e máquinas é visto como despesa e não como investimento. E todos sabemos que orçamento pra TI diminui a cada ano que passa. Para lidar com isso e usufruindo do que a tecnologia de virtualização hoje nos propcia, a indústria de cloud computing oferece a oportunidade de organizações utilizarem servidores e máquinas virtuais como um serviço, não implicando em custo de aquisição e manutenção. Neste caso, os servidores podem ser usados para atender uma demanda específica, e depois que esta demanda acabar eles podem ser "devolvidos" para o fornecedor da Cloud. Para usufruir desta capacidade, sua arquitetura precisa oferecer características de elasticidade.
Agora que vimos o que é Elastic Data Caching e porque isso é tão importante para a construção de arquiteturas de software emergentes, é hora de dedicar um tempo na avaliação de quais ofertas existem atualmente para isso, e com isso, conhecermos e avaliarmos quais são os fabricantes de software que estão disponíveis para avaliação e contratação.
Principais Ofertas de Elastic Data Caching e seus Players
As ofertas para soluções de Elastic Data Caching não poderiam ser melhores. Os principais fabricantes de software do mundo possuem pelo menos uma oferta nesta categoria. Alguns fabricantes porventura possuem mais de uma oferta, que podem ser combinados para compor uma solução mais abrangente. Dentre os principais fabricantes, encontram-se Oracle, GigaSpaces, IBM, Software AG e VMware. Querendo entrar nesta lista seleta de fabricantes constam também Microsoft, TIBCO e Red Hat, com ofertas interessantes mais ainda não tão maduras ou não disponíveis ainda como produtos para os clientes. A figura abaixo, retirada de um relatório do Forrester de Q2 de 2010, sintetiza os principais fornecedores e como suas soluções estão posicionadas:
Como o relatório é de 2010, ele acaba não refletindo a atual situação de fabricantes como a Terracota, que foi adquirida pela Software AG em 2011, e da GemStone Systems, que foi adqurida pela VMware em 2010. Os demais fabricantes permanecem até o presente momento. A figura mostra que Oracle, IBM, GigaSpaces e Software AG lideram a categoria, e que a Oracle com o seu Coherence possui maior base instalada de clientes sendo portanto a solução mais utilizada e madura.
Oracle Coherence: Visão Geral da Tecnologia e Aplicações
O Oracle Coherence é um produto para implementação de um grid de dados distribuído, ou seja, uma plataforma de distribuição (particionamento) dos dados em cima de um protocolo de peer-to-peer que suporta clusterização e altamente escalável. Isso possibilita que os dados sejam distribuídos num cluster de servidores formando uma grande e elástica área virtual de memória, garantindo assim que não existirá nenhum único ponto de falha, pois os dados podem ser recuperados de qualquer servidor do cluster. Quando um servidor entra na rede, o Coherence automaticamente detecta sua presença e passa a contar com ele em sua estratégia de grid. Quando um ou mais servidores sofrem falhas e param de responder, o Coherence também automaticamente detecta-os e expurga-os do cluster para que a área de memória virtual (o grid) não seja comprometido com a utilização de um servidor defeituoso. Os servidores "saudáveis" do grid assumem a responsabilidade dos servidores defeituosos. A figura abaixo mostra esta relação do grid e o processo de leitura de um dado mesmo quando um dos servidores do cluster sofre falha.
Uma característica do Coherence que o distingue e o melhor posiciona perante seus concorrentes é que nele, não existe de fato nenhum ponto de falha. Isso significa que tudo no Coherence é um grande grid formado por servidores num cluster que conhecem a localização de cada participante. Não existe um sistema de registro que cataloga os participantes do grid e também não existe um agente que controla o processo de atualização e de replicação dos dados no cluster. Todos os participantes do cluster sabem fazer esse trabalho, e eles colaboram entre si para que o processo seja feito sempre, garantindo assim a integridade e coerência dos dados. A maioria das soluções concorrentes apresentam componentes de registro e de lookup dos dados, e tais componentes controlam toda a arquitetura do grid de memória. Isso torna tais soluções inadequadas porque eles terão sempre um ponto de falha. Se porventura o componente responsável pelo registro dos servidores falhar, todo o grid irá parar de funcionar. E mesmo que esse componente de registro possa ser clusterizado, o seu processo de cluster será finito, e você sempre terá uma margem pra falhas se todas as cópias (backups e backup dos backups) falhar. Ou seja, cadê a elasticidade? No Coherence, tudo é 100% feito pelos participantes do cluster, de forma sincronizada, eficiente e atômica.
Outra particularidade que torna o Coherence atraente é sua simplicidade. Não só o fato de que você o pôe pra funcionar em poucos minutos (conforme será visto no próximo tópico) a sua API de manipulação também é muito trivial. Um cache para o Coherence nada mais é do que uma especialização da interface java.util.Map, implementada na API do Coherence como com.tangosol.net.NamedCache. Esta implementação de mapa é controlada internamente pelo Coherence, e em cima dela é feito todo o trabalho sujo de replicação e particionamento dos dados, sincronização das atualizações feitas, recuperação dos dados através de listeners e demais características do Coherence. Para interagir com um cache do Coherence, um programador Java simplesmente recupera uma instância de um com.tangosol.net.NamedCache e realiza suas operações de leitura, escrita, atualização ou remoção dos dados. O trecho de código abaixo mostra como solicitar um cache do Coherence conhecido como "clientes" e insere um objeto do tipo cliente usando seus CPF como chave da informação:
A API do Coherence está disponível tanto para Java quanto para C++ e também para .NET. Neste caso, usando qualquer uma destas linguagens você pode realizar o mesmo conjunto de operações e contando com as mesmas características já citadas. Para saber mais sobre como o Coherence dá suporte a demais linguagens que não Java, leia a documentação do produto que está disponível on-line no site da Oracle.
A Oracle disponibiliza o Coherence como um produto de Elastic Data Caching, ou integrado com os demais produtos da linha Fusion Middleware. Em especial, o Coherence já vem previamente integrado e configurado no servidor de aplicações WebLogic, dando ainda mais diferencial a este produto que já é fantástico. A partir desta integração, clientes do Oracle WebLogic podem usufruir das facilidades e características do Coherence sobre replicação e particionamento de dados, tendo por exemplo os principais componentes de um servidor de aplicação Java EE como sessões HTTP, JNDI Tree's, Servlets, JSF Managed Beans, Stateful e Stateless Session Beans controlados pelo grid do Coherence. Isso possibilita alta disponibilidade e performance em aplicações Java EE, além de possibilitar que desenvolvedores de componentes de Servlets ou EJB's possam usufruir também do Coherence, pois os seus cache's se tornam disponíveis através de JNDI ou através de injeção de dependência via anotação @Resource. Isso permite que as aplicações que porventura façam uso do cache do Coherence mantenham sua interoperabilidade com demais servidores de aplicações do mercado, uma vez que todo o acesso aos recursos é feito usando abordagens suportadas pela especificação do Java EE.
Finalmente, o Coherence possui um forte esquema de integração com outras tecnologias que não da Oracle, em especial com o JPA, Hibernate, Spring e o WSRP. Isso faz com que o Coherence possa ser embarcado em diversos tipos de aplicações e possa resolver diferentes tipos de demandas de cache. Esteja você criando uma aplicação Java simples e rodando num servidor Jetty ou mesmo numa aplicação standalone, o Coherence pode ajudar. Esteja você tentando melhorar a performance de suas entidades JPA ou Hibernate, o Coherence pode ajudá-lo na implementação de um cache de segundo nível. Esteja você querendo usar recursos de cache em aplicações baseadas em contêiners leves como Spring, o Coherence também poderá ser utilizado.
Demonstração do Oracle Coherence na Prática usando Java
Agora que criamos uma boa visão sobre o que é Elastic Data Caching e aprendemos um pouco sobre o que é o Oracle Coherence, é hora de nos aventurarmos em aprender como podemos utilizá-lo na prática. Irei mostrar agora como instalar e colocar o Coherence pra funcionar, e realizar alguns testes nele usando suas ferramentas internas e criando alguns programas em Java do tipo standalone. Vamos começar com o processo de instalação.
A primeira coisa a se fazer é realizar o download do produto no site da Oracle. Para isso, clique aqui para realizar o download. Para este artigo, utilizei a versão 3.7 do Coherence, que na época da escrita deste artigo era a mais atual. Você deverá ter uma conta de usuário no portal do Oracle Technology Network para poder realizar o download. O software pode ser utilizado gratuitamente para fins de aprendizado e testes no seu ambiente, mas lembre-se que se você planejar colocá-lo em produção em algum projeto, você deverá entrar em contato com a Oracle e providenciar seu licenciamento.
Quando você concluir o download, o que você terá em mãos um pequeno arquivo do tipo Zip. Descompacte este arquivo em um diretório de preferência do seu computador. Para este artigo, eu pûs o diretório descompactado no raiz do meu disco principal. Feito isso, você deverá providenciar algumas configurações relacionadas ao ambiente. A primeira coisa a se fazer é configurar a variável de ambiente JAVA_HOME. Se você é um desenvolvedor Java, você não deverá ter dificuldades quanto a isso. Para este artigo, usei um JDK versão 1.6 da Sun e não tive problemas. Lembre-se de colocar a pasta "bin" do seu JAVA_HOME na variável PATH. Isso será utíl principalmente pra utilizar os recursos de console e querying do Coherence.
Agora vá para o diretório de instalação do seu Coherence, e estando nela, entre no diretório "bin". Neste diretório, você encontrará vários arquivos do tipo shell e batch. Dentre eles, abra o arquivo cache-server.cmd (ou cache-server.sh se você estiver no Unix/Linux) para edição. Este arquivo cria uma instância do Coherence, que irá atuar tanto como cliente e como servidor dele mesmo. Quando você abrir este arquivo, você deverá editar a linha que define a variável COHERENCE_HOME. Faça com que esta variável aponte para o local onde você instalou seu Coherence, algo como "set COHERENCE_HOME=C:\coherence". Depois que você editar esse arquivo, você poderá executar um servidor do Coherence pela primeira vez em seu computador. Execute esse arquivo e veja no console qual será a saída apresentada. Se tudo estiver funcionando corretamente, você terá uma saída como a listagem abaixo:
O Coherence possui uma ferramenta bem poderosa de querying para que você possa remotamente administrar cache's e porventura alterar os valores que neles constam. Essa ferramenta chama-se "query" e pode ser encontrada dentro do diretório "bin" da instalação do seu Oracle Coherence. Para que possamos utilizá-la, é necessário realizar algumas configurações simples. A primeira coisa a fazer é realizar o download do framework JLine, que simplifica bastante a utilização de instruções do tipo shell. Descompacte o JLine em algum diretório do seu computador. Depois isso, edite o arquivo query.cmd (ou query.sh se você estiver no Unix/Linux) e edite o arquivo de tal forma que você defina as variáveis COHERENCE_HOME e JLINE_HOME, para que apontem para o local de instalação do Coherence e do JLine, respectivamente.
Pronto, agora temos tudo devidamente configurado para realizarmos nosso primeiro teste. Para começar os testes, execute uma instância do Coherence através do script "cache-server", encontrado no diretório "bin" do local de instalação do seu Coherence. Agora vá novamente ao diretório "bin" do local de instalação do Coherence e execute o script "query". Este script vai carregar um console do tipo schell para que você possa controlar atividades de criação e manipulação de cache's. O console deverá ser parecido com a figura abaixo:
Vamos criar um cache no Coherence e realizar algumas operações em cima deste cache. Para criar o cache, entre com a seguinte instrução no prompt e depois pressione a tecla "Enter":
create cache "teste"
Depois que você pressionar a tecla "Enter", você verá algumas mudanças no console do script "cache-server". O que irá acontecer é que o Coherence irá detectar que um novo agente quer participar do grid de dados e irá contar com este agente para delinear a memória do grid, formando o primeiro cluster. Tudo isso será feito automaticamente, pois o Coherence realiza todas estas operações através de broadcast na rede, usando seu robusto protocolo de peer-to-peer. A partir deste momento, ambos os agentes do cluster poderão manipular o cache "teste", e os dados que forem postos nele serão compartilhados por ambos os agentes. Vamos fazer um teste para verificar isso. Volte ao console de "query" e entre com a seguinte instrução e pressione "Enter":
insert into "teste" key "SP" value "Sao Paulo"
Isso irá inserir um valor dentro do cache conhecido no Coherence como "teste". Para verificar se a entrada foi corretamente adicionada no cache, você pode realizar uma consulta. Como você já deve ter notado, a linguagem de manipulação do Coherence se assemelha muito com a linguagem SQL, e a consulta não poderia ser diferente. Para ler os valores do cache "teste", entre com a seguinte instrução e pressione a tecla "Enter":
select key(), value() from "teste"
Será que os valores que entramos no cache "teste" está realmente dentro do grid e dados do Coherence? Vamos responder esta pergunta. Execute uma nova cópia do script "query". Feito isso, digite a instrução abaixo e pressione a tecla "Enter":
create cache "teste"
Quando você fizer isso, repare nas janelas dos consoles anteriores. Todos eles irão detectar o novo membro do cluster, e atualizar o grid de dados com este membro. Não se preocupe, a instrução que você acabou de digitar não vai "matar" o cache que já foi criado. Ao invés disso, ele irá notificar ao grid que um novo agente gostaria de manipular o cache "teste". O Coherence irá ver que já existe um cache com este nome, e ao invés de criar um novo ele irá devolver este cache existente. Existe uma instrução formal para remoção de um cache do grid. Agora, estando no novo console que você acabou de abrir, entre com a seguinte instrução e pressione a tecla "Enter":
select key(), value() from "teste"
Como você já deve imaginar, o resultado apresentado será a cidade de São Paulo, que foi inserido anteriomente no cache. Isso prova que, no Coherence, o cache é algo virtual, em que é distribuido entre todos os participantes do cluster. Toda operação feita no Coherence é executada contando com todos os participantes do cluster, por padrão. Você pode claro, configurar o Coherence para que certas operações sejam feitas apenas entre aguns membros. Para isso, você pode criar um grupo, ou como prefiro dizer, uma "sala de bate papo" particular. Neste caso somente os membros que estiverem nesse grupo irão trocar as informações.
Para fazer com que os consoles de "query" saiam do grid do Coherence, basta digitar a instrução "bye" e pressionar a tecla "Enter". Quando você fizer isso, repare que os demais consoles irão detectar a saída do membro, e passarão a não contar mais com aquele membro no cluster. Desta forma, toda nova instrução dada será de interesse apenas dos membros que sobrarem. Para terminar o console que contêm o script "cache-server", basta pressionar a combinação de teclas "Ctrl + C", como você faria com qualquer outro tipo de shell. Para conhecer mais sobre esta linguagem de manipulação e gerenciamento de dados, sugiro que você realiza os passos descritos na seção de instalação da documentação do Coherence, clicando neste link. Vamos agora tornar as coisas mais interessantes e verificar como podemos usar o Coherence dentro e através de uma aplicação Java.
Para começar nossos testes do Coherence em aplicações Java, use um IDE de sua preferência para realizar a codificação e execução dos programas. Eu usarei neste artigo o Eclipse, que pode ser baixado gratuitamente neste link. Baixe uma versão do Eclipse compatível com a JVM que você está utilizando. Após baixar o Eclipse, execute-o pela primeira vez configurando o workspace, ou seja, o local onde será armazenado os projetos. Quando o Eclipse for iniciado, você deverá criar uma biblioteca (library) que contenha a dependência do Coherence. Para isso, vá até o menu "Window" e clique na opção "Preferences". Na janela de preferências, acesse a opção "Java - Build Path - User Libraries". Na janela que aparece, Clique no botão "New" para adicionar uma nova biblioteca. Chame esta biblioteca de "Coherence37" e deixe marcado o checkbox "System library (added to the boot class path)". Clique em "OK" para confirmar a criação da biblioteca.
Depois de criar a biblioteca, clique no botão "Add JARs..." para adicionar a dependência do Coherence. A dependência será o arquivo JAR encontrado em $COHERENCE_HOME/lib/coherence.jar. Clique em "OK" para terminar o processo de criação da biblioteca. Como você pode perceber, o Coherence adiciona um footprint de dependências muito baixo as suas aplicações Java, além de ser extremamente simples de embarcar nas aplicações, por tratar-se de apenas uma dependência. Dependendo dos recursos que você precisar utilizar, pode ser necessário o uso de outras dependências, mas para as operações padrões do Coherence como o caso do grid de dados, apenas a sua biblioteca principal é necessária.
Vamos criar um projeto para exercitar a API do Coherence para Java. Para isso, crie um novo projeto do tipo Java no Eclipse, e dentre as configurações necessárias para o projeto, adicione a biblioteca "Coherence37" ao classpath. Para não perder o costume e as origens, chame esse projeto de "coherenceHelloWorld" :P
Uma vez criado o projeto, vamos criar um primeiro programa Java que irá criar um cache no Coherence, e inserir um valor neste cache. Para isso, crie uma classe Java chamada de "GravarPIUsandoCoherence.java" e implemente-a conforme a listagem abaixo:
O programa Java acima é simples de ler e acredito que seu código não mereça tanta explicação, exceto pela chamada de método "CacheFactory.ensureCluster()". Esta chamada na verdade realiza um broadcast na rede usando as configurações padrões do arquivo de configuração do Coherence (falaremos mais sobre ele adiante) a procura por outros membros que já formem um grid. Ao encontrar um, ele passa a fazer parte deste grid. Caso ele não encontre, como será o caso deste programa, ele irá criar o grid e se candidatar como primeiro membro. O restante do código apenas cria um cache e insere um valor dentro, que será lido posteriormente por outro programa Java. Para garantir que este programa "dure" até o momento que o outro programa leia a variável inserida, usamos uma instrução de espera, para que o programa fique aguardando pelo período de um minuto. Depois disso, o programa irá terminar, e irá sair do grid que foi montado a partir dele. Outros programas que permanecerem em execução e ainda conectados no grid irão perpetuá-lo até que eles se encerrem, do contrário, o grid inteiro irá ser finalizado.
Execute este programa Java e veja o resultado no console do Eclipse. Em verdade, nada de muito interessante irá acontecer, uma vez que este programa apenas grava num cache do Coherence uma variável que nunca será lida. Mas você deverá perceber pelo console que algumas saídas serão escritas, saídas estas semelhantes aos testes que fizemos usandos os scripts que acompanham a instalação do Oracle Coherence. Para completarmos nosso exemplo, é necessário que você crie outro programa Java. Crie uma nova classe Java no projeto, e chame-a de "LerPIUsandoCoherence.java", e implemente-a conforme a listagem abaixo:
Depois que terminar de implementar o programa Java acima, é hora de fazer o real teste usando o Coherence. Para isso, você deverá executar o primeiro programa Java, e esperar até que ele termine de montar o grid. Depois disso, você terá um minuto para executar esse segundo programa Java, que ao terminar sua execução deverá apresentar uma saída conforme a listagem abaixo:
Você deve estar se questionando: "OK, vi que o programa funcionou e leu a variável corretamente, e vi também que o Coherence é muito simples pois não precisei fazer nada para que o grid fosse montado e o cache fosse compartilhado". Mas imagino que justamente por estar pensando isso é que você possa estar incomodado com o fato de que tudo foi automático demais, certo?
Agora é hora de desvendar alguns mistérios. Quando você embute a API do Coherence dentro de um programa Java, a saber, o arquivo coherence.jar que usamos no classpath do projeto, você acaba embutindo também alguns arquivos de configuração que determinam o comportamento do Coherence quanto a montagem e/ou participação de um grid bem como o comportamento de particionamento e replicação no cluster. Esses arquivos de configuração estão dentro deste arquivo coherence.jar, no root do classpath do arquivo. Se você abri-lo com um programa de compactação como Winzip ou Winrar, você poderá ver e abrir tais arquivos de configuração.
Se você quiser usar seu próprio arquivo de configuração com as suas diretrizes de comportamento no Coherence, você deverá informar ao programa Java explicitamente que outros arquivos de configuração serão utilizados. Para fazer isso, basta que você crie os arquivo de configuração XML e grave-os no raiz do classpath. Se você estiver criando um programa Java e empacotando-o num arquivo JAR executável, então esses arquivos de configuração deverão estar no raiz deste arquivo JAR. Se você estiver criando uma aplicação Java EE pra Web, então os arquivos de configuração do Coherence deverão estar dentro da pasta WEB-INF/classes, exatamente no raiz deste diretório. A listagem abaixo mostra um exemplo de configuração do Coherence que sobreescreve as diretrizes padrões do Coherence:
Aprofundando no Oracle Coherence: Vídeos e Documentação
Este artigo mostrou alguns dos principais recursos do Oracle Coherence, mas é claro que o produto possui muito mais recursos e features do que os mostrados aqui. Para aprender mais sobre o Coherence, principalmente maiores detalhes sobre sua arquitetura, demais recursos e mecanismo de execução, recomendo fortemente você a assistir este vídeo abaixo. Este vídeo, é na verdade uma apresentação feita no evento Google Tech Talks, apresentada por nada mais nada menos do que Cameron Purdy, o criador e CEO da Tangosol, empresa adquirida pela Oracle em 2007 e criadora do Coherence.
Também hospedados no Youtube, a Oracle mantêm um canal dedicado exclusivamente a discussão e apresentação das novidades e recursos do Coherence. Recomendo você a assistir estes vídeos, que poderão dar a você maior insight sobre o produto e as possibilidades que ele abre, principalmente se você estiver em busca de soluções de Elastic Data Caching.
Boas Integrações ;)
Mas porque a capacidade de diminuir os recursos é mais importante do que a de aumento destes? A um tempo atrás, as aplicações eram projetadas para poderem oferecer transparência de localização, de forma que quando novos servidores fossem inseridos num cluster, a aplicação pudesse ser executada independente de onde estes servidores estiverem. Isso é interessante e poderoso, mas nos dias de hoje, isso não deve ser a unica preocupação. Inserir novos servidores em um cluster remete as organizações a investiram capital em hardware e máquinas, e isso do ponto de vista contábil não é nada interessante, pois, contabilmente falando, manter um servidor na organização é um custo contínuo e que sempre deprecia, tornando-o menos valioso ao longo do tempo. Se a organização que mantêm esse custo contínuo não for uma organização cujo fim é TI ou serviços de TI, então o problema se torna maior ainda, pois qualquer valor de capital investido em servidores e máquinas é visto como despesa e não como investimento. E todos sabemos que orçamento pra TI diminui a cada ano que passa. Para lidar com isso e usufruindo do que a tecnologia de virtualização hoje nos propcia, a indústria de cloud computing oferece a oportunidade de organizações utilizarem servidores e máquinas virtuais como um serviço, não implicando em custo de aquisição e manutenção. Neste caso, os servidores podem ser usados para atender uma demanda específica, e depois que esta demanda acabar eles podem ser "devolvidos" para o fornecedor da Cloud. Para usufruir desta capacidade, sua arquitetura precisa oferecer características de elasticidade.
Agora que vimos o que é Elastic Data Caching e porque isso é tão importante para a construção de arquiteturas de software emergentes, é hora de dedicar um tempo na avaliação de quais ofertas existem atualmente para isso, e com isso, conhecermos e avaliarmos quais são os fabricantes de software que estão disponíveis para avaliação e contratação.
Principais Ofertas de Elastic Data Caching e seus Players
As ofertas para soluções de Elastic Data Caching não poderiam ser melhores. Os principais fabricantes de software do mundo possuem pelo menos uma oferta nesta categoria. Alguns fabricantes porventura possuem mais de uma oferta, que podem ser combinados para compor uma solução mais abrangente. Dentre os principais fabricantes, encontram-se Oracle, GigaSpaces, IBM, Software AG e VMware. Querendo entrar nesta lista seleta de fabricantes constam também Microsoft, TIBCO e Red Hat, com ofertas interessantes mais ainda não tão maduras ou não disponíveis ainda como produtos para os clientes. A figura abaixo, retirada de um relatório do Forrester de Q2 de 2010, sintetiza os principais fornecedores e como suas soluções estão posicionadas:
Como o relatório é de 2010, ele acaba não refletindo a atual situação de fabricantes como a Terracota, que foi adquirida pela Software AG em 2011, e da GemStone Systems, que foi adqurida pela VMware em 2010. Os demais fabricantes permanecem até o presente momento. A figura mostra que Oracle, IBM, GigaSpaces e Software AG lideram a categoria, e que a Oracle com o seu Coherence possui maior base instalada de clientes sendo portanto a solução mais utilizada e madura.
Oracle Coherence: Visão Geral da Tecnologia e Aplicações
O Oracle Coherence é um produto para implementação de um grid de dados distribuído, ou seja, uma plataforma de distribuição (particionamento) dos dados em cima de um protocolo de peer-to-peer que suporta clusterização e altamente escalável. Isso possibilita que os dados sejam distribuídos num cluster de servidores formando uma grande e elástica área virtual de memória, garantindo assim que não existirá nenhum único ponto de falha, pois os dados podem ser recuperados de qualquer servidor do cluster. Quando um servidor entra na rede, o Coherence automaticamente detecta sua presença e passa a contar com ele em sua estratégia de grid. Quando um ou mais servidores sofrem falhas e param de responder, o Coherence também automaticamente detecta-os e expurga-os do cluster para que a área de memória virtual (o grid) não seja comprometido com a utilização de um servidor defeituoso. Os servidores "saudáveis" do grid assumem a responsabilidade dos servidores defeituosos. A figura abaixo mostra esta relação do grid e o processo de leitura de um dado mesmo quando um dos servidores do cluster sofre falha.
Uma característica do Coherence que o distingue e o melhor posiciona perante seus concorrentes é que nele, não existe de fato nenhum ponto de falha. Isso significa que tudo no Coherence é um grande grid formado por servidores num cluster que conhecem a localização de cada participante. Não existe um sistema de registro que cataloga os participantes do grid e também não existe um agente que controla o processo de atualização e de replicação dos dados no cluster. Todos os participantes do cluster sabem fazer esse trabalho, e eles colaboram entre si para que o processo seja feito sempre, garantindo assim a integridade e coerência dos dados. A maioria das soluções concorrentes apresentam componentes de registro e de lookup dos dados, e tais componentes controlam toda a arquitetura do grid de memória. Isso torna tais soluções inadequadas porque eles terão sempre um ponto de falha. Se porventura o componente responsável pelo registro dos servidores falhar, todo o grid irá parar de funcionar. E mesmo que esse componente de registro possa ser clusterizado, o seu processo de cluster será finito, e você sempre terá uma margem pra falhas se todas as cópias (backups e backup dos backups) falhar. Ou seja, cadê a elasticidade? No Coherence, tudo é 100% feito pelos participantes do cluster, de forma sincronizada, eficiente e atômica.
Outra particularidade que torna o Coherence atraente é sua simplicidade. Não só o fato de que você o pôe pra funcionar em poucos minutos (conforme será visto no próximo tópico) a sua API de manipulação também é muito trivial. Um cache para o Coherence nada mais é do que uma especialização da interface java.util.Map, implementada na API do Coherence como com.tangosol.net.NamedCache. Esta implementação de mapa é controlada internamente pelo Coherence, e em cima dela é feito todo o trabalho sujo de replicação e particionamento dos dados, sincronização das atualizações feitas, recuperação dos dados através de listeners e demais características do Coherence. Para interagir com um cache do Coherence, um programador Java simplesmente recupera uma instância de um com.tangosol.net.NamedCache e realiza suas operações de leitura, escrita, atualização ou remoção dos dados. O trecho de código abaixo mostra como solicitar um cache do Coherence conhecido como "clientes" e insere um objeto do tipo cliente usando seus CPF como chave da informação:
A API do Coherence está disponível tanto para Java quanto para C++ e também para .NET. Neste caso, usando qualquer uma destas linguagens você pode realizar o mesmo conjunto de operações e contando com as mesmas características já citadas. Para saber mais sobre como o Coherence dá suporte a demais linguagens que não Java, leia a documentação do produto que está disponível on-line no site da Oracle.
A Oracle disponibiliza o Coherence como um produto de Elastic Data Caching, ou integrado com os demais produtos da linha Fusion Middleware. Em especial, o Coherence já vem previamente integrado e configurado no servidor de aplicações WebLogic, dando ainda mais diferencial a este produto que já é fantástico. A partir desta integração, clientes do Oracle WebLogic podem usufruir das facilidades e características do Coherence sobre replicação e particionamento de dados, tendo por exemplo os principais componentes de um servidor de aplicação Java EE como sessões HTTP, JNDI Tree's, Servlets, JSF Managed Beans, Stateful e Stateless Session Beans controlados pelo grid do Coherence. Isso possibilita alta disponibilidade e performance em aplicações Java EE, além de possibilitar que desenvolvedores de componentes de Servlets ou EJB's possam usufruir também do Coherence, pois os seus cache's se tornam disponíveis através de JNDI ou através de injeção de dependência via anotação @Resource. Isso permite que as aplicações que porventura façam uso do cache do Coherence mantenham sua interoperabilidade com demais servidores de aplicações do mercado, uma vez que todo o acesso aos recursos é feito usando abordagens suportadas pela especificação do Java EE.
Finalmente, o Coherence possui um forte esquema de integração com outras tecnologias que não da Oracle, em especial com o JPA, Hibernate, Spring e o WSRP. Isso faz com que o Coherence possa ser embarcado em diversos tipos de aplicações e possa resolver diferentes tipos de demandas de cache. Esteja você criando uma aplicação Java simples e rodando num servidor Jetty ou mesmo numa aplicação standalone, o Coherence pode ajudar. Esteja você tentando melhorar a performance de suas entidades JPA ou Hibernate, o Coherence pode ajudá-lo na implementação de um cache de segundo nível. Esteja você querendo usar recursos de cache em aplicações baseadas em contêiners leves como Spring, o Coherence também poderá ser utilizado.
Demonstração do Oracle Coherence na Prática usando Java
Agora que criamos uma boa visão sobre o que é Elastic Data Caching e aprendemos um pouco sobre o que é o Oracle Coherence, é hora de nos aventurarmos em aprender como podemos utilizá-lo na prática. Irei mostrar agora como instalar e colocar o Coherence pra funcionar, e realizar alguns testes nele usando suas ferramentas internas e criando alguns programas em Java do tipo standalone. Vamos começar com o processo de instalação.
A primeira coisa a se fazer é realizar o download do produto no site da Oracle. Para isso, clique aqui para realizar o download. Para este artigo, utilizei a versão 3.7 do Coherence, que na época da escrita deste artigo era a mais atual. Você deverá ter uma conta de usuário no portal do Oracle Technology Network para poder realizar o download. O software pode ser utilizado gratuitamente para fins de aprendizado e testes no seu ambiente, mas lembre-se que se você planejar colocá-lo em produção em algum projeto, você deverá entrar em contato com a Oracle e providenciar seu licenciamento.
Quando você concluir o download, o que você terá em mãos um pequeno arquivo do tipo Zip. Descompacte este arquivo em um diretório de preferência do seu computador. Para este artigo, eu pûs o diretório descompactado no raiz do meu disco principal. Feito isso, você deverá providenciar algumas configurações relacionadas ao ambiente. A primeira coisa a se fazer é configurar a variável de ambiente JAVA_HOME. Se você é um desenvolvedor Java, você não deverá ter dificuldades quanto a isso. Para este artigo, usei um JDK versão 1.6 da Sun e não tive problemas. Lembre-se de colocar a pasta "bin" do seu JAVA_HOME na variável PATH. Isso será utíl principalmente pra utilizar os recursos de console e querying do Coherence.
Agora vá para o diretório de instalação do seu Coherence, e estando nela, entre no diretório "bin". Neste diretório, você encontrará vários arquivos do tipo shell e batch. Dentre eles, abra o arquivo cache-server.cmd (ou cache-server.sh se você estiver no Unix/Linux) para edição. Este arquivo cria uma instância do Coherence, que irá atuar tanto como cliente e como servidor dele mesmo. Quando você abrir este arquivo, você deverá editar a linha que define a variável COHERENCE_HOME. Faça com que esta variável aponte para o local onde você instalou seu Coherence, algo como "set COHERENCE_HOME=C:\coherence". Depois que você editar esse arquivo, você poderá executar um servidor do Coherence pela primeira vez em seu computador. Execute esse arquivo e veja no console qual será a saída apresentada. Se tudo estiver funcionando corretamente, você terá uma saída como a listagem abaixo:
O Coherence possui uma ferramenta bem poderosa de querying para que você possa remotamente administrar cache's e porventura alterar os valores que neles constam. Essa ferramenta chama-se "query" e pode ser encontrada dentro do diretório "bin" da instalação do seu Oracle Coherence. Para que possamos utilizá-la, é necessário realizar algumas configurações simples. A primeira coisa a fazer é realizar o download do framework JLine, que simplifica bastante a utilização de instruções do tipo shell. Descompacte o JLine em algum diretório do seu computador. Depois isso, edite o arquivo query.cmd (ou query.sh se você estiver no Unix/Linux) e edite o arquivo de tal forma que você defina as variáveis COHERENCE_HOME e JLINE_HOME, para que apontem para o local de instalação do Coherence e do JLine, respectivamente.
Pronto, agora temos tudo devidamente configurado para realizarmos nosso primeiro teste. Para começar os testes, execute uma instância do Coherence através do script "cache-server", encontrado no diretório "bin" do local de instalação do seu Coherence. Agora vá novamente ao diretório "bin" do local de instalação do Coherence e execute o script "query". Este script vai carregar um console do tipo schell para que você possa controlar atividades de criação e manipulação de cache's. O console deverá ser parecido com a figura abaixo:
Vamos criar um cache no Coherence e realizar algumas operações em cima deste cache. Para criar o cache, entre com a seguinte instrução no prompt e depois pressione a tecla "Enter":
create cache "teste"
Depois que você pressionar a tecla "Enter", você verá algumas mudanças no console do script "cache-server". O que irá acontecer é que o Coherence irá detectar que um novo agente quer participar do grid de dados e irá contar com este agente para delinear a memória do grid, formando o primeiro cluster. Tudo isso será feito automaticamente, pois o Coherence realiza todas estas operações através de broadcast na rede, usando seu robusto protocolo de peer-to-peer. A partir deste momento, ambos os agentes do cluster poderão manipular o cache "teste", e os dados que forem postos nele serão compartilhados por ambos os agentes. Vamos fazer um teste para verificar isso. Volte ao console de "query" e entre com a seguinte instrução e pressione "Enter":
insert into "teste" key "SP" value "Sao Paulo"
Isso irá inserir um valor dentro do cache conhecido no Coherence como "teste". Para verificar se a entrada foi corretamente adicionada no cache, você pode realizar uma consulta. Como você já deve ter notado, a linguagem de manipulação do Coherence se assemelha muito com a linguagem SQL, e a consulta não poderia ser diferente. Para ler os valores do cache "teste", entre com a seguinte instrução e pressione a tecla "Enter":
select key(), value() from "teste"
Será que os valores que entramos no cache "teste" está realmente dentro do grid e dados do Coherence? Vamos responder esta pergunta. Execute uma nova cópia do script "query". Feito isso, digite a instrução abaixo e pressione a tecla "Enter":
create cache "teste"
Quando você fizer isso, repare nas janelas dos consoles anteriores. Todos eles irão detectar o novo membro do cluster, e atualizar o grid de dados com este membro. Não se preocupe, a instrução que você acabou de digitar não vai "matar" o cache que já foi criado. Ao invés disso, ele irá notificar ao grid que um novo agente gostaria de manipular o cache "teste". O Coherence irá ver que já existe um cache com este nome, e ao invés de criar um novo ele irá devolver este cache existente. Existe uma instrução formal para remoção de um cache do grid. Agora, estando no novo console que você acabou de abrir, entre com a seguinte instrução e pressione a tecla "Enter":
select key(), value() from "teste"
Como você já deve imaginar, o resultado apresentado será a cidade de São Paulo, que foi inserido anteriomente no cache. Isso prova que, no Coherence, o cache é algo virtual, em que é distribuido entre todos os participantes do cluster. Toda operação feita no Coherence é executada contando com todos os participantes do cluster, por padrão. Você pode claro, configurar o Coherence para que certas operações sejam feitas apenas entre aguns membros. Para isso, você pode criar um grupo, ou como prefiro dizer, uma "sala de bate papo" particular. Neste caso somente os membros que estiverem nesse grupo irão trocar as informações.
Para fazer com que os consoles de "query" saiam do grid do Coherence, basta digitar a instrução "bye" e pressionar a tecla "Enter". Quando você fizer isso, repare que os demais consoles irão detectar a saída do membro, e passarão a não contar mais com aquele membro no cluster. Desta forma, toda nova instrução dada será de interesse apenas dos membros que sobrarem. Para terminar o console que contêm o script "cache-server", basta pressionar a combinação de teclas "Ctrl + C", como você faria com qualquer outro tipo de shell. Para conhecer mais sobre esta linguagem de manipulação e gerenciamento de dados, sugiro que você realiza os passos descritos na seção de instalação da documentação do Coherence, clicando neste link. Vamos agora tornar as coisas mais interessantes e verificar como podemos usar o Coherence dentro e através de uma aplicação Java.
Para começar nossos testes do Coherence em aplicações Java, use um IDE de sua preferência para realizar a codificação e execução dos programas. Eu usarei neste artigo o Eclipse, que pode ser baixado gratuitamente neste link. Baixe uma versão do Eclipse compatível com a JVM que você está utilizando. Após baixar o Eclipse, execute-o pela primeira vez configurando o workspace, ou seja, o local onde será armazenado os projetos. Quando o Eclipse for iniciado, você deverá criar uma biblioteca (library) que contenha a dependência do Coherence. Para isso, vá até o menu "Window" e clique na opção "Preferences". Na janela de preferências, acesse a opção "Java - Build Path - User Libraries". Na janela que aparece, Clique no botão "New" para adicionar uma nova biblioteca. Chame esta biblioteca de "Coherence37" e deixe marcado o checkbox "System library (added to the boot class path)". Clique em "OK" para confirmar a criação da biblioteca.
Depois de criar a biblioteca, clique no botão "Add JARs..." para adicionar a dependência do Coherence. A dependência será o arquivo JAR encontrado em $COHERENCE_HOME/lib/coherence.jar. Clique em "OK" para terminar o processo de criação da biblioteca. Como você pode perceber, o Coherence adiciona um footprint de dependências muito baixo as suas aplicações Java, além de ser extremamente simples de embarcar nas aplicações, por tratar-se de apenas uma dependência. Dependendo dos recursos que você precisar utilizar, pode ser necessário o uso de outras dependências, mas para as operações padrões do Coherence como o caso do grid de dados, apenas a sua biblioteca principal é necessária.
Vamos criar um projeto para exercitar a API do Coherence para Java. Para isso, crie um novo projeto do tipo Java no Eclipse, e dentre as configurações necessárias para o projeto, adicione a biblioteca "Coherence37" ao classpath. Para não perder o costume e as origens, chame esse projeto de "coherenceHelloWorld" :P
Uma vez criado o projeto, vamos criar um primeiro programa Java que irá criar um cache no Coherence, e inserir um valor neste cache. Para isso, crie uma classe Java chamada de "GravarPIUsandoCoherence.java" e implemente-a conforme a listagem abaixo:
O programa Java acima é simples de ler e acredito que seu código não mereça tanta explicação, exceto pela chamada de método "CacheFactory.ensureCluster()". Esta chamada na verdade realiza um broadcast na rede usando as configurações padrões do arquivo de configuração do Coherence (falaremos mais sobre ele adiante) a procura por outros membros que já formem um grid. Ao encontrar um, ele passa a fazer parte deste grid. Caso ele não encontre, como será o caso deste programa, ele irá criar o grid e se candidatar como primeiro membro. O restante do código apenas cria um cache e insere um valor dentro, que será lido posteriormente por outro programa Java. Para garantir que este programa "dure" até o momento que o outro programa leia a variável inserida, usamos uma instrução de espera, para que o programa fique aguardando pelo período de um minuto. Depois disso, o programa irá terminar, e irá sair do grid que foi montado a partir dele. Outros programas que permanecerem em execução e ainda conectados no grid irão perpetuá-lo até que eles se encerrem, do contrário, o grid inteiro irá ser finalizado.
Execute este programa Java e veja o resultado no console do Eclipse. Em verdade, nada de muito interessante irá acontecer, uma vez que este programa apenas grava num cache do Coherence uma variável que nunca será lida. Mas você deverá perceber pelo console que algumas saídas serão escritas, saídas estas semelhantes aos testes que fizemos usandos os scripts que acompanham a instalação do Oracle Coherence. Para completarmos nosso exemplo, é necessário que você crie outro programa Java. Crie uma nova classe Java no projeto, e chame-a de "LerPIUsandoCoherence.java", e implemente-a conforme a listagem abaixo:
Depois que terminar de implementar o programa Java acima, é hora de fazer o real teste usando o Coherence. Para isso, você deverá executar o primeiro programa Java, e esperar até que ele termine de montar o grid. Depois disso, você terá um minuto para executar esse segundo programa Java, que ao terminar sua execução deverá apresentar uma saída conforme a listagem abaixo:
Você deve estar se questionando: "OK, vi que o programa funcionou e leu a variável corretamente, e vi também que o Coherence é muito simples pois não precisei fazer nada para que o grid fosse montado e o cache fosse compartilhado". Mas imagino que justamente por estar pensando isso é que você possa estar incomodado com o fato de que tudo foi automático demais, certo?
Agora é hora de desvendar alguns mistérios. Quando você embute a API do Coherence dentro de um programa Java, a saber, o arquivo coherence.jar que usamos no classpath do projeto, você acaba embutindo também alguns arquivos de configuração que determinam o comportamento do Coherence quanto a montagem e/ou participação de um grid bem como o comportamento de particionamento e replicação no cluster. Esses arquivos de configuração estão dentro deste arquivo coherence.jar, no root do classpath do arquivo. Se você abri-lo com um programa de compactação como Winzip ou Winrar, você poderá ver e abrir tais arquivos de configuração.
Se você quiser usar seu próprio arquivo de configuração com as suas diretrizes de comportamento no Coherence, você deverá informar ao programa Java explicitamente que outros arquivos de configuração serão utilizados. Para fazer isso, basta que você crie os arquivo de configuração XML e grave-os no raiz do classpath. Se você estiver criando um programa Java e empacotando-o num arquivo JAR executável, então esses arquivos de configuração deverão estar no raiz deste arquivo JAR. Se você estiver criando uma aplicação Java EE pra Web, então os arquivos de configuração do Coherence deverão estar dentro da pasta WEB-INF/classes, exatamente no raiz deste diretório. A listagem abaixo mostra um exemplo de configuração do Coherence que sobreescreve as diretrizes padrões do Coherence:
Aprofundando no Oracle Coherence: Vídeos e Documentação
Este artigo mostrou alguns dos principais recursos do Oracle Coherence, mas é claro que o produto possui muito mais recursos e features do que os mostrados aqui. Para aprender mais sobre o Coherence, principalmente maiores detalhes sobre sua arquitetura, demais recursos e mecanismo de execução, recomendo fortemente você a assistir este vídeo abaixo. Este vídeo, é na verdade uma apresentação feita no evento Google Tech Talks, apresentada por nada mais nada menos do que Cameron Purdy, o criador e CEO da Tangosol, empresa adquirida pela Oracle em 2007 e criadora do Coherence.
Também hospedados no Youtube, a Oracle mantêm um canal dedicado exclusivamente a discussão e apresentação das novidades e recursos do Coherence. Recomendo você a assistir estes vídeos, que poderão dar a você maior insight sobre o produto e as possibilidades que ele abre, principalmente se você estiver em busca de soluções de Elastic Data Caching.
Boas Integrações ;)
