Tomcat 시작 스크립트 옵션들.

Tomcat 시작 스크립트에는 많은 옵션들이 있는데, 이에 대해서 기술합니다.

start.sh 스크립트

Tomcat 을 시작하기 위해서는 CATALINA_HOME/bin/startup.sh 파일을 실행하면 된다. 이 스크립트 내용을 간단히 살펴보면 다음과 같다.

최종적으로 catalina.sh 파일을 호출하고 있는데, 이 파일에는 시작시에 사용할 수 있는 각종 쉘 환경 변수들이 나온다.

Catalina.sh 스크립트

CATALINA_HOME

Catalina 가 빌드된 디렉토리. 여기서 빌드된 디렉토리는 설치한 홈 디렉토리를 말하기도 한다.

CATALINA_BASE

Catalina 설치에 동적 영역을 해결하기 위한 기본 디렉토리. 이는 Multi Instance 설치할때에 에 사용된다. 만일 지정하지 않으면 CATALINA_HOME 을 사용한다.

CATALINA_OUT

stdout, stderr 를 어디로 보낼지에 대한 전체 경로를 지정. 기본 값은 $CATALINA_BASE/logs/catalina.out 이 된다.

CATALINA_TMPDIR

JVM 에서 사용할 (java.io.tmpdir) 의 임시 디렉토리 위치. 기본값은 $CATALINA_BASE/temp 이다.

CATALINA_OPTS

“start”, “run”또는 “debug”명령이 실행될 때 사용되는 Java 런타임 옵션. JAVA_OPTS 에 포함되는 옵션이 아닌것이 여기에 포함된다. Tomcat 자체에서만 사용되는 옵션들만 포함되며 중지 프로세스, 버전 명령 등으로는 사용해서는 안된다.

JAVA_HOME

JDK 설치한 위치. debug 인자와 실행할때 필요하다.

JRE_HOME

JRE 설치한 위치. 지정하지 않으면 JAVA_HOME 을 사용하고, JRE_HOME 과 JAVA_HOME 지정되면, JRE_HOME 를 사용한다.

JAVA_OPTS

명령이 실행될때 사용되는 Java 런타임 옵션. CATALINA_OPTS 모든 옵션이 아닌것이 여기에 포함된다. Tomcat 에의해서 사용되어질 수 있고 중지 프로세스, 버전 명령에도 사용된다. 대부분의 옵션들은 CATALINA_OPTS 에 있어야 한다.

CATALINA_PID

catalina 시작 java 프로세스의 pid 를 가지고 있는 파일 경로.

LOGGING_CONFIG

Tomcat의 로깅 설정 파일을 재정의. 예를들면 다음과 같이 한다.

LOGGING_MANAGER

Tomcat 의 로깅 메니저를 재정의. 예를들면 다음과 같이 한다.

 

CATALINA_OPTS, JAVA_OPTS 예제

여기서 중요한 CATALINA_OPTS, JAVA_OPTS 이다. 대부분 이를 구분하지 않는다. 하지만 설명에서 나왔듯이 구분해서 사용하는 것이 좋다. 예를들면 다음과 같다.

JAVA_OPTS 는 Tomcat 에서 사용되어질 변수들을 정의할 수 있다.

 

위와같이 구분을 해서 사용하는 것이 좋다.

Java 8 람다 표현식

이 글은 다음의 Youtube 강의 내용을 요약 정리한 것입니다.

  • Java 8 Lambda Basics – Java Brains

왜 람다(Lambda) 인가?

  • 함수형 프로그램이 가능하다.
  • 읽기 쉽고 간결한 코드
  • API 나 라이브러리 사용이 좀 더 쉽다.
  • 패러럴 프로그래밍이 가능하다.

람다는 함수 자체를 값으롤 할당할 수 있는 Inline 함수처럼 표현된다.

 

람다 표현식(Lambda Expressions)

자바에서 메소드로 불리우는 함수 표현식은 대략 다음과 같은 형식을 갖는다.

Inline Values

위 예제는 Inline Values 가 무엇인지 보여준다. 별다른 객체, 메소드의 도움이 바로 할당하는 형식이 바로 Inline Values 라고 보면 된다.

그렇다면 코드 블럭(Code Block) 자체를 인라인으로 할당 할 수 있지 않을까? 다음과 같이 말이다.

실제로 JavaScript 에서는 Inline 함수라고 해서 존재한다. 다음과 같은 형식을 갖는다.

Java 8 에서의 람다 표현식은 JavaScript 에서의 인라인 표기와 유사하다.

HelloWorld 람다

HelloWorld 를 통해서 람다 표현식을 익혀보자.

전형적인 HelloWorld 코드다. 이것을 람다 표현식으로 어떻게 바꿀까? 먼저 메소드 자체를 Inline Value 할당하듯이 가상의 변수에 할당해보자. 다음과 같이.

public 은 접근제한자라고 해서 protected, private 등이 있다. 변수에 할당하는 행위에서 있어서 이러한 접근제한자는 의미가 없다. OOP 에서는 객체의 변수를 직접 받는것이 아니라 메소드를 통해서 할당 받는데, 람다 표현식에서는 Inline Value 로 직접 할당하는 방식이기 때문에 무의미하다. 지우자!

코드를 다시보면 perform  이라는 함수 이름이 존재한다. 하지만 코드 블럭자체를 왼쪽 변수에 할당하고 그러한 코드 블럭은 왼쪽 aBlockOfCode 를 호출함으로써 동작하게 될터이다. 따라서 perform 이라는 함수 자체를 지칭하는 이름은 불 필요하다. 이는 앞서본 JavaScript 의 인라인함수 표현식에서처럼 할당되는 함수의 이름이 없는것과 같다. 지우자!

void 는 리턴타입을 말한다. 아무런 리턴도 없다는 의미이기도 하다. Java 8 컴파일러는 똑똑하다. 람다 표현식에서 리턴타입을 명시하지 않더라도 컴파일러가 알아서 해준다. 지우자!

다 됐다. Java 8 에서 람다 표현식에서는 ->  를 이용한다. 다음이 Java 8의 람다 표현식의 완성이다.

이게 정상적인 코드라구? 그렇다. Java 8 에 도입된 람다표현식이다. 정확하게 잘 동작한다. 위를 좀 더 간결하게 바꿔 쓸수도 있다.

 

람다(Lambda) 예제.

다음을 람다 표현식으로 바꿔보자.

Inline 변수 할당이기 때문에 객체 접근제한자는 필요가 없다. public 삭제..

Inline 변수 할당이기 때문에 double 이라는 함수자체이 이름도 필요가 없다. double 삭제.. 그러면 다음과 같은 형태만 남는다.

자바 컴파일러는 매우 똑똑하다. 리턴타입을 추론해 맞춰준다. 먼저 인자 타입이 int 형이라 결과도 나름대로 int 형일것으로 추정하기도 하고 리턴 되는 계산을 하면서 리턴타입을 추론하기도한다. 별도로 리턴타입을 정의해줄 필요가 없다. int 리턴타입 삭제…

그렇게 하고 나면 다음과 같이 람다 표현식을 쓸수 있게 된다.

람다 표현식이다. 하지만 이를 좀 더 줄이면 다음과 같이 쓸 수 있다.

한줄로 다 작성할 수가 있다면 {} 블럭을 사용할 필요가 없고 {} 없는 경우에 return 을 쓰지 않아도 된다.

모든 람다가 {} 이 필요 없는 것은 아니다. 다음과 같이 블럭내에 로직이 들어갈 경우에 {} 블럭과 return 이 필요하다.

문자열 길이를 알아내고자 한다면 어떻게 람다 표현식을 쓸 수 있나? 다음과 같다.

물론, 앞에서 처럼 뭔가 로직을 넣어야 한다면 {} 감싸고 return 을 해주면 된다.

최근 알고리즘 논쟁을 보고 느낌점…

최근 인터넷에 난데 없이 알고리즘 논쟁이 있었던 모양이다. 뭐 인터넷이라는게 방대하고 거기다 한국이란 곳으로 국한한다고 하더라도 몇몇 커뮤니티를 타고 옥신각신 한 정도밖에 더 될까만은 매우 흥미롭게 지켜보게 됐다.

원래 성격상 흥미가 없으면 ‘별 시덥잖은 이야기’ 정도로 치부하는데, 알고리리즘 논쟁을 보고 흥미가 생긴 이유가 아주 근본적인 사고차이에서 비롯된 것이라 생각했기 때문이다.

발단은 다음의 글에서 출발 했다.

개인적으로 알고리즘 관련 논람에 민감한 이유

알고리즘이 더 이상 모든 분야의 기본 지식이 아니라고 생각하는 이유는 이미 그런 토론을 통해 충분히 이야기했기 때문에, 지금은 왜 제가 이런 문제를 특히 민감하게 느끼는지에 대해 적어볼까 합니다.

제 생각에 자바나 C#, 혹은 자바스크립트 개발자에게도 ‘기초 지식’으로 알고리즘이나 운영체제 등을 공부할 것을 주문하는 것은 대체로 그런 ‘기본’을 배우면 나머지 ‘응용분야’는 쉽게 익힐 수 있을 것이라는 가정에서 출발하는 것 같습니다.

그리고 경우에 따라선 한 걸음 더 나아가 자바 같은 고수준 언어로 다루는 분야는 모두 그런 ‘응용’에 해당하기 때문에 보다 근본적이고 깊이 있는 운영체제나 C언어 등만 제대로 하면 어렵지 않게 익힐 수 있을 것이라는 근거없는 자부심으로 표출되기도 합니다.

https://okky.kr/article/396435

전체적으로 댓글이 우호적으로 달리는데, 개인적으로 적지 않게 놀랐다. 도대체 저런 글에 저렇게 많은 공감을 얻은 이유는 무엇일까? 라는 의문이들게 되면서 이 논쟁을 지켜보게 되었다.

얼마 가지 않아 다른분이 반론글이 올라오기 시작했다.

저주스러운 대한민국의 SI와 6개월짜리 국비지원 학원들 때문에 우리나라는 개발자들에 대한 인식이 형편없어졌는데, 개발자는 노가다꾼이 아니고 공학자에 속하는 직종이다. 자신의 재능이 아무리 비천할지라도 언제나 높은 수준에 오르기 위해 공부하고 자신의 결과물이 완벽에 가까워지도록 노력해야 하는 종류의 사람들이라는 뜻이다. 그런데 지금 소개하는 주장은 대학교에서 배우는 CS Fundamental이 구시대적이기 때문에 대학교의 커리큘럼이 예비 개발자들에게 구현에 대해 능숙해지도록 좀 더 가이드해야 한다고 주장한다. (대학이 직업학교인가?) 그런데 재미있게도 이런 주장을 하는 사람들은 이른바 개발자 커뮤니티의 네임드라는 부류는 될지언정 누구나 인정하는 구글러나 페이스북 개발자, 스타개발자는 아니다. (사실, 그런 사람들은 그런 시시한 커뮤니티를 하지도 않는다. 나도 페친들 링크 타고 가게됐을 뿐이다) 오히려, 인터넷에서 이름을 보는 대가들은 자료구조와 알고리즘을 탄탄이 하기를 당부한다. 그런데 왜 많은 사람들이 이런 말도 안되는 주장에 동조하고 열광하는가?

https://medium.com/@ghilbut/%EC%8B%A4%EB%AC%B4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%97%90%EA%B2%8C-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%80-%EB%8D%9C-%EC%A4%91%EC%9A%94%ED%95%A0%EA%B9%8C-fcbab7f87074

많은 사람들이 이글을 보았을 텐데, 웃기게도 ‘글이 너무 격양되어 있다’, ‘논리적인 글보다 욕하는 글’이라는 씹선비질 하는데 웃음이 났다. ㅋㅋ 격양된 글이긴 하지만 나름대로 논지가 있었기 때문에 그 논지에 대한 말들은 없고 그져 글이 어떠내 저쪄네… ㅋㅋ

위 글은 1부, 2부로 나뉘는데 이 글을 쓴 사람의 논지는 ‘알고리즘은 문제를 해렬하기 위한 방법으로 기능적 유효성이 있다’ 정도로 보인다.

 

알고리즘=문제해결 능력

개발자도 아닌 나 같은 사람은 알고리즘을 몰라도 된다. 탐색트리가 어쪄네 뭐가 어쩌네 하는 골치아픈 것들은 개발자들이나 하는 것이지 나 같은 밑바닥 인생을 사는 사람과 거리가 먼 이야기다.

이렇게 말을 하면 첫번째 글에 동조하는 듯하지만, ‘알고리즘’ 이라는 전형적인 전산학이 의미를 버리고 ‘문재 해결 방법’ 이라는 의미를 부여하면 두번째 글이 더 설득력이 있게 된다. 나 또한 두번째 글쓴이에 말에 동의 하는 바이고 그가 주장하고 비토했던 것에 전적으로 동의한다.

개발이 아니라 시스템을 운영하다보면 별의별 사건사고가 발생한다. 흔히 ‘장애’ 가 발생하면 최대한 빠르게 문제를 해결해야 한다. 그렇지 않으면 고객으로부터 손해배상을 제기하겠다는 서슬퍼런 이야기를 듣게 될테니까.

전부 다 그렇게 일하는 것은 아니겠지만 시스템 운영측면에서 장애 발생하면 대부분의 사람들은 ‘경험’ 에 의존하게 된다. 과거에 유사한 장애가 발생한 경험을 기반으로 문제를 해결하는 것이 가장 빠른 방법이기 때문이다. 시간은 자꾸가는데 운영체제론이 어쩌고 컴퓨터이론이 어쩌고 떠들어대봤자 답이 안나온다.

문제는 이러한 경험을 문제를 해결하고 난 다음이 문제가 된다. 반드시 장애 처리 후에 복기를 해보는데, 이게 정말 제대로된 문제해결이였는지를 평가해 향후 같은 장애가 발생하지 않도록 하는 회의를 진행한다.

바로 이 회의에서 ‘알고리즘’ 이 나온다. 웽? 시스템 장애 대응 회의때에 개발자 알고리즘이 나온다고?

ㅋㅋㅋ 알고리즘을 문제해결 능력이라는 측면으로 본다면 시스템 장애 대응 회의는 알고리즘이 회의가 된다. 개발자들이라는 시각으로만 좁게 보다보니 알고리즘이라고 하면 전산학 이론의 알고리즘만을 생각하지만 그 시각을 좀 더 확대 해보면 알고리즘이라는 말 자체는 문제를 해결하는 방법론을 전부 총칭한다.

결국 알고리즘을 잘 하냐 못하냐는 문제를 해결할 능력이 있는냐 라는 말과 같은 것이다. 이렇게 보면 알고리즘이라는 것 자체는 우리가 살면서 매일매일 생각하고 해결하는 것들과 다를바 없다.

그래서 두번째 글의 글쓴이가 예를들었던 면접 관련 이야기가 알고리즘이 무엇인지를 정확하게 보여준거라 생각한다.

알고리즘 인터뷰가 시작되면, 면접관은 데이터와 해결해야 할 문제를 포함한 몇 가지 조건들을 준다. 다만, 이 조건들은 대부분 완벽하지 않다. 대부분은 필수 요소 몇 가지가 빠져있으며, 때로는 아무 쓸모없는 조건들이 함께 있을 때도 있다. 이 조건들을 질의응답을 통해 문제 정의 가능한 수준으로 정리해야 한다. 그리고 나면 그 문제를 해결하기 위해 어떤 전략을 사용할 것인지를 설명한다. 면접관과 문제 해결 전략과 솔루션의 공간복잡도 및 시간복잡도 등에 대해 토론한 뒤 정리가 되면 구현을 시작한다. 이 때, 면접관이 내가 생각하지 못한 예외 케이스들을 자꾸 제시해서 코드 수정이 잦아지면 인터뷰는 200% 망했다고 보면 된다. 합격하려면 일반적으로 코드가 한번에 완성되어야 하고, 그렇기 때문에 구현 전에 토론과 함께 주의 깊게 전략을 완성해야 한다. 일반적으로는 그렇게 문제 풀이가 끝나지만, 구글은 종종 해당 문제에서 데이터셋의 스케일이 매우 커졌을 때에 대한 질문을 던진다. 현재 솔루션으로 확장된 데이터 규모에 대응 가능한지, 그렇지 않다면 이유가 무엇인지, 그럼 어떤 방식으로 더 큰 규모의 데이터를 처리할 수 있는지에 대해 솔루션을 요청한다. 이 때, 인터뷰 내용은 구글 내부에서 실제로 처리하는 업무의 인터뷰 버전일 가능성도 있다. 다시 강조하지만, 알고리즘 인터뷰는 절대 당신이 얼마나 아름다운 알고리즘을 외우고 있는지 보려는 것이 아니라 당신의 커뮤니케이션 능력과 논리적 사고력을 보고 싶어하는 것이다.

구글이라는 회사의 예제인데, 당연히 구글은 컴퓨터 회사이고 우리가 알고 있는 전산학의 알고리즘쯤은 줄줄이 꽤고 있어야 하며 그것을 기반으로 구글이 문제를 풀어야 한다. 문제는 두번째 글쓴이가 예를든 글을 자세히 읽어보면 면접시에 단순하게 면접자에게 알아서 풀어봐식은 하지 않는다는 것이다.

개인적으로 외국계회사에 면접도 몇몇보고 느낀 것이 바로 두번째 글쓴이가 이야기한 구글의 면접과 비슷했다. 면접관이 문제를 주는데, 문제자체가 문제가 있는 경우가 많았다. 그것을 캐취해서 자신이 의견을 피력하고 면접관과 토론을 벌여야만 했다.

겁나, 아니 존나 힘들었다. 면접관가 토론을 한다고 ??? ㅅㅂ 그냥 화이트보드에 알고리즘 기술하고 ‘맞죠?’ 하고 말지… 면접관은 화이트보드에 마커를 집어들기 전까지 ‘니가 문제를 어떻게 할지 설명해봐~’ 를 계속 요구했다. 이미 내 머리는 김이나기 시작했고……

그런다음에 Python 으로 문제 해결을 구현해야하는데, 이때부터도 난제들이다 . Python 을 얼마나 알고 있는지를 테스트하기 위해서 코딩하는 내내 ‘이건 왜 일케 코딩했지?’ 라는 질문이 계속 쏟아졌다. ‘Python 은 글케 하면 비효율적이다’, ‘문자열 처리는 일케 하면 어케하냐?’ 식의 비난과 비판.. ㅋㅋ 물론 팁도 준다. ‘이건 이렇게 해야 더 좋아~’ 식인데, 문제는 그게 왜 좋은건지 모르면 답 없는 거지.. ㅋㅋㅋ (내가 그랬음.. ㅋㅋ 왜 글케 해야하는지 몰랐음.. ㅋㅋㅋ 그냥 면접관이 그게 좋다니까 그걸로 했지.. ㅋㅋ)

내가 봤던 외국회사에 면접에서는 전산학 알고리즘은 단 한줄도 나온적이 없다. 그렇다면 내가 그 면접에서 알고리즘을 사용한적이 없는가? 전혀 그렇지 않다. 면접관과 토론하고 문제에 어떤 문제가 있으며 조건을 어떻게 만족해야 하며 Python 이라는 언어적 특성을 살리고 이렇게 구현하면 컴퓨터의 Compute, Memory 를 적게 차지하면서도 많은 일을 하게 할 것인가? 이것을 풀어나가고 최종적인 완성품을 만든것이 모두 다 알고리즘 문제라고 보면 된다.

결국 알고리즘은 모든 것의 기본이라고 봐야 한다. 시스템 운영을 하던 개발을 하던 수많은 문제에 직면하게 되는데, 알고리즘이 없다? 자바스크립트를 배우는데 있어서 복잡 다단한 알고리즘보다는 라이브러리를 아는게 더 중요하다? 그런 다음에 수 많은 문제들을 어떻게 해결할 것인가? 라이브러리를 끼워 넣으면서 해결할 건가? 물론 이진트리, 정렬등을 다 알고 있어야 한다는 건 아니다. 그렇다 라이브러리를 많이 안다고 문제 해결 능력이 저절로 생겨나나?

시스템 운영이라는 직군에서 면접에서도 마찬가지다. 외국의 경우에 어떤 장애 발생시에 어떻게 문제를 해결했는지에서 관심이 있지 몇분만에 그것을 해결했는지에는 아무런 관심도 없다. 문제를 인식하고 니가 그 문제를 바라본 관점이 무엇인지를 설명하라고 하는데, 그 바라본 관점이란게 당연히 컴퓨터 이론을 기반으로 한 것이여야 했다. 그러다보면 당연히 컴퓨터 강의실의 토론처럼 변하는 경우가 많았다.

알고리즘이라는 말 자체가 ‘현실세계에서 발생한 문제를 컴퓨터라는 도구를 이용해서 어떻게 해결할 것인가?’ 라는 것 아닌가?

문제해결은 고사하고 검색하기 바쁨.

내가 왜 이런 글을 장황하게 쓰냐하면 SI 에서 밥벌이를 하다보니 느끼는게 많이 있었기 때문이다. 그중에 하나가 ‘문제 해결능력 없는 인간들이 너무나 많다’ 라는 거다.

내가 알고 있던 한 사람은 개발 경력만 15년정도 였는데, 그가 들고 다닌 컴퓨터에는 그가 그동안 했던 프로젝트의 소스코드들이 들어 있었다. 그는 그것을 자신이 프로젝트를 할때마다 활용한다고 자랑스럽게 이야기를 하곤 했다.

내가 보기에 그것은 자랑거리가 못된다. 그 사람은 구글를 이용한 검색을 하지 않을뿐, 자신이 했던 과거의 코드를 기반으로 모든 프로젝트를 수행하고 있는 것 뿐이다. 과거의 코드가 현 시점의 문제해결에 부합한다면 사용하는데 아무런 문제가 없겠지만 시간을 흐르고 문제해결의 관점도 바뀌는 경우가 많다.  과거의 코드를 재활용할 생각이 였다면 그것을 현시점의 문제해결에 적합한지 정도는 테스트해야 하는게 맞지만 뭐 그렇게 하는 인간을 본적이 없으니… 도대체 자신이 한 프로젝트의 소스 코드를 왜 들고 있는거냐? 그것도 이해 못할 일이다.

뭐가 문제냐? 문제 될 것은 없다. 문제는 이후에 벌어지는데, 적어도 구글이나 github 에서 따온 코드라면 적어도 그것을 이용할때에 테스트라도 한번 했어야 했다. 테스트 하는 인간 못봤다. 그냥 Copy&Paste 지.. ㅋㅋㅋ   그리고 문제 생기면 서버 안좋데.. -_-;;

구글 검색을 활용하는 것에 뭐라하는게 아니다. 활용을 잘 했으면 한다는 거다. 특히나 시스템 운영에서도 구글 검색을 많이 이용하는데, 구글 검색한 내용이 이미 10년전이나 몇년이 지난 내용들을 가져다 실무에 적용하는 인간들 적지 않다.

한국의 SI 산업에 가장 큰 문제는 문제 해결 능력이 없다는데 있다. 문제 해결 능력은 많은 프로젝트를 수행하고 경력이 많다고 쌓이는게 아니다. 문제 해결을 잘할려면 이론도 많이 알아야 하고 문제가 시사하는 관점을 정확하게 파악하고 문제 해결을 위한 기획, 설계를 잘 해야한다. 하지만 SI 산업에 그렇게 일을 하는 인간 없다고 봐야 한다.

이런 측면에서 알고리즘 논쟁은 흥미로운 것이다. 개발자만의 논쟁거리가 못된다. 알고리즘을 그져 트리, 정렬문제로만 축소해보면 답이 없다는 것이다. 그런 관점이 잘 들어난 것이 첫번째 글쓴이의 글로 보인다. 그나마 두번째 글쓴이 정도가 알고리즘의 대한 관점을 잘 제시했다고 본다.

MySQL USING VS ON 차이.

MySQL에서 JOIN 을 사용할때에 USING 이나 ON 을 사용한다. 결과적으로 뽑고자 하는 데이터는 모두 동일한데 과연 이둘의 차이는 무엇일까?

첫째로 사용법에서 차이가 있다. USING 은 두 테이블간 필드이름이 같은 경우에 사용한다.

employees 와 salaries 를 조인(JOIN)하는데 emp_no 를 키가 양쪽 테이블에 모두 있기 때문에 USING 을 사용할 수 있다.
하지만 만일 조인시에 컬럼 이름이 다를 경우에는 ON 을 사용한다. 물론, 컬럼 이름이 같은 것을 기반을 조인을 할때도 ON 을 상용해도 된다.

Database 를 위한 공유 메모리, HugePages 계산하기

Database 시스템은 공유메모리 혹은 HugePages 에 매우 의존적입니다. 서버에서 데이터베이스가 가동되면 Database 가 사용하는 메모리는 Database만을 위해서 사용되어 집니다. 대부분의 큰 Database 시스템은 다른 서버 프로그램 없이 단독으로 설치되어 운영되어지기 때문에 얼마만큼 물리적 메모리를 Database 에 할당할지가 Database 시스템 전체에 큰 영향을 미칩니다.

이 글에서 Database 시스템을 위한 공유메모리, HugePages 등을 할당할때에 고려사항은 무엇이며 얼마나 할당하는 것이 좋은지를 살펴보겠습니다.

Oracle 11g or 12c

먼저 Oracle 은 물리적 메모리에 약 80% 를 Oracle 이 사용하도록 할당하도록 합니다. 여기서 대략 80% 라고 했는데, 만일 몇가지 프로그램을 함께 돌린다면 약 75% 가 적당합니다.

물리 메모리의 약 80% 할당

여기서 고려해야할 사항이 하나 있습니다. 80%를 할당하라고 해서 무조건 80%를 할당하게 되면 문제가 됩니다. 예를들어 16GB 의 물리 메모리로 운영하는 경우에 80%면 12.8GB 이고 서버에서 사용가능한 용량은 3.2GB 입니다. 요새 데스크탑 컴퓨터도 안되도 4GB 는 사용하는데 아무리 가벼운(?) 리눅스 서버라도 3.2GB 는 운영하는데 너무 적어 보입니다.

이럴때는 운영체제에서 사용할 최소 메모리를 남겨두고 나머지를 Oracle 에 할당하는게 현명하다고 할 수 있습니다.

또하나 중요하게 고려해야할 사항은 Oracle 에서 AMM을 쓰느냐 안쓰느냐 하는 문제 입니다. 이 둘의 차이는 다음과 같습니다.

AMM 을 사용할 경우: /dev/shm 장치를 이용한 공유메모리 모델 사용. HugePages 사용 불가

AMM을 사용하지 않을 경우: System V 공유 메모리 모델 사용. HugePages 사용 가능

 

Oracle 11g 버전으로 넘어오면서 전에 없던 기능이 하나 생겼는데, 그것은 바로 AMM(Aotomactic Memory Management) 입니다. AMM은 Oracle의 메모리 모델인 SGA와 PGA 를 통틀어서 메모리 관리를 자동으로 해준다는 개념입니다.

AMM 기능을 이용하면 대략적으로 SGA 영역은 Oracle 할당받은 메모리 영역에서 85%, PGA 는 약 15%로 나눠서 관리한다고 합니다.

또 한가지 AMM의 특징이 있는데, 공유메모리 모델중에서 /dev/shm 장치를 이용한 Posix 규격의 공유메모리 모델을 사용한다고 합니다. 이 메모리 모델은 메모리 가상 장치를 통해서 프로세스가 공유할 내용을 파일로 저장해서 공유하는 방법으로 오로지 용량에만 제약사항이 있습니다. 공유할 내용을 파일로 생성할때에 얼마만한 크기로 생성할지는 전적으로 서버 프로그램, 여기서는 Oracle, 에 의해서 결정됩니다. 최근의 모든 리눅스 서버는 /dev/shm 이 자동으로 마운트되어 있으며 기본적으로 전체 물리메모리의 50%를 사용합니다.

용량을 바꾸기 위해서는 다음과 같이 해줍니다. CentOS 6과 CentOS 7 배포판 별로 차이가 조금 있습니다.

 

만일 AMM을 사용하지 않을 경우에는 SystemV 의 공유메모리 설정을 따르게 됩니다. 이때에 HugePages 도 함께 사용할 수 있습니다. 이 설정들은 커널 파라메터로 조정하며 그 설정 변수는 다음과 같습니다.

shmmax: 단일 프로세스가 공유메모리를 호출하기 위한 최대 값. 단위 Bytes

shmall: 시스템을 통틀어 사용가능한 공유 메모리 Page 량. 단위 Page

nr_hugepages: Huge 페이지 개수.

 

여기서 중요한 것이 만일 HugePages 를 사용한다면 shmall 은 사용되지 않습니다. shmall 은 리눅스 메모리의 기본단위인 4096bytes(4k) 를 기반으로 계산되어 지는데, HugPages 는 이보다 더 큰 2048k(2MB) 를 기반으로 페이지를 나누기 때문입니다.

어찌됐든 이런 모든 상황을 고려해서 사용가능한 메모리를 구한다면 다음과 같은 공식으로 구할 수 있습니다.

보시면 아시겠지만 다른분이 만들어놓은 것으로 최소 500MB 용량을 넘는 것으로해서 shmmax, shmall, hugepages 를 모두 계산하고 있습니다.

MySQL 5.x

MySQL 의 경우에, InnoDB 엔진만을 사용한다는 전제하에, 전체 메모리의 80%를 MySQL이 할당해서 사용하도록 설정합니다.

물리 메모리의 약 80%를 MySQL에 할당(InnoDB만 사용)

MySQL 은 오로지 SystemV 의 공유메모리 모델을 따릅니다. 따라서 HugePages 를 사용할 수 있는데, 이를 위해서는 다음과 같이 my.cnf 에 설정을 해줘야 합니다.

그리고 shmmax,shmall,nr_hugepages 는 앞에 스크립트를 이용해서 구합니다.

Linux 설정

SystemV 공유 메모리 모델의 경우에 몇가지를 더 해줘야 합니다.

첫째로 Transparent Huge Pages (THP) 설정을 꺼야 합니다. 성능저하가 발생한다고 하네요. 다음과 같이 간단히 처리 할 수 있습니다.

매번 부팅시마다 자동으로 설정하고 싶다면 부팅 파라메터를 수정해 줍니다.

Ubuntu 의 경우에는 다음과 같이 해줍니다.

CentOS 의 경우에는 다음과 같이 해줍니다.

확인도 가능한데, 다음과 같이 AnonHugePages 값이 0Kb 명 THP 가 비활성화 된 것입니다.

마지막으로 커널이 HugePage 를 사용할 그룹이 누군지를 지정해 줍니다.

위와같이 리눅스 시스템 사용자의 그룹ID 를 알아내도록 명령어를 입력할 수도 있고 아니면 그냥 그룹ID를 찾아서 적어줘도 됩니다.