HBase表数据倾斜治理_HBaseConfiguration配置参数
1.HBaseConfiguration配置文件加载过程
Configuration是hadoop作业的配置信息类,可以实现再多个mapper和多个reducer任务之间共享信息。当我们要通过java代码创建hbase client,首先要创建配置对象:
1 | Configuration conf = HBaseConfiguration.create(); |
该步骤包括创建hdfs client和加载hbase 配置文件:
1 | public static Configuration create() { |
Configuration类的静态代码块:
1 | static { |
HBaseConfiguration的addHbaseResources()方法:
1 | public static Configuration addHbaseResources(Configuration conf) { |
从源码中不难发现,在创建HBaseConfiguration对象过程中总共需要加载四个配置文件:core-default.xml、core-site.xml、hbase-default.xml、hbase-site.xml,多达数百项的默认配置信息以键值对的形式配置在这些文件当中。
配置文件中的参数配置形式如下所示,其中<final>true</final>表示在后续合并资源过程中或者谁用set方法也无法改变该配置参数。
1 | <configuration> |
阅读源码发现,执行addResource()方法后只是将配置文件的名字加载到了Configuration对象中,并没有将配置文件当中的配置信息键值对加载进来。这里采用了延时加载的设计模式,只有调用set()或get()方法时,才会通过getProps()方法将配置文件中的属性值加载到Configuration对象的properties属性中。
getProps()方法调用loadResources()寻找配置文件存储地址并读取文件:
1 | protected synchronized Properties getProps() { |
2.java -jar与hadoop jar的区别
2.1 Configuration加载文件内容源码
loadResources()源码:
1 | if (resource instanceof URL) { |
一般默认使用文件名的形式加载配置文件,所以要先根据文件名获取文件路径:
1 | public URL getResource(String name) { |
注意此次调用的是类加载器当中的getResource()方法:
1 | public URL getResource(String name) { |
2.2类对象和类加载器当中getResource()的区别
注意类对象和类加载器当中都有getResource(),两者作用不同。当两者的入参都是/开头的绝对路径时,两者都是从classpath下去寻找对应的文件路径;当类对象的getResource()入参为相对路径时,该方法只会在该类对象所在文件夹下寻找文件路径,而类加载器的getResource()方法还是从classpath下去寻找对应的文件路径。
现用如下实例说明:
1 | URL classpath1 = ConfDebug.class.getResource(""); |
控制台输出:
1 | file:/E:/files/JDIdeaProject/JDHBaseSnapshotDemo/target/classes/com/jd/hbase/conf/test/ |
- getResource(“”)方法用于获取当前根目录。
- 类对象getResource(“”)获取到的就是ConfDebug.class所在文件夹。
- 类加载器getResource(“”)获取到的就是该项目的classpath。
2.3 getResource()方法可以获取jar包文件
注意getResource()方法除了可以获取classpath下的文件,实际上还可以获取到项目依赖的所有jar包中的文件。
代码实例:
1 | URL classpath2 = ConfDebug.class.getClassLoader().getResource(""); |
控制台输出:
1 | file:/E:/files/JDIdeaProject/JDHBaseSnapshotDemo/target/classes/ |
2.4 java项目的classpath
对于本地运行的java项目的classpath默认就是target/classes文件夹;对于jar包或war包项目classpath为jar包或war包自己。
代码实例:
1 | URL classpath2 = ConfDebug.class.getClassLoader().getResource(""); |
在本地ide上运行结果:
1 | file:/E:/files/JDIdeaProject/JDHBaseSnapshotDemo/target/classes/ |
打包成jar包使用java -jar命令运行结果:
1 | null |
2.5添加calsspath的两种方式
2.5.1设置计算机环境变量(不推荐)
在计算机系统变量中添加java classpath。比如添加两个C:\work\project1\bin;C:\shared,那么在执行getResource()方法方法时就会依次从这两目录和jar包中去寻找文件。
2.5.2给java命令传入-classpath或-cp参数(推荐)
比如java -classpath C:\work\project1\bin abc.xyz.Hello,那么在编译abc.xyz.Hello类时临时设置classpath。
如果要使用java -classpath在执行jar包时添加classpath,则不能使用java -jar,只能用java -classpath添加jar包和目标路径为classpath。
代码实例:
1 | URL classpath2 = ConfDebug.class.getClassLoader().getResource(""); |
命令行运行:
1 | //重要:正常使用java -classpath执行jar包中的类,就必须指定jar包名为classpath同时指定执行类。 |
2.6 hadoop jar
hadoop jar与java -jar相比最主要的区别就是增加了运行时的classpath,主要是%hadoop_home/share目录下的jar包和%hadoop_home/etc/hadoop文件夹。
使用hadoop classpath命令可以查看hadoop环境下的classpath:
1 | E:\HBase\hadoop\sbin>hadoop classpath |
代码实例:
1 | URL classpath2 = ConfDebug.class.getClassLoader().getResource(""); |
命令行运行:
1 | //重要:java -jar的classpath就是jar包自己。 |
3.Configuration主要方法
3.1 addResource(String name)
使用该方法可以将指定的xml配置文件中的参数加载到Configuration。程序会到resource文件夹寻找该文件并加载配置参数。
1 | conf.addResource("hdfs-site.xml"); |
3.2 set(String name, String value)
Configuration对象当中使用一个Hashtable<Object, Object>类型的properties属性保存配置参数,使用该方法可以设置配置参数键值对,也可以覆盖properties属性当中key相同的配置参数
4.在Mapper和Reducer当中获取Configuration对象及参数
Mapper和Reducer的抽象方法中有一个输入参数Context,使用该对象可以直接获取到对应job任务的Configuration对象。
举一个例子,在该例子中实现了,在Mapper中获取java命令行参数:
1 | //将java命令行的第一个参数存入Configuration对象中 |
1 | //在Mapper中获取Configuration对象中的参数 |