UNIX Domain Socket
UNIX Domain Socket是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC),它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和 应答等,只是将应用层数据从一个进程拷贝到另一个进程。UNIX Domain Socket有SOCK_DGRAM或SOCK_STREAM两种工作模式,类似于UDP和TCP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
本地读还是远程读
1 先判断datanode 上的该block是否在 fileInputStreamCache 上,即前面读过,则直接从cache上拿到留。也相当于本地读。
2 如果属性 dfs.client.use.legacy.blockreader.local 配置为true(默认为false)而且该文件block不在写的状态,因为在写的Block
不能通过本地读。则开启本地读。注意,该属性是针对Windows环境的用户。
3 如果dfs.client.use.legacy.blockreader.local 没有启用,则通过DomainSocket,即Short-Circuit Local 来读,Short-Circuit Local
需要先创建DomainSocket,如果allowShortCircuitLocalReads(dfs.client.read.shortcircuit)为true,且useLegacyBlockReaderLocal为false,这个也需要datanode
通过DomainSocket 发送FileInputStream给Client。,datanode 需要配置dfs.client.read.shortcircuit为true。协议是
REQUEST_SHORT_CIRCUIT_FDS 87
4 最后才通过远程读。
要启用Short-Circuit Local来读block,在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.domain.socket.path 是给
Domain Socket用的,如果这个没有配置的话,默认是“”,则Short-Circuit Local读不会生效。
读文件的流式协议:
1 版本:DATA_TRANSFER_VERSION
2 命令参数:OP_READ_BLOCK
3 块ID
4 时间戳
5 偏移量
6 读数据的长度
7 客户端标示
8 是否做checksum
client发送到datanode后,datanode的DataXReceive 接收,解析协议,解析成功,后,发一个成功连接的标示
给client,然后准备发送,发送前,先会发送checksum和计算后的偏移量,
client批判的是否为成功的标示,如果是,则继续
建立输入流通过DFSClient ,建立输入流DFSInputStream,构成成功后,对storefile获取文件块的信息,默认是10个块,并对最后一个快的大小是否改变,如果有改变,则说明该文件正在被写,更新中,则等待400ms重试,直到该文件写完。
未完,待续。。