Fazendo leitura e compilação de arquivos de forma distribuida

Hoje vou mostrar como fazer leitura e compilação de uma grande quantidade de dados de forma distribuída,.

Para isso vou explicar como fiz o projeto da Nossa Caixa na primeira #CPBR, o desafio era pegar um arquivo contendo vários jogos da mega sena e analisar quantos ganhadores da mega, quina,sena e quadra existem dentro de arquivos, sendo que os numero podiam aparecer em qualquer ordem dentro de um grupo.

Existem algumas soluções prontas, mais como a ideia era ter o máximo de desempenho resolvi eu mesmo desenvolver uma em java.

Bem, a ideia e bem simples, vamos pegar um arquivo e dividir ele em varias threads, podendo ou na ser em maquina diferente, então para isso vamos precisar criar um “servidor” que vai delegar o serviço para as outras maquinas, esse servidor vai ser responsável por gravar os bits dos arquivos na memoria e dividir ele em vários pedaços, assim todo o processo de comparação e analise vai ficar com as maquinas clientes.

Vamos ao fonte, para a classe servidor  ele inicia escutando uma porta, essa porta vai ser aonde todos os clientes vão conectar,como nesse exemplo não vamos implementar um sistema de clientes dinâmicos, vamos apenas esperar todos os clientes conectarem e logo apos o ok ele começa a analisar o arquivo.

O fonte de conexões vai ficar dessa maneira:

public void aceitar(int i){
       try{
               Cliente cliente = new Cliente(this.conexao.accept(),this.clientes,this.bilhete);
               this.clientes.add(cliente);
               cliente.start();
        }catch (IOException e){
              e.printStackTrace();
        }
}

Agora vamos trabalhar no cliente, ele fica responsável por pegar partes dos arquivos e analisar, esse cliente pode ser aberto varias vezes em uma maquina sendo, cada cliente uma thread.

O código do cliente fica assim:

Conectar conecta = new Conectar(“localhost”,5050);
if(conecta.getSock().isConnected()){
       Processar pro = new Processar(conecta);
      Thread threadProcessar = new Thread(pro);
      threadProcessar.start();
}

Agora por ultimo, o cliente processa o arquivo e envia os resultados, nesse caso estaremos fazendo as comparações entre os números sorteados achando os ganhadores, logo em seguida enviamos esse dados ja mastigados para o nosso pequeno servidor guardar a informação que aquela parte X do arquivo tem N ganhadores.

O código de envio fica assim:

public void run() {
           boolean enviar = true;
           String tmp;
           while(this.sock.getSock().isConnected()){
                   this.envio.enviarMsg(“1″);
                  tmp = this.leitor.ler();
                 if(tmp.equals(“acabou”)){
                          if(enviar){
                                    this.envio.enviarMsg(“10″);
                                    enviar = false;
                           }
                 }
                if(tmp.length()<10){

               }else{
                       try{
                              this.envio.enviarMsg(contagem(tmp));
                     }catch(Exception e){}

              }
       }
}

Agora so rodar o programa e ver as maquinas trabalhando e dividindo o processamento do arquivo.

Vou estar disponibilizando o link para download do fonte completo aqui

 

Bookmark the permalink.