【hadoop摸索系列】记录使用libhdfs访问hdfs的关键问题
hadoop官方的二进制发布版本一直是32位平台编译的,对于java来说跨平台不影响使用,但是为了在c/c++程序中操作hdfs就做不到了,因为libhdfs.so是二进制不兼容的。
我使用的是stable版本的hadoop 2.20,直接从官方下载了二进制发布版本,在目录lib/native下有操作hadoop的c/c++库(.a和.so),但由于服务器是64位的原因无法链接。
解决方法就是下载hadoop的src源码,自行编译生成so,这个过程如果没有Yum会比较繁琐,因为依赖很多,在编译过程中会遇到若干错误,后续会将编译步骤完善起来,这里只说明libhdfs.so如何编译生成一个可运行的程序。
libhfds是基于libjvm运行的,也就是创造了一个java虚拟机然后直接调用hadoop的java jar包实现hdfs系统的访问,所以在编译程序时一定要注意以下几点要素:
1, 如果你是64位系统,必须自行编译hadoop生成64位版本的libhfds.so,如果你是32位系统那就不必了,可以直接使用目录下的lib/native里的so。
2, 编译时一定要链接libjvm.so,这个so在jdk/jre/lib/amd64/server/下面,其中amd64目录代表我是64位系统,你需要根据你的系统选择特定目录下的libjvm.so。
3, 由于libhdfs直接基于jvm加载jar包,而jvm是依靠系统环境变量CLASSPATH寻找jar包的,所以你一定要export导出CLASSPATH环境变量,保证它包含了java jdk和jre的所有jar包以及hadoop/shared/hadoop内的所有jar包,这样运行时jvm才能正确的load到jar包,否则会抛出java异常令程序终止。
4,由于程序依赖so动态库,为了运行时能够找到so,还需要导出libhdfs.so和libjvm.so的路径到LD_LIBRARY_PATH变量中去。
下面是一段简单的示例代码,打开一个hdfs文件并向文件写入了hello hdfs,之后关闭文件,重点关注其编译命令:
#include "hdfs.h" int main(int argc, char **argv)
{
hdfsFS fs = hdfsConnect("10.46.120.32", );
if (!fs) {
fprintf(stderr, "connect fail\n");
return -;
}
hdfsFile writeFile = hdfsOpenFile(fs, "/first.txt", O_WRONLY, , , );
if (!writeFile) {
fprintf(stderr, "openfile fali\n");
return -;
}
hdfsWrite(fs, writeFile, "hello hdfs", );
hdfsCloseFile(fs, writeFile);
hdfsDisconnect(fs);
return ;
}
编译命令如下:
gcc -o hdfs hdfs.c -L /hadoop/lib/native -lhdfs -I /hadoop/include -L /jdk/jre/lib/amd64/server/ -ljvm
下面的代码足以完成所有环境变量的初始化,不需要再做额外的任何工作,建议填好后放到.bashrc中,这里假设hadoop安装在/hadoop中,jdk安装在/jdk中,libhdfs在hadoop默认路径下:
export JAVA_HOME=/jdk #jdk安装路径
export JRE_HOME=${JAVA_HOME}/jre #jre路径
export LD_LIBRARY_PATH=/jdk/jre/lib/amd64/server:/hadoop/lib/native # libjvm.so目录和libhdfs.so目录
CLASSPATH=${JAVA_HOME}/lib:${JRE_HOME}/lib # jdk与jre的jar
HADOOP_HOME=/hadoop #hadoop安装路径
CLASSPATH=${CLASSPATH}":"`find ${HADOOP_HOME}/share/hadoop | awk '{path=path":"$0}END{print path}'` # hadoop的jar
export CLASSPATH
【hadoop摸索系列】记录使用libhdfs访问hdfs的关键问题的更多相关文章
- Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统
前言 我们知道HDFS集群中,所有的文件都是存放在DN的数据块中的.那我们该怎么去查看数据块的相关属性的呢?这就是我今天分享的内容了 一.HDFS中数据块概述 1.1.HDFS集群中数据块存放位置 我 ...
- Hadoop通过路径和和链接访问HDFS
如果既想在Hadoop服务器本地可以通过绝对路径如"/user/hadoop"方式访问hdfs,也想通过"hdfs://local host:9000/user/hado ...
- Hadoop(五)搭建Hadoop与Java访问HDFS集群
前言 上一篇详细介绍了HDFS集群,还有操作HDFS集群的一些命令,常用的命令: hdfs dfs -ls xxx hdfs dfs -mkdir -p /xxx/xxx hdfs dfs -cat ...
- Hadoop(五)搭建Hadoop客户端与Java访问HDFS集群
阅读目录(Content) 一.Hadoop客户端配置 二.Java访问HDFS集群 2.1.HDFS的Java访问接口 2.2.Java访问HDFS主要编程步骤 2.3.使用FileSystem A ...
- 配置伪分布模式下的hadoop以及采用fuse-dfs来访问HDFS
实验目标 配置环境的主要目的是得到HDFS的客户端fuse-dfs的IO性能.本来的服务器上没有任何环境,因此安装均是从无到有的.系统是Ubuntu server 14.04 amd64.整个过程参考 ...
- hadoop学习记录(一)HDFS
hadoop的灵感源于谷歌,最初目的是解决传统数据库处理数据成本高和速度慢的问题. hadoop两个核心项目是HDFS(hadoop分布式文件系统)和MapReduce. HDFS用来实现数据的存储, ...
- 【Hadoop】HA 场景下访问 HDFS JAVA API Client
客户端需要指定ns名称,节点配置,ConfiguredFailoverProxyProvider等信息. 代码示例: package cn.itacst.hadoop.hdfs; import jav ...
- Java程序中不通过hadoop jar的方式访问hdfs
一般情况下,我们使用Java访问hadoop distributed file system(hdfs)使用hadoop的相应api,添加以下的pom.xml依赖(这里以hadoop2.2.0版本 ...
- 访问HDFS报错:org.apache.hadoop.security.AccessControlException: Permission denied
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apac ...
随机推荐
- WinForm开发笔记
Button Button默认不产生DoubleClick事件 (MSDN说明:https://msdn.microsoft.com/zh-cn/library/system.windows.form ...
- java运行时内存模式学习
学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...
- solr DIH 知识梳理
solr DIH 知识梳理 web.xml中listener配置 <listener> <listener-class>org.apache.solr.handler.data ...
- sqlyog重复使用的方法(30天)
Sqlyog作为一款可视化的数据库管理工具,各种方便我就不说了,但是未经汉化或者绿色过的软件存在30天的生命期,到期后我们就不可以使用了,要摸卸载重装,我们还可以去修改注册表,来延长它的生命期,具体步 ...
- 从倒影说起,谈谈 CSS 继承 inherit(转)
从倒影说起,谈谈 CSS 继承 inherit 给定一张有如下背景图的 div: 制作如下的倒影效果: 方法很多,但是我们当然要寻找最快最便捷的方法,至少得是无论图片怎么变化,div 大小怎么变化,我 ...
- 使用spring的@Scheduled注解执行定时任务,启动项目不输出警告
在applicationContext.xml中添加: xmlns:task="http://www.springframework.org/schema/task" xsi:sc ...
- #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #endif
情况1:#ifdef _DEBUGvirtual void AssertValid() const; //assert(断言)valid(有效的,正确的)virtual ...
- 向mysql中插入Date类型的数据
先看数据库表的定义 date字段为sql.date类型.我要向其中插入指定的日期和当前日期. 一.插入当前日期 思路:先获取当前系统,在将当前系统时间转换成sql类型的时间,然后插入数据库.代码如下 ...
- day 2 Linux基础
6.用户.群组和权限 1) 新建用户natasha,uid为1000,gid为555,备注信息为"master" useradd natasha usermod -u1000 na ...
- Android 网络状态检测
package com.example.administrator.yunstore.net; import android.app.AlertDialog; import android.conte ...