Java hdfs连接池_Java使用连接池管理Hdfs连接

记录一下Java API 连接hadoop操作hdfs的实现流程(使用连接池管理)。

以前做过这方面的开发,本来以为不会有什么问题,但是做的还是坑坑巴巴,内心有些懊恼,记录下这烦人的过程,警示自己切莫眼高手低!

一:引入相关jar包如下

org.apache.hadoop

hadoop-common

2.8.2

org.apache.hadoop

hadoop-hdfs

2.8.2

org.apache.commons

commons-pool2

2.6.0

二:连接池开发的基本流程

2.1项目基本环境是SpringBoot大集成···

2.2hadoop相关包结构如下(自己感觉这结构划分的也是凸显了low逼水平【手动笑哭】)

9051ef3df767bb1eb8511b67db1d5ad3.png

2.2 画个图表达下开发思路

761d38a3bfb5588c62b9780d6db8c3af.png

三、上代码

importcom.cmcc.datacenter.hdfs.client.HdfsClient;importcom.cmcc.datacenter.hdfs.client.HdfsFactory;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;

@Configurationpublic classHdfsConfig {

@Value("${hadoop.hdfs.ip}")privateString hdfsServerIp;

@Value("${hadoop.hdfs.port}")privateString hdfsServerPort;

@Value("${hadoop.hdfs.pool.maxTotal}")private intmaxTotal;

@Value("${hadoop.hdfs.pool.maxIdle}")private intmaxIdle;

@Value("${hadoop.hdfs.pool.minIdle}")private intminIdle;

@Value("${hadoop.hdfs.pool.maxWaitMillis}")private intmaxWaitMillis;

@Value("${hadoop.hdfs.pool.testWhileIdle}")private booleantestWhileIdle;

@Value("${hadoop.hdfs.pool.minEvictableIdleTimeMillis}")private long minEvictableIdleTimeMillis = 60000;

@Value("${hadoop.hdfs.pool.timeBetweenEvictionRunsMillis}")private long timeBetweenEvictionRunsMillis = 30000;

@Value("${hadoop.hdfs.pool.numTestsPerEvictionRun}")private int numTestsPerEvictionRun = -1;

@Bean(initMethod= "init", destroyMethod = "stop")publicHdfsClient HdfsClient(){

HdfsClient client= newHdfsClient();returnclient;

}/*** TestWhileConfig - 在空闲时检查有效性, 默认false

* MinEvictableIdleTimeMillis - 逐出连接的最小空闲时间

* TimeBetweenEvictionRunsMillis - 逐出扫描的时间间隔(毫秒) 如果为负数则不运行逐出线程,默认-1

* NumTestsPerEvictionRun - 每次逐出检查时 逐出的最大数目

**/@BeanpublicHdfsPoolConfig HdfsPoolConfig(){

HdfsPoolConfig hdfsPoolConfig= newHdfsPoolConfig();

hdfsPoolConfig.setTestWhileIdle(testWhileIdle);

hdfsPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);

hdfsPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);

hdfsPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);

hdfsPoolConfig.setMaxTotal(maxTotal);

hdfsPoolConfig.setMaxIdle(maxIdle);

hdfsPoolConfig.setMinIdle(minIdle);

hdfsPoolConfig.setMaxWaitMillis(maxWaitMillis);returnhdfsPoolConfig;

}

@BeanpublicHdfsFactory HdfsFactory(){return new HdfsFactory("hdfs://" + hdfsServerIp + ":" +hdfsServerPort);

}

}

importorg.apache.commons.pool2.impl.GenericObjectPoolConfig;public class HdfsPoolConfig extendsGenericObjectPoolConfig {publicHdfsPoolConfig(){}/*** TestWhileConfig - 在空闲时检查有效性, 默认false

* MinEvictableIdleTimeMillis - 逐出连接的最小空闲时间

* TimeBetweenEvictionRunsMillis - 逐出扫描的时间间隔(毫秒) 如果为负数则不运行逐出线程,默认-1

* NumTestsPerEvictionRun - 每次逐出检查时 逐出的最大数目

**/

public HdfsPoolConfig(boolean testWhileIdle, long minEvictableIdleTimeMillis, long timeBetweenEvictionRunsMillis, intnumTestsPerEvictionRun){this.setTestWhileIdle(testWhileIdle);this.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);this.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);this.setNumTestsPerEvictionRun(numTestsPerEvictionRun);

}

}

packagecom.cmcc.datacenter.hdfs.client;importcom.cmcc.datacenter.hdfs.config.HdfsPoolConfig;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importjava.util.List;public classHdfsClient {private Logger logger = LoggerFactory.getLogger(this.getClass());privateHdfsPool hdfsPool;

@AutowiredprivateHdfsPoolConfig hdfsPoolConfig;

@AutowiredprivateHdfsFactory hdfsFactory;public voidinit(){

hdfsPool= newHdfsPool(hdfsFactory,hdfsPoolConfig);

}public voidstop(){

hdfsPool.close();

}public long getPathSize(String path) throwsException {

Hdfs hdfs= null;try{

hdfs=hdfsPool.borrowObject();returnhdfs.getContentSummary(path).getLength();

}catch(Exception e) {

logger.error("[HDFS]获取路径大小失败", e);throwe;

}finally{if (null !=hdfs) {

hdfsPool.returnObject(hdfs);

}

}

}public ListgetBasePath(){

Hdfs hdfs= null;try{

hdfs=hdfsPool.borrowObject();returnhdfs.listFileName();

}catch(Exception e) {

e.printStackTrace();return null;

}finally{if (null !=hdfs) {

hdfsPool.returnObject(hdfs);

}

}

}

}

importorg.apache.commons.pool2.PooledObject;importorg.apache.commons.pool2.PooledObjectFactory;importorg.apache.commons.pool2.impl.DefaultPooledObject;importjava.io.IOException;public class HdfsFactory implements PooledObjectFactory{private finalString url;publicHdfsFactory(String url){this.url =url;

}

@Overridepublic PooledObject makeObject() throwsException {

Hdfs hdfs= newHdfs(url);

hdfs.open();return new DefaultPooledObject(hdfs);

}

@Overridepublic void destroyObject(PooledObject pooledObject) throwsException {

Hdfs hdfs=pooledObject.getObject();

hdfs.close();

}

@Overridepublic boolean validateObject(PooledObjectpooledObject) {

Hdfs hdfs=pooledObject.getObject();try{returnhdfs.isConnected();

}catch(IOException e) {

e.printStackTrace();return false;

}

}

@Overridepublic void activateObject(PooledObject pooledObject) throwsException {

}

@Overridepublic void passivateObject(PooledObject pooledObject) throwsException {

}

}

packagecom.cmcc.datacenter.hdfs.client;importorg.apache.commons.pool2.PooledObjectFactory;importorg.apache.commons.pool2.impl.AbandonedConfig;importorg.apache.commons.pool2.impl.GenericObjectPool;importorg.apache.commons.pool2.impl.GenericObjectPoolConfig;public class HdfsPool extends GenericObjectPool{public HdfsPool(PooledObjectFactoryfactory) {super(factory);

}public HdfsPool(PooledObjectFactory factory, GenericObjectPoolConfigconfig) {super(factory, config);

}public HdfsPool(PooledObjectFactory factory, GenericObjectPoolConfigconfig, AbandonedConfig abandonedConfig) {super(factory, config, abandonedConfig);

}

}

importcom.cmcc.datacenter.hdfs.config.HdfsConfig;importcom.google.common.collect.Lists;importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.fs.ContentSummary;importorg.apache.hadoop.fs.FileStatus;importorg.apache.hadoop.fs.FileSystem;importorg.apache.hadoop.fs.Path;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Autowired;importjava.io.IOException;importjava.util.List;public classHdfs {private Logger logger = LoggerFactory.getLogger(this.getClass());privateFileSystem fs;privateString coreResource;privateString hdfsResource;private finalString url;private static final String NAME = "fs.hdfs.impl";publicHdfs(String url) {this.url =url;

}public voidopen() {try{

Configuration conf= newConfiguration();

conf.set("fs.defaultFS", url);

System.out.println("url is "+url);

fs=FileSystem.get(conf);

logger.info("[Hadoop]创建实例成功");

}catch(Exception e) {

logger.error("[Hadoop]创建实例失败", e);

}

}public voidclose() {try{if (null !=fs) {

fs.close();

logger.info("[Hadoop]关闭实例成功");

}

}catch(Exception e) {

logger.error("[Hadoop]关闭实例失败", e);

}

}public boolean isConnected() throwsIOException {return fs.exists(new Path("/"));

}public boolean exists(String path) throwsIOException {

Path hdfsPath= newPath(path);returnfs.exists(hdfsPath);

}public FileStatus getFileStatus(String path) throwsIOException {

Path hdfsPath= newPath(path);returnfs.getFileStatus(hdfsPath);

}public ContentSummary getContentSummary(String path) throwsIOException {

ContentSummary contentSummary= null;

Path hdfsPath= newPath(path);if(fs.exists(hdfsPath)) {

contentSummary=fs.getContentSummary(hdfsPath);

}returncontentSummary;

}public List listFileName() throwsIOException {

List res =Lists.newArrayList();

FileStatus[] fileStatuses= fs.listStatus(new Path("/"));for(FileStatus fileStatus : fileStatuses){

res.add(fileStatus.getPath()+":类型--"+ (fileStatus.isDirectory()? "文件夹":"文件"));

}returnres;

}

}

四、总结:

一共六个类,理清思路看是很easy的。

这里就是spring对类的管理和commons-pool2对连接类的管理混着用了,所以显得有点乱。

1.@Configuration注解加到Hdfsconfig类上,作为一个配置类,作用类似于spring-xml文件中的标签,springboot会扫描并注入它名下管理的类,其中

@Bean(initMethod = "init", destroyMethod = "stop") 标签表示spring在初始化这个类时调用他的init方法,销毁时调用他的stop方法。

2.HdfsClient 是业务方法调用的类,spring在初始化这个类时,调用它的init方法,这个方法会创建HdfsPool(即Hdfs的连接池)。其他方法是对Hdfs中方法的二次封装,即先使用连接池获取实例,再调用实例方法。

3.HdfsPoolConfig继承commons-pool2包中的GenericObjectConfig,受spring管理,作为线程池的配置类,创建HdfsPool时作为参数传入。

4.HdfsFactory继承commons-pool2包中的GenericObjectFactory,受spring管理,作为创建连接实例的工厂类,创建HdfsPool时作为参数传入。实际上连接池就是通过它获取的连接实例。

5.HdfsPool继承commons-pool2包中的GenericObjectPool,是连接池。

6.Hdfs,是底层的连接实例,所有增删改查的方法都要在这里实现,只不过获取/销毁连接交给池管理。

声明:这里用spring管理一些类是应为项目本身用的springboot,spring管理方便,并不是强制使用,愿意完全可以自己new。

五、不得不说的一些不是坑的坑。

1.我真的不记得windows上用Java API连接远程的hadoop还要有一些神操作。

报错如下:java.io.FileNotFoundException: java.io.FileNotFoundException: HADOOP_HOME and hadoop.home.dir are unset

解决如下:

1. 将已下载的 hadoop-2.9.0.tar 这个压缩文件解压,放到你想要的位置(本机任意位置);

2. 下载 windows 环境下所需的其他文件(hadoop2.9.0对应的hadoop.dll,winutils.exe 等),这步真是关键,吐槽某SDN想钱想疯了啊,霸占百度前10页,各种下载各种C币,各种要钱。

不多说了,附上github地址:github地址

3. 拿到上面下载的windows所需文件,执行以下步骤:

3.1:将文件解压到你解压的 hadoop-2.9.0.tar 的bin目录下(没有的放进去,有的不要替换,以免花式作死,想学习尝试的除外)

3.2:将hadoop.dll复制到C:\Window\System32下

3.3:添加环境变量HADOOP_HOME,指向hadoop目录

3.4:将%HADOOP_HOME%\bin加入到path里面,不管用的话将%HADOOP_HOME%\sbin也加进去。

3.5:重启 IDE(你的编辑工具,例如eclipse,intellij idea)

原文:https://www.cnblogs.com/peripateticism/p/10895903.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555849.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为了拿捏 Redis 数据结构,我画了 40 张图(完整版)

Redis 为什么那么快? 除了它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理。 因此,这次我们就来…

java put set_Java PutItemRequest.setItem方法代码示例

import com.amazonaws.services.dynamodbv2.model.PutItemRequest; //导入方法依赖的package包/类public List reindex(T instance) throws DataStoreException {DynamoClassMapping tableInfo getClassMapping(instance);log.debug("reindex {}", instance.getClas…

fastjson为什么默认是无序的

在做项目的时候,无意间发现添加到json中的元素是无存放顺序的。严格来说,json默认是有存放顺序的,不过是采用HashCode值来排序。下面来看一段源码 上图展示了创建json对象的一个过程,可以清晰的看出,无论用户调用哪个…

php一句话怎么写_PHP一句话木马后门

在我们进行渗透测试的最后阶段,入侵到内网里,无论是想要浏览网站结构,还是抓取数据库,或者是挂个木马等等,到最后最常用的就是执行一句话木马,从客户端轻松连接服务器。一句话木马的原理很简单,…

JSON书写格式

JSON是什么 JSON ( JavaScript Object Notation) ,是一种数据交互格式。 为什么有这个技术 Json之前,大家都用 XML 传递数据。XML 是一种纯文本格式,所以适合在网络上交换数据,但是 XML 格式比较复杂,终于道格拉斯克…

php判断目录是否有写的权限,php中判断文件空目录是否有读写权限

/*问题出现:如何检查一个目录是否可写,如何目录下还有目录和文件,那么都要检查思路:(1)首先先写出检查空目录是否可写的算法:在该目录中生成一个文件,如果不能生成,表明该目录没有写的权限(2)使…

List.addAll方法的入参不能为null

缘由: ​ 某天,发现一段日志中出现了诡异的NPE。经过定位,认为是ArrayList不能加入null所致。 验证: ​ new一个ArrayList,然后调用其addAll方法,并将入参设为null。 public static void main(String[] …

php 微信转账,php实现微信公众号企业转账功能

企业付款提供由商户直接付钱至用户微信零钱的能力,支持平台操作及接口调用两种方式,资金到账速度快,使用及查询方便。主要用来解决合理的商户对用户付款需求,比如:保险理赔、彩票兑换等等。特点发起方式灵活&#xff0…

Java之HashMap.values()转List时的错误和正确操作

因为项目中需要获取到Map的值的集合&#xff0c;所以调用了HashMap.values()方法转成List&#xff0c;当时是使用了以下代码。&#xff08;逻辑上这样想应该没问题&#xff0c;但生活总是会是不是给你一点小“”惊喜“”&#xff09; List<AreaItemOpt> areaItemOpts (…

php检测表大小,查询mysql数据库、表的大小

一、关于mysql表数据大小mysql存储数据文件一般使用表空间存储 &#xff1b;当mysql使用innodb存储引擎的时候&#xff0c;mysql使用表存储数据分为共享表空间和独享表空间两种方式 。共享表空间&#xff1a;Innodb的所有数据保存在一个单独的表空间里面&#xff0c;而这个表空…

Java利用stream(流)对map中的values进行过滤、排序操作

前言 对于Java8中的stream(流)这种优雅、方便、快捷、高效的操作已经是信手沾来了吧&#xff0c;但是却仅限List、Set。难道我Map不要面子得嘛&#xff1f;在工作中需要对从List转Map的数据进行操作&#xff0c;因此便有这随笔。 新建一个User类&#xff0c;注意下面使用lombok…

cls certificate.php,php加密解密处理类

PHP加密解密也是常有的事&#xff0c;发现discuz论坛里的PHP加密解密处理类代码&#xff0c;感觉挺不错&#xff0c;在用的时候&#xff0c;要参考Discuz论坛的passport相关函数&#xff0c;后面我会附上使用方法。php加密解密处理类<?php /* 文件名称&#xff1a;cls.sys_…

【redis】java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用

java操作redis时&#xff0c;StringRedisTemplate的expire()方法的作用&#xff0c;什么时候使用 //重新设置过期时间为30分钟&#xff0c;刷新时间 redisTemplate.expire(MsOpenApiRedisUtil.SESSION_KEY_IN_LOGIN_NAMEloginName,30,TimeUnit.MINUTES); redisTemplate.expire…

springboot使用redis(StringRedisTemplate的常用方法)

1. 先了解RedisTemplate和StringRedisTemplate之间的关系&#xff1a; RedisTemplate是Spring对于Redis的封装&#xff0c;而StringRedisTemplate继承RedisTemplate。两者的数据是不共通的&#xff1b;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据&…

html提交表单给php邮件发送,在HTML表单中通过PHP自动发送电子邮件

我最终解决了我的问题吧一个细节。我的HTML帖子回答:Navn: Kontakt e-post: Kontakt telefon: Fest:LokalfestHjemmefestKommune: Deltagere: Rydding: Vasking: Dorvakt: Noe annet?: 我的PHP帖子回答:if(isset($_POST[mailform]))$email $_POST[Epost] ;$name $_POST[Navn…

Arrays.asList()和Collections.singletonList()比较

Collections.singletonList(something)是不可变的&#xff0c; 对Collections.singletonList(something)返回的列表所做的任何更改将导致UnsupportedOperationException。 Arrays.asList(something)允许Arrays.asList(something) 更改 。 此外&#xff0c;由Collections.sin…

php 邮件类库,[3.3]-扩展类库:基于PHPMailer的邮件发送 | PhalApi(π框架) - PHP轻量级开源接口框架 - 接口,从简单开始!...

3.3.1 扩展类库&#xff1a;基于PHPMailer的邮件发送此扩展可用于发送邮件。3.3.2 安装和配置从 PhalApi-Library 扩展库中下载获取 PHPMailer 包&#xff0c;如使用&#xff1a;$ git clone https://git.oschina.net/dogstar/PhalApi-Library.git然后把 PHPMailer 目录复制到 …

spring boot报FileSizeLimitExceededException异常的解决方法

开发spring boot程序时&#xff0c;遇到了如下错误&#xff1a; The field file exceeds its maximum permitted size of 1048576 bytes. 原因&#xff1a; Spring Boot工程嵌入的tomcat限制了请求的文件大小&#xff0c;官方文档中这样描述&#xff1a; Spring Boot embraces…

js表单提交 php,JavaScript提交表单的几种方法

在我们工作中我们会经常使用到form表单&#xff0c;相信大家再熟悉不过了&#xff0c;那么提交表单有很多种方法&#xff0c;JavaScript提交表单的方法又是如何呢&#xff0c;今天就带大家介绍下JavaScript提交表单的几种方法&#xff01;第一种方式&#xff1a;表单提交&#…

前后端分离中的权限管理思路

在传统的前后端不分的开发中&#xff0c;权限管理主要通过过滤器或者拦截器来进行&#xff08;权限管理框架本身也是通过过滤器来实现功能&#xff09;&#xff0c;如果用户不具备某一个角色或者某一个权限&#xff0c;则无法访问某一个页面。 但是在前后端分离中&#xff0c;…