1.概述

在《HBase查询优化》一文中,介绍了基于HBase层面的读取优化。由于HBase的实际数据是以HFile的形式,存储在HDFS上。那么,HDFS层面也有它自己的优化点,即:Short-Circuit Local Reads。本篇博客笔者将从HDFS层面来进行优化,从而间接的提升HBase的查询性能。

2.内容

Hadoop系统在设计之初,遵循一个原则,那就是移动计算的代价比移动数据要小。故Hadoop在做计算的时候,通常是在本地节点上的数据中进行计算。即计算和数据本地化。流程如下图所示:

在最开始的时候,短回路本地化读取和跨节点的读取的处理方式是一样的,流程都是先从DataNode读取数据,然后通过RPC服务把数据传输给DFSClient,这样处理虽然流程比较简单,但是读取性能会受到影响,因为跨节点读取数据,需要经过网络将一个DataNode的数据传输到另外一个DataNode节点(一般来说,HDFS有3个副本,所以,本地取不到数据,会到其他DataNode节点去取数据)。

2.1 方案一:客户端直接读取DataNode文件

短回路本地化读取的核心思想是,由于客户端和数据在同一个节点上,所以DataNode不需要在数据路径中。相反,客户端本身可以简单地读取来自本地磁盘的数据。这种性能优化集成在CDH的Hadoop相关项目中,实现如下图所示:

这种短回路本地化读取的思路虽然很好,但是配置问题比较麻烦。系统管理员必须更改DataNode数据目录的权限,以便客户端有权限能够打开相关文件。这样就不得不专门为那些能够使用短回路本地化读取的用户提供白名单,不允许其他用户使用。通常,这些用也必须被放置在一个特殊的UNIX组中。

另外,这种本地化短回路读取的思路还存在另外一个安全问题,客户端在读取DataNode数据目录时打开了一些权限,这样意味着,拥有这个目录的权限,那么其目录下的子目录中的数据也可以被访问,比如HBase用户。由于存在这种安全风险,所以这个实现思路已经不建议使用了。

2.2 方案二:短回路本地化安全读取

为了解决上述问题,在实际读取中需要非常小心的选择文件。在UNIX中有这样一种机制,叫做“文件描述符传递”。使用这种机制来实现安全的短回路本地读取,而不是通过目录名称的客户端,DataNode打开Block文件和元数据文件,将它们直接给客户端。因为文件描述符是只读的,用户不能修改文件。由于它没有进入Block目录本身,它无法读取任何不应该访问的目录。

举个例子:

现有两个用户hbase1和hbase2,hbase1拥有访问HDFS目录上/appdata/hbase1文件的权限,而hbase2用户没有改权限,但是hbase2用户又需要访问这个文件,那么可以借助这种“文件描述符传递”的机制,可以让hbase1用户打开文件得到一个文件描述符,然后把文件描述符传递给hbase2用户,那么hbase2用户就可以读取文件里面的内容了,即使hbase2用户没有权限。这种关系映射到HDFS中,可以把DataNode看作hbase1用户,客户端DFSClient看作hbase2用户,需要读取的文件就是DataNode目录中的/appdata/hbase1文件。实现如下图所示:

2.3 缓存文件描述

HDFS客户端可能会有经常读取相同Block文件的场景,为了提升这种读取性能,旧的短回路本地读取实现具有Block路径的高速缓存。该缓存允许客户端重新打开其最近已读取的Block文件,而不需要再去访问DataNode路径读取。

新的短回路本地读取实现不是一个路径缓存,而是一个名为FileInputStreamCache的文件描述符缓存。这样比路径缓存要更好一些,因为它不需要客户端重新打开文件来重新读取Block,这种读取方式比就的短回路本地读取方式在读性能上有更好的表现。

缓存的大小可以通过dfs.client.read.shortcircuit.streams.cache.size属性来进行调整,默认是256,缓存超时可以通过dfs.client.read.shortcircuit.streams.cache.expiry.ms属性来进行控制,默认是300000,也可以将其设置为0来将其进行关闭,这两个属性均在hdfs-site.xml文件中可以配置。

2.4 如何配置

为了配置短回路本地化读取,需要启用libhadoop.so,一般来说所使用Hadoop通常都是包含这些包的,可以通过以下命令来检测是否有安装:

 $ hadoop checknative -a
Native library checking:
hadoop: true /home/ozawa/hadoop/lib/native/libhadoop.so.1.0.
zlib: true /lib/x86_64-linux-gnu/libz.so.
snappy: true /usr/lib/libsnappy.so.
lz4: true revision:
bzip2: false

短回路本地化读取利用UNIX的域套接字(UNIX domain socket),它在文件系统中有一个特定的路径,允许客户端和DataNode进行通信。在使用的时候需要设置这个路径到Socket中,同时DataNode需要能够创建这个路径。另外,这个路径应该不可能被除了hdfs用户或root用户之外的任何用户创建。因此,在实际创建时,通常会使用/var/run或者/var/lib路径。

短回路本地化读取在DataNode和客户端都需要配置,配置如下:

<configuration>
<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>
</configuration>

其中,配置dfs.client.read.shortcircuit属性是打开这个功能的开关,dfs.domain.socket.path属性是DataNode和客户端之间进行通信的Socket路径地址,核心指标配置参数如下:

属性 描述
dfs.client.read.shortcircuit 打开短回路本地化读取,默认false
dfs.client.read.shortcircuit.skip.checksum 如果配置这个参数,短回路本地化读取将会跳过checksum,默认false
dfs.client.read.shortcircuit.streams.cache.size 客户端维护一个最近打开文件的描述符缓存,默认256
dfs.domain.socket.path DataNode和客户端DFSClient通信的Socket地址
dfs.client.read.shortcircuit.streams.cache.expiry.ms 设置超时时间,用来设置文件描述符可以被放进FileInputStreamCache的最小时间
dfs.client.domain.socket.data.traffic 通过UNIX域套接字传输正常的数据流量,默认false

3.总结

短回路本地化读取能够从HDFS层面来提升读取性能,如果HBase场景中,有涉及到读多写少的场景,在除了从HBase服务端和客户端层面优化外,还可以尝试从HDFS层面来进行优化。

4.结束语

这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

另外,博主出书了《Hadoop大数据挖掘从入门到进阶实战》,喜欢的朋友或同学, 可以在公告栏那里点击购买链接购买博主的书进行学习,在此感谢大家的支持。

HBase查询优化之Short-Circuit Local Reads的更多相关文章

  1. HBase查询优化

    1.概述 HBase是一个实时的非关系型数据库,用来存储海量数据.但是,在实际使用场景中,在使用HBase API查询HBase中的数据时,有时会发现数据查询会很慢.本篇博客将从客户端优化和服务端优化 ...

  2. HDFS: The short-circuit local reads feature cannot be used

    问题: method:org.apache.hadoop.hdfs.DomainSocketFactory.<init>(DomainSocketFactory.java:69) The ...

  3. Short Circuit Protection Circuit

    http://www.daycounter.com/Circuits/Short-Circuit-Protection/Short-Circuit-Protection.phtml Short cir ...

  4. HBase查询优化——持续更新

    Scan:setBatch,setCaching,setCacheBlocks public void setBatch(int batch) public void setCaching(int c ...

  5. 十:HDFS Short-Circuit Local Reads 短路本地读取

    当client请求数据时,datanode会读取数据然后通过TCP协议发送给client.short-circuit绕过了datanode直接读取数据.short-circuit的前提是client和 ...

  6. Husky or C++ API - HDFS Short-Circuit Local Reads

    hdfs-site.xml added: <property> <name>dfs.client.read.shortcircuit</name> <valu ...

  7. HBase读延迟的12种优化套路

    任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少.总结 ...

  8. hbase读的性能优化

    任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少.总结 ...

  9. HBase读延迟的12种优化套

    任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少. 总 ...

随机推荐

  1. jquery ajax中success与complete的执行顺序

    jquery ajax中success与complete的执行顺序 jquery中各个事件执行顺序如下: 1.ajaxStart(全局事件) 2.beforeSend 3.ajaxSend(全局事件) ...

  2. ef.core Mysql

    Entity层 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; ...

  3. java编程目录

    目录结构 java常用数据类型使用 https://www.cnblogs.com/cerofang/p/10250535.html java中的排序  https://www.cnblogs.com ...

  4. linux 做了raid后,硬盘坏了更换问题

    系统做完raid1后发现 raid盘坏了,硬盘都是热插拔的,更换后,需要简单配置一下才能自动进行镜像拷贝. 在pd mgmt 页面,选择新加入的硬盘,按F2,选择 make global HS选项 选 ...

  5. ionic基于GPS定位并通过百度地图获取定位详细信息

    相信所有的前端攻城狮都会碰到移动端App.里面获取用户定位信息. 那么问题来了,怎么获取用户的定位信息(经纬度)呢. 当然方法有很多,通过百度地图API 以及 高德地图 API都是可以的.但是两个获取 ...

  6. centos7.5安装python3.7

    系统状态 CentOS Linux release 7.5.1804 (Core) mini版安装系统 Python-3.7.0.tgz 官方下载源码包 安装系统依赖包 # 编译必备 yum inst ...

  7. windows10下Kafka环境搭建

    内容小白,包含JDK+Zookeeper+Kafka三部分.JDK:1)   安装包:Java SE Development Kit 9.0.1      下载地址:http://www.oracle ...

  8. angular.js学习笔记(二)

    1.安装core ,shared模块 ng g m core  ng g m shared 2.在shared中导入core模块   core模块只加载一次所以将公共组件放到core中 3.创建公共组 ...

  9. H5混合开发问题总结

    1.This application is modifying the autolayout engine from a background thread, which can lead to en ...

  10. AI-2.梯度下降算法

    上节定义了神经网络中几个重要的常见的函数,最后提到的损失函数的目的就是求得一组合适的w.b 先看下损失函数的曲线图,如下 即目的就是求得最低点对应的一组w.b,而本节要讲的梯度下降算法就是会一步一步地 ...