赞
踩
Hadoop
权威指南》读书笔记之六 — Chapter 6
xml
文件的读取resources
文件夹中Configuration
类的 addResource()
方法.xml
文件中的属性xml
文件可以通过 variable expansion
的方式进行设置。 但是这个设置值的顺序是不是得有个先后呢?这个定义值的顺序是没有先后关系要求的,只要属性是全局唯一的,那么就能获取到。xml
文件中如果某个属性是finla修饰,则不能够在其它的.xml
文件中重置了。import org.apache.hadoop.conf.Configuration; public class PrintConfiguration { public static void main(String[] args) { Configuration conf = new Configuration(); conf.addResource("configuration-1.xml"); conf.addResource("configuration-2.xml"); System.out.println(conf.get("color")); //getInt: Get the value of the name property as an int. //如果不存在值,则直接返回 defaultValue System.out.println(conf.getInt("size",0)); System.out.println("weight: "+conf.get("weight")); //variable expansion System.out.println("size-weight: "+conf.get("size-weight")); // System.setProperty("length", "2"); System.out.println("length: "+conf.get("length")); } }
执行结果如下:
configuration-1.xml
<?xml version="1.0"?> <configuration> <property> <name>size-weight</name> <value>${size},${weight}</value> <description>Size and weight</description> </property> <property> <name>color</name> <value>yellow</value> <description>Color</description> </property> <property> <name>size</name> <value>10</value> <description>Size</description> </property> <property> <name>weight</name> <value>heavy</value> <final>true</final> <description>Weight</description> </property> </configuration>
configuration-2.xml
<?xml version="1.0"?> <configuration> <property> <name>color</name> <value>blue</value> <description>Color</description> </property> <property> <name>size</name> <value>20</value> <description>Size</description> </property> <property> <name>weight</name> <value>light</value> <description>Weight</description> </property> </configuration>
configuration-2.xml
文件中有一个属性weight
是对 configuration-1.xml
属性的覆写,但是因为configuration-1.xml
中的weight
属性是final
的,且代码的顺序是先加载configuration-1.xml
,再加载configuration-2.xml
文件,所以导致运行的时候会出现一个覆写警告。Note that although configuration properties can be defined in terms of system properties, unless system properties are redefined using configuration properties, they are not accessible through the configuration API.
注意:尽管在系统属性方面可以定义配置属性,【这句话我不是很理解】但是除非系统属性被重定义在配置文件中,否则它们是不能通过配置的API访问的。【例如:上面的length
属性,会得到一个null值】。
在了解Tool
类之前,先了解一下GenericOptionsParser
类。
GenericOptionsParser
GenericOptionsParser is a class that interprets common Hadoop command-line options and sets them on a Configuration object for your application to use as desired.
但是我们并不需要这么麻烦,因为很多时候,我们可以直接使用Tool
类就可以解决问题。因为Tool
内部其实就是使用了GenericOptionParser
类。因为Tool
类 继承自Configurable
类
public interface Tool extends Configurable {
int run(String [] args) throws Exception;
}
Tool
所有的 Tool
的实现类同时需要实现 Configurable
类 (因为Tool 继承了该类)。并且其(Configurable
)子类Configured
是最简单的实现。
package hadoopDefinitiveGuide.chapter_6; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; import java.util.Map; public class ConfigurationPrinter extends Configured implements Tool { static { Configuration.addDefaultResource("hdfs-default.xml"); } @Override public int run(String[] args) throws Exception { //这里可以直接调用getConf() 方法是因为:getConf()是从Configured 中继承来的 //而 Configured 的方法是从 Configurable 中实现而来的。 Configuration conf = getConf(); for (Map.Entry<String, String> entry : conf) { System.out.printf("%s=%s\n", entry.getKey(), entry.getValue()); } return 0; } public static void main(String[] args) throws Exception { int exitCode = ToolRunner.run(new ConfigurationPrinter(), args); System.exit(exitCode); } }
其中省略了部分输出。得到如上结果。
但是我们代码里又用到了ToolRunner
类,这个是干嘛的呢? 查看该方法如下:
可以看到这个 run()
其实底层调用了 另一个run()
方法, 但是在运行之前添加了一个tool.getConf()
参数,这个getConf()
方法是用于得到一个Configuration
实例,从而传递给run()
方法作为参数。接着调用的run()
方法如下:
可以看到里面分别维持了三个重要对象:conf
,parser
和tool
接着调用Tool
类的 run
方法,运行程序。
Configurable
是什么Configured
是什么Configurable 接口
Configured 类
并不是所有的属性都可以在 client
中配置。比如说 yarn.nodemanager.resource.memeory-mb
这个配置就必须在 yarn-site.xml
中配置,否则无效。
dfs.namenode
作为前缀了。mapreduce.job.name
Hadoop
和 JVM
设置属性的区别GenericOptionsParser
这个类去设置hadoop 的属性时,其语法是【-D property=value
】这个类和 JVM中的 -Dproperty=value
不同。注意-D 和 property的空格。java.lang.System
类中读取的; Hadoop 的属性值仅仅是从 Configuration
对象中获取Mapper
方法中的 <KeyIn,valuIn>
通常都是 Longwritable
, 和Text
?TextInputFormat
类,从而使得KeyIn = LongWritable, 而 valueIn = Text
。MapReduce
的job在不同的平台上运行的效果The local job runner uses a single JVM to run a job, so as long as all the classes that your
job needs are on its classpath, then things will just work.
本地作业运行程序使用单个jvm 来运行作业,因此只要作业所需的所有类都在其类路径中,那么就会起作用。
但是集群中的作业运行可能稍有不同。如果需要将写好的代码放到集群中运行,那么分为如下几步:
在一个集群(包括伪分布集群)上,map 以及 reduce 任务都是运行在单独节点的jvm上的。并且它们的类路径并不是由HADOOP_CLASSPATH
控制的。
HADOOP_CLASSPATH
是一个客户端设置并且仅仅为提交作业的驱动的JVM
设置。相反,用户的作业路径包含如下项:
User JAR
文件可以被添加到client classpath,以及task classpath之后,在这种情况下,这些用户的jar包可能会导致和 hadoop自带的jar包产生冲突。解决这种问题的办法常用:
MapReduce job IDs
的生成规则application
前缀Yarn application IDs
id
YARN resource Manager
生成,代表的是这个resource manager
所处理的应用数id = application_1410450250506_0003
举例application
timestamp = 1410450250506
这个时候创建的;同理,job的id,也是这么生成的,只不过是将前缀 application
替换成了job
。 例如:task_1410450250506_0003_m_000003
则表示是 job_1410450250506_0003
的第四个【000003
,从0计数】map
任务。
attempt_1410450250506_0003_m_000003_0
则表示的是 task
重试的次数。
因为task可能被执行超过一次,所以需要添加一个数字标记。 比如说上面的这个标志, 其后面的0 表示的则是第一次尝试运行【是从0开始计数】
Job history
Job history refers to the events and configuration for a completed MapReduce job. It is retained regardless of whether the job was successful.
Job history files are stored in HDFS by the MapReduce application master, in a directory set by the
mapreduce.jobhistory.done-dir property.
Job history files are kept for one week before being deleted by the system.
The history log includes job, task, and attempt events, all of which are stored in a file in JSON format
在开发job之后,开发者经常想到的问题就是:“可以让这个job运行的更快一点儿嘛?” 在Hadoop中有一些通常的可疑项,这些可疑项是值的检验并查看是否引起了性能问题。在你剖析以及优化任务之前,你应该检查如下这份清单。
Profiling Tasks
Hadoop allows you to profile a fraction of the tasks in a job and, as each task completes, pulls down the profile information to your machine for later analysis with standard profiling tools.
上面这句话的意思说的就是:Hadoop 允许开发者对一个job中的某个任务进行侧面剖查,并且在每个任务完成时,获取剖查信息,用于后期使用标准的profiling tools
的分析
在分布式的集群中剖析应用充满许多挑战。
profile
功能Enabling profiling is as simple as setting the property mapreduce.task.profile to true
例如:在运行任务的时候,指定参数 -D mapreduce.task.profile=true
。
如:hadoop jar hadoop-examples.jar -D mapreduce.task.profile=true ....
task
就能够看到程序哪里出了问题。所以默认分析的程序只有 id =0,1,2 会被分析。可以通过设置 mapreduce.task.profile.maps
以及 mapreduce.task.profile.reduces
参数去指定 profile
的task id
区间。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。