Hadoop 2.2中正式启用了hdfs nfs功能,使得hdfs的通用性迈进了一大步。在公司让小朋友搭建了一下,然后我自己进行了一点简单的试验,有一点收获,记录在此。

理论

 

[测试] 试用Hadoop 2.2中的HDFS NFS 

 

使用hdfs nfs功能的话,数据访问路径如上图:用户或程序通过Linux自带的nfs client访问hdfs nfs服务,然后再由nfs网关作为hdfs的客户端访问hdfs。

这张图中,中间的节点就是nfs代理服务器(hdfs nfs proxy)或nfs网关(hdfs nfs gateway)。蓝色代表该模块是一个进程或服务,绿色代表该模块是一个库。图中还画了两条虚线,下、上线分别表示操作系统级别和分布式操作系统(hadpp)级别的内核态与用户态分界。

部署

在nfs网关上部署hdfs nfs服务所需要的程序包,按hadoop 2.2的部署方式,应该存在这两个文件:

share/hadoop/common/hadoop-nfs-2.2.0.jar

share/hadoop/hdfs/hadoop-hdfs-nfs-2.2.0.jar

配置文件不需要改,使用默认即可;默认的几个配置分别是nfs的服务端口(标准的2049)、mount的监听端口(4242),还有一个dump目录(/tmp/.hdfs-nfs)与写逻辑有关,暂不明原理。

部署完成后,启用服务,需要依次启动portmap和nfs两个服务;

$ hadoop-daemon.sh start portmap

$ hadoop-daemon.sh start nfs3

注意,portmap需要用root用户启动(因为portmap标准端口111,小于1024,是超级资源),而nfs服务应该用hdfs的超级用户启动。如果出现冲突,应该将操作系统本身的nfs服务停掉。

启动完成后,检查确认是否可用,其中nfs_server_ip是nfs网关的地址:

$ rpcinfo -p $nfs_server_ip

program vers proto   port
100005    1   tcp   4242  mountd
100000    2   udp    111  portmapper
100005    3   tcp   4242  mountd
100005    2   udp   4242  mountd
100003    3   tcp   2049  nfs
100000    2   tcp    111  portmapper
100005    3   udp   4242  mountd
100005    1   udp   4242  mountd
100005    2   tcp   4242  mountd

 

$ showmount -e $nfs_server_ip

Export list for SY-0245:
/ *

 

挂载NFS服务

创建挂载的目录

$ mkdir /mnt/hdfs

安装mount.nfs

$ sudo apt-get install nfs-common

开始挂载

$ mount.nfs $nfs_server_ip:/ /mnt/hdfs

 

试用及分析

尝试访问/mnt/hdfs,试用了简单的ls、cp、rm等操作,也进行了md5sum,都可以正常使用,而且响应速度明显快于通过FsShell进行操作,这应该是得益于nfs的wcc缓存及hdfs nfs的实现中对连接的缓存;

但hdfs nfs是否是一个完全兼容标准文件系统接口的实现呢,为此我测试了一下最难处理的随机写和复写,代码如下,简单的说,就是做三次写,第一次写在文件头(字符1),第二次写在文件尾(字符2),第三次写在文件中间(字符3):

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void usage(char* argv[]) {
  fprintf(stdout, "%s <file_length>\n", argv[0]);
  fprintf(stdout, "NOTE:\n");
  fprintf(stdout, "    file_length >= 3\n");
}

bool open_and_check(FILE** fpp, int op_seq) {
  (*fpp) = fopen("testfile", "r+");

  if ((*fpp) == NULL) {
    fprintf(stderr, "%d.Can not open test file.\n", op_seq);
    return false;
  }

  return true;
}

int main(int args, char* argv[]) {
  if (args != 2) {
    usage(argv);
    return -1;
  }

  int length = atoi(argv[1]);
  if (length < 3) {
    fprintf(stdout, "file_length must be at least 3\n");
    return -1;
  }

  fclose(fopen("testfile", "w+"));

  FILE* fp;
  int op_seq = 1;

  if (!open_and_check(&fp, op_seq))
    return op_seq;
  putc('0'+op_seq, fp); // '1'
  fclose(fp);
  op_seq++;

  if (!open_and_check(&fp, op_seq))
    return op_seq;
  fseek(fp, length, SEEK_SET);
  putc('0'+op_seq, fp); // '2'
  fclose(fp);
  op_seq++;

  if (!open_and_check(&fp, op_seq))
    return op_seq;
  fseek(fp, length/2, SEEK_SET);
  putc('0'+op_seq, fp); // '3'
  fclose(fp);
  //op_seq++;

  return 0;
}
test_rrw.c

相关文章:

  • 2021-07-07
  • 2022-12-23
  • 2021-06-12
  • 2021-12-17
  • 2021-08-21
  • 2021-11-14
  • 2021-05-23
  • 2022-12-23
猜你喜欢
  • 2021-12-21
  • 2021-10-06
  • 2022-12-23
  • 2022-12-23
  • 2021-08-14
  • 2021-08-27
  • 2021-11-04
相关资源
相似解决方案