Naver Pinpoint 1.1.0 릴리즈

지난 7/6에 Pinpoint 1.1.0 릴리즈 되었다.
가장 큰 변화는 Pinpoint에서 사용하는 HBase 버전이 0.94.x 에서 1.0.x 로 업그레이드 되었다는 것이다.

이 변화는 여러가지 영향을 준다. HBase 1.0는 JDK 6는 지원하지 않으며 JDK 7을 사용해야한다. 그리고 Hadoop 버전 2.4이상으로 변경해야 한다.

Hadoop 2.x 버전은 1.x와 다르게 YARN(Yet Another Resource Negotiator)가 추가되었다.

Pinpoint 덕분에 이해해야 할 것이 늘어난다.

사용중인 소스를 병합하는 작업과 테스트, 기존의 데이터 마이그레이션 등 어느정도 시간이 소요될 것으로 보인다.

참고

HBase와 호스트이름

Naver Pinpoint GitHub에 한 중국 유저가 Windows 7 환경에서 데이터 수집이 안된다는 이슈를 등록하였다. Pinpoint를 Windows에서 실행할 수 있도록 추가한 사람으로써 해당 문제를 확인하고 싶었다.

그래서 최신 Pinpoint가 1.0.4 RC를 받아 Windows 8.1에서 실행했는데 이슈로 등록된 문제가 나에게도 재현되었다.

HBase와 Pinpoint를 분산모드에서 테스트하기 위해 Linux에 설치하기 전까지 Windows에서 정상적으로 사용했었는데? 왜??

일단 HBase 로그를 살펴보았는데 의심스러운 부분이 눈에 들어왔다.

INFO util.VersionInfo: HBase 0.94.26
INFO server.ZooKeeperServer: Server environment:host.name=BK-P2.FOO.COM
...
INFO regionserver.HRegionServer: Connected to master at BK-P2.FOO.COM/192.168.56.1:56332
INFO regionserver.HRegionServer: Telling master at BK-P2.FOO.COM,56332,1423732578852 that we are up with port=56360, startcode=1423732588081

Master 호스트는 내가 사용하던 것인데 Region Server에 대해 낯선 IP 주소로 있었다. IP 주소를 확인해보니 최근 설치한 Oracle VirtualBox 용 네트워크 어댑터에 할당된 것이다.

C:> ipconfig /all
Windows IP Configuration
   Host Name           : BK-P2
   Primary Dns suffix  : foo.com
...

Ethernet adapter Local Area Connection:
   Description          : Realtek PCIe GBE Family Controller
   IPv4 Address         : 192.168.123.306

Ethernet adapter VirtualBox Host-Only Network:
   Description          : VirtualBox Host-Only Ethernet Adapter
   IPv4 Address         : 192.168.56.1

그리고 Pinpoint Collector와 TestApp을 실행했을 때 quickstart.collector.log 파일에 다음과 같은 로그가 발생했다.

[INFO ](o.a.z.ClientCnxn                   :1207) Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x14b7d1318ed0003, negotiated timeout = 40000
[DEBUG](c.n.p.r.s.PinpointServerSocket     :202) messageReceived:RequestPacket{requestId=2, payloadLength=84} channel:[id: 0xb2ae16b0, /127.0.0.1:56526 => /127.0.0.1:29994]
[INFO ](c.n.p.c.h.ApiMetaDataHandler       :51) Received ApiMetaData=TApiMetaData(agentId:test-agent, agentStartTime:1423733151414, apiId:-1, apiInfo:sun.net.www.protocol.http.HttpURLConnection.connect(), line:846)
[DEBUG](c.n.p.c.d.h.HbaseApiMetaDataDao    :53) insert:TApiMetaData(agentId:test-agent, agentStartTime:1423733151414, apiId:-1, apiInfo:sun.net.www.protocol.http.HttpURLConnection.connect(), line:846)
[INFO ](o.a.h.i.HBaseRPC                   :261) Server at BK-P2.FOO.COM/192.168.123.306:56360 could not be reached after 1 tries, giving up.

HBaseRPC가 접속하지 못하는 56360에 대해 확인하기 위해 아래 명령어를 실행했다.

C:\> netstat -an | findstr 56360
  TCP    192.168.56.1:56360     0.0.0.0:0              LISTENING

HBase에서 사용하는 IP 주소와 Pinpoint에서 사용하려는 IP 주소가 달라서 발생한 문제라고 판단했다(나중에 다시 확인하니 이것은 나의 틀린 판단이었다.) 일단 문제 해결을 위해 VirtualBox Host-Only Network 어댑터를 사용 중지 시키고 HBase를 다시 실행해보니 Pinpoint가 정상적으로 동작하는 것을 확인했다.

중국 유저에게 이런 문제가 아닌가 싶어서 이슈에 댓글을 달았는데, 그 유저의 문제는 이것이 아니고 기본적인 HBase 버전 차이 때문에 발생한 것이었다. Pinpoint는 HBase 0.94.x 버전만 지원하는데 0.98.x 버전을 실행한 것이다.

나의 경우는 단지 hosts 파일에 192.168.56.1에 대한 호스트명만 등록만 해주면 해결되었다.

192.168.56.1 bk.vm

이렇게 등록한 후 다시 HBase를 실행하면 다음과 같은 로그를 확인할 수 있다.

INFO util.VersionInfo: HBase 0.94.26
INFO server.ZooKeeperServer: Server environment:host.name=bk.vm
...
INFO regionserver.HRegionServer: Connected to master at bk.vm/192.168.56.1:56332
INFO regionserver.HRegionServer: Telling master at bk.vm,56332,1423732578852 that we are up with port=56360, startcode=1423732588081

즉, Master와 Region Server가 모두 bk.vm 이라는 호스트명으로 동작하는 것이다. 호스트명을 등록하기 전에는 BK-P2.FOO.COM 가 호스트명으로 사용되었다.

결론 적으로 이렇게 호스트명이 바뀐 이유는 Windows 8.1의 IPv6와 내가 사용하는 네트워크의 DHCP에서 IPv6를 지원하기 때문이며, HBase 실행시 네트워크 주소에서 IPv4를 우선하도록 설정했기 때문이다.

hbase-env.cmd 파일을 보면 아래와 같이 java.net.preferIPv4Stack=true 로 정의하여 IPv4를 우선하도록 되어 있다.

set HBASE_OPTS="-XX:+UseConcMarkSweepGC" "-Djava.net.preferIPv4Stack=true"

기본 네트워크 어댑터와는 다르게 Oracle VirtualBox 용 어댑터는 IPv4만 설정되어 있기 때문에 HBase에서 확인하는 호스트명이 바뀐 것이다.

간단하게 호스트명을 확인하는 클래스를 만들어 보고 실행해보았다.

public class Hostname {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress localhost = InetAddress.getLocalHost();
        String hostname = localhost.getHostName();
        String canonicalName = localhost.getCanonicalHostName();
        String hostAddress = localhost.getHostAddress();
        System.out.println("hostname=" + hostname + ",canonicalName=" + canonicalName + ",hostAddress=" + hostAddress);
    }
}

hosts 파일에 호스트 bk.vm 을 등록하지 않으면  getCanonicalHostName() 의 실행 결과가 상당히 오래 걸리는 것을 알 수있다. ZooKeeper는 FQDN을 위해 getCanonicalHostName()을 사용한다.

C:> java Hostname
hostname=BK-P2,canonicalName=BK-P2.FOO.COM/192.168.123.36
C:> java -Djava.net.preferIPv4Stack=true Hostname
hostname=BK-P2,canonicalName=bk.vm/192.168.56.1

AWS EC2 시스템 장애과 복구

2월 2일 어제는 나에게 무척이나 힘든 날이었다.

이미지 출처:http://matrix.wikia.com/wiki/Reload
출처:http://matrix.wikia.com/wiki/Reload

회사 PC

회사의 PC가 망가져서 PC 교체와 함께 OS 및 소프트웨어 설치등을 해야 했다. 작업용으로 사용하던 SSD는 괜찮았는데 백업용으로 사용하던 HDD가 인식되지 않는 문제가 발생했다. 2010년부터 백업했던 것들이 들어 있어서 꽤나 큰 충격을 받았다.

AWS EC2

그리고 New Relic으로 부터 AWS에서 사용중인 EC2서버 메모리 사용량이 90%가 초과했다는 알림 메일을 새벽에 받았었는데, 그 이후 알림이 해제되었다는 메일도 왔었다. 퇴근길에 혹시나 해서 AWS 콘솔로 확인해보니 EC2 서버는 문제가 없어 보였지만, AWS 콘솔에는 메모리와 관련된 모니터링이 없는 것이 마음에 걸렸다.

집에 돌아와 EC2 서버에 접속해보려고 했더니 반응이 없다. 국내가 아닌 일본에 있다보니 ISP 업체에서 연결을 제대로 못해주나 싶었으나 그것도 아니었다.

인스턴스 재부팅을 시도했는데 반응이 없어 인스턴스를 중지시키고 콘솔 로그를 확인했는데 아래와 같이 문제가 있었다.

[1982949.054580] Out of memory: Kill process 14993 (foo) score 47 or sacrifice child
[1982949.057875] Killed process 14993 (foo) total-vm:327252kB, anon-rss:47792kB, file-rss:124kB
[2051399.726500] end_request: I/O error, dev xvda, sector 12893328
[2051399.729576] end_request: I/O error, dev xvda, sector 12893392
...
[2051399.766446] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007

인스턴스를 다시 시작했으나 상태는 초기화중이고 한참 후에야 상태 확인(Status Check)이 1개 실패한 것으로 나타났다. EC2의 상태 확인은 시스템 상태 확인과 인스턴스 상태 확인으로 구성되어 있다. 이 중에 인스턴스 상태 확인이 실패되었다. 관련 도움말을 보니 여러가지 항목에서 오류가 발생할 수 있는데 나의 경우는 메모리와 블럭 디바이스 오류가 의심되었다. 물론 New Relic의 알림을 보면 주 원인은 메모리일 것이다.

메모리 오류

메모리를 많이 사용하는 경우 AWS에서 제시하는 방법은 메모리가 좀 더 있는 인스턴스로 바꾸는 것인데 Free Tier를 사용하는 나에게 해결책은 되지 못했다.

블럭 디바이스 오류

설명서에 따라 볼륨을 떼고 스냅샷을 만들고 다시 붙여보았지만 역시 문제해결이 되지 않았다. 별도의 EC2 인스턴스를 만들고 해당 볼륨을 붙였지만 부팅이 안되었다.

복원

일단 해결 방법이 쉽지 않다고 판단하여 새로운 볼륨에 서버 설정들을 다시 하고 복원을 하였다.

그나마 복원이 쉬웠던 것은 AWS 사용할 때 백업해 놓았던 것이 있었고 DB의 경우 RDS로 분리했기때문이다. 만약 RDS로 분리하지 않았다면 데이터는 손실이 발생했을 것이다.

참고