mongodb 备份恢复有没有办法实现将数据备份到hdfs中

后使用快捷导航没有帐号?
按发布时间阅读主题
按时间阅读主题 --日当日共有517个主题贴关系型数据库数据分析Hadoop分布式数据分析平台Oracle数据库与大数据解决方案Hadoop分布式数据分析平台Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案SAS中国用户组数据分析与数据挖掘技术关系型数据库数据分析关系型数据库数据分析供应链管理供应链管理Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案R中国用户组Oracle数据库与大数据解决方案Hadoop分布式数据分析平台Oracle数据库与大数据解决方案关系型数据库数据分析Hadoop分布式数据分析平台Oracle数据库与大数据解决方案关系型数据库数据分析数据分析与数据挖掘技术关系型数据库数据分析电信运营商数据分析应用与案例讨论Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组R中国用户组关系型数据库数据分析Hadoop分布式数据分析平台Hadoop分布式数据分析平台关系型数据库数据分析Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Hadoop分布式数据分析平台关系型数据库数据分析Hadoop分布式数据分析平台R中国用户组电信运营商数据分析应用与案例讨论R中国用户组R中国用户组Oracle数据库与大数据解决方案SAS中国用户组关系型数据库数据分析SAS中国用户组Hadoop分布式数据分析平台NoSQL及其应用SAS中国用户组NoSQL及其应用SAS中国用户组金融数据分析应用与案例讨论Hadoop分布式数据分析平台关系型数据库数据分析供应链管理NoSQL及其应用Oracle数据库与大数据解决方案关系型数据库数据分析Oracle数据库与大数据解决方案R中国用户组关系型数据库数据分析关系型数据库数据分析关系型数据库数据分析关系型数据库数据分析关系型数据库数据分析数据分析与数据挖掘技术NoSQL及其应用Hadoop分布式数据分析平台R中国用户组NoSQL及其应用Hadoop分布式数据分析平台Hadoop分布式数据分析平台Oracle数据库与大数据解决方案Hadoop分布式数据分析平台Hadoop分布式数据分析平台Hadoop分布式数据分析平台NoSQL及其应用Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案关系型数据库数据分析NoSQL及其应用招聘与商务Java语言开发技术关系型数据库数据分析Hadoop分布式数据分析平台Oracle数据库与大数据解决方案电信运营商数据分析应用与案例讨论Java语言开发技术关系型数据库数据分析SAS中国用户组SAS中国用户组Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组Hadoop分布式数据分析平台供应链管理Oracle数据库与大数据解决方案数据分析与数据挖掘技术Hadoop分布式数据分析平台关系型数据库数据分析关系型数据库数据分析金融数据分析应用与案例讨论Hadoop分布式数据分析平台SAS中国用户组SAS中国用户组R中国用户组Oracle数据库与大数据解决方案SAS中国用户组Hadoop分布式数据分析平台Hadoop分布式数据分析平台Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组Oracle数据库与大数据解决方案R中国用户组SAS中国用户组电信运营商数据分析应用与案例讨论Java语言开发技术Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案数据分析与数据挖掘技术SAS中国用户组Hadoop分布式数据分析平台Java语言开发技术SAS中国用户组电信运营商数据分析应用与案例讨论金融数据分析应用与案例讨论R中国用户组R中国用户组Hadoop分布式数据分析平台数据分析与数据挖掘技术Hadoop分布式数据分析平台R中国用户组R中国用户组电信运营商数据分析应用与案例讨论关系型数据库数据分析电信运营商数据分析应用与案例讨论金融数据分析应用与案例讨论R中国用户组R中国用户组电信运营商数据分析应用与案例讨论关系型数据库数据分析Hadoop分布式数据分析平台NoSQL及其应用NoSQL及其应用Oracle数据库与大数据解决方案R中国用户组关系型数据库数据分析Hadoop分布式数据分析平台R中国用户组数据分析与数据挖掘技术电信运营商数据分析应用与案例讨论Hadoop分布式数据分析平台关系型数据库数据分析Hadoop分布式数据分析平台Hadoop分布式数据分析平台数据分析与数据挖掘技术Hadoop分布式数据分析平台Oracle数据库与大数据解决方案电信运营商数据分析应用与案例讨论Hadoop分布式数据分析平台电信运营商数据分析应用与案例讨论Oracle数据库与大数据解决方案Hadoop分布式数据分析平台电信运营商数据分析应用与案例讨论Oracle数据库与大数据解决方案电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论Hadoop分布式数据分析平台电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论R中国用户组金融数据分析应用与案例讨论Hadoop分布式数据分析平台Hadoop分布式数据分析平台电信运营商数据分析应用与案例讨论Oracle数据库与大数据解决方案关系型数据库数据分析Hadoop分布式数据分析平台Oracle数据库与大数据解决方案R中国用户组电信运营商数据分析应用与案例讨论R中国用户组关系型数据库数据分析Oracle数据库与大数据解决方案Java语言开发技术Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组Hadoop分布式数据分析平台R中国用户组关系型数据库数据分析关系型数据库数据分析关系型数据库数据分析数据分析与数据挖掘技术Hadoop分布式数据分析平台Hadoop分布式数据分析平台关系型数据库数据分析Hadoop分布式数据分析平台R中国用户组关系型数据库数据分析供应链管理SAS中国用户组SAS中国用户组Hadoop分布式数据分析平台R中国用户组Hadoop分布式数据分析平台Hadoop分布式数据分析平台数据分析与数据挖掘技术Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案电信运营商数据分析应用与案例讨论关系型数据库数据分析电信运营商数据分析应用与案例讨论关系型数据库数据分析NoSQL及其应用金融数据分析应用与案例讨论关系型数据库数据分析数据分析与数据挖掘技术关系型数据库数据分析关系型数据库数据分析SAS中国用户组R中国用户组R中国用户组Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组Hadoop分布式数据分析平台关系型数据库数据分析Hadoop分布式数据分析平台R中国用户组数据分析与数据挖掘技术Oracle数据库与大数据解决方案NoSQL及其应用NoSQL及其应用Hadoop分布式数据分析平台Hadoop分布式数据分析平台Oracle数据库与大数据解决方案金融数据分析应用与案例讨论关系型数据库数据分析Oracle数据库与大数据解决方案关系型数据库数据分析电信运营商数据分析应用与案例讨论关系型数据库数据分析数据分析与数据挖掘技术Hadoop分布式数据分析平台Hadoop分布式数据分析平台关系型数据库数据分析关系型数据库数据分析数据分析与数据挖掘技术Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Hadoop分布式数据分析平台关系型数据库数据分析Hadoop分布式数据分析平台关系型数据库数据分析Oracle数据库与大数据解决方案供应链管理Hadoop分布式数据分析平台Hadoop分布式数据分析平台供应链管理关系型数据库数据分析Hadoop分布式数据分析平台SAS中国用户组电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论关系型数据库数据分析关系型数据库数据分析Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案关系型数据库数据分析Hadoop分布式数据分析平台Oracle数据库与大数据解决方案Hadoop分布式数据分析平台Hadoop分布式数据分析平台社会网络分析应用与案例讨论电信运营商数据分析应用与案例讨论关系型数据库数据分析电信运营商数据分析应用与案例讨论Oracle数据库与大数据解决方案SAS中国用户组Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Hadoop分布式数据分析平台Oracle数据库与大数据解决方案Hadoop分布式数据分析平台R中国用户组Java语言开发技术Java语言开发技术电信运营商数据分析应用与案例讨论SAS中国用户组Java语言开发技术电信运营商数据分析应用与案例讨论关系型数据库数据分析Oracle数据库与大数据解决方案供应链管理SAS中国用户组NoSQL及其应用Hadoop分布式数据分析平台关系型数据库数据分析Hadoop分布式数据分析平台SAS中国用户组Hadoop分布式数据分析平台R中国用户组电信运营商数据分析应用与案例讨论Hadoop分布式数据分析平台Oracle数据库与大数据解决方案R中国用户组NoSQL及其应用SAS中国用户组Hadoop分布式数据分析平台SAS中国用户组SAS中国用户组R中国用户组Hadoop分布式数据分析平台Mahout数据挖掘Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案关系型数据库数据分析R中国用户组Mahout数据挖掘Java语言开发技术R中国用户组NoSQL及其应用数据分析与数据挖掘技术Hadoop分布式数据分析平台NoSQL及其应用Hadoop分布式数据分析平台Hadoop分布式数据分析平台NoSQL及其应用关系型数据库数据分析关系型数据库数据分析SAS中国用户组NoSQL及其应用数据分析与数据挖掘技术关系型数据库数据分析Oracle数据库与大数据解决方案Java语言开发技术Hadoop分布式数据分析平台数据仓库技术Oracle数据库与大数据解决方案Java语言开发技术金融数据分析应用与案例讨论Oracle数据库与大数据解决方案R中国用户组数据仓库技术Oracle数据库与大数据解决方案R中国用户组R中国用户组关系型数据库数据分析关系型数据库数据分析Oracle数据库与大数据解决方案关系型数据库数据分析电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论关系型数据库数据分析Oracle数据库与大数据解决方案R中国用户组数据分析与数据挖掘技术数据分析与数据挖掘技术SAS中国用户组数据分析与数据挖掘技术电信运营商数据分析应用与案例讨论Hadoop分布式数据分析平台Oracle数据库与大数据解决方案电信运营商数据分析应用与案例讨论供应链管理Hadoop分布式数据分析平台关系型数据库数据分析关系型数据库数据分析电信运营商数据分析应用与案例讨论关系型数据库数据分析R中国用户组Hadoop分布式数据分析平台数据分析与数据挖掘技术关系型数据库数据分析关系型数据库数据分析关系型数据库数据分析Oracle数据库与大数据解决方案R中国用户组关系型数据库数据分析Oracle数据库与大数据解决方案关系型数据库数据分析Oracle数据库与大数据解决方案SAS中国用户组Oracle数据库与大数据解决方案R中国用户组图书资料和软件下载SAS中国用户组关系型数据库数据分析Hadoop分布式数据分析平台Hadoop分布式数据分析平台图书资料和软件下载SAS中国用户组电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论SAS中国用户组Mahout数据挖掘R中国用户组电信运营商数据分析应用与案例讨论数据分析与数据挖掘技术电信运营商数据分析应用与案例讨论图书资料和软件下载电信运营商数据分析应用与案例讨论Mahout数据挖掘电信运营商数据分析应用与案例讨论图书资料和软件下载金融数据分析应用与案例讨论电信运营商数据分析应用与案例讨论关系型数据库数据分析电信运营商数据分析应用与案例讨论R中国用户组R中国用户组金融数据分析应用与案例讨论Oracle数据库与大数据解决方案R中国用户组R中国用户组SAS中国用户组R中国用户组R中国用户组Java语言开发技术Hadoop分布式数据分析平台Hadoop分布式数据分析平台Oracle数据库与大数据解决方案R中国用户组关系型数据库数据分析电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论R中国用户组社会网络分析应用与案例讨论数据分析与数据挖掘技术R中国用户组R中国用户组关系型数据库数据分析SAS中国用户组电信运营商数据分析应用与案例讨论电信运营商数据分析应用与案例讨论R中国用户组关系型数据库数据分析R中国用户组Oracle数据库与大数据解决方案R中国用户组电信运营商数据分析应用与案例讨论NoSQL及其应用R中国用户组NoSQL及其应用Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案Oracle数据库与大数据解决方案R中国用户组图书资料和软件下载Hadoop分布式数据分析平台关系型数据库数据分析R中国用户组R中国用户组关系型数据库数据分析Oracle数据库与大数据解决方案SAS中国用户组关系型数据库数据分析关系型数据库数据分析金融数据分析应用与案例讨论Oracle数据库与大数据解决方案关系型数据库数据分析金融数据分析应用与案例讨论数据分析与数据挖掘技术NoSQL及其应用Java语言开发技术Oracle数据库与大数据解决方案金融数据分析应用与案例讨论NoSQL及其应用R中国用户组R中国用户组Oracle数据库与大数据解决方案R中国用户组Hadoop分布式数据分析平台Hadoop分布式数据分析平台互联网和电子商务数据分析应用与案例讨论Hadoop分布式数据分析平台数据分析与数据挖掘技术Hadoop分布式数据分析平台Hadoop分布式数据分析平台金融数据分析应用与案例讨论关系型数据库数据分析关系型数据库数据分析Hadoop分布式数据分析平台NoSQL及其应用NoSQL及其应用Hadoop分布式数据分析平台Hadoop分布式数据分析平台Hadoop分布式数据分析平台R中国用户组SAS中国用户组供应链管理SAS中国用户组SAS中国用户组SAS中国用户组Hadoop分布式数据分析平台R中国用户组Hadoop分布式数据分析平台供应链管理R中国用户组Hadoop分布式数据分析平台关系型数据库数据分析关系型数据库数据分析后使用快捷导航没有帐号?
查看: 315|回复: 8
关于Hadoop hdfs 数据冗余副本的问题?
注册会员, 积分 75, 距离下一级还需 125 积分
论坛徽章:2
& && & HDFS 的数据可以设置 冗余度。
& & 问题:
& &&&1& &是否可以理解为和普通的关系型数据库比,HDFS的存存储方式更耗费空间?
中级会员, 积分 205, 距离下一级还需 295 积分
论坛徽章:1
HDFS 冗余应该是用“空间”换取“安全”
中级会员, 积分 417, 距离下一级还需 83 积分
论坛徽章:2
个人理解HDFS不是数据库,主要是数据分析计算
高级会员, 积分 598, 距离下一级还需 402 积分
论坛徽章:7
HDFS属于一种文本数据库吧
注册会员, 积分 75, 距离下一级还需 125 积分
论坛徽章:2
beiyefenglin 发表于
HDFS属于一种文本数据库吧
HDFS 是文件系统,MongoDB 是非结构化的数据库
高级会员, 积分 660, 距离下一级还需 340 积分
论坛徽章:3
带着FS说是数据库....
中级会员, 积分 375, 距离下一级还需 125 积分
论坛徽章:2
本帖最后由 FINDHYG 于
10:52 编辑
先看下HDFS的定义:HDFS通过一个高效的分布式算法,将数据的访问和存储分布在大量的廉价服务器中,在用户访问时,动态计算网络最近和访问量最小的服务器给用户提供访问。
它的特点是:高容错性和高吞吐量。
那么为了实现这样的特性,数据冗余是必然选择,类似的关系型数据Oracle的ASM也一样有数据冗余度设置。
再回到楼主的问题,如果有1T的数据分别存储在Oracle数据文件和HDFS中,谁耗费的空间更大?
这个没有做实验,但是理论上应该是后者占用空间更大。
但是我理解其实空间不是最终目的,成本才是,HDFS用的是一堆廉价的服务器和存储,显然成本更低,而且会带来更好的性能和扩展性。
高级会员, 积分 589, 距离下一级还需 411 积分
论坛徽章:6
由于hadoop的环境是分布式的集群环境,数据离散的保存在各个datanode结点,在一个庞大的集群环境下,结点损坏、网络问题等都是不可避免的,但是为了数据的完整性就不得不使用一定的数据冗余HDFS写文件过程分析 - 推酷
HDFS写文件过程分析
HDFS是一个分布式文件系统,在HDFS上写文件的过程与我们平时使用的单机文件系统非常不同,从宏观上来看,在HDFS文件系统上创建并写一个文件,流程如下图(来自《Hadoop:The Definitive Guide》一书)所示:
具体过程描述如下:
Client调用DistributedFileSystem对象的create方法,创建一个文件输出流(FSDataOutputStream)对象
通过DistributedFileSystem对象与Hadoop集群的NameNode进行一次RPC远程调用,在HDFS的Namespace中创建一个文件条目(Entry),该条目没有任何的Block
通过FSDataOutputStream对象,向DataNode写入数据,数据首先被写入FSDataOutputStream对象内部的Buffer中,然后数据被分割成一个个Packet数据包
以Packet最小单位,基于Socket连接发送到按特定算法选择的HDFS集群中一组DataNode(正常是3个,可能大于等于1)中的一个节点上,在这组DataNode组成的Pipeline上依次传输Packet
这组DataNode组成的Pipeline反方向上,发送ack,最终由Pipeline中第一个DataNode节点将Pipeline ack发送给Client
完成向文件写入数据,Client在文件输出流(FSDataOutputStream)对象上调用close方法,关闭流
调用DistributedFileSystem对象的complete方法,通知NameNode文件写入成功
下面代码使用Hadoop的API来实现向HDFS的文件写入数据,同样也包括创建一个文件和写数据两个主要过程,代码如下所示:
static String[] contents = new String[] {
&aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&,
&bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&,
&cccccccccccccccccccccccccccccccccccccccccccccccccccccccccc&,
&dddddddddddddddddddddddddddddddd&,
&eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee&,
public static void main(String[] args) {
String file = &hdfs://h1:8020/data/test/test.log&;
Path path = new Path(file);
Configuration conf = new Configuration();
FileSystem fs =
FSDataOutputStream output =
fs = path.getFileSystem(conf);
output = fs.create(path); // 创建文件
for(String line : contents) { // 写入数据
output.write(line.getBytes(&UTF-8&));
output.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
output.close();
} catch (IOException e) {
e.printStackTrace();
结合上面的示例代码,我们先从fs.create(path);开始,可以看到FileSystem的实现DistributedFileSystem中给出了最终返回FSDataOutputStream对象的抽象逻辑,代码如下所示:
public FSDataOutputStream create(Path f, FsPermission permission,
boolean overwrite,
int bufferSize, short replication, long blockSize,
Progressable progress) throws IOException {
statistics.incrementWriteOps(1);
return new FSDataOutputStream
(dfs.create(getPathName(f), permission, overwrite, true, replication, blockSize, progress, bufferSize), statistics);
上面,DFSClient dfs的create方法中创建了一个OutputStream对象,在DFSClient的create方法:
public OutputStream create(String src,
FsPermission permission,
boolean overwrite,
boolean createParent,
short replication,
long blockSize,
Progressable progress,
int buffersize
) throws IOException {
创建了一个DFSOutputStream对象,如下所示:
final DFSOutputStream result = new DFSOutputStream(src, masked,
overwrite, createParent, replication, blockSize, progress, buffersize,
conf.getInt(&io.bytes.per.checksum&, 512));
下面,我们从DFSOutputStream类开始,说明其内部实现原理。
DFSOutputStream内部原理
打开一个DFSOutputStream流,Client会写数据到流内部的一个缓冲区中,然后数据被分解成多个Packet,每个Packet大小为64k字节,每个Packet又由一组chunk和这组chunk对应的checksum数据组成,默认chunk大小为512字节,每个checksum是对512字节数据计算的校验和数据。
当Client写入的字节流数据达到一个Packet的长度,这个Packet会被构建出来,然后会被放到队列dataQueue中,接着DataStreamer线程会不断地从dataQueue队列中取出Packet,发送到复制Pipeline中的第一个DataNode上,并将该Packet从dataQueue队列中移到ackQueue队列中。ResponseProcessor线程接收从Datanode发送过来的ack,如果是一个成功的ack,表示复制Pipeline中的所有Datanode都已经接收到这个Packet,ResponseProcessor线程将packet从队列ackQueue中删除。
在发送过程中,如果发生错误,所有未完成的Packet都会从ackQueue队列中移除掉,然后重新创建一个新的Pipeline,排除掉出错的那些DataNode节点,接着DataStreamer线程继续从dataQueue队列中发送Packet。
下面是DFSOutputStream的结构及其原理,如图所示:
我们从下面3个方面来描述内部流程:
创建Packet
Client写数据时,会将字节流数据缓存到内部的缓冲区中,当长度满足一个Chunk大小(512B)时,便会创建一个Packet对象,然后向该Packet对象中写Chunk Checksum校验和数据,以及实际数据块Chunk Data,校验和数据是基于实际数据块计算得到的。每次满足一个Chunk大小时,都会向Packet中写上述数据内容,直到达到一个Packet对象大小(64K),就会将该Packet对象放入到dataQueue队列中,等待DataStreamer线程取出并发送到DataNode节点。
发送Packet
DataStreamer线从dataQueue队列中取出Packet对象,放到ackQueue队列中,然后向DataNode节点发送这个Packet对象所对应的数据。
发送一个Packet数据包以后,会有一个用来接收ack的ResponseProcessor线程,如果收到成功的ack,则表示一个Packet发送成功。如果成功,则ResponseProcessor线程会将ackQueue队列中对应的Packet删除。
DFSOutputStream初始化
首先看一下,DFSOutputStream的初始化过程,构造方法如下所示:
DFSOutputStream(String src, FsPermission masked, boolean overwrite,
boolean createParent, short replication, long blockSize, Progressable progress,
int buffersize, int bytesPerChecksum) throws IOException {
this(src, blockSize, progress, bytesPerChecksum, replication);
computePacketChunkSize(writePacketSize, bytesPerChecksum); // 默认 writePacketSize=64*1024(即64K),bytesPerChecksum=512(没512个字节计算一个校验和),
if (createParent) { // createParent为true表示,如果待创建的文件的父级目录不存在,则自动创建
namenode.create(src, masked, clientName, overwrite, replication, blockSize);
namenode.create(src, masked, clientName, overwrite, false, replication, blockSize);
} catch(RemoteException re) {
throw re.unwrapRemoteException(AccessControlException.class,
FileAlreadyExistsException.class,
FileNotFoundException.class,
NSQuotaExceededException.class,
DSQuotaExceededException.class);
streamer.start(); // 启动一个DataStreamer线程,用来将写入的字节流打包成packet,然后发送到对应的Datanode节点上
上面computePacketChunkSize方法计算了一个packet的相关参数,我们结合代码来查看,如下所示:
int chunkSize = csize + checksum.getChecksumSize();
int n = DataNode.PKT_HEADER_LEN + SIZE_OF_INTEGER;
chunksPerPacket = Math.max((psize - n + chunkSize-1)/chunkSize, 1);
packetSize = n + chunkSize*chunksPerP
我们用默认的参数值替换上面的参数,得到:
int chunkSize = 512 + 4;
int n = 21 + 4;
chunksPerPacket = Math.max((64*1024 - 25 + 516-1)/516, 1);
packetSize = 25 + 516*127;
上面对应的参数,说明如下表所示:
每个chunk的字节数(数据+校验和)
每个chunk数据的字节数
每个packet的最大字节数(不包含header)
DataNode.PKT_HEADER_LEN
每个packet的header的字节数
chunksPerPacket
组成每个packet的chunk的个数
packetSize
25+516*127=65557
每个packet的字节数(一个header+一组chunk)
在计算好一个packet相关的参数以后,调用create方法与Namenode进行RPC请求,请求创建文件:
if (createParent) { // createParent为true表示,如果待创建的文件的父级目录不存在,则自动创建
namenode.create(src, masked, clientName, overwrite, replication, blockSize);
namenode.create(src, masked, clientName, overwrite, false, replication, blockSize);
远程调用上面方法,会在FSNamesystem中创建对应的文件路径,并初始化与该创建的文件相关的一些信息,如租约(向Datanode节点写数据的凭据)。文件在FSNamesystem中创建成功,就要初始化并启动一个DataStreamer线程,用来向Datanode写数据,后面我们详细说明具体处理逻辑。
Packet结构与定义
Client向HDFS写数据,数据会被组装成Packet,然后发送到Datanode节点。Packet分为两类,一类是实际数据包,另一类是heatbeat包。一个Packet数据包的组成结构,如图所示:
上图中,一个Packet是有一个Header和Data两部分组成,其中Header部分包含了一个Packet的概要属性信息,如下表所示:
4 + dataLen + checksumLen
offsetInBlock
Packet在Block中偏移量
Packet序列号,在同一个Block唯一
lastPacketInBlock
是否是一个Block的最后一个Packet
dataPos – dataStart,不包含Header和Checksum的长度
Data部分是一个Packet的实际数据部分,主要包括一个4字节校验和(Checksum)与一个Chunk部分,Chunk部分最大为512字节。
在构建一个Packet的过程中,首先将字节流数据写入一个buffer缓冲区中,也就是从偏移量为25的位置(checksumStart)开始写Packet数据的Chunk Checksum部分,从偏移量为533的位置(dataStart)开始写Packet数据的Chunk Data部分,直到一个Packet创建完成为止。如果一个Packet的大小未能达到最大长度,也就是上图对应的缓冲区中,Chunk Checksum与Chunk Data之间还保留了一段未被写过的缓冲区位置,这种情况说明,已经在写一个文件的最后一个Block的最后一个Packet。在发送这个Packet之前,会将Chunk Data部分向前移动,使得Chunk Data 1与Chunk Checksum N相邻,然后才会被发送到DataNode节点。
我们看一下Packet对应的Packet类定义,定义了如下一些字段:
// only one of buf and buffer is non-null
// sequencenumber of buffer in block
// 该packet在block中的偏移量
boolean lastPacketInB
// is this the last packet in block?
// number of chunks currently in packet
// 一个packet中包含的chunk的个数
Packet类有一个默认的没有参数的构造方法,它是用来做heatbeat的,如下所示:
Packet() {
this.lastPacketInBlock =
this.numChunks = 0;
this.offsetInBlock = 0;
this.seqno = HEART_BEAT_SEQNO; // 值为-1
int packetSize = DataNode.PKT_HEADER_LEN + SIZE_OF_INTEGER; // 21+4=25
buf = new byte[packetSize];
checksumStart = dataStart = packetS
checksumPos = checksumS
dataPos = dataS
maxChunks = 0;
通过代码可以看到,一个heatbeat的内容,实际上只有一个长度为25字节的header数据。通过this.seqno = HEART_BEAT_SEQNO;的值可以判断一个packet是否是heatbeat包,如果seqno为-1表示这是一个heatbeat包。
Client发送Packet数据
可以DFSClient类中看到,发送一个Packet之前,首先需要向选定的DataNode发送一个Header数据包,表明要向DataNode写数据,该Header的数据结构,如图所示:
上图显示的是Client发送Packet到第一个DataNode节点的Header数据结构,主要包括待发送的Packet所在的Block(先向NameNode分配Block ID等信息)的相关信息、Pipeline中另外2个DataNode的信息、访问令牌(Access Token)和校验和信息,Header中各个字段及其类型,详见下表:
Transfer Version
Client与DataNode之间数据传输版本号,由常量DataTransferProtocol.DATA_TRANSFER_VERSION定义,值为17
操作类型,由常量DataTransferProtocol.OP_WRITE_BLOCK定义,值为80
Block的ID值,由NameNode分配
时间戳(Generation Stamp),NameNode分配blkId的时候生成的时间戳
DataNode复制Pipeline中DataNode节点的数量
Recovery Flag
Recover标志
Client主机的名称,在使用Text进行序列化的时候,实际包含长度len与主机名称字符串ClientHost
是否发送src node的信息,默认值为false,不发送src node的信息
nonSrcDNCnt
由Client写的该Header数据,该数不包含Pipeline中第一个节点(即为DNCnt-1)
DatanodeInfo
DataNode信息,包括StorageID、InfoPort、IpcPort、capacity、DfsUsed、remaining、LastUpdate、XceiverCount、Location、HostName、AdminState
DatanodeInfo
DataNode信息,包括StorageID、InfoPort、IpcPort、capacity、DfsUsed、remaining、LastUpdate、XceiverCount、Location、HostName、AdminState
Access Token
访问令牌信息,包括IdentifierLength、Identifier、PwdLength、Pwd、KindLength、Kind、ServiceLength、Service
CheckSum Header
DataChecksum
校验和Header信息,包括type、bytesPerChecksum
Header数据包发送成功,Client会收到一个成功响应码(DataTransferProtocol.OP_STATUS_SUCCESS = 0),接着将Packet数据发送到Pipeline中第一个DataNode上,如下所示:
Packet one =
one = dataQueue.getFirst(); // regular data packet
ByteBuffer buf = one.getBuffer();
// write out data to remote datanode
blockStream.write(buf.array(), buf.position(), buf.remaining());
if (one.lastPacketInBlock) { // 如果是Block中的最后一个Packet,还要写入一个0标识该Block已经写入完成
blockStream.writeInt(0); // indicate end-of-block
否则,如果失败,则会与NameNode进行RPC调用,删除该Block,并把该Pipeline中第一个DataNode加入到excludedNodes列表中,代码如下所示:
if (!success) {
(&Abandoning & + block);
namenode.abandonBlock(block, src, clientName);
if (errorIndex & nodes.length) {
(&Excluding datanode & + nodes[errorIndex]);
excludedNodes.add(nodes[errorIndex]);
// Connection failed.
Let's wait a little bit and retry
DataNode端服务组件
数据最终会发送到DataNode节点上,在一个DataNode上,数据在各个组件之间流动,流程如下图所示:
DataNode服务中创建一个后台线程DataXceiverServer,它是一个SocketServer,用来接收来自Client(或者DataNode Pipeline中的非最后一个DataNode节点)的写数据请求,然后在DataXceiverServer中将连接过来的Socket直接派发给一个独立的后台线程DataXceiver进行处理。所以,Client写数据时连接一个DataNode Pipeline的结构,实际流程如图所示:
每个DataNode服务中的DataXceiver后台线程接收到来自前一个节点(Client/DataNode)的Socket连接,首先读取Header数据:
Block block = new Block(in.readLong(), dataXceiverServer.estimateBlockSize, in.readLong());
(&Receiving & + block + & src: & + remoteAddress + & dest: & + localAddress);
int pipelineSize = in.readInt(); // num of datanodes in entire pipeline
boolean isRecovery = in.readBoolean(); // is this part of recovery?
String client = Text.readString(in); // working on behalf of this client
boolean hasSrcDataNode = in.readBoolean(); // is src node info present
if (hasSrcDataNode) {
srcDataNode = new DatanodeInfo();
srcDataNode.readFields(in);
int numTargets = in.readInt();
if (numTargets & 0) {
throw new IOException(&Mislabelled incoming datastream.&);
DatanodeInfo targets[] = new DatanodeInfo[numTargets];
for (int i = 0; i & targets. i++) {
DatanodeInfo tmp = new DatanodeInfo();
tmp.readFields(in);
targets[i] =
Token&BlockTokenIdentifier& accessToken = new Token&BlockTokenIdentifier&();
accessToken.readFields(in);
上面代码中,读取Header的数据,与前一个Client/DataNode写入Header字段的顺序相对应,不再累述。在完成读取Header数据后,当前DataNode会首先将Header数据再发送到Pipeline中下一个DataNode结点,当然该DataNode肯定不是Pipeline中最后一个DataNode节点。接着,该DataNode会接收来自前一个Client/DataNode节点发送的Packet数据,接收Packet数据的逻辑实际上在BlockReceiver中完成,包括将来自前一个Client/DataNode节点发送的Packet数据写入本地磁盘。在BlockReceiver中,首先会将接收到的Packet数据发送写入到Pipeline中下一个DataNode节点,然后再将接收到的数据写入到本地磁盘的Block文件中。
DataNode持久化Packet数据
在DataNode节点的BlockReceiver中进行Packet数据的持久化,一个Packet是一个Block中一个数据分组,我们首先看一下,一个Block在持久化到磁盘上的物理存储结构,如下图所示:
每个Block文件(如上图中blk_文件)都对应一个meta文件(如上图中blk__.meta文件),Block文件是一个一个Chunk的二进制数据(每个Chunk的大小是512字节),而meta文件是与每一个Chunk对应的Checksum数据,是序列化形式存储。
写文件过程中Client/DataNode与NameNode进行RPC调用
Client在HDFS文件系统中写文件过程中,会发生多次与NameNode节点进行RPC调用来完成写数据相关操作,主要是在如下时机进行RPC调用:
写文件开始时创建文件:Client调用create在NameNode节点的Namespace中创建一个标识该文件的条目
在Client连接Pipeline中第一个DataNode节点之前,Client调用addBlock分配一个Block(blkId+DataNode列表+租约)
如果与Pipeline中第一个DataNode节点连接失败,Client调用abandonBlock放弃一个已经分配的Block
一个Block已经写入到DataNode节点磁盘,Client调用fsync让NameNode持久化Block的位置信息数据
文件写完以后,Client调用complete方法通知NameNode写入文件成功
DataNode节点接收到并成功持久化一个Block的数据后,DataNode调用blockReceived方法通知NameNode已经接收到Block
具体RPC调用的详细过程,可以参考源码。
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见

我要回帖

更多关于 mongodb数据库备份 的文章

 

随机推荐