반응형

데이터 엔지니어로 살아가기 105일째


오늘은 어제 미처 다 끝내지 못한 프로젝트 로컬셋팅 및 배포 프로세스를 잡는데 대부분의 시간을 할애했다.

관심사 타겟팅의 프로젝트의 경우 submodule로 카산드라에 벌크업로드를 하는 프로젝트가 물려있어 생각보다 셋팅 후 배포 프로세스를 만드는데 까지 시간이 오래 걸렸다. 


submodule인 카산드라 벌크업로드 프로젝트의 경우 maven dependency에서 사용하는 하둡 라이브러리들이 알파와 리얼에 jar로 묶여 있어 로컬에서 빌드를 따로 수행하지 못하고 소스코드만 배포 시스템으로 그대로 서버로 옮겨놓은 후 해당 서버에서 직접 'mvn package'명령을 주어 빌드를 실행해주어야 했다.


간만에 젠킨스 셋팅부터 시작해서 사내 배포시스템을 사용하여 빌드 배포를 쉽게할 수 있도록 작업하였다.


그 후에 시간이 좀 남아 실시간 스트리밍 spark job중에 log4j가 프로젝트에 셋팅되어있는데 실제로 로그가 남지 않아 해당 이슈를 찾아보다가 해결을 하지 못하고 오늘 하루를 마무리 하였다. 내일 출근하자마자 관련 부분 확인해서 처리하고 알파에서도 데이터 파이프라인에 데이터들이 실시간으로 흘러다닐 수 있는 환경을 구축하도록 해야겠다.


갈수록 배움의 즐거움이 커진다.

반응형
반응형

 


 월 초(15.01)에 현재 팀에 분산 되어 있는 빌드 및 CI 서버 통합 작업을 진행하였다. 이번 포스팅은 서버 통합 작업을 하다가 발생한 java.lang.OutOfMemoryError: PermGen space문제에 대해 알아보도록 하겠다. 먼저 첫 번째로 문제가 발생한 현상에 대해 살펴보고 둘 째, 어떻게 해결했는지 살펴보고 마지막 셋째, java.lang.OutOfMemoryError: PermGen space에 대해 자세히 알아보자.



 1. 서버 작업 중 발생한 현상


 기존 서버에서 빌드 되는 프로젝트들도 많았지만 (약 50개 정도) 해당 부분에 대해서는 많은 문제가 되지 않았다. 왜냐하면 여러 프로젝트(10개 이상)가 동시에 빌드 작업을 진행하는 경우는 제로에 가까웠기 때문이다. 문제는 특정 소스코드가 수행되었을 때 자동으로 빌드되 commit_build와 특정 시간 간격마다 수행되게 하는 배치 빌드 등을 추가하면서 부터 발생하였다. 처음에는 서버 통합작업을 잘 진행하고 있었는데 어느 순간 부터(c_build, i_build)가 여러 개 추가되는 시점부터 서버가 뻗어버리는 현상이 발생하였다. 


 


 다음 그림과 같이 java.lang.OutOfMemoryError: PermGen space 에러가 발생한 것을 볼 수 있다. 이로 인해 서버가 뻗어 버리는 현상이 주기적(약1시간 간격)으로 나타났다. 그래서 일차적으로 주기적으로 빌드 되는 프로젝트들에 대해 주기적으로 빌드 되지 않도록 작업하였다.



  2. 해결한 방법

먼저 해결책을 말하자면 해당 서버의 톰캣/bin catalina.sh 에 들어가서 밑의 그림과 같이 추가해주었다.

 

그림이 잘 안보인다 ㅠㅠ 아무튼

 JAVA_OPTS="-server -Xms2048m -Xmx2048m -XX:MaxPermSize=512m -XX:-UseConcMarkSweepGC"

를 선언해주어 해결하였다. (기존에는 -XX:MaxPermSize가 선언되어 있지 않았다. (기본 20m로 설정되있다고 한다)


# -XX:+UseConcMarkSweepGC

 // 표준 garbage collector가 아닌 perm gen도 gc하는 concurrent collector를 사용하도록 한다.


-XX:+CMSPermGenSweepingEnabled

 // perm gen 영역도 gc의 대상이 되도록 한다.


-XX:+CMSClassUnloadingEnabled

// 클래스 데이타도 gc의 대상이 되도록 한다.


# -XX:MaxPermSize=64m

// 어느정도 크기가되어야 gc가 자주 발생하지 않는다. 기본값이 8M인듯.




  3. java.lang.OutOfMemoryError: PermGen space 관련 정보들에 대해 알아보자. (두서 없이 정리됨을 양해바람)


# java.lang.OutOfMemoryError: PermGen space문제는 기본적으로 동적 클래스를 많이 사용할 경우 빈번히 발생하는 문제로 JSP->SERVLET 변화. SPIRNG에서의 동적 클래스를 많이 사용하는 프레임워크로 인해 발생한다.


# JVM이 새로운 클래스 정의를 로드해야 하는데 이를 수행하기 위한 PerGen 공간이 충분하지 않아 발생한다. 즉, 이미 너무 많은 클래스들이 로딩되어 있으며 서버가 현재 크기의 PermGen이 처리할 수 없을 만큼 많은 클래스들을 사용하고 있기 때문이기도 하다. 


# 보통 Java heap이나 힙의 특정 영역에 객체를 할당 할 수 있는 공간이 충분하지 않을 때 발생


# PermGen space 라는 메시지는 permanent generation 이 가득 찬 상태라는 것을 알려준다. permanent generation은 클래스와 메쏘드 객체가 저장되는 힙의 영역을 나타낸다. 어플리케이션이 많은 수의 클래스를 로드하면, -XX:MaxPermSize 옵션을 사용하여 permanent generation의 크기를 증가시킬 필요가 있다. 


# 보통 톰캣을 사용하다가 이 에러를 보았다면 대체로 웹 어플리케이션을 너무 많이 Update 하거나 Reload 한 것이 원인이 될 수 있다. 톰캣과 JVM은 웹 어플리케이션을 삭제하고 다시 생성할 때 할당한 모든 메모리를 해제하지는 않는다. 톰캣을 여러 번 리로드 하면 할당된 메모리가 바닥나서 동작하지 않게 된다. 


# 톰캣에서 이 에러가 발생했을 경우 해결 방법은 1. 톰캣을 재시작 하는 것(임시적으로 해결) 2. 톰캣이 할당할 수 있는 메모리를 늘려 준다. 3. 메모리 누수가 발생하지 않도록 톰캣을 설정 (불필요한 프로젝트 들이 로딩되지 않도록 정리)


# Heap은 프로그램이 돌아가는 도중에 생성 삭제되는 곳으로 garbage-collected가 일어나는 곳이며 Permenant는 프로그램이 끝날 때까지 영원히 메모리를 차지하고 있는 공간으로 garbage-collected가 일어나지 않는 곳이다. Heap에는 동적으로 생기는 메모리 들이 들어가는 곳이고, Permenanat는 Class names, Internalized strings, Objects 등이 들어가며 PermGen도 이곳에 해당한다. 


참조 :

http://mindasom.tistory.com/96

http://jwchoi85.tistory.com/155#recentComments





반응형

+ Recent posts