package scs.demos.mapreduce.schedule; import java.io.FileInputStream; import java.io.IOException; import java.util.Hashtable; import java.util.Iterator; import java.util.Properties; import java.util.concurrent.LinkedBlockingQueue; import org.omg.CORBA.ORB; import scs.core.AlreadyConnected; import scs.core.ExceededConnectionLimit; import scs.core.IComponent; import scs.core.IReceptacles; import scs.core.IReceptaclesHelper; import scs.core.InvalidConnection; import scs.core.InvalidName; import scs.demos.bigtable.Sorter; import scs.demos.bigtable.SorterHelper; import scs.demos.bigtable.servant.BigTableInitializer; import scs.demos.mapreduce.ChannelException; import scs.demos.mapreduce.ConectionToExecNodesException; import scs.demos.mapreduce.IOFormat; import scs.demos.mapreduce.MasterPOA; import scs.demos.mapreduce.PropertiesException; import scs.demos.mapreduce.Reporter; import scs.demos.mapreduce.StartFailureException; import scs.demos.mapreduce.Task; import scs.demos.mapreduce.TaskInstantiationException; import scs.demos.mapreduce.TaskStatus; import scs.demos.mapreduce.Worker; import scs.demos.mapreduce.WorkerInstantiationException; /** * Servant que implementa a interface scs::demos::mapreduce::Master * @author Sand Luz Correa */ enum Phase {MAP,REDUCE,ERROR}; public class MasterServant extends MasterPOA { /* Nome do arquivo de dados a ser processado pelas fun��es map e reduce*/ private String inputFileName; /* Lista de endere�os dos n�s de execu��o usados no processamento */ private String[] execNodeList; /* numero de mappers */ private int num_mappers; /* numero de reducers */ private int num_reducers; /* numero de bigTables*/ private int num_sorters; /* nome do container onde master executa*/ private String containerName; /* nome do servant mapper */ private String mapperServantName; /* nome do servant reducer */ private String reducerServantName; /* nome do servant bigTables */ private String sorterServantName; /* nome do servant partitioner */ private String partitionerServantName; /* nome do servant combiner */ private String combinerServantName; /* nome do host onde master executa*/ private String masterHost; /* port onde master executa*/ private String masterPort; /* nome do arquivo de configuracao */ private String configFileName; /* flag que indica se a operacao combine deve ser executada */ private boolean combineFlag; /* nome da classe que implementa a interface IOFormat */ private String ioformatClassName; /* flag que indica se os resultados dos reduces devem * ser juntados em um unico arquivo */ private boolean joinFlag; /* nome do arquivo resultado da juncao dos reduces*/ private String joinFileName; /* Lista de objetos Execution Node */ private Hashtable hashNodes = null; /* Lista de objetos Execution Node dos Sorters*/ private Hashtable hashSorterNodes = null; /* Objeto que instancia workers */ private WorkerInitializer workerInitializer = null; /* Objeto que instancia bigtables */ private BigTableInitializer bigTableInitializer = null; /* referencia para o componente Master*/ private MasterComponent myComp = null; private Properties config; private ORB orb; private LinkedBlockingQueue workerQueue; private LinkedBlockingQueue<IComponent> workerComponentQueue; private LinkedBlockingQueue taskQueue; private IComponent bigTableComponent; private IComponent channel; private Hashtable workingOn; private int num_partitions; private Reporter reporter; private IOFormat ioformat; private String exception; private Phase currentStatus; public MasterServant(MasterComponent comp){ String[] args = new String[1]; args[0] = "inicio"; orb = ORB.init(args, null); num_partitions = 0; myComp = comp; } private boolean getProperties(String configFileName) { this.configFileName = configFileName; this.config = new Properties(); try { config.load(new FileInputStream(configFileName)); } catch (IOException e) { exception = LogError.getStackTrace(e); reporter.report(0,"MasterServant::getProperties - Erro ao ler arquivo de configuracao " + configFileName + ".\n" + exception); return false; } /* Obtendo configuracoes para o mapreduce*/ masterHost = this.config.getProperty("mapred.Master.corbaloc-host"); if (masterHost == null) { reporter.report(0,"MasterServant::getProperties - Erro ao obter host onde Master executara"); return false; } masterPort = this.config.getProperty("mapred.Master.corbaloc-port"); if(masterPort == null) { reporter.report(0,"MasterServant::getProperties - Erro ao obter port onde Master executara"); return false; } inputFileName = this.config.getProperty("mapred.Input.name"); if (inputFileName == null) { reporter.report(0,"MasterServant::getProperties - Erro ao ler nome do arquivo de entrada"); return false; } containerName = this.config.getProperty("mapred.Master.container-name"); if (containerName == null) { reporter.report(0,"MasterServant::getProperties - Erro ao ler nome do container do master"); return false; } mapperServantName = this.config.getProperty("mapred.Mapper.servant-name"); if (mapperServantName == null) { reporter.report(0,"MasterServant::getProperties - Erro ao ler nome do servant Mapper"); return false; } reducerServantName = this.config.getProperty("mapred.Reducer.servant-name"); if (reducerServantName == null) { reporter.report(0,"MasterServant::getProperties - Erro ao ler nome do servant Reducer"); return false; } partitionerServantName = this.config.getProperty("mapred.Partitioner.servant-name"); if (mapperServantName == null) { reporter.report(0,"MasterServant::getProperties - Erro ao ler nome do servant Partitioner"); return false; } String execNodes = this.config.getProperty("mapred.Workers.exec-nodes"); if( execNodes == null ){ reporter.report(0,"MasterServant::getProperties - Erro ao ler execution nodes " + "onde workers serao instanciados"); return false; } else { execNodeList = execNodes.split(";"); } num_mappers = Integer.parseInt(this.config.getProperty("mapred.Mappers.number", String.valueOf(execNodeList.length))); num_reducers = Integer.parseInt(this.config.getProperty("mapred.Reducers.number","0")); num_sorters = Integer.parseInt(this.config.getProperty("mapred.Sorters.number", "0")); if (num_mappers < execNodeList.length){ reporter.report(0,"MasterServant::getProperties - Numero de mappers nao pode ser menor que " + "numero de execution nodes"); return false; } if (num_mappers < num_reducers) { reporter.report(0,"MasterServant::getProperties - Numero de mappers nao pode ser menor que " + "numero de reducers"); return false; } if (num_sorters > num_reducers) { reporter.report(0,"MasterServant::getProperties - Numero de sorters nao pode ser maior que " + "numero de reducers"); return false; } combineFlag = Boolean.valueOf(this.config.getProperty("mapred.Combine.flag","false")).booleanValue(); if (combineFlag) { combinerServantName = this.config.getProperty("mapred.Combiner.servant-name", reducerServantName); } ioformatClassName = this.config.getProperty("mapred.IOFormat.class-name"); if (ioformatClassName == null) { reporter.report(0,"MasterServant::getProperties - Erro ao ler nome da classe que implementa " + "a interface IOFormat"); return false; } joinFlag = Boolean.valueOf(this.config.getProperty("mapred.Join.flag","true")).booleanValue(); joinFileName = inputFileName.split(".txt") + "Result" + ".txt"; joinFileName = this.config.getProperty("mapred.Join.file-name",joinFileName); return true; } private boolean schedule() { try{ /* hash com os workers em processamento. Indexado pela tarefa*/ workingOn = new Hashtable(); currentStatus = Phase.MAP; while(!currentStatus.equals(Phase.ERROR)) { Worker worker = (Worker) workerQueue.take(); //IComponent workerComponent = (IComponent) workerQueue.take(); Task task = (Task) taskQueue.take(); TaskStatus op = task.getStatus(); /* termina escalonamento se encontra flag de fim*/ if (op.value()==TaskStatus._END) { break; } //Worker worker = WorkerHelper.narrow(workerComponent.getFacetByName("Worker")); workingOn.put(task, worker); worker.execute(task); } if (currentStatus.equals(Phase.ERROR)) { return false; } return true; } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0,"MasterServant::schedule - Escalonamento interrompido. \n" + exception); return false; } } public void start(String configFileName, Reporter reporter) throws PropertiesException, ConectionToExecNodesException, ChannelException, WorkerInstantiationException, TaskInstantiationException, StartFailureException { this.reporter = reporter; reporter.report(1,"MasterServant::start - Lendo configuracoes de " + configFileName); /* l� arquivo de configura��o */ if(!getProperties(configFileName)) { throw new PropertiesException(); } reporter.report(1,"MasterServant::start - Arquivo de configuracao lido"); /* cria objeto que inicializa workers e fila de tarefas */ try { workerInitializer = new WorkerInitializer(this); } catch (Exception e) { throw new WorkerInstantiationException(); } reporter.report(1,"MasterServant::start - WorkerInitializer instanciado"); /* cria objeto que inicializa sorters */ try { bigTableInitializer = new BigTableInitializer(this); } catch (Exception e) { // TODO // throw new BigTableInstantiationException(); } reporter.report(1,"MasterServant::start - BigTableInitializer instanciado"); /* conecta-se com os execution nodes dos workers*/ reporter.report(1,"MasterServant::start - Conectando aos outros execution nodes"); hashNodes = this.workerInitializer.connectToExecNodes(); if (hashNodes == null) { throw new ConectionToExecNodesException (); } reporter.report(1,"MasterServant::start - Conectado ao execution node dos workers"); /* conecta-se com os execution nodes dos sorters*/ reporter.report(1,"MasterServant::start - Conectando aos outros execution nodes"); hashSorterNodes = this.bigTableInitializer.connectToExecNodes(); if (hashSorterNodes == null) { throw new ConectionToExecNodesException (); } reporter.report(1,"MasterServant::start - Conectado ao execution node dos sorters"); /* cria canal de evento entre master e workers*/ reporter.report(1,"MasterServant::start - Criando canal de evento entre master e workers"); channel = workerInitializer.buildChannel(); if (channel == null) { throw new ChannelException (); } /*instancia workers*/ reporter.report(1,"MasterServant::start - Instanciando Workers"); workerQueue = workerInitializer.buildWorkerQueue(); if (workerQueue == null) { throw new WorkerInstantiationException (); } /*Enche a lista de componentes de workers*/ workerComponentQueue = workerInitializer.buildWorkerComponentQueue(); /*instancia sorters*/ reporter.report(1,"MasterServant::start - Instanciando Sorters"); bigTableComponent = bigTableInitializer.buildBigTableComponent(); if (bigTableComponent == null) { // TODO: criar excecao da bigTable // throw new BigTableInstantiationException (); } // Connect big table components to workers // Implementation with only one big table component reporter.report(1, "MasterServant::start - Connecting to big table..."); connectWorkersToSorter(); /*instancia tarefas*/ reporter.report(1,"MasterServant::start - Instanciando Tarefas"); ioformat = workerInitializer.createIOFormatServant(ioformatClassName); if (ioformat == null) { throw new TaskInstantiationException (); } taskQueue = workerInitializer.buildTaskQueue(); if ((taskQueue == null) || (taskQueue.toArray().length == 0)) { throw new TaskInstantiationException (); } num_partitions = taskQueue.toArray().length; /* inicia escalonamento das tarefas map-reduce*/ reporter.report(1,"MasterServant::start - Iniciando escalonamento"); if (!schedule()) { //initializer.finish(); throw new StartFailureException(); } //initializer.finish(); } private void connectWorkersToSorter(){ Iterator<IComponent> iteWorker = workerComponentQueue.iterator(); Sorter sorter = SorterHelper.narrow(bigTableComponent.getFacetByName("Sorter")); sorter.setNumberOfReducers(num_reducers); IComponent workerComponent; while(iteWorker.hasNext()){ workerComponent = iteWorker.next(); IReceptacles workerReceptacles = IReceptaclesHelper.narrow(workerComponent.getFacetByName("infoReceptacle")); try { workerReceptacles.connect("Sorter", sorter); } catch (InvalidName e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvalidConnection e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (AlreadyConnected e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExceededConnectionLimit e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // private void connectBigTableToWorkers(){ // // Iterator<IComponent> iteWorker = workerComponentQueue.iterator(); // Iterator<IComponent> iteBigTable = bigTableComponentQueue.iterator(); // // IComponent workerComponent; // IComponent bigTableComponent; // // while(iteBigTable.hasNext()){ // bigTableComponent = iteBigTable.next(); // // IReceptacles bigTableReceptacles = IReceptaclesHelper.narrow(bigTableComponent.getFacetByName("infoReceptacle")); // while(iteWorker.hasNext()){ // workerComponent = iteWorker.next(); // try { // bigTableReceptacles.connect("Reducer", WorkerHelper.narrow(workerComponent.getFacetByName("Reducer"))); // } catch (InvalidName e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (InvalidConnection e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (AlreadyConnected e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (ExceededConnectionLimit e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } // // } // } public ORB getOrb(){ return orb; } public String[] getExecNodeList(){ return execNodeList; } public String getContainerName() { return containerName; } public int getNum_Mappers() { return num_mappers; } public int getNum_Reducers() { return num_reducers; } public int getNum_sorters() { return num_sorters; } public String getConfigFileName(){ return configFileName; } public Hashtable getWorkingOn(){ return workingOn; } public void addWorkerQueue(Worker w){ workerQueue.add(w); } /*public void addWorkerQueue(IComponent w){ workerQueue.add(w); }*/ public void addTaskQueue(Task t){ taskQueue.add(t); } public int getNum_Partitions (){ return num_partitions; } public MasterComponent getComponent(){ return myComp; } public String getMasterHost(){ return masterHost; } public String getMasterPort() { return masterPort; } public void setCurrentPhase(Phase phase) { currentStatus = phase; } public Phase getCurrentPhase() { return currentStatus; } public Reporter getReporter() { return reporter; } public IOFormat getIOFormat() { return ioformat; } public boolean getCombineFlag() { return combineFlag; } public String getInputFileName() { return inputFileName; } public boolean getJoinFlag() { return joinFlag; } public String getJoinFileName() { return joinFileName; } public IComponent getChannel(){ return channel; } }