일반적인 HDFS에서는 데이터를 읽으려면 무조건 DataNode를 경유해야 함.

Client가 데이터를 요청하면 DataNode는 Disk에서 데이터를 읽어 TCP socket을 통해 Client에 전송하는 방식.


하지만 Short-Circuit Local Reads를 설정하면,

요청한 데이터가 Local에 있을 경우 Client는 DataNode를 통해서가 아니라 Local Disk를 바로 읽을 수 있게 되어,

TCP socket 통신비용이 빠지므로 성능이 향상됨.





준비


Short-Circuit Local Reads를 사용하려면 우선 Native Library(libhadoop.so)가 필요함.

이미 Native Library를 빌드해서 쓰고 있다면 건너뛰고 없다면 아래 페이지를 참고해서 빌드할 것.

http://bloodguy.tistory.com/939






설정


다음은 hdfs-site.xml 에 아래 2개의 property를 추가함. (최소설정)

그리고 DataNode 전체 배포.

<!-- Short-Circuit Local Reads 사용함 -->
<property>
    <name>dfs.client.read.shortcircuit</name>
    <value>true</value>
</property>
<!-- Short-Circuit Local Reads에 사용할 UNIX domain socket 경로 -->
<property>
    <name>dfs.domain.socket.path</name>
    <value>/var/lib/hadoop-hdfs/dn_socket</value>
</property>



그리고 DataNode 전체에 dfs.domain.socket.path 에 지정한 디렉토리를 만들어 줘야함.

[root@server02]# mkdir -p /var/lib/hadoop-hdfs

[root@server03]# mkdir -p /var/lib/hadoop-hdfs

[root@server04]# mkdir -p /var/lib/hadoop-hdfs

[root@server05]# mkdir -p /var/lib/hadoop-hdfs

... 전체 데이터 노드 ...



전체 DataNode 재시작

[root@server01]# /home/hadoop/sbin/hadoop-daemons.sh stop datanode

[root@server01]# /home/hadoop/sbin/hadoop-daemons.sh start datanode



DataNode에 Short-Circuit Local Reads가 적용되었는지는 로그파일을 통해 확인 가능.

DataNode 시작시 로그파일에 아래 2줄의 로그가 있으면 Short-Circuit Local Reads가 적용된 것.


INFO org.apache.hadoop.hdfs.server.datanode.DataNode: File descriptor passing is enabled.

INFO org.apache.hadoop.hdfs.server.datanode.DataNode: Listening on UNIX domain socket: /var/lib/hadoop-hdfs/dn_socket







확인


테스트로 MapReduce를 한 번 돌려보고 전체 DataNode의 로그를 뒤져 Short-Circuit Local Reads 관련 로그만 추출해봤음.

대충 아래와 같은 식으로 진행되는 듯.


// client와 DataNode가 정보를 교환할 shared memory segment 요청 = /dev/shm

2015-04-02 14:35:51,485 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: cliID: DFSClient_NONMAPREDUCE_1985717107_123, src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_SHM, shmId: f0b4377d46601e0c546ac6b76d0578cc, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true


// blockid별로 file descriptor 요청

2015-04-02 14:35:51,560 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS,blockid: 1073742425, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true

2015-04-02 14:35:51,804 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS,blockid: 1073742424, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true

2015-04-02 14:35:51,983 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS,blockid: 1073742426, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true

2015-04-02 14:35:52,447 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: REQUEST_SHORT_CIRCUIT_FDS, blockid: 1073742427, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true


// file descriptor release

// 첫번째 release가 거의 정확히 5분(300초=300000ms) 뒤에 일어났음.

// dfs.client.read.shortcircuit.streams.cache.expiry.ms 설정값과 관련 있는 듯.

2015-04-02 14:40:51,660 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: RELEASE_SHORT_CIRCUIT_FDS, shmId: f0b4377d46601e0c546ac6b76d0578cc, slotIdx: 0, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true

2015-04-02 14:42:06,612 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: RELEASE_SHORT_CIRCUIT_FDS, shmId: f0b4377d46601e0c546ac6b76d0578cc, slotIdx: 1, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true

2015-04-02 14:42:06,614 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: RELEASE_SHORT_CIRCUIT_FDS, shmId: f0b4377d46601e0c546ac6b76d0578cc, slotIdx: 3, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true

2015-04-02 14:42:06,616 INFO org.apache.hadoop.hdfs.server.datanode.DataNode.clienttrace: src: 127.0.0.1, dest: 127.0.0.1, op: RELEASE_SHORT_CIRCUIT_FDS, shmId: f0b4377d46601e0c546ac6b76d0578cc, slotIdx: 2, srvID: 0a41e39f-88a5-4c97-9ffe-4298a446c20e, success: true






마치며


아래 [참고] 중 cloudera쪽 문서를 보면 벤치마킹 자료도 있음. 확실히 성능은 향상되는 듯.


몇몇 Hadoop 곁다리(-_-)들은 Short-Circuit Local Reads를 권장(Hbase) 혹은 의무(Impala)로 하는 듯.


개인적으로 한 가지 의문점은 이렇게 좋은게 왜 기본설정이 아닌가 하는 것.

여기저기 뒤져봐도 보안상의 문제라는 추측/짐작만 난무하고 있음...





[참고]

http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-hdfs/ShortCircuitLocalReads.html

http://blog.cloudera.com/blog/2013/08/how-improved-short-circuit-local-reads-bring-better-performance-and-security-to-hadoop

http://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.1.7/bk_system-admin-guide/content/ch_short-circuit-reads-hdfs.html














Posted by bloodguy
,