HDFS高阶优化方案
- 短路本地读取:short circuit local reads
- 背景
- 实现
- 老版本的设计实现
- 安全性改进版设计实现
- Unix domain socket
- 配置
- 配置一----libhadoop.so
- 配置二---hdfs-site.xml
- 节点block负载平衡器:balancer
- 背景
- 命令行配置
- 运行balancer
短路本地读取:short circuit local reads
背景
- 在HDFS中,不管是local reads(DFSClient和Datanode在同一个结点)还是Remote reads(DFSClient和DataNode不在同一个结点),底层处理方式都是一样的,都先由DataNode读取数据,然后再通过RPC(基于TCP)把数据传给DFSClient。这样处理是比较简单的,但是性能会受到一些影响,因为需要DataNode在中间做一次中转。
- 尤其Local Reads的时候,既然DFSClient社数据是在一个机器上面,那么很自然的想法,就是让DFSClient绕开DataNode自己去读取数据。所谓的“短路”读取绕过来DataNode,从而允许客户端直接读取文件。显然,这仅在客户端与数据位于同一机器的情况下才可行。短路读取为许多应用提供了显著的性能提升。
实现
老版本的设计实现
- 在HDFS-2246这个JIRA中,因为读取数据DFSClient和数据在同一台机器上,那么DataNode就把数据在文件中的路径,从什么地方开始读(offset)和需要读取多少(length)等信息告诉DFSClient,然后DFSClient去打开文件自己读取。
- 问题在于配置复杂以及安全问题
- 首先是配置问题,因为是让DFSClient自己打开文件读取数据,那么就需要配置一个白名单,定义哪些用户拥有访问DataNode的数据目录权限
- 如果有新用户加入,那么就得修改白名单。需要注意的是,这里是允许客户端访问DataNode的数据目录,也就意味着,任何用户拥有了这个权限,就可以访问目录下其他数据,从而导致了安全漏洞。
安全性改进版设计实现
-
在HDFS-347中提出来一种新的解决方案,让短路本地读取数据更加安全
-
在linux中,有个技术叫做Unix domain socket。这是一种进程间的通讯方式,它使得同一个机器上的两个进程能以socket的方式通讯
-
它带来的另一大好处就是,利用它两个进程处理可以传递普通数据外,还可以在进程间传递文件描述符
- 假设机器上的两个用户a和b,a又有访问某个文件的权限而b没有,而b又需要访问这个文件
- 借助Unix domain socket可以让a打开文件得到一个文件描述符,然后把文件描述符传递个b,b就能读取文件里买你的内容了,及时它没有相应的权限。
- 在HDFS的场景里,a就是DataNode,b就是DFSClient,需要读取的文件就是DataNode数据目录中的某个文件
Unix domain socket
Unix domain socket(Unix域套接字)是一种用于进程间通信的机制,特别适用于同一台计算机上的进程间通信。它是在Unix和类Unix操作系统中实现的。
Unix domain socket与网络套接字(例如TCP/IP套接字)相比具有以下特点:
安全性:Unix domain socket只能用于同一台计算机上的进程通信,不通过网络,因此相对来说更安全,不容易受到网络攻击。
性能:由于不涉及网络协议的处理,Unix domain socket具有较低的延迟和较高的吞吐量,速度更快。
权限控制:Unix domain socket可以利用文件系统的权限设置,对访问进行精确控制,从而实现更细粒度的权限管理。
Unix domain socket通常被用于本地进程间的通信需求,如某个进程提供服务,其他进程通过Unix domain socket与之进行通信。它广泛应用于各种场景,包括Web服务器、数据库、消息队列等。例如,Nginx等Web服务器可以使用Unix domain socket与后端应用程序进行通信,提高性能和安全性。
总结起来,Unix domain socket是一种本地进程间通信的机制,具有高性能、安全性好,适用于同一台计算机上的进程间通信需求。
配置
配置一----libhadoop.so
- 因为java不能直接操作Unix domain socket,所以需要安装hadoop的native包libhadoop.so。在编译hadoop源码的时候课可以通过编译native模块获取。可以用如下命令来检查native包时候安装好。
hadoop checknative
配置二—hdfs-site.xml
- dfs.client.read.shorticrcuit是打开短路本地读取功能的开关
- dfs.domain.socket.path是DataNode和DFSClient之间沟通的socket的本地路径
- 还要确保socket本地路径提前创建好
mkdir -p /var/lib/hadoop-hdfs
注意:这里创建的是文件夹hadoop-hdfs,而上述配置中的dn_socket是DataNode自己创建的,不是文件夹
节点block负载平衡器:balancer
背景
- HDFS数据可能并不总是在DataNode之间均匀分布。一个常见的原因是向现有的集群中添加了新的DataNode。HDFS提供了一个Balancer程序,分析block防止信息并且在整个DataNode节点之间平衡数据,知道被视为平衡为止
- 所谓的平衡指的是每个DataNode的利用率(本机已用空间与本机总容量之比)与集群的利用率(HDFS整体已利用空间与HDFS集群总容量的比)之间相差不超过给定阈值百分比
- 平衡器无法在单个DataNode上的各个卷(磁盘)之间进行平衡
命令行配置
运行balancer
- 设置平衡数据传出带宽
hdfs dfsadmin -setBalcanerBandwidth newbandwidth
其中newbandwidth是每个DataNode在平衡操作起价可以使用最大网络带宽量,以每秒字节数为单位
比如:hdfs dfsadmin -setBalcanerBandwidtth 104857600(100M)
- 运行balancer
默认参数运行:hdfs balancer
指定阈值运行:hdfs balancer -threshold 5 balancer将阈值5%运行(默认值10%)