现在的位置: 首页 > 综合 > 正文

HDFS之StorageInfo

2018年01月21日 ⁄ 综合 ⁄ 共 10852字 ⁄ 字号 评论关闭

StorageInfo是NameNode,DataNode 和JNStorage Storage的基类,其包含6个比较重要的字段:

public int   layoutVersion;   // namenode和datanode怎么在磁盘上存储信息的布局版本号
  public int   namespaceID;     //文件系统的ID
  public String clusterID;      // 集群的ID
  public long  cTime;           // 文件系统创建的时间
 protected final NodeType storageType; // 存储的类型,为(NAMENODE,DATANODE,JOURNAL_NODE)三种
protected static final String STORAGE_FILE_VERSION    = "VERSION";

namespaceID

此值是namenode执行format命令的时候分配的值,为一个int值,为一个非零的随机数,以后不会发生变化,当datanodes注册的时候,他们会收到namespaceID作为注册id,当每次datanode与namenode通信的时候,namenode都会检查此值,如果不认识此id,将会被拒绝。namespaceID被所有文件系统的组件所共享。

此值是有namenode在NNStorage(继承之StorageInfo)类中生成的,具体的生成方法如下:

private static int newNamespaceID() {
    int newID = 0;
    while(newID == 0)
      newID = DFSUtil.getRandom().nextInt(0x7FFFFFFF);  // use 31 bits only
    return newID;
  }

clusterID

clusterID的生成方式为:CID+一个随机的UUID

  public static String newClusterID() {
    return "CID-" + UUID.randomUUID().toString();
  }

layoutVersion

在format的时候,来之NameNodeLayoutVersionEDITLOG_LENGTH(-56, "Add length field to every edit log op");,所以目前固定值为-56

LayoutVersion:

/**
   * Enums for features that change the layout version before rolling
   * upgrade is supported.
   * <br><br>
   * To add a new layout version:
   * <ul>
   * <li>Define a new enum constant with a short enum name, the new layout version
   * and description of the added feature.</li>
   * <li>When adding a layout version with an ancestor that is not same as
   * its immediate predecessor, use the constructor where a specific ancestor
   * can be passed.
   * </li>
   * </ul>
   */
  public static enum Feature implements LayoutFeature {
    NAMESPACE_QUOTA(-16, "Support for namespace quotas"),
    FILE_ACCESS_TIME(-17, "Support for access time on files"),
    DISKSPACE_QUOTA(-18, "Support for disk space quotas"),
    STICKY_BIT(-19, "Support for sticky bits"),
    APPEND_RBW_DIR(-20, "Datanode has \"rbw\" subdirectory for append"),
    ATOMIC_RENAME(-21, "Support for atomic rename"),
    CONCAT(-22, "Support for concat operation"),
    SYMLINKS(-23, "Support for symbolic links"),
    DELEGATION_TOKEN(-24, "Support for delegation tokens for security"),
    FSIMAGE_COMPRESSION(-25, "Support for fsimage compression"),
    FSIMAGE_CHECKSUM(-26, "Support checksum for fsimage"),
    REMOVE_REL13_DISK_LAYOUT_SUPPORT(-27, "Remove support for 0.13 disk layout"),
    EDITS_CHESKUM(-28, "Support checksum for editlog"),
    UNUSED(-29, "Skipped version"),
    FSIMAGE_NAME_OPTIMIZATION(-30, "Store only last part of path in fsimage"),
    RESERVED_REL20_203(-31, -19, "Reserved for release 0.20.203", true,
        DELEGATION_TOKEN),
    RESERVED_REL20_204(-32, -31, "Reserved for release 0.20.204", true),
    RESERVED_REL22(-33, -27, "Reserved for release 0.22", true),
    RESERVED_REL23(-34, -30, "Reserved for release 0.23", true),
    FEDERATION(-35, "Support for namenode federation"),
    LEASE_REASSIGNMENT(-36, "Support for persisting lease holder reassignment"),
    STORED_TXIDS(-37, "Transaction IDs are stored in edits log and image files"),
    TXID_BASED_LAYOUT(-38, "File names in NN Storage are based on transaction IDs"),
    EDITLOG_OP_OPTIMIZATION(-39,
        "Use LongWritable and ShortWritable directly instead of ArrayWritable of UTF8"),
    OPTIMIZE_PERSIST_BLOCKS(-40,
        "Serialize block lists with delta-encoded variable length ints, " +
        "add OP_UPDATE_BLOCKS"),
    RESERVED_REL1_2_0(-41, -32, "Reserved for release 1.2.0", true, CONCAT),
    ADD_INODE_ID(-42, -40, "Assign a unique inode id for each inode", false),
    SNAPSHOT(-43, "Support for snapshot feature"),
    RESERVED_REL1_3_0(-44, -41,
        "Reserved for release 1.3.0", true, ADD_INODE_ID, SNAPSHOT),
    OPTIMIZE_SNAPSHOT_INODES(-45, -43,
        "Reduce snapshot inode memory footprint", false),
    SEQUENTIAL_BLOCK_ID(-46, "Allocate block IDs sequentially and store " +
        "block IDs in the edits log and image files"),
    EDITLOG_SUPPORT_RETRYCACHE(-47, "Record ClientId and CallId in editlog to "
        + "enable rebuilding retry cache in case of HA failover"),
    EDITLOG_ADD_BLOCK(-48, "Add new editlog that only records allocation of "
        + "the new block instead of the entire block list"),
    ADD_DATANODE_AND_STORAGE_UUIDS(-49, "Replace StorageID with DatanodeUuid."
        + " Use distinct StorageUuid per storage directory."),
    ADD_LAYOUT_FLAGS(-50, "Add support for layout flags."),
    CACHING(-51, "Support for cache pools and path-based caching"),
    // Hadoop 2.4.0
    PROTOBUF_FORMAT(-52, "Use protobuf to serialize FSImage"),
    EXTENDED_ACL(-53, "Extended ACL"),
    RESERVED_REL2_4_0(-54, -51, "Reserved for release 2.4.0", true,
        PROTOBUF_FORMAT, EXTENDED_ACL);

NameNodeLayoutVersion:

ROLLING_UPGRADE(-55, -53, "Support rolling upgrade", false),
 EDITLOG_LENGTH(-56, "Add length field to every edit log op");

DataNodeLayoutVersion:

FIRST_LAYOUT(-55, -53, "First datenode layout", false);

cTime

目前为0

storageType

目前分为

    NAME_NODE,
    DATA_NODE,
    JOURNAL_NODE;

三个值。

STORAGE_FILE_VERSION

上面的几个字段保存的文件名称,目前为VERSION

VERSION文件内容例如:

#Fri Jul 18 15:31:08 CST 2014
namespaceID=2137650844
clusterID=CID-87f4e5d6-8a7a-45da-a6a6-eba8ffecbebb
cTime=0
storageType=NAME_NODE
blockpoolID=BP-1028050584-192.168.1.110-1405668065552
layoutVersion=-56

源代码:

public class StorageInfo {

  public int   layoutVersion;   // layout version of the storage data
  public int   namespaceID;     // id of the file system
  public String clusterID;      // id of the cluster
  public long  cTime;           // creation time of the file system state

  protected final NodeType storageType; // Type of the node using this storage

  protected static final String STORAGE_FILE_VERSION    = "VERSION";
 
  public StorageInfo(NodeType type) {
    this(0, 0, "", 0L, type);
  }

  public StorageInfo(int layoutV, int nsID, String cid, long cT, NodeType type) {
    layoutVersion = layoutV;
    clusterID = cid;
    namespaceID = nsID;
    cTime = cT;
    storageType = type;
  }
 
  public StorageInfo(StorageInfo from) {
    this(from.layoutVersion, from.namespaceID, from.clusterID, from.cTime,
        from.storageType);
  }

  /**
   * Layout version of the storage data.
   */
  public int    getLayoutVersion(){ return layoutVersion; }

  /**
   * Namespace id of the file system.<p>
   * Assigned to the file system at formatting and never changes after that.
   * Shared by all file system components.
   */
  public int    getNamespaceID()  { return namespaceID; }

  /**
   * cluster id of the file system.<p>
   */
  public String    getClusterID()  { return clusterID; }
 
  /**
   * Creation time of the file system state.<p>
   * Modified during upgrades.
   */
  public long   getCTime()        { return cTime; }
 
  public void   setStorageInfo(StorageInfo from) {
    layoutVersion = from.layoutVersion;
    clusterID = from.clusterID;
    namespaceID = from.namespaceID;
    cTime = from.cTime;
  }

  public boolean versionSupportsFederation(
      Map<Integer, SortedSet<LayoutFeature>> map) {
    return LayoutVersion.supports(map, LayoutVersion.Feature.FEDERATION,
        layoutVersion);
  }
 
  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("lv=").append(layoutVersion).append(";cid=").append(clusterID)
    .append(";nsid=").append(namespaceID).append(";c=").append(cTime);
    return sb.toString();
  }
 
  public String toColonSeparatedString() {
    return Joiner.on(":").join(
        layoutVersion, namespaceID, cTime, clusterID);
  }

  /**
   * Get common storage fields.
   * Should be overloaded if additional fields need to be get.
   *
   * @param props
   * @throws IOException
   */
  protected void setFieldsFromProperties(
      Properties props, StorageDirectory sd) throws IOException {
    setLayoutVersion(props, sd);
    setNamespaceID(props, sd);
    setcTime(props, sd);
    setClusterId(props, layoutVersion, sd);
    checkStorageType(props, sd);
  }

  /** Validate and set storage type from {@link Properties}*/
  protected void checkStorageType(Properties props, StorageDirectory sd)
      throws InconsistentFSStateException {
    if (storageType == null) { //don't care about storage type
      return;
    }
    NodeType type = NodeType.valueOf(getProperty(props, sd, "storageType"));
    if (!storageType.equals(type)) {
      throw new InconsistentFSStateException(sd.root,
          "Incompatible node types: storageType=" + storageType
          + " but StorageDirectory type=" + type);
    }
  }
 
  /** Validate and set ctime from {@link Properties}*/
  protected void setcTime(Properties props, StorageDirectory sd)
      throws InconsistentFSStateException {
    cTime = Long.parseLong(getProperty(props, sd, "cTime"));
  }

  /** Validate and set clusterId from {@link Properties}*/
  protected void setClusterId(Properties props, int layoutVersion,
      StorageDirectory sd) throws InconsistentFSStateException {
    // Set cluster ID in version that supports federation
    if (LayoutVersion.supports(getServiceLayoutFeatureMap(),
        Feature.FEDERATION, layoutVersion)) {
      String cid = getProperty(props, sd, "clusterID");
      if (!(clusterID.equals("") || cid.equals("") || clusterID.equals(cid))) {
        throw new InconsistentFSStateException(sd.getRoot(),
            "cluster Id is incompatible with others.");
      }
      clusterID = cid;
    }
  }
 
  /** Validate and set layout version from {@link Properties}*/
  protected void setLayoutVersion(Properties props, StorageDirectory sd)
      throws IncorrectVersionException, InconsistentFSStateException {
    int lv = Integer.parseInt(getProperty(props, sd, "layoutVersion"));
    if (lv < getServiceLayoutVersion()) { // future version
      throw new IncorrectVersionException(getServiceLayoutVersion(), lv,
          "storage directory " + sd.root.getAbsolutePath());
    }
    layoutVersion = lv;
  }
 
  /** Validate and set namespaceID version from {@link Properties}*/
  protected void setNamespaceID(Properties props, StorageDirectory sd)
      throws InconsistentFSStateException {
    int nsId = Integer.parseInt(getProperty(props, sd, "namespaceID"));
    if (namespaceID != 0 && nsId != 0 && namespaceID != nsId) {
      throw new InconsistentFSStateException(sd.root,
          "namespaceID is incompatible with others.");
    }
    namespaceID = nsId;
  }

  public int getServiceLayoutVersion() {
    return storageType == NodeType.DATA_NODE ? HdfsConstants.DATANODE_LAYOUT_VERSION
        : HdfsConstants.NAMENODE_LAYOUT_VERSION;
  }

  public Map<Integer, SortedSet<LayoutFeature>> getServiceLayoutFeatureMap() {
    return storageType == NodeType.DATA_NODE? DataNodeLayoutVersion.FEATURES
        : NameNodeLayoutVersion.FEATURES;
  }

  protected static String getProperty(Properties props, StorageDirectory sd,
      String name) throws InconsistentFSStateException {
    String property = props.getProperty(name);
    if (property == null) {
      throw new InconsistentFSStateException(sd.root, "file "
          + STORAGE_FILE_VERSION + " has " + name + " missing.");
    }
    return property;
  }
 
  public static int getNsIdFromColonSeparatedString(String in) {
    return Integer.parseInt(in.split(":")[1]);
  }
 
  public static String getClusterIdFromColonSeparatedString(String in) {
    return in.split(":")[3];
  }
 
  /**
   * Read properties from the VERSION file in the given storage directory.
   */
  public void readProperties(StorageDirectory sd) throws IOException {
    Properties props = readPropertiesFile(sd.getVersionFile());
    setFieldsFromProperties(props, sd);
  }
 
  /**
   * Read properties from the the previous/VERSION file in the given storage directory.
   */
  public void readPreviousVersionProperties(StorageDirectory sd)
      throws IOException {
    Properties props = readPropertiesFile(sd.getPreviousVersionFile());
    setFieldsFromProperties(props, sd);
  }

  public static Properties readPropertiesFile(File from) throws IOException {
    RandomAccessFile file = new RandomAccessFile(from, "rws");
    FileInputStream in = null;
    Properties props = new Properties();
    try {
      in = new FileInputStream(file.getFD());
      file.seek(0);
      props.load(in);
    } finally {
      if (in != null) {
        in.close();
      }
      file.close();
    }
    return props;
  }
}

抱歉!评论已关闭.