HBase查询优化之Short-Circuit Local Reads
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的更多相关文章
- HBase查询优化
1.概述 HBase是一个实时的非关系型数据库,用来存储海量数据.但是,在实际使用场景中,在使用HBase API查询HBase中的数据时,有时会发现数据查询会很慢.本篇博客将从客户端优化和服务端优化 ...
- HDFS: The short-circuit local reads feature cannot be used
问题: method:org.apache.hadoop.hdfs.DomainSocketFactory.<init>(DomainSocketFactory.java:69) The ...
- Short Circuit Protection Circuit
http://www.daycounter.com/Circuits/Short-Circuit-Protection/Short-Circuit-Protection.phtml Short cir ...
- HBase查询优化——持续更新
Scan:setBatch,setCaching,setCacheBlocks public void setBatch(int batch) public void setCaching(int c ...
- 十:HDFS Short-Circuit Local Reads 短路本地读取
当client请求数据时,datanode会读取数据然后通过TCP协议发送给client.short-circuit绕过了datanode直接读取数据.short-circuit的前提是client和 ...
- Husky or C++ API - HDFS Short-Circuit Local Reads
hdfs-site.xml added: <property> <name>dfs.client.read.shortcircuit</name> <valu ...
- HBase读延迟的12种优化套路
任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少.总结 ...
- hbase读的性能优化
任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少.总结 ...
- HBase读延迟的12种优化套
任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少. 总 ...
随机推荐
- PBRT笔记(12)——蒙特卡洛积分
这里还涉及到pdf.方差等概念,推荐去看<全局光照技术:从离线到实时渲染> 积累分布函数 cumulative distribution function (CDF) 蒙特卡洛估算 为了计 ...
- Spring Cloud微服务笔记(四)客户端负载均衡:Spring Cloud Ribbon
客户端负载均衡:Spring Cloud Ribbon 一.负载均衡概念 负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容.因为负载均衡对系统的高可用性. 网络压力的缓解和处理能力的扩容的 ...
- Android SDK提供的常用控件Widget “常用控件”“Android原生”
Android提供一个标准的视图工具箱来帮助创建简单的UI界面.通过使用这些控件(必要时,可以对这些控件进行修改). 创建一个简单的.xml文件,从预览窗口可以看到Android SDK提供的原生控件 ...
- [CF1140C]Playlist
Description: 给你n首歌,每首歌有一个长度\(a_i\)和美丽度\(b_i\) 现在可以选出最多k首,动听值为\(\sum a_i*min_{\sum b_i}\) Hint: \(n \ ...
- MT7688交叉编译环境配置
在ubuntu下设置MT7688交叉编译环境,用于编译mt7688下使用的程序 1.首先在vmware下安装ubuntu64位,由于交叉编译工具需要64位系统,此次安装的是ubuntu14 2.在ub ...
- 机器学习——KMeans
导入类库 from sklearn.cluster import KMeans from sklearn.datasets import make_blobs import numpy as np i ...
- Shell中sed使用
sed是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往 ...
- 关于XML
一.XML定义 XML(eXtensible Markup Language)即可扩展标记语言,它与HTML一样,都是处于SGML,标准通用语言.Xml是Internet环境中跨平台的,依赖于内容的技 ...
- LeetCode笔记:140. Word Break II
题目描述 给定一个非空的字符串s,一个非空的字符串list作为字典.通过在s中添加空格可以将s变为由list中的word表示的句子,要求返回所有可能组成的句子.设定list中的word不重复,且每一个 ...
- K8S 安装 Wordpress
基本概念 Helm 可以理解为 Kubernetes 的包管理工具,可以方便地发现.共享和使用为Kubernetes构建的应用,它包含几个基本概念 Helm是目前Kubernetes服务编排领域的唯一 ...