Package org.apache.hadoop.hdfs.server.namenode

Source Code of org.apache.hadoop.hdfs.server.namenode.ImageSet

/**
* 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.server.namenode;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.net.URI;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.Transition;
import org.apache.hadoop.hdfs.server.common.Storage;
import org.apache.hadoop.hdfs.server.common.StorageErrorReporter;
import org.apache.hadoop.hdfs.server.common.StorageInfo;
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
import org.apache.hadoop.hdfs.server.common.Util;
import org.apache.hadoop.hdfs.server.namenode.FSImageStorageInspector.FSImageFile;
import org.apache.hadoop.hdfs.server.namenode.NNStorage.NameNodeDirType;
import org.apache.hadoop.hdfs.server.namenode.metrics.NameNodeMetrics;
import org.apache.hadoop.io.MD5Hash;

/**
* ImageSet provides an abstraction for all image locations on the namenode. The
* image managers can be local (FileImageManager), or some other locations
* (e.g., QJM, which is implemented by QuorumJournalManager). This set provides
* basic functionality for checkpointing (i.e., establishing write streams,
* saving md5 hash).
*/
public class ImageSet {

  static final Log LOG = LogFactory.getLog(ImageSet.class);

  private final List<ImageManager> imageManagers;
 
  private final NameNodeMetrics metrics;

  public ImageSet(FSImage fsImage, Collection<URI> fsDirs,
      Collection<URI> fsEditsDirs, NameNodeMetrics metrics) throws IOException {
    this.imageManagers = new ArrayList<ImageManager>();
    this.metrics = metrics;

    // get all IMAGE directories
    Iterator<StorageDirectory> it = fsImage.storage
        .dirIterator(NameNodeDirType.IMAGE);
    while (it.hasNext()) {
      StorageDirectory sd = it.next();
      validate(sd.getRoot(), fsDirs);
      imageManagers.add(new FileImageManager(sd, fsImage.storage));
    }
   
    // add all journal managers that store images
    List<JournalManager> nonFileJournalManagers = fsImage.editLog.getNonFileJournalManagers();
    for (JournalManager jm : nonFileJournalManagers) {
      if (jm instanceof ImageManager && jm.hasImageStorage()) {
        ImageManager im = (ImageManager) jm;
        validate(im.getURI(), fsDirs);
        imageManagers.add(im);
      }
    }
   
    // initialize metrics
    updateImageMetrics();
  }
 
  /**
   * For sanity checking that the given storage directory was configured.
   */
  private void validate(File root, Collection<URI> dirs) throws IOException {
    if (dirs == null)
      return;
    for (URI dir : dirs) {
      if (new File(dir.getPath()).getAbsolutePath().equals(
          root.getAbsolutePath())) {
        // we found the corresponding entry
        return;
      }
    }
    throwIOException("Error. Storage directory: " + root
        + " is not in the configured list of storage directories: " + dirs);
  }

  /**
   * For sanity checking that the given location was configured.
   */
  private void validate(URI location, Collection<URI> dirs) throws IOException {
    if (dirs != null && !dirs.contains(location)) {
      throwIOException("Error. Location: " + location
          + " is not in the configured list of storage directories: " + dirs);
    }
  }

  /**
   * Get the list of output streams for all underlying image managers, given the
   * checkpoint transaction id.
   */
  public synchronized List<OutputStream> getCheckpointImageOutputStreams(
      long imageTxId) throws IOException {
    List<OutputStream> list = new ArrayList<OutputStream>();
    for (ImageManager im : imageManagers) {
      list.add(im.getCheckpointOutputStream(imageTxId));
    }
    return list;
  }

  /**
   * Save digest in all underlying image managers, and rename the checkpoint
   * file. This will throw an exception if all image managers fail.
   */
  public synchronized void saveDigestAndRenameCheckpointImage(long txid,
      MD5Hash digest) throws IOException {
    for (ImageManager im : imageManagers) {
      if (im.saveDigestAndRenameCheckpointImage(txid, digest)) {
        // restore enabled state
        im.setImageDisabled(false);
      } else {
        // failed image
        im.setImageDisabled(true);
      }
    }
    checkImageManagers();
  }
 
  /**
   * Check if any image managers are available.
   */
  void checkImageManagers() throws IOException {
    updateImageMetrics();
    int numAvailable = 0;
    for (ImageManager im : imageManagers) {
      if (!im.isImageDisabled()) {
        numAvailable++;
      }
    }
    if (numAvailable == 0) {
      throwIOException("No image locations are available");
    }
  }
 
  void restoreImageManagers() {
    for (ImageManager im : imageManagers) {
      im.setImageDisabled(false);
    }
    updateImageMetrics();
  }
 
  /**
   * Count available image managers and update namenode metrics.
   */
  void updateImageMetrics() {
    if (metrics == null) {
      return;
    }
    int failedImageDirs = 0;
    for (ImageManager im : imageManagers) {
      if(im.isImageDisabled()) {
        failedImageDirs++;
      }
    }
    // update only images, journals are handled in JournalSet
    metrics.imagesFailed.set(failedImageDirs);
  }
 
  /**
   * Get the latest image from all non-file image managers.
   */
  public FSImageFile getLatestImageFromNonFileImageManagers()
      throws IOException {
    FSImageFile latestImage = null;
    for (ImageManager im : imageManagers) {
      if (!(im instanceof FileImageManager)) {
        FSImageFile current = im.getLatestImage();
        if (latestImage == null
            || latestImage.getCheckpointTxId() < current.getCheckpointTxId()) {
          latestImage = current;
        }
      }
    }
    return latestImage;
  }

  /**
   * Format the non-file images.
   */
  public void transitionNonFileImages(StorageInfo nsInfo, boolean checkEmpty,
      Transition transition, StartupOption startOpt)
      throws IOException {
    for (ImageManager im : imageManagers) {
      if (!(im instanceof FileImageManager)) {
        if (checkEmpty && im.hasSomeImageData()) {
          LOG.warn("Image " + im + " is not empty.");
          continue;
        }
        LOG.info(transition + " : " + im);
        im.transitionImage(nsInfo, transition, startOpt);
      }
    }
  }

  /**
   * Get the list of image managers
   */
  public List<ImageManager> getImageManagers() {
    return imageManagers;
  }
 
  /**
   * Get the list of non-file image managers.
   */
  List<ImageManager> getNonFileImageManagers() {
    List<ImageManager> nonFile = new ArrayList<ImageManager>();
    for (ImageManager im : imageManagers) {
      if (!(im instanceof FileImageManager)) {
        nonFile.add(im);
      }
    }
    return nonFile;
  }
 
  /**
   * Return the number of image managers in this set
   */
  public int getNumImageManagers() {
    return imageManagers.size();
  }

  /**
   * Convert given list of files to a list of output streams.
   */
  public static List<OutputStream> convertFilesToStreams(File[] localPaths,
      Storage dstStorage, String str) throws IOException {
    List<OutputStream> outputStreams = new ArrayList<OutputStream>();
    if (localPaths != null) {
      for (File f : localPaths) {
        try {
          if (f.exists()) {
            LOG.warn("Overwriting existing file " + f
                + " with file downloaded form " + str);
          }
          outputStreams.add(new FileOutputStream(f));
        } catch (IOException ioe) {
          LOG.warn("Unable to download file " + f, ioe);
          if (dstStorage != null
              && (dstStorage instanceof StorageErrorReporter)) {
            ((StorageErrorReporter) dstStorage).reportErrorOnFile(f);
          }
        }
      }

      if (outputStreams.isEmpty()) {
        throw new IOException("Unable to download to any storage directory");
      }
    }
    return outputStreams;
  }
 
  private void throwIOException(String msg) throws IOException {
    LOG.error(msg);
    throw new IOException(msg);
  }
 
  void reportErrorsOnImageManager(StorageDirectory badSD) {
    try {
      for (ImageManager im : imageManagers) {
        if (Util.fileAsURI(badSD.getRoot()).equals(im.getURI())) {
          im.setImageDisabled(true);
        }
      }
    } catch (IOException e) {
      LOG.info("Error when reporting problems with : " + badSD.getRoot());
    }
  }
}
TOP

Related Classes of org.apache.hadoop.hdfs.server.namenode.ImageSet

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.