《Hadoop MapReduce实战手册》一2.9 使用HDFS的C API(libhdfs)

简介:

本节书摘来异步社区《Hadoop MapReduce实战手册》一书中的第2章,第2.9节,作者: 【美】Srinath Perera , Thilina Gunarathne 译者: 杨卓荦 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.9 使用HDFS的C API(libhdfs)

Hadoop MapReduce实战手册
libhdfs是一个原生共享库,提供了一套C API,允许非Java程序与HDFS进行交互。libhdfs使用JNI通过Java与HDFS进行交互。

准备工作
目前的Hadoop发行版中包含了为32位和64位Linux操作系统预编译的libhdfs库。如果你的操作系统与预编译库不兼容,则可能需要下载Hadoop的标准发行版并从源代码编译libhdfs库。有关编译libhdfs库的信息请参见2.10节。

操作步骤
下列步骤显示了如何在HDFS环境下使用HDFS的C API执行操作。

  1. 下面的示例程序会在HDFS中创建一个新文件,向新建文件中写入一些文本信息,并从HDFS读回该文件。用HDFS集群中NameNode的相关值替换NAMENODE_HOSTNAME和端口变量。该hdfs_cpp_demo.c源文件中的源代码包位于该文件夹的HDFS_C_API目录中。
#include "hdfs.h"

int main(intargc, char **argv) {

hdfsFSfs =hdfsConnect( "NAMENODE_HOSTNAME,PORT");

if (!fs) {
     fprintf(stderr, "Cannot connect to HDFS.\n");
     exit(-1);
  }

char* fileName = "demo_c.txt";
char* message = "Welcome to HDFS C API!!!";
int size = strlen(message);

int exists = hdfsExists(fs, fileName);

if (exists > -1) {
   fprintf(stdout, "File %s exists!\n", fileName);
}else{
 // Create and open file for writing
 hdfsFileoutFile = hdfsOpenFile(fs, fileName, O_WRONLY|O_CREAT, 0, 0, 0);
if (!outFile) {
 fprintf(stderr, "Failed to open %s for writing!\n", fileName);
       exit(-2);
  }

  // write to file
hdfsWrite(fs, outFile, (void*)message, size);
  hdfsCloseFile(fs, outFile);
  }

  // Open file for reading
hdfsFileinFile = hdfsOpenFile(fs, fileName, O_RDONLY, 0, 0, 0);
  if (!inFile) {
fprintf(stderr, "Failed to open %s for reading!\n", fileName);
     exit(-2);
  }

  char* data = malloc(sizeof(char) * size);
  // Read from file.
tSizereadSize = hdfsRead(fs, inFile, (void*)data, size);
fprintf(stdout, "%s\n", data);
  free(data);

hdfsCloseFile(fs, inFile);
hdfsDisconnect(fs);
  return 0;
}
  1. 通过使用如下gcc命令编译上面的程序。当编译时,需要链接libhdfs和JVM库。因此,还必须包括Java安装路径的JNI头文件。一个示例编译命令如下所示。将ARCH和架构依赖的路径替换成当前系统的路径。
>gcchdfs_cpp_demo.c \
-I $HADOOP_HOME/src/c++/libhdfs \
-I $JAVA_HOME/include \
-I $JAVA_HOME/include/linux/ \
-L $HADOOP_HOME/c++/ARCH/lib/ \
-L $JAVA_HOME/jre/lib/ARCH/server\
-l hdfs -ljvm -o hdfs_cpp_demo
  1. 重置环境变量CLASSPATH,将其指向Hadoop的依赖环境。一种保险的方法是将$HADOOP_HOME和$HADOOP_HOME/lib中的所有jar文件全部包括在环境变量中。
export CLASSPATH=$HADOOP_HOME/hadoop-core-xx.jar:...

Ant构建脚本生成类路径

在2.8节步骤2中给出的build文件的末尾,添加下面的Anttarget。本章源码包的HDFS_C_API文件夹中提供了修改后的build.xml脚本。

<target name="print-cp">
   <property name="classpath"`
     refid="hadoop-classpath"/>`
   <echo message="classpath= ${classpath}"/>`
</target>`

用ant print-cp执行Ant构建,之后会生成一个包含$HADOOP_HOME和$HADOOP_HOME/lib中的所有jar文件名的字符串。复制这个字符串导出到CLASSPATH环境变量中。

  1. 执行程序。
>LD_LIBRARY_PATH=$HADOOP_HOME/c++/ARCH/lib:$JAVA_HOME/jre/lib/ARCH/
server./hdfs_cpp_demo

Welcome to HDFS C API!!!

工作原理
首先,我们通过hdfsConnect命令输入NameNode的主机名(或IP地址)和端口来连接到一个HDFS集群。hdfsConnectAsUser命令可以作为一个特定的用户连接到一个HDFS集群。

hdfsFSfs =hdfsConnect("NAMENODE_HOSTNAME",PORT);

使用hdfsOpenFile命令新建文件,并获得新新建文件的句柄。O_WRONLY | O_CREAT标志表示新建一个文件或重写现有文件,并用只写模式打开它。其他支持的标志还有O_RDONLY和O_APPEND。该hdfsOpenFile命令的第四、第五和第六个参数分别表示进行读/写操作的缓冲区大小、块的冗余因子和新创建文件的块大小。如果想使用这三个参数的默认值,可以将它们指定为0。

hdfsFileoutFile = hdfsOpenFile(fs, fileName,flags, 0, 0, 0);

该hdfsWrite指令将提供的数据写入到outFile句柄指定的文件中。数据大小需要以字节数为单位指定。

hdfsWrite(fs, outFile, (void*)message, size);

hdfsRead命令从inFile指定的文件中读取数据。需要提供以字节为单位的缓冲区大小作为第四个参数。hdfsRead命令返回文件读取的实际字节数,该数量可能小于缓冲区大小。如果想要确保从文件中读取一定的字节数,最好是在循环内使用hdfsRead命令,直到读完了指定的字节数为止。

char* data = malloc(sizeof(char) * size);
tSizereadSize = hdfsRead(fs, inFile, (void*)data, size);

更多参考
HDFS的C API(libhdfs)支持的文件系统操作比前面示例中用到的多。请参见$HADOOP_HOME/src/
c++/libhdfs/hdfs.h头文件获得更多有关的详细信息。

使用HDFS的配置文件配置
还可以使用HDFS的配置文件来告诉libhdfsNameNode的主机名和端口号,而不是通过hdfs-
Connect命令以参数的方式传入。

  1. 在hdfsConnect命令中,将NameNode的主机名和端口号改为"default"和0。(将主机名设置为NULL将使libhdfs使用本地文件系统)。
hdfsFSfs = hdfsConnect("default",0);
  1. 将HDFS安装的conf目录添加到CLASSPATH环境变量中。
export CLASSPATH=$HADOOP_HOME/hadoop-core-xx.jar:...:$HADOOP_HOME/conf
相关文章
|
2天前
|
存储 分布式计算 Hadoop
Hadoop生态系统详解:HDFS与MapReduce编程
Apache Hadoop是大数据处理的关键,其核心包括HDFS(分布式文件系统)和MapReduce(并行计算框架)。HDFS为大数据存储提供高容错性和高吞吐量,采用主从结构,通过数据复制保证可靠性。MapReduce将任务分解为Map和Reduce阶段,适合大规模数据集的处理。通过代码示例展示了如何使用MapReduce实现Word Count功能。HDFS和MapReduce的结合,加上YARN的资源管理,构成处理和分析大数据的强大力量。了解和掌握这些基础对于有效管理大数据至关重要。【6月更文挑战第12天】
13 0
|
3天前
|
分布式计算 Hadoop Java
Hadoop MapReduce编程
该教程指导编写Hadoop MapReduce程序处理天气数据。任务包括计算每个城市ID的最高、最低气温、气温出现次数和平均气温。在读取数据时需忽略表头,且数据应为整数。教程中提供了环境变量设置、Java编译、jar包创建及MapReduce执行的步骤说明,但假设读者已具备基础操作技能。此外,还提到一个扩展练习,通过分区功能将具有相同尾数的数字分组到不同文件。
7 1
|
3天前
|
分布式计算 Java Hadoop
简单的java Hadoop MapReduce程序(计算平均成绩)从打包到提交及运行
简单的java Hadoop MapReduce程序(计算平均成绩)从打包到提交及运行
8 0
|
4天前
|
分布式计算 自然语言处理 大数据
【大数据】MapReduce JAVA API编程实践及适用场景介绍
【大数据】MapReduce JAVA API编程实践及适用场景介绍
10 0
|
4天前
|
Java 大数据 API
【大数据】HDFS、HBase操作教程(含指令和JAVA API)
【大数据】HDFS、HBase操作教程(含指令和JAVA API)
30 0
【大数据】HDFS、HBase操作教程(含指令和JAVA API)
|
4天前
|
分布式计算 Hadoop Java
使用Hadoop MapReduce分析邮件日志提取 id、状态 和 目标邮箱
使用Hadoop MapReduce分析邮件日志提取 id、状态 和 目标邮箱
|
10天前
|
数据采集 SQL 分布式计算
|
21天前
|
分布式计算 Hadoop Java
Hadoop MapReduce 调优参数
对于 Hadoop v3.1.3,针对三台4核4G服务器的MapReduce调优参数包括:`mapreduce.reduce.shuffle.parallelcopies`设为10以加速Shuffle,`mapreduce.reduce.shuffle.input.buffer.percent`和`mapreduce.reduce.shuffle.merge.percent`分别设为0.8以减少磁盘IO。
|
1月前
|
分布式计算 并行计算 搜索推荐
Hadoop MapReduce计算框架
【5月更文挑战第10天】HadoopMapReduce计算框架
22 3
|
1月前
|
分布式计算 数据可视化 Hadoop
大数据实战——基于Hadoop的Mapreduce编程实践案例的设计与实现
大数据实战——基于Hadoop的Mapreduce编程实践案例的设计与实现
249 0