HDFS简介HDFS是Hadoop项目的核心子项目,是一种具有高容错性、高可靠性、高可扩展性、高吞吐量等特征的分布式文件系统。HDFS特点HDFS作为一种分布式文件系统,主要有以下特点:主要用于存储和管理大数据文件(由于HDFS默认数据块为128M,所以它主要适合于存储百M级别及以上大小的文件)。其数据节点可横向扩展,且可选择廉价的商业硬件。设计理念为“一次写,多次读”。当前不支持在文件任意位置修改文件内容,只能在文件尾部执行append操作。不适合低延迟(几十毫秒)数据访问应用(低延迟应用可以考虑HBASE分布式数据库或者ES+分布式文件系统的架构)。
LIBHDFS接口简单应用实践这里主要介绍部分API的使用示例。获取HDFS文件系统的容量和已使用空间大小信息如GetHdfsInfo函数所示:
void GetHdfsInfo(void)
{
hdfsFS pfs = NULL;
int iRet = 0;
tOffset iTmp = 0;
pfs = hdfsConnect('hdfs://127.0.0.1:9000/', 0); // 与HDFS文件系统建立连接
if (NULL == pfs)
{
WRITELOGEX(LOG_ERROR, ('GetHdfsInfo(): hdfsConnect failed! errno=%d.', errno));
return;
}
WRITELOG(LOG_INFO, 'GetHdfsInfo(): hdfsConnect success!');
iTmp = hdfsGetCapacity(pfs); // 获取HDFS文件系统容量
if (-1 == iTmp)
{
WRITELOGEX(LOG_ERROR, ('GetHdfsInfo(): hdfsGetCapacity failed! errno=%d.', errno));
hdfsDisconnect(pfs);
pfs = NULL;
return;
}
WRITELOGEX(LOG_INFO, ('GetHdfsInfo(): hdfsGetCapacity success! offset=%ld.', iTmp));
iTmp = hdfsGetUsed(pfs); // 获取HDFS文件系统中所有文件占用空间大小,即已使用量
if (-1 == iTmp)
{
WRITELOGEX(LOG_ERROR, ('GetHdfsInfo(): hdfsGetUsed failed! errno=%d.', errno));
hdfsDisconnect(pfs);
pfs = NULL;
return;
}
WRITELOGEX(LOG_INFO, ('GetHdfsInfo(): hdfsGetUsed success! offset=%ld.', iTmp));
iRet = hdfsDisconnect(pfs); // 关闭与HDFS文件系统的连接
if (-1 == iRet)
{
WRITELOGEX(LOG_ERROR, ('GetHdfsInfo(): hdfsDisconnect failed! errno=%d.', errno));
return;
}
WRITELOGEX(LOG_INFO, ('GetHdfsInfo(): hdfsDisconnect success! ret=%d.', iRet));
pfs = NULL;
return;
}
总结本文对HDFS和用C语言访问HDFS的操作进行了详细的介绍,可供相关项目的开发人员参考。HDFS作为一种分布式文件系统,并不是万能的,例如并不适合于存储量太小或要求低访问延迟的应用场景,又或者需要频繁更新数据的系统。即使应用了HDFS文件系统,为了发挥HDFS文件系统的最大效率,仍可能需要通过我们修改业务分层或逻辑实现等手段来规避HDFS的一些缺点。
在HDFS文件系统中新增文件并写入数据如HdfsWriteTest函数所示:
void HdfsWriteTest(hdfsFS pfs)
{
int iRet = 0;
hdfsFile pfile = NULL;
char szTestFile[200] = '/test/ write.test';
if (NULL == pfs)
{
WRITELOG(LOG_ERROR, 'HdfsWriteTest():pfs is null.');
return;
}
pfile = hdfsOpenFile(pfs, szTestFile, O_WRONLY || O_CREAT, 0, 0, 0); // 打开文件句柄
if (NULL == pfile)
{
WRITELOGEX(LOG_ERROR, ('HdfsWriteTest(): hdfsOpenFile failed! szFilePath=%s,errno=%d.', szTestFile, errno));
return;
}
WRITELOGEX(LOG_INFO, ('HdfsWriteTest(): hdfsOpenFile success! szFilePath=%s.', szTestFile));
iRet = hdfsWrite(pfs, pfile, 'hello world!', strlen('hello world!')); // 写入数据
if (-1 == iRet)
{
WRITELOGEX(LOG_ERROR, ('HdfsWriteTest(): hdfsWrite failed! ret=%d,errno=%d.', iRet, errno));
hdfsCloseFile(pfs, pfile);
pfile = NULL;
return;
}
WRITELOGEX(LOG_INFO, ('HdfsWriteTest(): hdfsWrite success! ret=%d.', iRet));
iRet = hdfsHFlush(pfs, pfile); // 将缓冲区中数据写入磁盘
if (-1 == iRet)
{
WRITELOGEX(LOG_ERROR, ('HdfsWriteTest(): hdfsFlush failed! ret=%d,errno=%d.', iRet, errno));
hdfsCloseFile(pfs, pfile);
pfile = NULL;
return;
}
WRITELOGEX(LOG_INFO, ('HdfsWriteTest(): hdfsFlush success! ret=%d.', iRet));
iRet = hdfsCloseFile(pfs, pfile); // 关闭文件句柄,释放资源
if (-1 == iRet)
{
WRITELOGEX(LOG_ERROR, ('HdfsWriteTest(): hdfsCloseFile failed! ret=%d,errno=%d.', iRet, errno));
return;
}
WRITELOGEX(LOG_INFO, ('HdfsWriteTest(): hdfsCloseFile success! ret=%d.', iRet));
pfile = NULL;
return;
}
C语言访问HDFS应用实践编译和运行环境搭建为了成功编译C语言客户端程序,我们需要预先安装0及以上版本的JAVAJDK和Hadoop发行版,前者提供libjvso等库,后者则提供LIBHDFS连接所需要的库。为了成功运行C语言客户端程序,除了预先安装上面提到的程序外,我们还需要正确地设置几个关键环境变量,包括LD_LIBRARY_PATH和CLASSPATH的设置。关于LD_LIBRARY_PATH环境变量,主要是需要添加libjvso和libhdfs.so库所在路径;而针对CLASSPATH则需要囊括Hadoop提供的所有jar包的全路径信息(具体可通过find+awk组合命令来实现),否则C语言客户端程序总会报缺少某个类而无法运行的错误。
文章为作者独立观点,不代表股票交易接口观点