hadoop的配置文件
hadoop的每个组件都使用一个XML文件配置,核心属性在core-site.xml中,HDFS在hdfs-site.xml配置文件中配置,MapReduce属性在mapred-site.xml配置文件中配置,这些文件都在conf子目录中。
hadoop可以在三个模式中运行
本地模式、伪分布模式,完全分布模式
本地模式:没有守护进程会进行运行而且一切都运行在单个JVM上,独立模式适用于在开发过程中运行MapReduce程序,因为它很容易测试和调试。
伪分布模式:hadoop的守护程序在本地计算机上运行,因此是在小范围内模拟集群
完全分布模式:hadoop的守护程序在一群机器上运行,在后面会详细描述
SSH的配置
生成SHH免密码登陆两种方式:
1
(1)执行命令ssh-keygen -t rsa 产生密钥文件,一直回车。
(2)执行命令 cp~/.ssh/id_rsa.pub ~/.ssh/authorized_keys 产生授权文件
(3)验证:执行命令 sshhadoop221 如果不输入密码就正确了。
2
ssh-keygen–t rsa –P ‘’–f ~/.ssh/id_rsa
cat~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
sshlocalhost测试
如果没有成功,若原本存在.ssh文件夹,先将其删除,再重新执行上面步骤。
HDFS文件系统格式化
可以在使用hadoop之前,格式化一个全新的HDFS文件系统:hadoop namenode –format
HDFS的设计前提与目标
1. 硬件错误是常态而不是异常。错误检测并快速自动恢复是HDFS的最核心的设计目标
2. 流失数据访问,运行在HDFS上的应用主要是以流失数据读取为主,做批量处理而不是用户交互处理,因此HDFS更关注数据访问的高吞吐量。
3. 大规模数据集
4. 简单一致性模型
5. 移动计算比移动数据更划算。
一个集群拥有一个namenode和一些datanode,NameNode管理文件系统的元数据,DataNode存储实际的数据,客户端通过与NameNode和DatNode的交互访问文件系统。客户端联系NameNode以获取文件的元数据,而真正的文件I/O操作时直接和DataNode进行交互的。
NameNode负责管理文件系统的命名空间,记录文件数据块在每个DataNode上的位置和副本信息,协调客户端对文件的访问,以及记录命名空间内的改动或命名本身属性的改动。
DataNode负责他们所在的无力节点上的存储管理。HDFS开放文件系统的命名空间一遍用户文件的形式存储数据。HDFS的数据都是“一次写入、多次读取”。
HDFS还设有SecondaryNameNode节点,他辅助NameNode处理映像文件盒事务日志。NameNode启动的时候合并映像文件和事务日志,而SecondaryNameNode会周期地从NameNode上复制映像文件和合并事务日志到临时目录,合并生成新的映像文件后再重新上传到NameNode,NameNode更新映像文件并清理事务日志,使得事务日志的大小始终控制在可配置的限度下。
保障HDFS的可靠性措施
在hadoop conf/配置文件目录下,可配置hdfs-site.xml其中配置备份的数量
HDFS的一些命令
删除
查看内容
退出和进入安全模式
hadoop的守护进程
start-dfs.sh
start-mapred.sh
stop-dfs.sh
start-mapred.sh
--MapReduce的概述
MR的两个阶段Map和Reduce,用户只需要实现map()和reduce()两个函数
(进)Map函数中接收数据来源,是Reduce处理数据的来源,是最终的输出(出)
指定Map的输入,Reduce的输出
都与hdfs相关
这两个函数的形参是以key,value的形式存在的
--MapReduce原理
MapReduce是主从式结构,jobTracker是master,TaskTracker是slaves
----map任务处理
----reduce任务处理
--MapReduce的执行流程
HBase的安装和hadoop的版本是有关系的,根据hadoop的版本匹配不同版本hbase的版本,如果不匹配会有一些匪夷所思的错误
新增DataNode节点
添加一个新的DataNode节点,首先在新加节点上安装好Hadoop,要和NameNode使用相同的胚子(可以直接从NameNode复制),修改$HADOOP_HOME/conf/master文件,加入NameNode主机名,然后再NameNode节点上修改$HADOOP_HOME/conf/slaves文件,加入新的节点主机名,再重新建立SSH连接,运行。
在没有任何节点的情况下,master和slaves的配置都是localhost
负载均衡
HDFS的数据在各个DataNode中的分布可能很不均匀,尤其是在DataNode节点出现故障或者新增DataNode节点的时候,新增数据块NameNode对DataNode节点的选择策略也有可能导致数据分布的不均匀,可以通过命令:
重新平衡DataNode上的数据块分布。
HDFS的API
由于本机不是Linux系统,eclipse操作在本机win7,hadoop安装在虚拟机Linux中
1.上传本地文件到HDFS
publicclass CopyFile {
publicstaticStringHDFS_PATH = "hdfs://hadoop221:9000";
publicstaticvoid main(String[] args)throwsIOException, URISyntaxException {
Configuration conf = new Configuration();
//获取hdfs
FileSystem hdfs = FileSystem.get(new URI(HDFS_PATH), conf);
Path src = new Path("F:\\test.txt");
Path dst = new Path("hdfs://hadoop221:9000/test");
hdfs.copyFromLocalFile(src, dst);
System.out.println("Upload To :: "+conf.get("fs.default.name"));
finalFileStatus[] files = hdfs.listStatus(dst);
for(FileStatus file : files) {
System.out.println("filepath :: "+file.getPath());
}
}
}
上传成功查看 hdfs
2.创建带内容的文件
publicclass CreateFile{
publicstaticvoid main(String[] args)throwsIOException, URISyntaxException {
finalConfiguration conf =new Configuration();
finalFileSystem hdfs = FileSystem.get(newURI("hdfs://hadoop221:9000"), conf);
finalbyte[] bytes ="my name is hadoop".getBytes();
finalPath path =new Path("hdfs://hadoop221:9000/test");
if(hdfs.exists(path)){
hdfs.delete(path, true);
}
finalFSDataOutputStream outputStream = hdfs.create(path);
outputStream.write(bytes, 0,bytes.length);
}
}
3.重命名hdfs上的文件
publicclass RenameFile{
publicstaticfinal StringHDFS_PATH = "hdfs://hadoop221:9000";
publicstaticvoid main(String[] args)throwsURISyntaxException, IOException {
finalURI uri =new URI("hdfs://hadoop221:9000/test");
finalConfiguration conf =new Configuration();
finalFileSystem hdfs = FileSystem.get(uri, conf);
finalPath frompath =new Path("hdfs://hadoop221:9000/test");
finalPath renamepath =new Path("hdfs://hadoop221:9000/renametest");
finalbooleanrename = hdfs.rename(frompath, renamepath);
System.out.println(rename);
}
}
查看
4.删除hdfs文件
publicclass DeleteFile{
publicstaticStringHDFS_PATH = "hdfs://hadoop221:9000";
publicstaticvoid main(String[] args)throwsURISyntaxException, IOException {
finalConfiguration conf =new Configuration();
finalURI uri =new URI(HDFS_PATH);
finalPath deletepath =new Path("hdfs://hadoop221:9000/renametest");
finalFileSystem hdfs = FileSystem.get(uri, conf);
finalbooleanisDelete = hdfs.delete(deletepath,true);
System.out.println(isDelete);
}
}
查看
还有其他API,获取最后修改时间,获取文件所在节点等等。
MapReduce编程模型
MapReduce采用“分而治之”的思想,把对大规模数据集的操作分发给一个主节点管理下的各个分节点共同完成,然后通过整合各分节点的中间结果,得到最终的结果。
上述过程被MapReduce高度抽象成两个函数:map和reduce。
map负责把任务分解成多个任务,reduce负责把分解后多任务处理的结果汇总起来。
在Map阶段,MpaReduce框架将任务的输入数据分割成固定大小的片段(splits),随后将每个split进一步分解成一批键值对<K1, V1>。Hadoop为每一个split创建一个map任务用于执行用户自定义的map函数,并将对应split中的<K1, V1>对作为输入,得到计算的中间结果<K2, V2>。接着讲中间结果按照K2进行排序,并将key值相同的value进行合并形成一个新的列表<K2, list(V2)>元组,最后再根据key值的范围将这些元祖进行分组,对应不同的reduce任务。
在Reduce阶段,reduce把不同map接收来的数据整合在一起并进行排序,然后调用用户自定义的reduce函数,对输入<K2, list(V2)>对进行相应的处理,得到键值对<K3, V3>并输出到HDFS上,既然MapReduce框架为每一个split创建一个map,那么谁来确定reduce的数目呢?答案时用户。在mapred.site.xml配置文件中有一个表示reduces数目的属性mapred.reduce.tasks,该属性的默认值为1,开发人员可以通过job.setNumReduceTasks()方法重新设置改值。
map的输出结果被直接写到了本地硬盘而非HDFS,因为Mapper输出的是中间数据,当任务完成之后就可以直接删除了,如果存储在HDFS上,HDFS的备份机制会造成性能的损失。
编写MapReduce基本程序
首先去http://www.nber.org/patents/,获取专利引用数据集cite75_99.txt和专利描述数据集apat63_99.txt
使用 MapReduce构建HBase索引
Hbase索引主要用于提高Hbase中表数据的访问速度,有效地避免了全表扫描。
Hbase中的表根据行健分成了多个Regions,通常一个Region的一行都会包含的较多的数据,如果以列值作为查询条件,就只能从第一行数据开始往下查找,直到找到数据为止,这显然很低效。
如果将经常被查询的列作为行健、行健作为列重新构造一张表,即可实现根据列值快速地定位相关数据所在的行,这就是索引。
------------------------------------------------------------------------------------------------------------
hadoop数据处理平台存在的问题
1) NameNode/JobTracker单点故障,hadoop采用的是master/slaves架构,该架构管理起来比较简单,但存在致命的单点故障和空间容量不足等缺点,这已经严重影响了hadoop的可扩展性。
2) HDFS小文件问题,在HDFS中,任何block,文件或者目录在内存中均以对象的形式存储,每个对象约占150byte,如果有10000000个小文件,每个文件占用一个block,则namenode需要2G,如果存储1亿个文件,则namenode需要20G,这样namenode内存容量严重制约了集群的扩展。
3) jobTracker同时进行监控和调度,负载过大,为了解决该问题,yahoo已经开始着手设计下一代hadoop MapReduce,他们的主要思路是将监控和调度分离,独立出一个专门的组件进行监控,而jobtracker只负责总体调度,至于局部调度,交给作业所在的client
4) 数据处理性能,很多实验表明,其处理性能有很大的提升空间,hadoop类似于数据库,可能需要专门的优化工程师根据实际的应用需要对hadoop进行调优
MapReduce调优
避免不必要的reduce任务、外部文件引入、为job添加一个Combiner、中庸Writable类型、使用StringBuffer而不是String、调试程序跟踪程序的瓶颈。
参数优化
hadoop通用参数调整
dfs.namnode.handler.count或mapred.job.tracker.handler.count是namenode和jobtracker 中用于处理RPC的线程数 默认是10
对于较大集群可适当调大比如64
dfs.datanode.handler.count是datanode上用于处理RPC的线程数默认是3 对于较大集群可适当调大比如8TaskTracker.http.
threads 是HTTP server上的线程数运行在每个TaskTracker上用于处理map task输出大集群可以设置为40~50
dfs.block.size HDFS中的数据block大小默认是64M 对于较大集群可以设置为128或264Mmapred.local.dir和dfs.data.dir
这两个参数配置的值应当是分布在各个磁盘上的目录这样可以充分利用IO读写能力
map task 相关配置
io.sort.mb,当map task开始运算并产生中间数据时,其产生的中间结果并非直接写入磁盘,而是利用内存buffer来进行已经产
生的部分结果的缓存。当buffer达到一定阈值,会启动一个后台线程对buffer的内容进行排序然后写入本地磁盘(一个spill文件)。
默认是100M对于大集群可设置为200M。
io.sort.spill.percent 这个值就是上述buffer的阈值,默认是80% ,当buffer中的数据达到这个阈值,后台线程会起来对buffer中已
有的数据进行排序,然后写入磁盘
io.sort.factor 当一map task执行完之后,本地磁盘上(mapred.local.dir)有若干个spill文件,map task最后做的一件事就是执行
merge sort,把这些spill文件合成一个文件(partition)。执行merge sort的时候,每次同时打开多少个spill文件由该参数决定。打开的文件越多,不一定merge sort就越快,所以要根据数据情况适当的调整
mapred.compress.map.output是否对中间结果和最终结果进行压缩,如果是,指定压缩方式,推荐使用LZO压缩。Inter内部测试
表明,相比未压缩,使用LZO的作业运行时间减少60%
reduce task相关配置
mapred.reduce.parallel.copies表示Reduceshuffle阶段copier线程数。reduce分为三个阶段,分别是copy->sort->reduce。 copy即
shuffle,当job 已完成5%的map tasks数量之后开始启动reduce,从不同的已经完成的map上去下载属于自己这个reduce部分数据,由于map数量很多,对于一个reduce来说,可以并行的从多个map下载。 默认值5,对于大集群可调整为16-25
mapred.job.shuffle.input.buffer.percent(default0.7),在shuffle阶段下载来的map数据,并不是立刻写入磁盘,而是先缓存在内存
中,这个百分比是shuffle在reduce内存中的数据最多使用量为: 0.7 ×maxHeap of reduce task。
这种基于参数的调优比较“静态”,因为一套参数配置只对于一类作业是最优的。通过对这些参数的研究,可以寻找参数配置与
不同作业特征之间的关联。(未完结)