一、Eclipse中准备开发环境。
准备:解压hadoop、hadoop-src.建立hadoop-lib目录放入所有jar包。bin下替换一下。还有hadoop.dll放入system32下。
这个放入eclipse下plugins下。
1、配置环境变量:HADOOP_HOME,加到PATH中(与jdk类似,不再描诉),配置HADOOP_USER_ROOT(值为root)
2、eclipse使用高一些的版本,jdk使用1.7.show view-->other-->mapreduce localtions打开。
新建项目,preferences-->java-->buildpath-->user libray 新建一个后将外部的hadoop-lib引入。项目huildpath 使用刚才的user libray
再引入个Junit方便测试。项目下新建conf/ha目录下面将之前搭建的nameNode中的core-site.xml和hdfs-site.xml放入其中。
这个ha目录 build path-->use as source
环境准备完毕。
二、java代码操作HDFS
ps:好几天不写,还是Java爽。代码如下:
Configuration config = null;
FileSystem fs = null;
@Before
public void conn() throws IOException{
//连接集群,true读取默认信息
config = new Configuration(true);
//api集群操作底层集群,此角色相当于客户端角色
fs = FileSystem.get(config);
}
/**
* 创建目录
* @throws IOException
*/
@Test
public void mkdirs() throws IOException{
Path path = new Path("/temp829");
if(fs.exists(path)){
fs.delete(path,true);
}
fs.mkdirs(path);
}
/**
* 上传文件
* @throws IOException
*/
@Test
public void upFile() throws IOException{
//输出路径
Path outPath = new Path("/temp829/test.txt");
//文件操作对象
FSDataOutputStream fdos = fs.create(outPath);
//获取输入流 (以文件读取为例)
InputStream is = new BufferedInputStream(new FileInputStream("F:\\赵俊杰大数据\\03 hadoop\\06test\\test.txt"));
//hadoop封装类,会自动将输入流数据读取过去
IOUtils.copyBytes(is, fdos, config, true);
}
/**
* 获取文件信息
* @throws IOException
*/
@Test
public void getFileInformation() throws IOException{
Path path = new Path("/user/root/test.txt");
FileStatus file = fs.getFileStatus(path);
//文件的分布信息既block列表
BlockLocation[] blks = fs.getFileBlockLocations(file,0,file.getLen());
/*for (BlockLocation blk : blks) {
System.out.println(blk);
}*/
//拿到输入流
FSDataInputStream fdis = fs.open(path);
//从某下表开始查找
fdis.seek(1048576);
System.out.println((char)fdis.readByte());
System.out.println((char)fdis.readByte());
System.out.println((char)fdis.readByte());
System.out.println((char)fdis.readByte());
}
@After
public void close() throws IOException{
fs.close();
}
三、MapReduce分布式计算框架
由Map和Reduce两部分组成。MR计算大致流程:
上传文件至hdfs后,首先、文本文件先进行一个K-V映射转为k-V模式,然后交给Map框架映射成为中间数据集(K-V)。完成后被reduce拉取,“相同的”key为组进行归并,调用一次reduce方法处理,方法内迭代这一组的数据进行计算。
MR整体分为四大阶段:split(分片)--》map(中间的数据映射)-->shuffler(数据拉取)-->Reduce
为什么分片?既分片与map对应为什么不是block与map对应呢?
为了防止单个block过大导致的map计算缓慢的问题进而阻塞影响计算结果效率。由于blocklocation 中存在偏移量和size所以完全可以分片(逻辑上的),若单个block过大则将单个分成多篇计算。进而提高集群计算效率稳定性。
reduce的工作:将对应数据进行迭代计算。
map就是逻辑计算,中间映射方式由程序员设计,k-v模型除了key-value只玩还会生成partition(分区),这个分区是由reduce决定的,数据昨晚映射后会按照分区排序且同一分区内部的key进行排序。然后数据读到缓冲区(默认100M)。缓冲区将每次的数据读取到磁盘,后将这些小文件合并成为大文件,并再次对内容排序。然后传输到reduce处,由于有多个map存在,多个map的处理结果文件(处理完成有先后顺序)先完成的几个先合并,最后处理成几个文件(不一定是一个)reduce通过归并算法计算完成。