您好,登录后才能下订单哦!
这篇文章主要为大家展示了“HDFS如何进行升级管理”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HDFS如何进行升级管理”这篇文章吧。
Hadoop的官方文档中,对于HDFS的升级建议分三个步骤,1,先停掉HDFS服务,再启动,HDFS合并FsEditLog到FsImage之中,再停掉HDFS服务,2,备份namenode的meta文件,在新版本HDFS安装目录的配置文件中,配置namenode的meta文件目录指向旧有的meta文件目录,以-upgrade选项启动HDFS,让HDFS服务执行升级过程,3,升级进度达到100%后,执行hadoop dfsadmin -finlizeUpgrade告诉HDFS服务,升级结束。如果升级失败,以-rollback选项启动HDFS,执行回滚。
从升级到本身使命来说,升级到目的就是为了保护现有数据,如果在升级过程中,出现因为升级而导致数据丢失,或者整个HDFS文件系统的损坏,那升级就失败了。看完Hadoop官方文档的升级过程和命令后,我很好奇,如此简单的描述,能保证升级过程一定是“达到”目的的吗?或者至少保证不会损坏HDFS文件系统本身!
怀疑是怀疑,等了解它,再对它下结论!然而HDFS升级的资料非常少,这里从源码分析,力求做到最接近作者升级设计的意图。
在HDFS文件系统中,NameNode的一个基本职责是分配块到datanode上;告诉客户端一个块的内容可以从哪台机器上能读取到。块信息对于HDFS文件系统来说,是非常重要的,为了不丢失块信息,并能让客户端,datanode能快速懂检索块信息,HDFS的开发者们在设计NameNode的存储结构时,借鉴了数据库的WAH一些做法,但同时又采用了一种非常不常见到做法。
为了保证块信息不丢失,HDFS在分配一个块时,先写块信息的日志到磁盘的文件系统,这个存储在HDFS中叫fsEditLog,日志写成功后,再向处于JVM heap中的一种可以存储重复HASH值条目的Map中,添加这个块信息,如果是删除块操作,则是从这个Map中删除相应的条目。这个Map中保存了HDFS中所有块信息,而不是常见的缓存部分数据。在HDFS的namenode存储中,磁盘上存储的块信息和Map中存储的块信息的实际数量是一样的。为了保证这个Map所存储的数据不超过JVM Heap的限制,Namenode在启动的时候,默认JVM的-Xx启动参数值的2%作为计算这个Map最多可以容纳条目的数量,Map中的条目达到这个最大值时,则不可以添加新的块。在磁盘端,块信息主要存储在fsImage中,块操作日志存储在fsEditLog中,自fsImage文件中最后的事务点后,对于块的操作是首先顺序对追加到fsEditLog中,而不是直接写入fsImage。HDFS服务在启动时会启动一个checkpointer组件,定期的把当前的fsImage和fsEditLog合并到新的fsImage中。
NameNode的meta内部物理结构如下图所示:
`-- current |-- edits_0000000000000000001-0000000000000000007 |-- edits_inprogress_0000000000000000008 |-- fsimage_0000000000000000000 |-- fsimage_0000000000000000000.md5 |-- seen_txid `-- VERSION
从存储上看HDFS的存储结构,只有在HDFS启动时,从fsImage中载人块信息到内存端的Map,或者在需要时,把内存端的Map写入磁盘端去。对于块的增、删、改这样的操作,内存端和磁盘端独立,日志能保证最终的块信息在两端是一致的。这样设计的好处是,简单,容易实现,缺点是内存端大小会受到限制,不容易扩展。
相对NameNode对于块的存储结构,DataNode上对于块的存储结构简单很多,DataNode只存储<块,大小>对。一个块被写入到DataNode上后,会写一个和这个块名相同的meta文件,存储块大小和块生成的时间。DataNode中,对块的生命周期进行了细致的划分,当向文件追加的新块时,块的是位于RBW目录(1.x则是在BlockBeingWritten目录),当这个块达到系统指定的块大小或者文件写关闭,这个块会变成finallized状态,DataNode把此块移动到current/finallized目录中。
在HDFS 2.x中,对于数据块的存储是按照BlockPoolSlice来管理的,从逻辑上说,一个BlockPoolSlice代表DataNode配置项dfs.datanode.data.dir中的一个目录。DataNode上新建块,移动和删除块是通过BlockPoolSlice完成逻辑上的操作。BlockPoolSlice内部的物理结构如下图所示:
|-- current | |-- BP-1134876178-10.1.101.51-1427874067591 | | |-- current | | | |-- dfsUsed | | | |-- finalized | | | |-- rbw | | | `-- VERSION | | |-- dncp_block_verification.log.curr | | |-- dncp_block_verification.log.prev | | `-- tmp | `-- VERSION |-- detach |-- in_use.lock |-- storage `-- tmp
对于NameNode meta文件的升级,NameNode在启动时,如果分析带有upgrade命令选项,会升级meta文件夹中的current目录,现在假设HDFS刚重启过一次,并没有新的块添加到HDFS中,此时,fsEditLog都是空的,对于此目录的操作按照下面的操作步骤进行。
如果meta文件夹中有previous目录,删除它
把current重名为previous.tmp
新建current目录
把previous.tmp文件下的VERSION文件升级为当前安装的版本,写入current目录
载人previous.tmp文件下fsImage到中的文件和块到内存,载入这个过程是向下兼容的,经载入后的文件和块已经被转化成当前安装版本的格式。
旧版本fsImage中的genStamp、clusterId、numFiles信息保留不变,但旧版本的fsImage文件名和fsEditLog文件可能会改变
在fsImage载入成功后,把处于内存端的文件和块按照最新的格式写入磁盘的current目录,并且在这个时候,告诉系统,NameNode的meta文件升级操作完成!
从这个过程中,可以看出,NameNode在升级的过程中,并没有在旧版本的fsImage和fsEditLog上直接进行操作,而是新建一个文件夹,这样的方式是非常安全的。首先解开了开篇的一半疑问。
DataNode升级的过程和NameNode的fsImage升级的方式比较类似,但在具体操作上有很大的不同,DataNode上存储的主要是数据块,如果采用复制数据块到新的目录,那复制PB,EB级别的数据,这个过程将变得不可想象。大师们为DataNode的升级寻找到了一个合适的方案。
对于一个BlockPoolSlice的物理文件夹,升级执行下面的步骤
如果BlockPoolSlice的物理文件夹中有previous,删除它
重命名current目录为previous.tmp
在DataNode文件中创建current/{bpid}/current目录, 这里的bpid是blockpool ID,是HDFS 2.x版本中引入的新术语,用于管理block pool slice
遍历previous.tmp文件中所有的块,为这些块建立硬连接,保存到current/{bpid}/current目录,这个过程中,块文件的名称可能会因版本跨度而发送变化。回想一下NameNode中块信息的升级,由于块信息中块的文件名主要包户一个生成的时间戳和文件的序列号,因此,在变更块文件名的时候,只要NameNode和DataNode按照相同的规则进行变换,在升级后,仍能保持和HDFS升级前在用户层面上是的一致的。
重命名previous.tmp目录为previous,并在这个时候告诉HDFS,此block pool slice升级完成
硬连接是某些文件系统的一个高级特性,某些文件系统中设计有两种Node,一种是INode,存储文件的索引信息,一种是DataBlock,存储文件真正的数据,文件的名字是存储在INode中的,INode还使用一个指针指向此文件的第一个DataBlock,建立硬连接实质上是为文件的数据块新建一个INode,这个INode也是指向此文件的第一个数据块。而这个INode中包含的文件名可以和此文件的原名字不同。当然,原文件名其实也是存储该文件DataBlock的硬连接。在这样的文件系统上,删除一个文件,只是删除这个文件的INode,如果一个文件的DataBlock没有INode指向它,这些DataBlock就可以被文件系统回收。只要还有一个INode指向这些DataBlock,它们就不会被回收。在这样的文件系统中,INode可以被设计得很小,比如Ext4,一个INode占512字节,一个DataBlock至少是4K,在格式化磁盘时,系统分配INode的个数约为DataBlock个数的1/8。
所以,采用硬连接的方式升级DataNode所需要操作的磁盘空间就小很多了。从逻辑上说,也不会对文件系统造成损坏。
如果升级过程失败,需要通过rollback命令选项,让HDFS回滚到升级之前到状态。由于此时两个版本的HDFS文件系统信息都是是存在的,回滚的过程其实是一个文件夹重命名的过程,具体的步骤如下面:
把current目录重名为remove.tmp
把previous目录重命名为current
删除remove.tmp目录
到此时,HDFS升级的细节讨论的差不多,对HDFS能成功升级也抱有信心,当然能安全回滚也不是问题,当HDFS程序正确的执行完升级各步骤后,还需要手工的执行
hadoop dfsadmin -upgradeFinallized
让HDFS删除升级之前到文件,这个命令执行完后,也就不能回滚到以前的HDFS版本了。
以上是“HDFS如何进行升级管理”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。