• Nenhum resultado encontrado

Capítulo 4 – Sistema de pré-seleção e pré-carga de dados em bancos de dados móveis

4.3 Agente interceptador

4.3.1 O servidor fixo

Nesta seção, abordaremos os detalhes da implementação da prova de conceito deste trabalho quanto ao lado do servidor fixo.

Como SGBD do servidor fixo, foi escolhido o PostgreSQL6, em sua versão 8.0.3, por ser de código aberto, estável, objeto-relacional e de alta-tecnologia, o que faz dele um produto confiável. O PostgreSQL existe há mais de 15 anos, possuindo versões para Linux, Unix, BeOS, e Windows. Ele respeita as propriedades ACID, possui suporte para chaves estrangeiras, junções, visões, triggers, e stored procedures em várias linguagens, além de possuir interface para linguagens como C/C++, Java, Perl, entre outras.

Para a aprendizagem de máquina, foi utilizada, nesta implementação, a biblioteca do Waikato Environment for Knowledge Analysis, ou WEKA7 [WF05], como é conhecido. O WEKA é uma ferramenta que contém uma coleção de métodos de aprendizagem de máquina. Ela foi desenvolvida utilizando a linguagem Java, na Universidade de Waikato, na Nova Zelândia, dentro do projeto Aprendizagem de máquina8 sob a orientação dos professores Ian Witten e Eibe Frank.

Um dos fatores que contribuiu para a escolha desta ferramenta foi por ela ter seu código fonte aberto, permitindo, dessa maneira, que ela possa ser estendida e suas bibliotecas possam ser acessadas por qualquer programa.

Modelo de comunicação do PostgreSQL

O SGBD PostgreSQL segue um modelo de comunicação cliente-servidor. Um processo no servidor é criado para cada cliente que deseja se conectar ao banco. Como a quantidade de conexões que serão realizadas não é conhecida no momento em que o

6

http://www.postgresql.org

7

sistema é iniciado, um processo principal, denominado postmaster, é criado para gerenciar a chegada de novos clientes. Este processo também e responsável por iniciar as estruturas compartilhadas na memória que serão utilizadas por todos os processos do SGBD no servidor. Outro papel importante do processo postmaster é o de gerenciar tarefas especiais, como inicializações, paradas e checkpoints.

Cada conexão ao sistema é tratada por um processo no servidor, denominado

postgres, como ilustrado na Figura 4.5. Estes processos postgres recebem os comandos

enviados pelos clientes e se comunicam uns com os outros utilizando semáforos e memória compartilhada. Desta forma, o PostgreSQL consegue garantir a integridade dos dados mesmo trabalhando concorrentemente em comandos enviados por clientes distintos.

Figura 4.5 - Processos e módulos do PostgreSQL (adaptado de [Lan00])

A Figura 4.5 mostra processos no cliente e processos do lado servidor do sistema, envolvidos no processamento de consultas.

Processos no Cliente Processos no Servidor

Aplicação Cliente Consultas SQL e respostas Postmaster Conexão inicial postgres Client Interface Library Consultas e respostas via API Criação de processos

Processamento de Consultas no PostgreSQL

Quando um processo postgres recebe um comando SQL, ele invoca o seu analisador sintático [Lan00] (parser, veja a Figura 4.6). Este módulo é responsável por garantir que a sintaxe do comando está correta e por gerar uma árvore que o representa. Comandos são de dois tipos principais: utilitários e complexos.

Comandos utilitários são executados imediatamente, sem passar por transformações adicionais. Exemplos deste tipo de comando são os comandos da linguagem de definição de dados (DDL), como create index, create table, entre outros.

Já comandos complexos exigem transformações antes de sua execução. São aplicados os passos de reescrita de consultas e de otimização. Comandos complexos compreendem comandos como, por exemplo, select, insert, delete, update.

A reescrita de consultas transforma a árvore original proveniente do analisador sintático em uma árvore semanticamente validada, com tipos checados e regras de reescrita aplicadas. Um exemplo comum de reescrita é a expansão de visões na árvore [GMUW00]. A árvore validada é enviada para o otimizador, que busca pelas melhores combinações de métodos de acesso e operadores físicos que podem ser utilizados para responder a consulta. Para consultas com um número aceitável de junções (configurado como uma variável do sistema), o sistema utiliza um algoritmo de busca exaustiva. Caso o número de junções seja maior, é utilizada uma heurística de busca baseada em algoritmos genéticos [Mit97].

Após a etapa de otimização, é obtido um plano de execução para a consulta, juntamente com estimativas de custos para as operações. Este plano é dado como entrada para o executor, que se encarrega de interpretar as operações estipuladas e acessar módulos de mais baixo nível no SGBD, como as interfaces dos métodos de acesso e do gerente de armazenamento. Os registros obtidos pelo executor são enviados de volta ao cliente que originou o comando.

Componente de pré-seleção de dados

Para a pré-seleção de dados, foi optado pela técnica de descoberta de regras de associação, escolhendo o algoritmo Apriori [AS94], apresentado mais detalhadamente na seção 4.3.2 neste capítulo. Para a implementação, foram utilizados módulos da ferramenta WEKA, em seu pacote de regras de associação, como ilustra o diagrama de classes do pacote weka.assossiations na Figura 4.7.

OptionHandler interface CARuleMiner Cloneable Serializable Associator OptionHandler Runnable Tertius OptionHandler Apriori OptionHandler PredictiveApriori Serializable PriorEstimation Serializable CaRuleGeneration Comparable Serializable RuleItem Serializable RuleGeneration Serializable AprioriItemSet Serializable LabeledItemSet Serializable ItemSet

A ponte entre o dispositivo móvel, onde se cataloga todas as consultas feitas pelo usuário, e o servidor fixo, onde as consultas devem ser processadas a fim de se pré- selecionar que dados devem ser pré-carregados, dá-se através do componente

QueriesHoard.

QueriesHoard Apriori AprioriItemSet

QueriesStack postmaster postgres

5: //buildAssociations 6: //findLargeItemSets 6.1: //find k-1 itemset 6.2: //pruneItemsets 7: //findRulesQuickly 7.1: //generateRules 2: //getConnection 3: //create 4: //executeQuery 1: //sendStack

Figura 4.8- Diagrama de seqüência do QueriesHoard

O diagrama de seqüência das iterações entre o dispositivo móvel e o servidor fixo é ilustrado na Figura 4.8. As iterações acontecem através da classe QueriesStack e o

QueriesHoard. Em um determinado momento, como por exemplo numa reconexão, o QueriesStack envia um conjunto de consultas acumuladas. O QueriesHoard tem como

propósito dar condições para que o Apriori possa descobrir regras a partir dos resultados das consultas enviadas pelo dispositivo móvel. O algoritmo Apriori, implementado na classe Apriori do diagrama da Figura 4.8, é detalhado na seção 4.3.2.

Documentos relacionados