Package org.apache.hadoop.hdfs.notifier.benchmark

Source Code of org.apache.hadoop.hdfs.notifier.benchmark.TxnConsumer

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.hadoop.hdfs.notifier.benchmark;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.notifier.EventType;
import org.apache.hadoop.hdfs.notifier.NamespaceNotification;
import org.apache.hadoop.hdfs.notifier.NamespaceNotifierClient;
import org.apache.hadoop.hdfs.notifier.NamespaceNotifierClient.NotConnectedToServerException;
import org.apache.hadoop.hdfs.notifier.NamespaceNotifierClient.WatchAlreadyPlacedException;
import org.apache.hadoop.hdfs.notifier.NotifierUtils;
import org.apache.hadoop.hdfs.notifier.TransactionIdTooOldException;
import org.apache.hadoop.hdfs.notifier.Watcher;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.RunningJob;
import org.apache.hadoop.mapred.TextInputFormat;
import org.apache.hadoop.mapred.TextOutputFormat;

public class TxnConsumer {
 
  final static Log LOG = LogFactory.getLog(TxnConsumer.class);
 
  public static String TEST_FILE_LABEL = "test.file.label";
  public static String TEST_DIR_LABEL = "test.dir.label";
  public static String SERVER_ADDR_STR_LABEL = "server.addr.str.label";
  public static String SERVER_PORT_STR_LABEL = "server.port.str.label";
 
  private static final String NUM_MAPPERS_KEY = "-numtasks";
  private static final String NUM_SUBDIRS_KEY = "-numsubdirs";
  private static final String NUM_FILES_SUB_DIR_KEY = "-numfiles";
  private static final String NUM_ROUND_KEY = "-round";
  private static final String WORKPLACE_KEY = "-workplace";
  private static final String NOTIFIER_SERVER_ADDR_KEY = "-notifieraddr";
  private static final String NOTIFIER_SERVER_PORT_KEY = "-notifierport";
 
  private static final int SERVER_DEFAULT_PORT = 31000;
  private static final int CLIENT_PROT = 32000;
 
  private static int numMappers = 10;
  private static int numSubDirs = 100;
  private static int numFilesEachSubDirs = 100;
  private static int round = 100;
  private static String workplace = "";
 
  // the namespace notifier server address string
  // sample: address1,address2
  private static String notifierServerAddrStr = "";
  // the namespace notifier server port string
  // sample: port1, port2
  private static String notifierServerPortStr = "";
 
  private Configuration conf;
 
  public TxnConsumer(Configuration conf) {
    this.conf = conf;
  }
 
  static class ConsumerMapper implements Mapper<LongWritable, Text, Text, Text> {

    private JobConf jobConf;
    private String workplace;
    private NamespaceNotifierClient myClient;
   
    private long expectedTotal;
    private long expectedFileAdd;
    private long expectedFileClose;
    private long expectedDirAdd;
    private long expectedNodeDelete;
   
    private static List<String> notifierServerAddrList;
    private static List<Integer> notifierServerPortList;

    @Override
    public void configure(JobConf job) {
      this.jobConf = job;
      this.workplace = jobConf.get(TEST_DIR_LABEL);
     
      expectedFileAdd = round * numSubDirs * numFilesEachSubDirs;
      expectedFileClose = expectedFileAdd;
      expectedDirAdd = round * numSubDirs;
      expectedNodeDelete = expectedFileAdd + expectedDirAdd;
      expectedTotal = expectedFileAdd + expectedFileClose + expectedDirAdd + expectedNodeDelete;
     
      String serverAddrStr = jobConf.get(NOTIFIER_SERVER_ADDR_KEY);
      String serverPortStr = jobConf.get(NOTIFIER_SERVER_PORT_KEY);
     
      LOG.info("serverAddr: " + serverAddrStr + ", serverPort: " + serverPortStr);
     
      notifierServerAddrList = Arrays.asList(serverAddrStr.split(","));
      int index = 0;
      notifierServerPortList = new ArrayList<Integer>(notifierServerAddrList.size());
      if (!notifierServerPortStr.trim().isEmpty()) {
        List tmpList = Arrays.asList(serverPortStr.split(","));
        while (index < notifierServerAddrList.size() && index < tmpList.size()) {
          notifierServerPortList.add(Integer.valueOf((String) tmpList.get(index++)));
        }
      }
     
      while (index++ < notifierServerAddrList.size()) {
        notifierServerPortList.add(SERVER_DEFAULT_PORT);
      }
    }

    @Override
    public void close() throws IOException {
     
    }

    @Override
    public void map(LongWritable key, Text value,
        OutputCollector<Text, Text> output, Reporter reporter)
        throws IOException {
      workplace += value.toString();
     
      SimpleWatcher myWatcher = new SimpleWatcher();
     
      try {
        myClient = new NamespaceNotifierClient(myWatcher,
            notifierServerAddrList, notifierServerPortList, CLIENT_PROT);
     
        Thread clientThread = new Thread(myClient);
        clientThread.start();
       
        LOG.info("Expected number of notifications:\nTotal Notifications: " + expectedTotal+
          "\nAdd_file Notifications: " + expectedFileAdd +
          "\nClose_file Notifications: " + expectedFileClose +
          "\nAdd_dir Notifications: " + expectedDirAdd +
          "\nNode_delete Notifications: " + expectedNodeDelete);
       
        while (!getAllExpectedNotis(myWatcher)) {
          countReceivedNotis(myWatcher);
          Thread.sleep(10000);
          reporter.progress();
        }
       
        output.collect(value, new Text(myWatcher.toString()));
       
      } catch (Exception e) {
        LOG.error("Got error: " + e.getMessage(), e);
        throw new IOException (e);
      }
    }
   
    private boolean getAllExpectedNotis(SimpleWatcher watcher) {
     
      return (watcher.totalNoti.get() == expectedTotal)
          && (watcher.totalAddFile.get() == expectedFileAdd)
          && (watcher.totalCloseFile.get() == expectedFileClose)
          && (watcher.totalAddDir.get() == expectedDirAdd)
          && (watcher.totalDeleteNode.get() == expectedNodeDelete);
    }
   
    private void countReceivedNotis(SimpleWatcher watcher) {
      LOG.info("Received: \nTotal Notifications: " + watcher.totalNoti.get() +
          "\nAdd_file Notifications: " + watcher.totalAddFile.get() +
          "\nClose_file Notifications: " + watcher.totalCloseFile.get() +
          "\nAdd_dir Notifications: " + watcher.totalAddDir.get() +
          "\nNode_delete Notifications: " + watcher.totalDeleteNode.get());
    }
   
    private void placeWatch() throws TransactionIdTooOldException,
          NotConnectedToServerException, InterruptedException,
          WatchAlreadyPlacedException {
      String path = new Path(workplace).toUri().getPath();
      myClient.placeWatch(path, EventType.FILE_ADDED, -1);
      myClient.placeWatch(path, EventType.FILE_CLOSED, -1);
      myClient.placeWatch(path, EventType.DIR_ADDED, -1);
      myClient.placeWatch(path, EventType.NODE_DELETED, -1);
    }
   
    public class SimpleWatcher implements Watcher {
      public volatile boolean connected = false;
      public AtomicLong totalNoti = new AtomicLong();
      public AtomicLong totalAddFile = new AtomicLong();
      public AtomicLong totalCloseFile = new AtomicLong();
      public AtomicLong totalAddDir = new AtomicLong();
      public AtomicLong totalDeleteNode = new AtomicLong();
     
      @Override
      public void handleNamespaceNotification(NamespaceNotification notification) {
        LOG.info("Received notification: " + NotifierUtils.asString(notification));
        totalNoti.incrementAndGet();
       
        if (notification.type == EventType.FILE_ADDED.getByteValue()) {
          totalAddFile.incrementAndGet();
        } else if (notification.type == EventType.FILE_CLOSED.getByteValue()) {
          totalCloseFile.incrementAndGet();
        } else if (notification.type == EventType.NODE_DELETED.getByteValue()) {
          totalDeleteNode.incrementAndGet();
        } else if (notification.type == EventType.DIR_ADDED.getByteValue()) {
          totalAddDir.incrementAndGet();
        }
      }

      @Override
      public void connectionFailed() {
        LOG.warn("Connection failed.");
        connected = false;
      }

      @Override
      public void connectionSuccesful() {
        LOG.info("Connection successful.");
        connected = true;
       
        try {
          placeWatch();
          LOG.info("Watch placed.");
        } catch (TransactionIdTooOldException e) {
          LOG.warn(e.getMessage(), e);
        } catch (NotConnectedToServerException e) {
          LOG.warn(e.getMessage(), e);
        } catch (InterruptedException e) {
          LOG.warn(e.getMessage(), e);
        } catch (WatchAlreadyPlacedException e) {
          LOG.warn(e.getMessage(), e);
        }
      }
     
      public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("total Notification: ").append(totalNoti.get());
        sb.append("total File Add: ").append(totalAddFile.get());
        sb.append("total File Close: ").append(totalCloseFile.get());
        sb.append("total Add Dir: ").append(totalAddDir.get());
        sb.append("total Delete Node: ").append(totalDeleteNode.get());
       
        return sb.toString();
      }
    }
  }
 
  static class ConsumerReducer implements Reducer<Text, Text, Text, Text> {
    @Override
    public void configure(JobConf job) {
    }

    @Override
    public void close() throws IOException {
    }

    @Override
    public void reduce(Text key, Iterator<Text> values,
        OutputCollector<Text, Text> output, Reporter reporter)
        throws IOException {
      while (values.hasNext()) {
        output.collect(key, values.next());
      }
    }
  }
 
 
  private static void createSplitFiles(Configuration conf, Path splitDir)
      throws IOException {
    FileSystem fs = splitDir.getFileSystem(conf);
    for (int i = 0; i < numMappers; i++) {
      String mapperDir = "mapper" + i;
      Path path = new Path(splitDir, mapperDir);
      OutputStream os = fs.create(path, true);
      os.write(mapperDir.getBytes());
      os.close();
    }
  }
 
  private JobConf createJobConf(Configuration conf2) throws IOException {
    JobConf jobConf = new JobConf(conf);
    String jobName = "transaction_consumer";
    jobConf.setJobName(jobName);
   
    String splitDir = workplace + "split/";
   
    jobConf.set(TEST_DIR_LABEL, workplace);
    jobConf.set(NOTIFIER_SERVER_ADDR_KEY, notifierServerAddrStr);
    jobConf.set(NOTIFIER_SERVER_PORT_KEY, notifierServerPortStr);
   
    jobConf.setMapSpeculativeExecution(false);
    jobConf.setReduceSpeculativeExecution(false);
   
    jobConf.setJarByClass(TxnConsumer.class);
    jobConf.setMapperClass(ConsumerMapper.class);
    jobConf.setReducerClass(ConsumerReducer.class);
   
    jobConf.setMapOutputKeyClass(Text.class);
    jobConf.setMapOutputValueClass(Text.class);
    jobConf.setOutputKeyClass(Text.class);
    jobConf.setOutputValueClass(Text.class);
    jobConf.setInputFormat(TextInputFormat.class);
    jobConf.setOutputFormat(TextOutputFormat.class);
   
    FileInputFormat.addInputPath(jobConf, new Path(splitDir));
    Random random = new Random();
    FileOutputFormat.setOutputPath(jobConf, new Path(workplace, "output" + random.nextLong()));
   
    jobConf.setNumMapTasks(numMappers);
   
    createSplitFiles(conf, new Path(splitDir));
   
    return jobConf;
  }
 
  private void printUsage() {
    System.out.println("NotifierShell -consumetxn -workplace workplace " +
              NOTIFIER_SERVER_ADDR_KEY + " notifierAddrList " +
              "[" + NOTIFIER_SERVER_PORT_KEY + " notifierPortList] " +
              "[" + NUM_MAPPERS_KEY + " numMappers] " +
              "[" + NUM_SUBDIRS_KEY + " numSubDirs] " +
              "[" + NUM_FILES_SUB_DIR_KEY + " numFiles] " +
              "[" + NUM_ROUND_KEY + " numRound]");
  }
 
  public void start(String[] args, int startIndex) throws IOException {
    try {
      while(startIndex < args.length) {
        String cmd = args[startIndex ++];
        if (cmd.equals(NUM_MAPPERS_KEY)) {
          numMappers = Integer.valueOf(args[startIndex ++]);
        } else if (cmd.equals(NUM_SUBDIRS_KEY)) {
          numSubDirs = Integer.valueOf(args[startIndex ++]);
        } else if (cmd.equals(NUM_FILES_SUB_DIR_KEY)) {
          numFilesEachSubDirs = Integer.valueOf(args[startIndex ++]);
        } else if (cmd.equals(NUM_ROUND_KEY)) {
          round = Integer.valueOf(args[startIndex ++]);
        } else if (cmd.equals(WORKPLACE_KEY)) {
          workplace = args[startIndex ++];
        } else if (cmd.equals(NOTIFIER_SERVER_ADDR_KEY)) {
          notifierServerAddrStr = args[startIndex ++];
        } else if (cmd.equals(NOTIFIER_SERVER_PORT_KEY)) {
          notifierServerPortStr = args[startIndex ++];
        } else {
          printUsage();
          System.exit(-1);
        }
      }
    } catch (Exception e) {
      printUsage();
      System.exit(-1);
    }
   
    if (workplace.trim().isEmpty() ||
        notifierServerAddrStr.trim().isEmpty()) {
      printUsage();
      System.exit(-1);
    }
   
    if (!workplace.endsWith(Path.SEPARATOR)) {
      workplace += Path.SEPARATOR;
    }
   
    JobConf jobConf = createJobConf(conf);
   
    JobClient client = new JobClient(jobConf);
    RunningJob runningJob = client.submitJob(jobConf);
    runningJob.waitForCompletion();
  }
}
TOP

Related Classes of org.apache.hadoop.hdfs.notifier.benchmark.TxnConsumer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.