티스토리 뷰

집필 마무리 때문에 정신이 없다가, 이제서야 다시 블로그 포스팅을 시작하네요.

오늘은 하둡의 Secondary NameNode (이하: 보조 네임노드) 에 대해서 포스팅 하겠습니다.


HDFS의 마스터 역할을 수행하는 네임노드(NameNode) 서버는 HDFS내에서 발생하는 모든 파일 트랜잭션을 editlog(이하: 에디트 로그) 라는 파일에 저장합니다. 에디트 로그 파일의 용량은 별도의 제한이 없어서, 네임 노드가 다운되지 않는 한 무한대로 저장이 됩니다. 문제는 HDFS가 재구동(restart)될 때인데, HDFS는 재구동을 할 때 에디트 로그와 파일 시스템 이미지(fsimage)를 병합해서 인메모리 형태로 메타 정보를 로딩합니다. 하지만 이때 에디트 로그가 지나치게 크다면 HDFS가 인메모리에 메타 데이터를 로딩하지 못하거나, 로딩이 지연되어서 HDFS가 구동되지 못하는 상황이 발생할 수도 있습니다.


이를 위해서 HDFS에는 보조 네임노드를 제공하며, 보조 네임노드는 네임노드의 에디트 로그를 주기적으로 축약시켜주는 역할을 수행합니다. 이러한 에디트 로그의 축약 작업을 체크 포인트(check point)라고 하며, 보조 네임노드를 체크 포인팅 서버라고 부르기도 합니다. 또한 네임노드의 파일 시스템 이미지나 에디트 로그가 깨졌을 때, 보조 네임노드에 저장된 데이터를 이용해 복구도 가능합니다. 물론 체크 포인팅 주기만큼의 유실은 감안해야 하지만, 트랜잭션이 매우 빈번하지 않다면 보조 네임노드 만으로도 일정한 백업 서버 역할을 커버할 수 있는 것입니다.


하지만 보조 네임노드를 운영할 때 주의할 점이 있습니다. 보조 네임노드 데몬이 다운되어 있거나, 체크 포인팅을 안하고 있더라도 HDFS의 파일 읽기/쓰기는 아무런 문제가 없이 진행이 됩니다. 그래서 보조 네임노드가 제대로 동작하고 있지 않은 상태에서 HDFS를 재구동하면, 앞서 말씀 드린 것처럼 HDFS가 구동되지 않는 최악의 상황이 발생할 수도 있습니다. 이를 위해 하둡 클러스터를 구성하셨을 때 보조 네임노드가 정상적으로 동작하는 지 반드시 확인을 하셔야 합니다. 


실제로 제가 테스트로 구성한 하둡 클러스터의 보조 네임노드에서는 아래와 같은 오류 메시지가 발생하고 있었습니다.


2012-09-28 16:00:11,912 ERROR org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: Exception in doCheckpoint: 

2012-09-28 16:00:11,914 ERROR org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: java.net.ConnectException: Connection refused

at java.net.PlainSocketImpl.socketConnect(Native Method)

at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)

at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:211)

at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)

at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)

at java.net.Socket.connect(Socket.java:529)

at java.net.Socket.connect(Socket.java:478)

at sun.net.NetworkClient.doConnect(NetworkClient.java:163)

at sun.net.www.http.HttpClient.openServer(HttpClient.java:388)

at sun.net.www.http.HttpClient.openServer(HttpClient.java:523)

at sun.net.www.http.HttpClient.<init>(HttpClient.java:227)

at sun.net.www.http.HttpClient.New(HttpClient.java:300)

at sun.net.www.http.HttpClient.New(HttpClient.java:317)

at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:970)

at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:911)

at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:836)

at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1172)

at org.apache.hadoop.hdfs.server.namenode.TransferFsImage.getFileClient(TransferFsImage.java:160)

at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode$3.run(SecondaryNameNode.java:347)

at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode$3.run(SecondaryNameNode.java:336)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.Subject.doAs(Subject.java:396)

at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121)

at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.downloadCheckpointFiles(SecondaryNameNode.java:336)

at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.doCheckpoint(SecondaryNameNode.java:411)

at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.doWork(SecondaryNameNode.java:312)

at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.run(SecondaryNameNode.java:275)

at java.lang.Thread.run(Thread.java:662)



네임 노드와 보조 네임노드간에 SSH도 접속이 되고, 네임노드의 포트도 살아 있어서 원인을 찾아내기가 어려웠는데요. 알고 보니 hdfs-site.xml에 dfs.http.address 프로퍼티를 정의하지 않았기 때문입니다. 보조 네임노드는 HTTP 프로토콜로 체크 포인팅을 시도하는데, 이때 dfs.http.address에 정의된 네임노드의 IP 혹은 호스트로 접근을 시도하게 됩니다. 그런데 dfs.http.address는 디폴트값으로 0.0.0.0:50070을 사용하고 있어서, 커넥션 오류가 발생한 것입니다. 한 대의 서버에서 네임노드, 보조 네임노드, 데이터 노드를 모두 함께 구동할 때는 0번 IP로 접근이 가능했지만, 제 경우 별도의 서버에서 구성을 했기 때문에 0번 IP 접근이 불가능한 것이었습니다. 인터넷으로 하둡 설치 방법을 검색하다 보면 대부분 한대의 서버에서 모든 데몬을 설치하기 때문에, dfs.http.address 프로퍼티에 대한 설정이 누락되는 경우가 많습니다. 네임 노드와 보조 네임노드를 물리적으로 별도의 서버로 구성할 경우에는 반드시 dfs.http.address 프로퍼티를 추가하시기 바랍니다. 또한 네임노드에서 보조 네임노드로 접근할 때도 문제가 없도록, hdfs-site.xml 파일에  dfs.secondary.http.address 프로퍼티도 함께 추가하시기 바랍니다. 이 프로퍼티에는 보조 네임노드의 IP 혹은 호스트명과 포트(50090)을 설정하시면 됩니다.



저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
댓글
댓글쓰기 폼