Hadoop 系统管理 (Administering Hadoop)

1.  HDFS

-----------------------------------------------------------------------------------------------------------------------------------------------------------



1.1 永久性数据结构( Persistent Data Structures )
----------------------------------------------------------------------------------------------------------------------------------------------------------
作为管理员,对 HDFS 组件 ———— the namenode, the secondary namenode, and the datanodes 等在磁盘上如何组织它们的持久化数据有一个基本理解是非常重要的。


    Namenode 的目录结构( Namenode directory structure)
    ------------------------------------------------------------------------------------------------------------------------------------------------------
    一个运行的 namenode 具有如下的目录结构:
    
        ${dfs.namenode.name.dir}/
        ├── current
        │ ├── VERSION
        │ ├── edits_0000000000000000001-0000000000000000019
        │ ├── edits_inprogress_0000000000000000020
        │ ├── fsimage_0000000000000000000
        │ ├── fsimage_0000000000000000000.md5
        │ ├── fsimage_0000000000000000019
        │ ├── fsimage_0000000000000000019.md5
        │ └── seen_txid
        └── in_use.lock

    dfs.namenode.name.dir 属性是一个目录列表,每个目录里镜像为相同的内容。这种机制提供了快速复原能力,即系统弹性(resilience),特别是如果其中一个
    一个目录是由 NFS 挂载的,建议这样做。
    
    VERSION 文件是一个 Java 属性文件,包含当前运行的 HDFS 版本信息,典型文件包含如下内容:
        
        #Mon Sep 29 09:54:36 BST 2014
        namespaceID=1342387246
        clusterID=CID-01b5c398-959c-4ea8-aae6-1e0d9bd8b142
        cTime=0
        storageType=NAME_NODE
        blockpoolID=BP-526805057-127.0.0.1-1411980876842
        layoutVersion=-57

    layoutVersion    :是一个负整数,定义 HDFS 的持久化数据结构的版本。这个版本号与 Hadoop 分发包的发布版本号没有关系。当布局发生变化时,版本号递减(例如,
                         -57 之后是 -58),此时, HDFS 需要升级,因为一个新的 namenode (or datanode) 不会在一个旧版本的存储布局上工作。
    namespaceID        :是一个文件系统名称空间的唯一标识符,在 namenode 首次格式化时创建。
    clusterID         :是 HDFS 集群作为一个整体的唯一标识符,这对 HDFS 联邦( federation ) 非常重要,在其中,集群由多个名称空间组成,每个名称空间由一个
                        namenode 管理。
    blockpoolID     :是块池的( block pool )唯一标识符,块池包含由这个 namenode 管理的名称空间内所有的文件。
    cTime             :标记 namenode 存储系统的创建时间。刚刚格式化的存储系统,这个属性值为 0 ,但文件系统升级后,这个值会更新为新时间戳。
    storageType        :指明存储目录包含的是 namenode 数据结构
    

    in_use.lock 文件是一个锁文件, namenode 使用该锁文件锁定存储目录,阻止另外一个 namenode 实例同时使用同一存储目录运行(有可能造成数据损坏)。
    
    namenode 存储目录内其他文件文件还有 edits 文件、 fsimage 文件以及 seen_txid  
    
    

    文件系统映像和编辑日志( The filesystem image and edit log )
    ---------------------------------------------------------------------------------------------------------------------------------------------------------
    文件系统客户端执行一个写操作(例如创建或移动一个文件)时,这些操作事务( transaction )会首先记录到编辑日志( edit log )。 namenode 在内存中(in-memory)
    维护文件系统的元数据,编辑日志被修改后,相应的元数据信息随之更新。内存中的元数据用于为读请求提供服务。

    概念上来讲,编辑日志是一个单一实体( a single entity ),但它表现为磁盘上的多个文件( as a number of files on disk )。每个文件被称为一个分段(a segment),
    并且文件名有一个 edits 前缀和一个后缀指明它包含的事务ID( transaction IDs ),例如, edits_inprogress_0000000000000000020
    同一时刻只有一个文件是打开的用于写操作,并且在每个事务完成之后,返回给客户端一个成功代码( success code )之前 刷新或同步磁盘( flushed or syned )
    对于有多个存储目录的 namenode ,写操作必须在返回成功代码之前刷新或同步到每个副本。这确保了任何操作不会因为机器故障而丢失。

    每个 fsimage 文件是一个完整的永久性文件系统元数据检查点( checkpoint ),文件名后缀指明在镜像中最后的事务。然而,并非每次文件系统的写操作都会更新 fsimage
    文件,因为写出到 fsimage 文件,会增大它的文件大小至几个GB ,会非常慢。这不会影响系统的弹性恢复能力,如果 namenode 发生故障,可以通过从磁盘载入最新的
    fsimage 到内存中重新构造元数据的最新状态,然后从编辑日志中记录的相关点向前执行各个事务。事实上, namenode 启动阶段正是这么做的。

    
        提示:
        ------------------------------------------------------------------------------------------------------------------------------------------------------
        每个 fsimage 文件包含了文件系统中所有的目录和文件 inode 的序列化形式。每个 inode 是一个文件或目录的元数据的内部表现,对于文件来说,包含了这样一些信息,
        文件的复本级别(replication level),修改和访问时间,访问许可权限(access permission),数据块大小(block size),以及组成文件的数据块信息(the blocks
        the file is made up of)对于目录来说,存储目录的修改时间,许可权限,以及限额(quota)等元数据信息。
        
        fsimage 不记录数据块存储的 datanode 信息,而是由 namenode 在内存中保持 datanode 的块映射信息,datanode 加入到集群时,由 namenode 向 datanode 索取其块
        列表来构建块映射信息,之后, namenode 定期征询 datanode 以确保 namenode 的块映射信息是最新的。
    
    
    编辑日志会无限制增长(尽管它被分散到几个物理上的 edits 文件),尽管这在 namenode 运行时不会对系统造成影响,但在 namenode 重新启动时,会花费很长时间来应用
    编辑日志中的每个事务。在此期间,文件系统会处于离线状态,这通常是不理想的。
    
    解决方案是运行辅助名称节点(secondary namenode), 目的是为主名称节点(primary namenode)的内存中文件系统元数据创建检查点(produce checkpoints)。
    检查点的创建过程如下:
    
        1. secondary namenode 请求 primary namenode 轮转( roll )它正在使用的(in-process) 编辑(edits)文件,将新的编辑内容(edits)写入到新的文件中。
            primary namenode 也更新所有存储目录中的 seen_txid 文件。
        2. secondary namenode 从 primary namenode 获取最新的 fsimage 和 edits 文件(使用 HTTP GET 方法)
        3. secondary namenode 将 fsimage 文件加载到内存,从 edits 文件应用每一个事务(applies each transaction from edits),然后创建一个新的合并的 fsimage 文件。
        4. secondary namenode 将这个新的 fsimage 文件发送回 primary namenode (使用 HTTP PUT 方法),primary namenode 把它保存为一个临时的 .ckpt 文件。
        5. primary namenode 重命名这个临时的 fsimage 文件以使之可用。
        
    这个过程结束后,primary namenode 拥有一个最新的 fsimage 文件和一个很短的使用中的(in-process)编辑文件(edits file),这个文件没必要是空的,因为在检查点创建过程中,
    可能会收到一些编辑。在 namenode 安全模式下,管理员可以手动运行这个过程创建检查点,命令:
    
        hdfs dfsadmin -saveNamespace
        
    这个过程清晰地解释了为什么 secondary namenode 和 primary namenode 有相近的内存需求(因为它将 fsimage 文件加载到内存中),也是在大型集群中secondary namenode需要
    一台专用机器的原因。
    
    检查点创建调度受两个配置参数控制:
    secondary namenode 每隔小时(由 dfs.namenode.checkpoint.period 属性设置,以秒为单位,默认为3600秒,即 1 小时)创建检查点。或者更早,如果编辑日志自从上个检查点
    之后有多达一百万个事务(由 dfs.namenode.checkpoint.txns 属性控制,默认值为 1000000), 即使没有到达 1 小时,也会创建检查点。检查事务数量每分钟进行一次,由
    dfs.namenode.checkpoint.check.period 属性控制,单位为秒,默认 60 秒,即 1 分钟。
    
    
    
        
    Secondary namenode 的目录结构( Secondary namenode directory structure)
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------    
    Secondary namenode 的检查点目录(dfs.namenode.checkpoint.dir 属性设置)布局与 primary namenode 的目录布局相同。这是设计使然,因为在整个 primary namenode 失效的情况下,
    (没有可恢复的备份,甚至从 NFS 中也无法恢复),可以从一个 secondary namenode 恢复。这可以通过复制相关的存储目录到一个新的 namenode 实现,或者把这个 secondary namenode
    作为新的 primary namenode ,使用 -importCheckpoint 选项启动 namenode 守护进程。
    
    -importCheckpoint 选项会从由 dfs.namenode.checkpoint.dir 属性定义的目录中最新的检查点加载 namenode 元数据,但仅当 dfs.namenode.name.dir 属性定义的目录中没有元数据的
    情况下才可以,这样确保了之前的元数据不会被复写的风险。


    Datanode 的目录结构( Datanode directory structure )
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
    与 namenode 不同,datanode 不需要显式格式化,因为它们在启动时自动创建存储目录。它的关键文件和目录如下:

        ${dfs.datanode.data.dir}/
        ├── current
        │ ├── BP-526805057-127.0.0.1-1411980876842
        │ │ └── current
        │ │ ├── VERSION
        │ │ ├── finalized
        │ │ │ ├── blk_1073741825
        │ │ │ ├── blk_1073741825_1001.meta
        │ │ │ ├── blk_1073741826
        │ │ │ └── blk_1073741826_1002.meta
        │ │ └── rbw
        │ └── VERSION
        └── in_use.lock

    
    HDFS 数据块存储在以 blk_ 为前缀的块文件中,由存储文件的一部分的原始字节组成(consist of the raw bytes)。每个块有一个与之关联的元数据文件,以 .meta 为
    后缀名,它由一个含有版本和类型信息的文件头,后面跟随一系列块的各个区段校验和(a series of checksums for sections of the block)。

    每个块属于一个块池( block pool ),每个块池有它自己的存储目录,从它的 ID 形成,它是 namenode 的 VERSION 文件中 blockpoolID 同一个块池 ID (it’s the same
    block pool ID from the namenode’s VERSION file)

    当目录中数据块数量增长到一定规模时, datanode 会创建一个新的子目录来存放新的数据块及其元数据信息。每当一个目录已经存储的数据块数量多达64个(由
    dfs.datanode.numblocks 配置属性设置)时,它就会创建一个新的子目录。其效果是产生一个高分散的目录树,因此即使是持有数据块数量非常多的系统,目录也仅仅有几层
    的深度。通过这种方式,datanode 确保每个目录含有可管理数量的文件,从而避免了大多数操作系统会遇到的问题,即很大数量的文件放入一个单一的目录中。

    如果 dfs.datanode.data.dir 属性指定了不同磁盘上的多个目录,数据块会以轮转的方式(round-robin fashion)写入到各个目录中。注意,块不会在一个 datanode 上的
    不同磁盘上放置复本(replicated),块复制是跨不同数据节点的。
    
    

1.2 安全模式 (Safe Mode)
----------------------------------------------------------------------------------------------------------------------------------------------------------
    当 namenode 启动时,它做的第一件事就是将它的镜像文件( fsimage )载入内存,并从编辑日志中应用各项操作。一旦它重新构建了一个完好的文件系统元数据的内存镜像,
    它就创建一个新的 fsimage 文件和一个空的编辑日志(自己创建检查点,不需要借助 secondary namenode )。在这个过程中, namenode 运行于安全模式( safe mode ),
    也就是说它仅仅为客户端提供文件系统的只读视图。

    系统内数据块的位置不是由 namenode 持有的,这些信息以存储的数据块列表的形式存在于 datanode 中。在正常的系统操作期间, namenode 拥有一个块位置映射存储在内存中,
    安全模式下需要给各个 datanode 一些时间将它们的块列表信息提交( check in )给 namenode ,这样 namenode 才能有足够的块位置信息来高效地运行文件系统。

    如果 namenode 没有等到 datanode 提交足够的信息,它会启动复制进程,将数据块复制到新 datanode 。大多数情况下这是不必要的,而且会浪费集群资源(因为它仅仅需要
    等待更多的 datanode 签入 —— check in ),实际上,在安全模式下, namenode 不向 datanode 发出任何块复制( block-replication )和删除指令。

    安全模式会在满足最小复本条件(minimal replication condition),再加上一个30秒的延迟时间后退出。最小复本条件是当整个文件系统有99.9﹪的数据块符合它们的
    最小复本级别(由 dfs.namenode.replication.min 属性设置,默认值为 1)

    当启动一个新格式户的 HDFS 集群时,因为系统中还没有任何数据块, namenode 不会进入安全模式。

                
                                                    Safe mode properties
                            
    +=======================================+=======+===========+===========================================================================================+
    |            属性名                        | 类型    | 默认值    |                        描述                                                                |
    +---------------------------------------+-------+-----------+-------------------------------------------------------------------------------------------+
    | dfs.namenode.replication.min            | int    |    1        | The minimum number of replicas that have to be written for a write to be successful.        |
    +---------------------------------------+-------+-----------+-------------------------------------------------------------------------------------------+
    | dfs.namenode.safemode.threshold-pct    | float    | 0.999        | The proportion of blocks in the system that must meet the minimum replication level        |
    |                                        |        |            | defined by dfs.namenode.replication.min before the namenode will exit safe mode.            |
    |                                        |        |            | Setting this value to 0 or less forces the namenode not to start in safe mode. Setting    |
    |                                        |        |            | this value to more than 1 means the namenode never exits safe mode.                        |
    +---------------------------------------+-------+-----------+-------------------------------------------------------------------------------------------+
    | dfs.namenode.safemode.extension        | int    | 30000        | The time, in milliseconds, to extend safe mode after the minimum replication                |
    |                                        |        |            | condition defined by dfs.namenode.safemode.threshold-pct has been satisfied.                 |
    |                                        |        |            | For small clusters (tens of nodes), it can be set to 0.                                    |
    +---------------------------------------+-------+-----------+-------------------------------------------------------------------------------------------+


    进入和离开安全模式
    --------------------------------------------------------------------------------------------------------------------------------------------------------
    查看是否运行于安全模式:
        
        % hdfs dfsadmin -safemode get
        Safe mode is ON
        
    HDFS 的 web UI 也能显示 namenode 是否运行于安全模式

    有时需要在执行一个命令之前等待 namenode 退出安全模式,特别是脚本。 wait 选项可以达到此目的
        
        % hdfs dfsadmin -safemode wait
        # command to read or write a file

    管理员可以在任何时候使 namenode 进入或离开安全模式。有时候在集群上执行维护时这样做是很必要的,或者在集群升级完成后,确认数据依然可读。
    进入安全模式:
    
        % hdfs dfsadmin -safemode enter
        Safe mode is ON
    
    能使用这条命令在 namenode 启动仍然运行于安全模式时,确保它永远不会离开安全模式。另一个确保 namenode 无限期处于安全模式的方法是设置属性
    dfs.namenode.safemode.thresholdpct 的值大于 1
    
    使 namenode 离开安全模式:
    
        % hdfs dfsadmin -safemode leave
        Safe mode is OFF
    
1.3 日志审计( Audit Logging )
----------------------------------------------------------------------------------------------------------------------------------------------------------
    HDFS 能把所有文件系统的访问请求记录日志,有些组织需要这个特性进行审计( for auditing purposes )。审计日志使用 log4j 日志的 INFO 级别实现。默认配置是
    禁用的,但很容易通过在 hadoop-env.sh 文件内添加如下变量来启用:
    
        export HDFS_AUDIT_LOGGER="INFO,RFAAUDIT"
        
    每个 HDFS 事件都会有一行日志写入审计日志 (hdfs-audit.log)
    Here’s an example for a list status request on /user/tom:
    
    2014-09-30 21:35:30,484 INFO FSNamesystem.audit: allowed=true ugi=tom (auth:SIMPLE) ip=/127.0.0.1 cmd=listStatus src=/user/tom dst=null perm=null proto=rpc


1.4 工具( Tools )
------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    dfsadmin
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------
    dfsadmin 是一个多用途工具,可用于查找有关 HDFS 状态的信息,也可以在 HDFS 上执行管理操作。由
    
            hdfs dfsadmin
            
    执行,并要求超级用户权限( superuser privileges )
    
    下面表中描述一些可用的 dfsadmin 命令,使用 -help 命令获得更多信息
    
                                
                                        dfsadmin commands
    
    +=======================+===========================================================================================================================================+
    |        命令            |                        描述                                                                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -help                    | 显示给定命令的帮助,如果未指定命令显示所有命令                                                                                            |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -report                | Shows filesystem statistics (similar to those shown in the web UI) and information on connected datanodes.                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -metasave                | Dumps information to a file in Hadoop’s log directory about blocks that are being replicated or deleted,                                     |
    |                        | as well as a list of connected datanodes.                                                                                                    |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -safemode                | Changes or queries the state of safe mode.                                                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -saveNamespace        | Saves the current in-memory filesystem image to a new fsimage file and resets the edits file.                                             |
    |                        | This operation may be performed only in safe mode.                                                                                        |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -fetchImage            | Retrieves the latest fsimage from the namenode and saves it in a local file                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -refreshNodes            | Updates the set of datanodes that are permitted to connect to the namenode.                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -upgradeProgress        | Gets information on the progress of an HDFS upgrade or forces an upgrade to proceed                                                        |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -finalizeUpgrade        | Removes the previous version of the namenode and datanode storage directories. Used after an upgrade has been applied                        |
    |                        | and the cluster is running successfully on the new version.                                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -setQuota                | Sets directory quotas. Directory quotas set a limit on the number of names (files or directories) in the directory tree.                    |
    |                        | Directory quotas are useful for preventing users from creating large numbers of small files, a measure that helps preserve                |
    |                        | the namenode’s memory (recall that accounting information for every file, directory, and block in the filesystem is stored in memory).    |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -clrQuota                | Clears specified directory quotas.                                                                                                        |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -setSpaceQuota        | Sets space quotas on directories. Space quotas set a limit on the size of files that may be stored in a directory tree.                     |
    |                        | They are useful for giving users a limited amount of storage.                                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -clrSpaceQuota        | Clears specified space quotas                                                                                                                |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -refreshServiceAcl    | Refreshes the namenode’s service-level authorization policy file.                                                                            |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -allowSnapshot        | Allows snapshot creation for the specified directory                                                                                        |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
    | -disallowSnapshot        | Disallows snapshot creation for the specified directory                                                                                    |
    +-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------+

    
    Filesystem check (fsck)
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Hadoop 提供了 fsck utility 用于检查 HDFS 上文件的健康状况。该工具从所有的 datanode 上查找缺失的数据块,以及少于或高于复本数的块。
    
    下面的例子在一个小型集群上检查整个文件系统:
    
        % hdfs fsck /
        ......................Status: HEALTHY
        Total size: 511799225 B
        Total dirs: 10
        Total files: 22
        Total blocks (validated): 22 (avg. block size 23263601 B)
        Minimally replicated blocks: 22 (100.0 %)
        Over-replicated blocks: 0 (0.0 %)
        Under-replicated blocks: 0 (0.0 %)
        Mis-replicated blocks: 0 (0.0 %)
        Default replication factor: 3
        Average block replication: 3.0
        Corrupt blocks: 0
        Missing replicas: 0 (0.0 %)
        Number of data-nodes: 4
        Number of racks: 1
        The filesystem under path '/' is HEALTHY
    
    fsck 工具从给定的路径(本例是文件系统根目录 / )开始递归遍历文件系统的名称空间,并检查它找到的文件。它为每个检查的文件打印一个 . (It prints a dot for every file it checks)
    检查一个文件, fsck 获取文件的数据块的元数据并查找问题或检查其是否一致。注意, fsck 从 namenode 获取所有信息,它不与任何 datanode 通信来实际获取任何块数据。
    
    从 fsck 输出的的信息是自解释的,下面说明几个内容:
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        Over-replicated blocks    :多于复本数的块。这些是超出所属文件目标复本数的数据块。一般来说, over-replication 不是一个问题, HDFS 会自动删除多余的复本。
        
        Under-replicated blocks    :低于复本数的块。这些是没有达到所属文件目标复本数的数据块。 HDFS 会自动为under-replicated 数据块创建新的复本,直到满足目标复本数。
                                    可以使用 hdfs dfsadmin -metasave 命令获得有关正在复制信息(或等待复制)
        
        Mis-replicated blocks    :错误复制的块。这些是不满足块复本放置策略的数据块。例如,复制级别为 3 的(for a replication level of three)多机架(multirack)集群,如果所有的三个
                                    块复本都在同一个机架上,那么块就是错误的(misreplicated),因为复本应该跨至少两个机架分散放置以获得弹性能力(resilience)。 HDFS 会自动
                                    重新复制错误复制的块(re-replicate misreplicated blocks)使其满足机架放置策略(rack placement policy)。
        
        Corrupt blocks            :损坏的块。是指所有复本都已损坏了的数据块。至少有一个未损坏复本的数据块不会报告为损坏(reported as corrupt),namenode 会复制未损坏的数据块直到满足
                                    目标复制数量。
                                    
        Missing replicas        :缺失的复本。集群上任何地方都没有复本的数据块。
    
    Corrupt 或 missing 的数据块是需要考虑的,因为它们意味着数据已经丢失。默认情况下, fsck 对于损坏或丢失块的文件不做任何操作,但可以让 fsck 执行下列操作:
    
        □ 使用 -move 选项,移动受影响的文件到 HDFS 的 /lost+found 目录。文件被分割到连续数据块链有助于用户挽回数据
        □ 使用 -delete 选项,删除受影响的文件。文件被删除后不能再恢复。
    
    
    查找一个文件的数据块(Finding the blocks for a file)
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    fsck 工具提供了一个方便的方法来找出属于任何特定文件的数据块,例如:
    
        % hdfs fsck /user/tom/part-00007 -files -blocks -racks
        /user/tom/part-00007 25582428 bytes, 1 block(s): OK
        0. blk_-3724870485760122836_1035 len=25582428 repl=3 [/default-rack/10.251.43.2:
        50010,/default-rack/10.251.27.178:50010, /default-rack/10.251.123.163:50010]
        
    输出说明文件 /user/tom/part-00007 由一个数据块组成,并且显示了数据块所在的 datanode 。fsck 所用的选项如下:
    
        □ -files    : 显示一行信息,内容包括文件名,文件大小(size),块数量,它的健康状况(是否由任何缺失的块)
        □ -blocks    : 显示文件内每个块有关的信息,一行一个块
        □ -racks     : 显示每个块的机架位置和 datanode 地址
    
    运行 hdfs fsck 没有任何参数显示全部指令用法
        
        
    Datanode 块扫描器(Datanode block scanner)
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------        
    每个 datanode 运行一个块扫描器( block scanner )定期校验(verify)存储在该 datanode 上的所有数据块。这使得坏的数据块在客户端读取之前被检查出来并得到修复。
    扫描器维护一个数据块列表用来检验并依次扫描它们的校验和错误。它使用了一个节流的机制(a throttling mechanism)来保护 datanode 上磁盘带宽。
    
    数据块每三周进行一次校验来应对随时可能的磁盘故障(这个周期由 dfs.datanode.scan.period.hours 属性控制,默认值为 504 小时,即 3 周)。损坏的数据块报告给 namenode 来修复。
    
    可以通过访问 datanode 的 web 界面 http://datanode:50075/blockScannerReport 来获得一个 datanode 的块检验报告( a block verification report )。下面是一个报告示例:
    
        Total Blocks : 21131
        Verified in last hour : 70
        Verified in last day : 1767
        Verified in last week : 7360
        Verified in last four weeks : 20057
        Verified in SCAN_PERIOD : 20057
        Not yet verified : 1074
        Verified since restart : 35912
        Scans since restart : 6541
        Scan errors since restart : 0
        Transient scan errors : 0
        Current scan rate limit KBps : 1024
        Progress this period : 109%
        Time left in cur period : 53.08%
        
    如果指定 listblocks 参数, http://datanode:50075/blockScannerReport?listblocks 报告会在前面列出 datanode 上所有块的最近验证状态。下面是个片段:
    
        blk_6035596358209321442 : status : ok type : none scan time : 0 not yet verified
        blk_3065580480714947643 : status : ok type : remote scan time : 1215755306400 2008-07-11 05:48:26,400
        blk_8729669677359108508 : status : ok type : local scan time : 1215755727345 2008-07-11 05:55:27,345

    第一列为块ID ( block ID ), 后面跟一些 key-value 对。状态可以是 failed 或 ok, 根据最后一次块扫描是否检测到校验和错误。
    如果由后台线程(background thread)执行扫描的 type 为 local,如果由一个客户端或远程 datanode 执行 type 值为 remote, 如果这个块还没有被校验,type 值为 none
    最后一条信息为扫描时间,显示为1970年1月1日午夜12点开始以来的毫秒数,以及一个更易读的值
    
        
    均衡器(Balancer)
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------        
    随着时间的推移,各个 datanode 上的数据块分布会变得不均衡。一个不均衡的集群 MapReduce 的本地化,会给高使用率的 datanode 更繁重的工作负荷,最好避免这种状况。
    
    balancer 程序是一个 Hadoop 守护进程,它重新分布数据块(redistributes blocks),将数据块从高占用率的 datanode 移动到低占用率的 datanode ,同时遵循块复本放置策略,
    将数据放置到不同的机架上以避免数据丢失。它不停地移动数据块,直到集群达到均衡,即每个 datanode 的利用率(the utilization of every datanode, 节点上已使用的空间与该节点
    整体容量的比率)与集群的使用率(the utilization of the cluster 集群上已使用的空间与集群总体容量之间的比率)之间的差距不超过给定的临界百分值。
    
    启动均衡器:
    
        % start-balancer.sh
        
    -threshold 参数指定临界百分数值定义集群为均衡的阈值。这个参数是可选的,如果忽略,阈值为 10% 。任何时候,集群上只能运行一个均衡器。
    
    均衡器一直运行,直到集群均衡,它不能再移动任何数据块了,或者失去了与 namenode 的联系。均衡器在标准日志目录产生一个日志文件,执行每轮重新分布(iteration of redistribution)
    时在日志文件中写入一行。示例:
    
        Time Stamp Iteration# Bytes Already Moved ...Left To Move ...Being Moved
        Mar 18, 2009 5:23:42 PM 0 0 KB 219.21 MB 150.29 MB
        Mar 18, 2009 5:27:14 PM 1 195.24 MB 22.45 MB 150.29 MB
        The cluster is balanced. Exiting…
        Balancing took 6.072933333333333 minutes
    
    均衡器设计为后台运行,不会过度地增大集群工作负荷,也干扰其他客户端使用集群。它限制数据块从一个节点到另一节点复制的带宽,默认是很小的 1 MB/s ,可以通过 hdfs-site.xml
    文件中的 dfs.datanode.balance.bandwidthPerSec 属性设置。
    
*
*
*
    
2 监控( Monitoring )
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
监控的目标是在集群未能提供期望的服务级别时发现到问题之所在。主守护进程(The master daemons)是最重点监控的: namenode (primary and secondary) 和 resource manager.
datanode 和 node manager 故障是可预期的,特别是在大型集群上,因此应该预留额外的容量,无论何时即便集群内有一小部分节点宕机,集群也能够正常运行。

除了下面介绍的这些工具外,管理员还应该定期运行一些作业以测试集群的健康状况。
    

    1. 记录日志(Logging)
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------
    所有的 Hadoop 守护进程都生成日志文件,这些文件对于查明系统上已发生的事件非常有用。
    
    
        设置日志级别(Setting log levels)
        ----------------------------------------------------------------------------------------------------------------------------------------------------------------
        在调试一个问题的时候,能对系统上一个特定组件临时改变日志级别是非常方便实用的。
        Hadoop daemons 都有一个 web 页用于为任何 log4j 日志名称改变日志级别,可以在 daemon 的 web UI 的 /logLevel 下找到。按照惯例, Hadoop 中的日志名称对应记录日志的类
        名称,当然也有例外,那就需要查看源代码来找到日志名称了。
    
        为所有以一个给定前缀开始的包启用日志也是可以的。例如,为 resource manager 相关的所有的类启用 debug 级别日志,可以访问 web UI:
        
            http://resource-manager-host:8088/logLevel
        
        然后设置日志名称 org.apache.hadoop.yarn.server.resourcemanager 为 DEBUG 级别。
        
        同样的事可以通过命令行完成:
        
            % hadoop daemonlog -setlevel resource-manager-host:8088 \
                org.apache.hadoop.yarn.server.resourcemanager DEBUG
    
        通过这种方式改变的日志级别会在 daemon 重启后被重置,通常这也符合用户预期。要永久性改变日志级别,可以简单地修改配置目录下log4j.properties文件。对于这个例子,添加
        这样一行:
        
            log4j.logger.org.apache.hadoop.yarn.server.resourcemanager=DEBUG
    
    
        获取堆栈跟踪( Getting stack traces )
        --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        Hadoop daemon 提供一个 web 页面 (/stacks in the web UI) 可以为守护进程的 JVM 上运行的所有线程产生一个线程转储(a thread dump)。例如,为resource manager获得一个线程
        转储:
        
            http://resource-manager-host:8088/stacks
        
    
    
    2. Metrics and JMX
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Hadoop daemon 收集有关事件和度量信息(information about events and measurements)统称为度量( metrics )。例如, datanode 收集如下 metrics (还有更多):写入的字节数,
    已复制的数据块数量,客户端读请求的数量(包括本地的和远程的)。
    
        注意:
        ------------------------------------------------------------------------------------------------------------------------------------------------------------------
        在 Hadoop 2 和以后版本中 metrics system 有时称之为 metrics2 以区别在早期版本 Hadoop 中旧的 metrics system,已不推荐使用。
    
    Metrics 属于一个特定上下文(context):“dfs,” “mapred,” “yarn,” and “rpc” 是不同上下文的例子。 Hadoop daemon 综合在几个上下文下收集 metrics 。例如, datanode 为 "dfs"
    和"rpc" 上下文收集 metrics 。
    
    
        Metrics 和计数器区别在哪 (HOW DO METRICS DIFFER FROM COUNTERS?)
        --------------------------------------------------------------------------------------------------------------------------------------------------------------------
        主要的区别是它们的作用域:Metrics 由 Hadoop daemon 收集,而计数器由 MapReduce 任务收集并为整个作业聚集。它们也有不同的受众,概括地说,metrics 为管理员服务,而计数器
        为 MapReduce 用户服务。
        
        它们收集和聚集的过程也不同。
        计数器是 MapReduce 特性,MapReduce 系统确保计数器的值从任务 JVM 传播,产生后回传给 application master, 最后传回运行 MapReduce 作业的客户端。(计数器经由 RPC 心跳传播)
        任务进程和 application master 都执行聚集操作。
        
        metrics 的收集机制独立于接收更新的组件,而且有很多可插拔的输出,包括本地文件,Ganglia, 和 JMX 。收集 metrics 的 daemon 在把它们发送到输出之前执行聚集操作。
        
    所有的 Hadoop metrics 都发布到 JMX (Java Management Extensions), 因此可以使用标准的 JMX 工具如 JConsole (which comes with the JDK) 查看。对于远程监控,必须设置 JMX 系统
    属性:com.sun.management.jmxremote.port 以允许访问。比如要对 namenode 执行远程监控,需要在 hadoop-env.sh 文件中添加如下设置:
    
        HADOOP_NAMENODE_OPTS="-Dcom.sun.management.jmxremote.port=8004"
        
    也可以通过连接某个特定 Hadoop daemon 的 /jmx web 页面来查看由它收集的 JMX metrics(in JSON format), 这对调试很方便。例如,查看 namenode 的 metrics, 访问:

        http://namenode-host:50070/jmx
    
    Hadoop 自带了一些 metrics 接收器(metrics sinks)用于向外部系统发布 metrics ,例如 local files 或 Ganglia 监控系统。接收器由 hadoop-metrics2.properties 文件配置。
    
    
*
*
*

3 维护( Maintenance )
------------------------------------------------------------------------------------------------------------------------------------------------------------------------    
    
    
    1. 日常管理例程( Routine Administration Procedures )
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------    
    
    
        元数据备份 ( Metadata backups )
        ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        如果 namenode 的永久性元数据丢失或损坏,则整个文件系统也就不可用了,因此元数据的备份至关重要。应该分别保存不同时间段的(one hour, one day, one week, and one month)
        多个拷贝来防护数据损毁,或者在这些文件的拷贝中,或者在正运行在 namenode 上的活动文件中。
        
        制作元数据备份最直接的方法是使用 dfsadmin 命令下载一个 namenode 的最新 fsimage 文件拷贝:
        
            % hdfs dfsadmin -fetchImage fsimage.backup
            
        可以写个脚本从一个场外位置运行这个命令来存档 fsimage 文件拷贝。脚本可以额外测试文件拷贝的完整性。这可以通过启动一个本地 namenode daemon 并验证它已成功读取 fsimage
        和 edits 文件到内存中。
    
        
        
        数据备份 ( Data backups )
        ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        尽管 HDFS 设计可靠地存储数据,数据丢失也可能发生,就像任何存储系统一样,因此,备份策略是必要的。 Hadoop 可以存储海量数据,决定什么数据需要备份和在哪存储备份很
        具有挑战性。这里关键是划分优先级。最高优先级的数据是不可重新生成并且商业价值至关重要的;而可以重新生成或者基本上是一次性的有限商业价值的数据具有最低优先级,无
        须备份。
    
        distcp 是一个理想的备份工具,因其并行复制文件可以将数据备份到另一个 HDFS 集群,或其他 Hadoop 文件系统(如 S3 )。也可以部署一个完全不同的存储系统用于备份,利用
        从 HDFS 导出数据的方法备份数据。
    
        HDFS 允许管理员和用户创建文件系统快照(snapshots)。快照是某个给定时间点一个文件系统子树的只读的拷贝。由于不复制数据,快照非常高效,它们简单地记录每个文件的
        元数据和数据块列表,足够重建创建快照时文件系统的内容。
    
        快照不是数据备份的替代,但它们在文件被用户错误地删除的时间点数据恢复是很有用的工具。用户应该有一个策略来定期创建快照,并保留一定的时间周期。例如,保留前一天
        每小时的快照和上个月每天的快照。
    
    
        文件系统检查 (fsck)
        ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        建议定期在整个文件系统上运行 HDFS 的 fsck 工具查看丢失或损坏的数据块。
    
    
        文件系统均衡器 (Filesystem balancer)
        ---------------------------------------------------------------------------------------------------------------------------------------------------------------    
        定期运行均衡器工具,保持文件系统数据节点比较均衡。
    
    
    
    
    2. 服役和退役节点 (Commissioning and Decommissioning Nodes)
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------    
    作为 Hadoop 集群管理员,随时需要添加或移除节点。例如,为了扩充集群存储容量,要服役新的节点(commission new nodes)。相反,有时需要收缩集群规模,就要退役一些节点(
    decommission nodes)。有时候退役个一个表现反常的节点是不可避免的,或许它经常发生故障,或者性能明显缓慢。
    
    通常节点同时运行一个 datanode 和一个 node manager ,因此通常它们两个一般同时服役或退役。
    
    
        服役新节点( Commissioning new nodes )
        -------------------------------------------------------------------------------------------------------------------------------------------------------------
        服役一个新节点非常简单,配置 hdfs-site.xml 文件指向 namenode, 配置 yarn-site.xml 文件指向 resource manager, 然后启动 datanode 和 resource manager daemon。
        最好一个授权的节点列表。
    
        随便允许一台机器作为 datanode 连接到 namenode 存在潜在风险,因为这台机器可以访问到未许可它看到的数据。更严重的情况是,这台机器如果不是一个真正的 datanode, 它
        不在用户的控制之下并且可能随时会停止,潜在地造成数据丢失。因此, datanodes (and node managers) 应该明确管理在所有的生产集群上。
    
        允许连接到 namenode 的 datanode 应该在一个文件中指定,文件名由 dfs.hosts 属性指定。这个文件存在于 namenode 的本地文件系统,它含有的每一行对应一个 datanode,
        由网络地址指定。如果需要为一个 datanode 指定多个网络地址,把它们放到同一行,空格分隔。
        
        类似地,连接到 resource manager 的 node manager 也在一个文件中指定,文件名由 yarn.resourcemanager.nodes.include-path 属性指定。大多数情况下,由于集群内节点同时
        运行 datanode 和 node manager 守护进程,因此使用一个共享的文件,称为 include 文件,由 dfs.hosts 和 yarn.resourcemanager.nodes.include-path 同时指向它。
    
            提示:
            ---------------------------------------------------------------------------------------------------------------------------------------------------------
            由 dfs.hosts 和 yarn.resourcemanager.nodes.include-path 属性指定的文件不同于 slaves 文件。前者用于 namenode 和 resource manager 确定哪些工作节点(
            worker nodes)可以连接。 slaves 文件用于 Hadoop 控制脚本执行集群范围的操作(perform cluster-wide operations),如集群重启。它永远不会被 Hadoop 守护进程使用
    
        
            向集群添加新节点的步骤:
            ----------------------------------------------------------------------------------------------------------------------------------------------------------
                ① 向include 文件中添加新节点的网络地址        
                ② 使用新的许可 datanode 信息更新 namenode
                    
                    % hdfs dfsadmin -refreshNodes
                
                ③ 使用新的许可 node manager 信息更新 resource manager
                    
                    % yarn rmadmin -refreshNodes
                
                ④ 使用新的节点信息更新 slaves 文件,这样它们就包含在将来由 Hadoop 控制脚本执行的操作中
                ⑤ 启动新 datanodes 和 node managers.
                ⑥ 在 web UI 上检查新 datanodes 和 node managers 是否出现
                
            HDFS 不会将数据块从旧的 datanode 移动到新的 datanode 来均衡集群,需要手动运行 balancer 工具。
            
            

        退役节点( Commissioning new nodes )
        -------------------------------------------------------------------------------------------------------------------------------------------------------------            
        虽然 HDFS 设计为 datanode 故障容错,但并不意味者可以随意终止 datanode 。以一个复制级别( replication level )为 3 的集群为例,如果同时关机不同机架上的
        三个 datanode,数据丢失的几率非常高。退役 datanode 的正确方法是,通知 namenode 要退出集群的节点信息,这样namenode就能在 datanode关机之前将数据块给其他datanode
            
        对于 node manager, Hadoop 更加宽容。如果关闭一个正在运行 MapReduce 任务的 node manager, application master 会通告失败并重新调度任务到其他节点上运行。
        
        退役过程(decommissioning process)由一个 exclude 文件控制,由 HDFS dfs.hosts.exclude 属性和 YARN 的 yarn.resourcemanager.nodes.exclude-path 属性设置。一般情况
        这两个属性指向同一个文件, exclude 文件列出不许可连接到集群上的节点。
        
        一个 node manager 是否可以连接到 resource manager 的规则非常简单:一个 node manager 可以连接仅当其在 include 文件中出现并且不在 exclude 文件中出现时。一个未指定
        的或空的 include 文件意味着所有的节点都在 include 文件中。
            
        对于 HDFS,规则稍有不同。如果一个 datanode 同时出现在 include 和 exclude 文件,那么它可以连接,但只能被退役。
            
                        
                                HDFS include and exclude file precedence
                                
                +===========================+===========================+===============================+
                | 节点出现在 include 文件中    | 节点出现在 exclude 文件中    |            解释                |
                +---------------------------+---------------------------+-------------------------------+
                | No                        | No                        | 节点不能连接                    |
                +---------------------------+---------------------------+-------------------------------+
                | No                        | Yes                        | 节点不能连接                    |
                +---------------------------+---------------------------+-------------------------------+
                | Yes                        | No                        | 节点可以连接                    |
                +---------------------------+---------------------------+-------------------------------+
                | Yes                        | Yes                        | 节点可以连接并且将被退役        |
                +---------------------------------------------------------------------------------------+
        
        
            从集群中移除节点的步骤:
            -------------------------------------------------------------------------------------------------------------------------------------------------------
            ① 将要退役节点的网络地址添加到 exclude 文件。这时不要更新 include 文件。
            ② 使用下面的命令更新 namenode
                
                % hdfs dfsadmin -refreshNodes
                
            ③ 使用下面的命令更新 resource manager
                
                % yarn rmadmin -refreshNodes
                
            ④ 转到 web UI 页面检查要退役的 datanode 的 admin state 是否已变成 "Decommission In Progress" 。 datanode 要开始复制它们的数据块到集群内其他 datanode 上
            ⑤ 当所有的 datanode 报告它们的状态为 "Decommissioned", 表明所有数据块已复制完毕,关闭退役的节点。
            ⑥ 从 include 文件移除退役的节点,然后运行:
                % hdfs dfsadmin -refreshNodes
                % yarn rmadmin -refreshNodes
            ⑦ 从 slaves 文件移除退役的节点。
        
        
        
        
    3. 升级 Upgrades )
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------            
    升级一个 HDFS 集群需要细致的规划,最重要的考虑是 HDFS 的升级。如果文件系统布局版本改变了,那么升级会自动迁移文件系统数据和元数据到兼容新版本的格式。
    与任何涉及数据迁移的过程类似,升级操作存在数据丢失的风险,因此应该确保用户数据和元数据都已备份。
        
    规划过程的部分应该包括一个运行在一个小型测试集群上的试运行(a trial),使用一个可以承受损失的数据拷贝。试运行可以在运行生产环境集群升级过程之前悉升级过程,自定义
    特定的集群配置和工具集,消除任何技术障碍。一个测试集群还有好处是在它上面测试客户端升级。
        
        
        
        兼容性(COMPATIBILITY)
        ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        当从一个版本迁移到另一个版本,需要考虑需要的升级步骤。有几个方面需要考虑:API 兼容性,数据兼容性,以及通信兼容性。
        
        API 兼容性关注的用户代码和发布的 Hadoop API间的协议(contract),比如 Java 的 MapReduce API. 主版本(Major releases,如从 1.x.y to 2.0.0)允许打破 API 兼容性,
        因此,用户程序可能需要修改并重新编译。Minor releases (e.g., from 1.0.x to 1.1.0) 以及 point releases (e.g., from 1.0.1 to 1.0.2)不会打破兼容性。
        
        数据兼容性关注持久性数据和元数据的格式,例如 HDFS namenode 存储它的永久性数据的格式。数据格式可以跨 minor 或 major releases 改变,但这种改变对用户是透明的,因为
        升级会自动迁移数据。升级路径可能有些限制,这些内容会在 release notes 中描述。例如,可能需要经由升级到一个必要的中间版本,而不是一步升级到最终版本。
        
        通信兼容性关注客户端与服务器间通信协议例如 RPC 和 HTTP 的互操作性。通信兼容性的规则是客户端必须与服务器具有相同的主版本号(have the same major release number),
        可以有不同的 minor or point release number (e.g., client version 2.0.2 will work with server 2.0.1 or 2.1.0, but not necessarily with server 3.0.0)。
        
    当文件系统布局没有改变时升级集群是非常直接的:在集群上安装新版本的 Hadoop(同时也安装到客户端上),关闭老版本的守护进程,升级配置文件,然后启动新的守护进程,并切换
    客户端使用新的库文件(libraries)。这个过程是可逆的,因此回滚一个升级也是很容易的。
        
    每次成功升级之后,应该执行几个最后的清理步骤:
    
        ① 从集群上移除旧的安装文件和配置文件
        ② 修复用户代码和配置文件中任何 deprecation 警告
    
    升级在 Hadoop 集群管理工具,像 Cloudera Manager 和 Apache Ambari 中都带有它们自己的工具。它们简化升级过程。也容易在升级间滚动,批处理节点升级(nodes are upgraded
    in batches),因此,客户端不会体验到服务中断。
        
        
    HDFS 数据和元数据升级( HDFS data and metadata upgrades )
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
    如果使用上述过程升级到一个新版本的 HDFS 并检测到不同版本的布局,那么 namenode 会拒绝运行。在它日志中会有一条类似下面的消息:
    
        File system image contains an old layout version -16.
        An upgrade to version -18 is required.
        Please restart NameNode with -upgrade option
        
    找出是否需要升级文件系统最可靠的途径是在一个测试集群上执行试运行。

    HDFS 升级创建了一个前一版本的元数据和数据的拷贝。升级操作不会加倍集群的存储要求,因为 datanode 使用硬链接持有同一个数据块的两个引用(分别对应当前版本和前一个版本)
    这种设计使文件系统回滚到前一版本非常直接,如果需要的话。然而,需要理解的是,在完成回滚到前一个版本之后,对升级的系统上的数据做的任何更改都会丢失。
    
    仅可以保留前一个版本的文件系统(only the previous version of the filesystem),也就意味着不能在几个版本间滚动。因此,要对 HDFS 数据和元数据执行另一次升级,需要
    删除前一版本,这个过程称为定型升级(called finalizing the upgrade)。一旦升级是定型的(finalized), 就没有回滚到前一版本的途径了。
    
    一般情况下,可以跳过版本升级,但有些情况,必须通过升级到中间版本。需要的时候, 发布声明(release note)会清楚声明。
    
    应该只升级健康的文件系统。在运行升级之前,全面地运行一次 fsck。作为额外的防护措施,保留一份 fsck 输出文件的拷贝,其中列出了系统内所有的文件和块信息,这样,就可以
    在升级之后运行 fsck ,比较两次输出的结果。
        
    进行升级操作之前清除临时文件也是很有用的 ———— 包括本地临时文件和 HDFS 上 MapReduce 系统目录的临时文件。
    
    
    解决了这些准备工作之后,下面是升级文件系统布局需要迁移集群的高级别进程(high-level procedure):
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        ① 继续进行下一个升级之前,确保任何之前的升级定型( finalized )
        ② 停止 YARN 和 MapReduce 守护进程
        ③ 停止 HDFS , 备份 namenode 目录
        ④ 在集群和客户端安装新版本的 Hadoop
        ⑤ 用 -upgrade 选项启动 HDFS
        ⑥ 等待直到升级完成
        ⑦ 在 HDFS 上执行一些正常性检查
        ⑧ 启动 YARN 和 MapReduce 守护进程
        ⑨ 回滚或 finalize 本次升级(可选)
        
    运行升级过程时,最好从 PATH 环境变量移除 Hadoop 脚本路径。这使用户明确知道运行的是哪个版本的脚本。为新安装的目录定义两个环境变量也能提供便利,下面这两个:
    
        OLD_HADOOP_HOME
        NEW_HADOOP_HOME
        
    启动升级(Start the upgrade)
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        执行升级,运行下面命令(高级升级过程第 ⑤ 步)
            
            % $NEW_HADOOP_HOME/bin/start-dfs.sh -upgrade
        
        该命令使 namenode 升级它的元数据,将前一版本的元数据放入 dfs.namenode.name.dir 目录下的 previous 目录。类似地,datanode 更新它的存储目录,
        保留旧的拷贝到 previous 目录。
        
        
    等待直到升级完成(Wait until the upgrade is complete)
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        升级进程不会瞬时完成,可以使用 dfsadmin 检查升级进度,升级事件也会出现在守护进程的日志文件中(高级升级过程第 ⑥ 步)
            
            % $NEW_HADOOP_HOME/bin/hdfs dfsadmin -upgradeProgress status
            Upgrade for version -18 has been completed.
            Upgrade is not finalized.
                
                
    检验升级(Check the upgrade)    
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------
        显示升级完成。这个阶段,应该在文件系统上运行一些正常性检查(第 ⑦ 步)。例如使用 fsck 检查文件和数据块,测试基本的文件操作。在运行这些检查工作时可以选择让
        HDFS 进入安全模式,防止其他人做出改变。
        
        
    回滚升级(Roll back the upgrade (optional))
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------    
        如果发现新版本无法正确工作,可以选择回滚到前一版本(第 ⑨ 步)。 仅当还没有定型升级(finalize)时可行。
            
            警告:
            -----------------------------------------------------------------------------------------------------------------------------------------------------------
            回滚操作是使文件系统的状态回到升级执行之前的状态,因此在这之间放生的变化会丢失。换句话说,它是回滚到文件系统以前的状态,而不是降级文件系统的当前状态到
            一个从前的(former)版本
        
        首先,停止新的守护进程:

            % $NEW_HADOOP_HOME/bin/stop-dfs.sh
        
        然后,使用 -rollback 选项启动旧版本的 HDFS
        
            % $OLD_HADOOP_HOME/bin/start-dfs.sh -rollback
        
        这个命令使 namenode 和 datanode 用之前的拷贝替换当前的存储目录。文件系统会返回到它之前的状态。
        
    
    定型升级(Finalize the upgrade (optional))
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------        
        对版本的 HDFS 感到满意时,可以定型升级(第 ⑨ 步) 移除之前的存储目录。
        
            警告:
            --------------------------------------------------------------------------------
            在一个升级被定型之后,就没有方法回滚到前一版本了。
        
        这一步是执行另一个升级所必须的,执行命令:
        
            % $NEW_HADOOP_HOME/bin/hdfs dfsadmin -finalizeUpgrade
            % $NEW_HADOOP_HOME/bin/hdfs dfsadmin -upgradeProgress status
                There are no upgrades in progress.
        
        现在, HDFS 完全升级到新版本了。
        
        
        
        

猜你喜欢

转载自blog.csdn.net/devalone/article/details/80730801