文档章节

详解HDFS Short Circuit Local Reads

n
 newlife111
发布于 2015/04/24 16:51
字数 1583
阅读 225
收藏 0
点赞 0
评论 0

详解HDFS Short Circuit Local Reads

Hadoop的一大基本原则是移动计算的开销要比移动数据的开销小。因此,Hadoop通常是尽量移动计算到拥有数据的节点上。这就使得Hadoop中读取数据的客户端DFSClient和提供数据的Datanode经常是在一个节点上,也就造成了很多“Local Reads”。

最初设计的时候,这种Local Reads和Remote Reads(DFSClient和Datanode不在同一个节点)的处理方式都是一样的,也就是都是先由Datanode读取数据,然后再通过RPC把数据传给DFSClient。这样处理是比较简单的,但是性能会受到一些影响,因为需要Datanode在中间做一次中转。本文将介绍针对这个问题的一些优化。

既然DFSClient和数据是在一个机器上面,那么很自然的想法,就是让DFSClient绕开Datanode自己去读取数据,在具体实现上有如下两种方案。

HDFS-2246

在这个JIRA中,工程师们的想法是既然读取数据DFSClient和数据在同一台机器上,那么Datanode就把数据在文件系统中的路径,从什么地方开始读(offset)和需要读取多少(length)等信息告诉DFSClient,然后DFSClient去打开文件自己读取。想法很好,问题在于配置复杂以及安全问题。

首先是配置问题,因为是让DFSClient自己打开文件读取数据,那么就需要配置一个白名单,定义哪些用户拥有访问Datanode的数据目录权限。如果有新用户加入,那么就得修改白名单。需要注意的是,这里是允许客户端访问Datanode的数据目录,也就意味着,任何用户拥有了这个权限,就可以访问目录下其他数据,从而导致了安全漏洞。因此,这个实现已经不建议使用了。

HDFS-347

在Linux中,有个技术叫做Unix Domain Socket。Unix Domain Socket是一种进程间的通讯方式,它使得同一个机器上的两个进程能以Socket的方式通讯。它带来的另一大好处是,利用它两个进程除了可以传递普通数据外,还可以在进程间传递文件描述符。

假设机器上的两个用户A和B,A拥有访问某个文件的权限而B没有,而B又需要访问这个文件。借助Unix Domain Socket,可以让A打开文件得到一个文件描述符,然后把文件描述符传递给B,B就能读取文件里面的内容了即使它没有相应的权限。在HDFS的场景里面,A就是Datanode,B就是DFSClient,需要读取的文件就是Datanode数据目录中的某个文件。

这个方案在安全上就比上一个方案上好一些,至少它只允许DFSClient读取它需要的文件。

如果你想了解更多关于Unix Domain Socket的知识,可以看看:http://www.thomasstover.com/uds.html 和http://troydhanson.github.io/misc/Unix_domain_sockets.html

如何配置

因为Java不能直接操作Unix Domain Socket,所以需要安装Hadoop的native包libhadoop.so。如果你的集群是用各大Hadoop发行版(比如Pivotal HD,CDH等)来安装的,这些native包通常在安装Hadoop的时候会被安装好的。你可以用如下命令来检查这些native包是否安装好。

[vagrant@c6402 ~]$ hadoop checknative
hadoop: true /usr/lib/hadoop/lib/native/libhadoop.so.1.0.0
zlib:   true /lib64/libz.so.1
snappy: true /usr/lib64/libsnappy.so.1
lz4:    true revision:99
bzip2:  true /lib64/libbz2.so.1

Short Circuit Local Reads相关的配置项(在hdfs-site.xml中)如下:

  <property>
    <name>dfs.client.read.shortcircuit</name>
    <value>true</value>
  </property>
  <property>
    <name>dfs.domain.socket.path</name>
    <value>/var/lib/hadoop-hdfs/dn_socket</value>
  </property>

其中:dfs.client.read.shortcircuit是打开这个功能的开关,dfs.domain.socket.path是Datanode和DFSClient之间沟通的Socket的本地路径。

如何确认配置生效了

按照上面的配置,如何确认从HDFS读取数据的时候,Short Circuit Local Reads真的起作用了?有两个途径:

  1. 查看Datanode的日志

在Datanode的启动日志中,也可以看到如下相关的日志表明Unix Domain Socket被启用了。

2014-10-17 08:18:59,789 INFO  datanode.DataNode (DataNode.java:<init>(277)) - File descriptor passing is enabled.
...
2014-10-17 08:18:59,867 INFO  datanode.DataNode (DataNode.java:initDataXceiver(579)) - Listening on UNIX domain socket: /var/lib/hadoop-hdfs/dn_socket

我们再来读取一个文件看看。在我的测试集群中文件/tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm及其相关信息如下:

[hdfs@c6402 ~]$ hdfs dfs -ls /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm
-rw-r--r--   3 hdfs hdfs  109028097 2014-10-17 08:31 /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm
[hdfs@c6402 ~]$ hdfs fsck /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm -files -blocks
Connecting to namenode via http://c6404.ambari.apache.org:50070
FSCK started by hdfs (auth:SIMPLE) from /192.168.64.102 for path /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm at Fri Oct 17 08:40:47 UTC 2014
/tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm 109028097 bytes, 1 block(s):  OK
0. BP-1796216370-192.168.64.104-1413533983834:blk_1073741962_1138 len=109028097 repl=3

该文件有一个block,id是:blk_1073741962

现在我把该文件拷贝到本地

hadoop fs -get /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm /tmp

然后打开该节点上的Datanode的日志,下面的日志就表明读取block1073741962的时候用到了Short Circuit Local Reads。

2014-10-17 08:32:53,983 INFO  DataNode.clienttrace (DataXceiver.java:requestShortCircuitFds(334)) - src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS, blockid: 1073741962, srvID: 4ff4d539-1bca-480d-91e3-e5dc8c6bc4a8, success: true

2 . ReadStatistics API 
另外一种方法是通过HdfsDataInputStream的getReadStatistics API来获取读取数据的统计信息。相关实例代码如下:

public class FileSystemCat {
  public static void main(String[] args) throws IOException {
    String uri = args[0];
    Configuration conf = new Configuration();
    FileSystem fs = FileSystem.get(URI.create(uri), conf);
    OutputStream out = new FileOutputStream("/tmp/out");
    FSDataInputStream in = null;
    try {
      in = fs.open(new Path(uri));
      IOUtils.copy(in, out);
      if (in instanceof HdfsDataInputStream) {
        HdfsDataInputStream hdfsIn = (HdfsDataInputStream) in;
        DFSInputStream.ReadStatistics readStatistics = hdfsIn.getReadStatistics();
        System.out.println("Total Bytes Read Bytes: " + readStatistics.getTotalBytesRead());
        System.out.println("Short Circuit Read Bytes: " + readStatistics.getTotalShortCircuitBytesRead());
        System.out.println("Local Read Bytes:" + readStatistics.getTotalLocalBytesRead());
      }
    } finally {
      IOUtils.closeQuietly(in);
      IOUtils.closeQuietly(out);
    }
  }
}

我们再来试试:

[hdfs@c6402 classes]$ hdfs dfs -ls /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm
-rw-r--r--   3 hdfs hdfs  109028097 2014-10-17 08:31 /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm
[hdfs@c6402 classes]$ hadoop FileSystemCat /tmp/hive-0.13.1.phd.3.0.0.0-1.el6.src.rpm
Total Bytes Read Bytes: 109028097
Short Circuit Read Bytes: 109028097
Local Read Bytes:109028097

可以看到所有的数据都是通过Short Circuit Local Read来读取的。

© 著作权归作者所有

共有 人打赏支持
n
粉丝 7
博文 28
码字总数 15927
作品 0
深圳
高级程序员
Apache Hadoop 3.0.1 发布,bug 修复和性能增强

Apache Hadoop 3.0.1 版本正式发布,属于 3.0 版本线,包含了 42 处 bug 修复和性能加强。 请注意:NameNode 的默认 RPC 端口改回了 8020(在 3.0.0 版本中为 9820) HADOOP-15027 AliyunOSS...

wenbody ⋅ 03/26 ⋅ 0

Hive & Performance 学习笔记

注:本文来源于 Hortonworks 的 Adam Muise 在 July 23 2013 日的 Toronto Hadoop User Group 大会上的一次演讲, 本文只是稍作增删、整理,以备忘。 原文请见:http://www.slideshare.net/a...

xrzs ⋅ 2013/09/02 ⋅ 0

如何编写高质量的代码四 - 代码优化之Logic

短路评估 除了Loop, 逻辑控制也非常重要,好的逻辑控制能够大大的提高代码效率 if ( 5 < x ) and ( x < 10 ) then ... 比如你希望你的代码在x<5的情况下停止继续后面的表达式。 现代的语言都...

billzheng ⋅ 2012/10/24 ⋅ 0

Struts 2.3.15.1 GA 安全更新,请立即升级

Struts 2 发布最新安全补丁版本,修复了两个关键的安全问题: Remote code execution vulnerability when using short-circuit navigation parameter prefixes Open redirect vulnerability......

oschina ⋅ 2013/07/17 ⋅ 13

MapReduce执行过程分析

这个是个问题贴,由about云会员提问。会员答疑。提问和回答都比较有水平,分享出来。 1. MapReduce输入的时候,会对HDFS上面的文件进行split,切分的原则是什么样子的?假如HDFS默认文件存储...

wypersist ⋅ 04/23 ⋅ 0

NameNode Recovery Tools for the Hadoop Distributed

Most system administrators have had to deal with a bad hard disk at some point. One moment, the hard disk is a mechanical marvel; the next, it is an expensive paperweight. The H......

闵开慧 ⋅ 2014/07/02 ⋅ 0

hdfs--hadoop--双namenode三datanode

前提:搭建zookeeper集群、java环境、无秘互通注意:文中加粗部分表示需要按实际情况修改的部分> zookeeper可以参考:zookeeper传送门 下载安装包> https://mirrors.tuna.tsinghua.edu.cn/ap...

yr_linux运维 ⋅ 2017/12/27 ⋅ 0

往HIVE表中导入导出数据的几种方式详解

一:往HIVE表中导入导出数据 语法结构:[ ]带括号的表示可选择字段 LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)......

qq_26442553 ⋅ 03/08 ⋅ 0

hadoop2-shell操作详解

转载之: https://www.cnblogs.com/870386641drh/p/4262593.html FS Shell 调用文件系统(FS)Shell命令应使用 bin/hadoop fs 的形式。 所有的的FS shell命令使用URI路径作为参数。URI格式是s...

断臂人 ⋅ 06/14 ⋅ 0

关于struts2验证器显示信息问题

我在用struts2写一个表单验证,希望在不符合表单验证信息的地方出现提示,但结果无法显示,我贴出代码,麻烦给为给我看看,谢谢。 JSP页面代码: <%@ page language="java" contentType="te...

KYLINLIAO ⋅ 2013/02/24 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

ARMS: 原来实时计算可以这么简单!

摘要: 业务实时监控服务( ARMS)是一款阿里云应用性能管理(APM)类监控产品。借助本产品,您可以基于前端、应用、业务自定义等服务,迅速便捷地为企业构建秒级响应的业务监控能力。 业务实...

阿里云云栖社区 ⋅ 3分钟前 ⋅ 0

Monkey入门_琉璃

先下载android sdk安装配置好路径,然后adb shell 如果给你显示这个,说明目前没有有效的移动设备链接,可以开个安卓模拟器或者使用真机,usb或wifi链接到电脑都可以,打开usb调试模式;然后...

EvanDev ⋅ 4分钟前 ⋅ 0

Idea类注释模板

一、设置类注释模板 1.选择File–>Settings–>Editor–>File and Code Templates–>Includes–>File Header. 2.设置完成后,创建类时自动生成注释,效果如下。...

Clarence_D ⋅ 6分钟前 ⋅ 0

vuejs题

1、active-class是哪个组件的属性?嵌套路由怎么定义? 答:vue-router模块的router-link组件。 2、怎么定义vue-router的动态路由?怎么获取传过来的动态参数? 答:在router目录下的index.j...

自由小鸟 ⋅ 6分钟前 ⋅ 0

2018年社交系统ThinkSNS年中大促

致各大商企事业单位及粉丝用户: 为感谢大家对ThinkSNS品牌的关注与支持,2018年6月18日官方诚推出:年中大促,限时抢购活动! “ThinkSNS 年中大促,¥6.18超值特惠 名额有限,预购从速! ...

ThinkSNS账号 ⋅ 11分钟前 ⋅ 0

MYSQL主从复制搭建及切换操作(GTID与传统)

如下: MYSQL主从复制方式有默认的复制方式异步复制,5.5版本之后半同步复制,5.6版本之后新增GTID复制,包括5.7版本的多源复制。 MYSQL版本:5.7.20 操作系统版本:linux 6.7 64bit 1、异步...

rootliu ⋅ 12分钟前 ⋅ 0

Java强软弱虚引用Reference

Java强软弱虚引用Reference 本文目的:深入理解Reference 本文定位:学习笔记 学习过程记录,加深理解,提升文字组合表达能力。也希望能给学习Reference的同学一些灵感 源码说明 源码基于jdk...

lichuangnk ⋅ 14分钟前 ⋅ 0

plsql 表中字段及注释时为乱码

在windows中创 建一个名为“NLS_LANG”的系统环境变量,设置其值为“SIMPLIFIED CHINESE_CHINA.ZHS16GBK”, 然后重新启动 pl/sql developer,这样检索出来的中文内容就不会是乱码了。如...

江戸川 ⋅ 17分钟前 ⋅ 0

Docker创建JIRA 7.2.7中文破解版

1、介绍 1.1、什么是JIRA?   关于JIRA网上的介绍有很多,以下摘自百度百科:   JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任...

谢思华 ⋅ 21分钟前 ⋅ 0

Java Class 类使用

Java Class 类使用 我们可以通过已知的包名来获取到 Class 对象,从而可以通过反射动态的来操作对象。 获取Class有三种方式 //通过对象.class直接获取Class integerClass = Integer.class;...

gaob2001 ⋅ 26分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部