2014년 11월 11일 화요일

OpenVPN 윈도우즈 설치기

먼저...OpenVPN 을 설치하게 된 이유부터 밝힙니다.

회사에서 자체적인 인터넷 회선을 사용하지 않고 공동으로 사용하는 회선을 사용하고 있습니다. 그래서 원하는 포트를 마음대로 포트 포워딩 하기 힘듭니다.

그리고 망 관리자가 VPN 도 열어주기 쉽지 않은 상황입니다.

회선의 포트 포워딩도 A 회사는 14001~14009 번까지, B 회사는 14002~14009 까지...이런 식으로 일괄적으로 IP 하나를 정해서 회사에 부여를 해주더군요. 그런데 사용하는 Couchbase 는 포트를 임의로 바꾸면 컨트롤 하기 어렵습니다.

결론은???  포트를 하나만 이용하는 OpenVPN 이 해결책입니다. 물론 SSH Tunneling 도 괜찮은 방법이지만 사용상의 까다로움은 OpenVPN 쪽이 덜하다고 생각합니다. 물론 구축은???

어쨌든...



회사에서 이미 서버를 Windows...그것도 Windows 7 으로 깔아놓은 상황이라(도대체 전임자는 무슨 생각인건지) 몇 가지 문제점과 그에 따른 해결을 모색하면서 기존에 오해했던 부분들도 바로 잡을 수 있었습니다.



1. 설치

www.openvpn.net 에 접속합니다. Community 에 들어가 Download 메뉴에 들어갑니다. 지금 이 글을 쓰는 시점에선 OpenVPN 2.3.5 -- released on 2014.10.28 버전이 가장최신 버전입니다. 본인의 OS 에 맞는 설치 파일을 다운로드 받습니다.
여기서 잠깐...서버와 클라이언트가 같이 있으므로 접속 대상자에게도 이 파일을 제공해야 합니다.

종래의 *NIX 에는 갖가지 패키지 시스템(ports, pkgsrc, apt-get, yum 등)을 통해 의존성이 있는 프로그램을 설치해주지만, 윈도우즈의 경우 중간에 선택하여 설치할 수 있습니다. 중요한 건 TAP 이라는 네트워크 드라이버를 설치해주는데, 이건 설치를 해야 한다는 것입니다.

설치를 마치면 보통  C:\Program Files\OpenVPN 에 프로그램이 설치됩니다. 하위 디렉토리인 sample-config 디렉토리로 이동하면 sample 이 3 개 존재합니다. 당연히 Server 구축 시에는 server.ovpn 을 이용해야 합니다. 이 파일을 OpenVPN 디렉토리 하위의 config 디렉토리에 복사합니다.

그리고 설정 파일을 텍스트 편집기(저는 Editplus 정식 구매자로, Editplus 을 애용합니다)로 열어서 편집합니다. 주의할 것은 Administrator 로 접속하지 않았다면 텍스트 편집기를 열 때 관리자 권한으로 열어서 설정 파일을 열어야 합니다.

주의깊게 봐야 될 옵션은 다음과 같습니다.

port 1194
proto udp
dev tun

ca ca.crt
cert server.crt
key server.key

dh dh1024.pem

server 10.8.0.0 255.255.255.0

ifconfig-pool-persist ipp.txt

push "route 10.0.0.0 255.255.255.0"
push "redirect-gateway"
push "dhcp-option DNS 168.126.63.1"
client-to-client

keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3

사실 위 옵션만 있으면 모든게 끝납니다.

port 와 proto, dev 는 각각 OpenVPN 의 포트, 프로토콜, 방식입니다. 포트는 외부에서 접근 가능하게 열려있는 포트, 포로토콜은 말 그대로 프로토콜입니다. 방식의 경우 tun 와 tap 이 있는데, 국내 문서는 대부분 tun 으로 되어 있습니다. tun 은 공유기와 같이 해당 머신에서 다시 NAT 을 이용해서 가상의 IP 대역을 만들어 분배를 하는 방식입니다. 상단에 DHCP 가 존재하고 IP 발급이 자유롭다면 tap 형식으로 바꾼 뒤 bridge 방식으로 설정하면 머신과 동일한 레벨에서 IP 을 받아 사용할 수 있습니다. 하지만, 이 경우 네트워크 연결(제어판\네트워크 및 인터넷\네트워크 연결)에서 기존의 랜카드와 새롭게 생긴 TAP(로컬 영역 연결로 생성되며 TAP-Windows Adapter V9 으로 장치 이름이 나타납니다) 장비와 bridge 을 미리 생성해야합니다. 이 때 원격에서 작업하게 되면 네트워크 연결이 끊겨서 재접속이 안되니 주의를 해야 합니다. tun 은 기존의 랜카드로 들어가 인터넷 연결 공유(속성>공유>인터넷 연결 공유)을 체크하고 홈 네트워킹 연결에서 TAP 장치를 선택해주면 됩니다.

tun 으로 설정할 것이기 때문에 아래의 server 옵션과 push 옵션이 중요합니다.
server 옵션은 새롭게 생성할 가상 IP 의 대역입니다. 공유기를 써보신 분들은 아시겠지만 공유기 내에서는 외부의 IP 하나를 가상의 IP 여러개가 공유해서 쓰는 방식입니다.
 그래서 저렇게 새로운 가상 IP 영역이 필요한데, 기본값은 10.8.0.x 를 사용하도록 되어 있습니다. 본인이 평소 쓰는 대역과 다르게 해주는게 좋습니다.

그리고 push 에서 route 부분은 외부의 인터넷의 대역을 적어줘야 합니다. 이 값은 기존의 랜카드의 자세히 보기를 통해 확인할 수 있는데, 제가 있는 곳은 10.0.0.x 형태로 아이피를 발급하고 Subnet Mask 는 255.255.255.0 을 제공해주기 때문에 위와 같이 적었습니다. 이런 mask 기입은 여기서 설명하자면 좀 기니까...명령 프롬프트에서 ipconfig 명령 등으로 확인하고 기입하는 법을 좀 공부하시는 것도 좋겠네요.
나머지 두 개의 push 는 저와 같이 그대로 적어주시는 것도 좋습니다. 저 옵션은 VPN 으로 연결한 뒤에도 VPN 서버를 통해 인터넷을 하기 위해 적어주는 옵션입니다. redirect-gateway 을 통해 VPN 서버를 통해 인터넷을 하겠다는 것과 dhcp-option DNS 을 통해 새로 발급한 가상 IP 에 DNS 정보를 적어주는 것입니다. 168.126.63.1 은 우리나라 대표 DNS(KT 에서 운영)로 자신의 환경에 맞는 DNS 을 적어줄 수 있고, 여러 개를 쓰고 싶을 경우 이어적지 마시고 여러줄 적어주시면 됩니다.

그 외에 OpenVPN 은 개인키/공개키 방식의 보안 접속을 기본으로 하기 때문에 ca, cert, key 을 생성해서 등록해줘야 하고, config 디렉토리에 넣어둘 경우 저렇게 파일 이름만, 다른 위치에 두고자 할 때에는 ca "C:\\ca.crt" 와 같이 쌍따옴표를 이용해 경로를 지정해주고 역슬래쉬(\)는 두 번을 적어줘야 합니다.

keepalive 는 접속 유지 시간, comp-lzo 는 통신 내용 압축, status 는 로그 파일, verb 는 로그 단계(내용)에 관련된 내용입니다. 기본값 유지를 권장합니다.

이렇게 서버를 설정하신 뒤 server.ovpn 파일에서 마우스 우측 버튼으로 Start OpenVPN on this config file 을 실행하시면 서버가 실행됩니다. 명령 프롬프트 창이 뜨니까 거기에 나오는 내용을 잘 보세요. 혹시 에러가 있을 경우 내용을 보고 수정을 해야 합니다.

물론 서비스에도 등록이 되기 때문에 서비스로 가셔서 OpenVPN 을 실행해도 됩니다.




클라이언트의 경우 서버와 비슷합니다. 마찬가지로 sample-config 에서 client.ovpn 을 config 디렉토리로 복사한 디 설정파일을 서버와 내용을 맞춰가면서 설정하면 됩니다.

client
dev tun
proto udp

remote 123.123.123.123 1194

resolv-retry infinite
nobind
persist-key
persist-tun

ca ca.crt
cert client.crt
key client.key

ns-cert-type server
comp-lzo
verb 3

dev와 proto 는 서버와 동일하게 해주시고, remote 에서 OpenVPN 서버를 생성한 서버의 실제 IP 와 포트를 적어줍니다. 그 외에는 모두 그대로 두시고, ca, cert, key 역시 생성된 것을 config 디렉토리에 넣어줍니다. ca 는 서버와 동일한 파일이고 cert, key 는 클라이언트용 파일입니다. 이 역시 생성 방법은 찾아보면 많습니다.

주의하실 점은 처음 생성할 때에는 client 키를 잘 만들었는데, 그 다음부턴 오류가 난다(C:\*.old을 찾을 수 없습니다)는 분들이 계신데, easy-rsa 에서 init-config 와 vars 을 다시 실행한 뒤 생성하시면 됩니다.

그리고 클라이언트에서는 openvpn-gui.exe 파일로 트레이에 아이콘을 띄워놓고 쓰는게 편한데, 관리자 권한으로 실행되야 합니다. 그러므로 해당 파일을 항상 관리자 권한으로 띄우도록 설정한 뒤 사용하는게 편합니다.

이상 끝!!!



이 문서는 처음 OpenVPN 을 설치하는 분이 아닌, 기존 문서를 보고 좀 막힌다 싶은 분들을 위한 문서입니다. 처음 구축을 하시는 분들은 구글에서 "openvpn 윈도 설치" 로 먼저 검색(http://goo.gl/OqFdM5) 한 번 해보시고 문서들 보면서 좀 익히신 뒤 따라해보세요.

2014년 8월 17일 일요일

Couchbase 사용기 - 2

Couchbase 는 기본적으로 key/value 타입의 NoSQL 제품입니다. 다시 말해 Unique 한 Key 을 이용해서 문서(Document)을 빠르게 가져오는 것을 목적으로 한 제품이라는 것이죠. 그렇다면 사용자가 읽어오길 원하는 문서의 Key 을 알고 있다면 언제든지 문서를 가져올 수 있습니다. 실제로 Couchbase SDK 에서는 set() 와 get() 을 통해서 문서를 저장하고 가져올 수 있으며 매우 단순한 형태이기 때문에 초급 개발자도 금새 배울 수 있습니다.
하지만, 현실상 특정 key 의 문서만 가져오는 경우는 매우 드뭅니다. 가까운 예로 게시판의 경우만 해도 특정 조건을 만족하는 데이터(=문서)의 집합을 가져와서 화면에 출력하는 형태가 되죠. Couchbase 는 이러한 것을 map/reduce 기반의 View 을 통해 처리할 수 있도록 하고 있습니다. map/reduce 는 Couchbase 의 독자적인 기술은 아닙니다만, 솔루션마다 처리 방식을 조금씩 다르게 하기 때문에 여기서 Couchbase 의 View 을 통해 Couchbase 만의 특징을 살펴보고자 합니다.

Couchbase 의 웹콘솔에 접속하면 Views 항목을 볼 수 있습니다. 여기서 View 을 생성할 수 있습니다. 이 때 "Design Document Name" 이라는 항목과 "View Name" 을 입력하게 되어 있는데, 쉽게 말해 Design Document Name 은 뷰의 그룹명, View Name 은 View 의 이름입니다. 생성을 하게 되면 "VIEW CODE" 부분에 "Map" 와 "Reduce" 을 입력할 수 있습니다. 모두 Javascript 문법을 이용한 하나의 function 이며, 매개변수는 doc 와 meta 을, View 에서 생성되는 인덱스에 들어가는 정보는 emit() 으로 입력할 수 있습니다.

자세한 사용법을 설명하는 것은 아니므로 구현 부분에 대해서는 다른 기회가 되면 글을 적어보겠습니다. 여기서 설명할 내용은 View 에 대한 특성입니다.

먼저, View 은 처음 생성할 때를 제외하고는 문서를 추가하거나 갱신, 삭제 등의 작업을 할 때 처리된 후 저장됩니다. 처음 생성할 때에는 모든 문서를 읽어서 View 의 인덱스를 구축합니다. 이 구축 작업은 비동기로 이루어지기 때문에 생성 버튼을 눌러도 바로 적용되지 않고 수초~수십초의 시간이 흐른 뒤에야 제대로 View 의 결과가 나타납니다. 그리고 문서가 추가되는 등의 작업이 발생하면 메모리에 저장을 하면서 map/reduce 코드를 통해 인덱스 정보가 생성된 뒤에 2.5.1 까지는 디스크에, 3.0 부터는 메모리에 인덱스 정보가 저장되기 때문에 저장 완료 후 즉시 조회를 하면 바로 적용이 되질 않아서 추가/갱신/삭제된 문서 정보가 제대로 반영이 안되어 있습니다. 2.5.1 이하 버젼에서는 3초 정도 걸리는 경우가 비일비재합니다. 3.0 부터는 메모리에 저장되기 때문에 1초 이하가 될꺼라고 합니다만 완벽히 동기화 된다고 볼 수 없습니다.

그리고 View 는 조건에 대한 처리가 아니라 문서에 대한 처리이기 때문에 사용자가 조회시 보내는 매개변수에 따라 그때그때 조회하는 것이 아니라 인덱스된 문서의 key의 범위 사이의 값을 돌려보내주는 것입니다. 그래서 배열 형태로 2개 이상의 매개변수를 보낼 경우 일반적인 RDBMS 의 검색과는 판이한 검색결과가 나옵니다. 게다가 숫자형의 값일 경우 일반적인 조회에서는 숫자형태로 저장되어 있지만, View 을 생성하면 숫자형이 문자형으로 바뀌기 때문에 인덱스 생성시 1,2,3,...,10,11,12,...,20,21,22,... 와 같은 형태가 아닌 1,10,100,...,11,... 와 같이 정렬이 됩니다. 복합적인 매개변수의 경우도 아래와 같이 됩니다.


  1. [1,"daum","korea"]
  2. [1,"naver","korea"]
  3. [3,"bing","usa"]
  4. [3,"google","usa"]


위와 같이 인덱스가 생성되면(입력 순서에 상관없이 세 값의 순서대로 정렬되어서 인덱스가 생성됩니다) 아래와 같은 형태로 범위검색을 할 수 있습니다.

startKey : [1,"dreamwiz", "korea"]
endKey : [3,"facebook", "usa"]

처음에는 RDBMS 의 or 조건처럼 검색이 되나 싶었습니다만(엔투엠에서도 그런 식으로 이해하시면 될 것 같다고 했습니다만...) 사실 그렇지 않더군요. 어찌보면 더 간단한 것인데요...
추가로 startKey 와 endKey 을 입력한다고 하면 어떤 위치에 값이 들어가게 될까요? 각각 1 번 다음과 3번 다음에 위치하게 될 것입니다. 그러므로 위의 범위 검색 결과는 2 번과 3 번이 되게 됩니다. 이런 식으로 범위 검색을 통해서 이미 입력된 인덱스의 값을 가져오기 때문에 RDBMS 의 like 검색과 같은 것은 이용할 수도 없고, 숫자를 이용한 범위 검색도 불가능합니다. 그래서 항상 View 을 생성하고 난 뒤 원하는 결과가 나오는지 꼼꼼히 확인하는 것이 중요합니다.

좀 더 다양한 검색 결과를 원하신다면 검색엔진과의 연동이 필요합니다. Couchbase 에서는 Elasticsearch 와 연동하는 방법을 제공하고 있습니다. 이 방법을 통해 View 의 map/reduce 방식이 가지는 한계를 어느 정도 극복할 수 있습니다.

또다른 사용기는 다음 글에...

2014년 8월 15일 금요일

Couchbase 사용기 - 1

Couchbase 을 도입해서 Web REST 기반의 서버를 제작했습니다. 실제 서비스를 제공중에 있구요. 동시접속 2만명 테스트도 진행했었는데, Couchbase 는 잘 버틴다는 표현을 쓰기 무색하게...한가로이 데이터를 처리하더라구요. 하나의 요청에 Couchbase 의 문서(Document) 갱신이 최소 2회가 이루어지는데도 말이죠. MariaDB with Galera Cluster 라면 몇 분 마다 한 번씩 SlowQuery 로그가 떨어질 환경이었는데 별 걱정 없이 프로그래밍 할 수 있게 해줘서 다행이다 싶었습니다.

하지만, 게임이 매우 잘되어서 저장공간이 부족해지거나, Log 를 Couchbase 에 담는다거나 해서 용량증설의 시기가 다가오면, 장비의 추가냐 램의 증설이냐를 따져야할 때가 옵니다. 보통은 서버에 램을 추가로 꼽는 것이 훨씬 비용이 저렴하기 때문에 램 증설(Scale-Up)을 고려하게 되지만, 문서의 크기가 점점 불어나서 저장 공간이 부족해질 때에 적합한 것이지 사용자가 늘어나서 증설의 필요성이 생긴 것이라면(다시 말해 문서의 개수가 많아졌을 경우) 장비의 추가(Scale-Out)가 필요하게 되었다고 판단해야 합니다.
이는 Couchbase 가 기본적으로 Sharding 을 지원하기 때문에 장비가 늘어나면 늘어날수록 문서(Document)가 각 서버에 분산 배치되어 처리되기 때문에 서버가 늘어날수록 요청이 서버수만큼 분산되어 전체 처리량을 늘릴 수 있게 되기 때문입니다.

그런데 살짝 딜레마에 빠지게 되는게 두 가지가 있습니다.

먼저, Couchbase 는 가상머신(Cloud Server인 AWS 나 UCloudBiz, 혹은 VMWare, Zen Server 등)보다는 실제머신을 사용할 것을 권합니다. 아무래도 가상머신들은 메모리를 공유하는 형태가 많기 때문에 이 부분에서 속도 문제나 오염 문제가 생길 가능성을 배제할 수 없을 것 같기도 하고, CPU 등의 설정이나 Couchbase 의 네트워크 환경의 문제도 약간 걸림돌이 될 수 있습니다.
특히 가상머신을 이용할 경우 하나의 공인IP 을 여러 가상머신이 공유해서 사용하는 경우가 대부분인데 Couchbase SDK 는 편리한 Connection Pool 을 이용해 접속을 하는 대신, 8091 와 11210 포트를 이용해 Pool 에 등록된 Couchbase Server 에 접속을 하기 때문에 포트 포워딩을 통해 각 서버에 접속할 수 있도록 해줄 수가 없습니다. 좀 더 자세히 설명하자면,


  1. Client 는 Server 의 8091 포트를 통해 접속 시도
  2. Server 는 Client 에게 Clustering 된 Server 접속정보(HOST:PORT 형식) 목록을 제공
  3. Client 는 Connection Pool 에 Server 목록을 저장
  4. 저장된 Server 목록을 이용해 각 Server 에 접속


위와 같은 동작 방식을 취하고, 이는 Couchbase SDK 뿐만 아니라 Couchbase Server 간에도 이와 같은 방식을 취하기 때문에 외부 접속시에만 포트 번호를 임의로 바꿔서 처리하는 포트 포워딩 방식의 처리도 쉽지 않습니다.
그리고, 처음에는 1 대의 머신으로 테스트를 하는 경우가 많아서 간과할 수 있는 부분이 있습니다. Couchbase 는 장비를 기존 Cluster 에 추가할 때에는 IP 혹은 Domain(FQDN)을 이용해서 기존 서버(신규 서버에서 기존 클러스터에 참여하려고 할 때) 혹은 신규 서버(기존 서버에서 신규 서버를 등록하려고 할 때)에 접속해서 연결을 하는데, 위의 2 번에서 돌려주는 Server 접속정보가 이 때 등록한 IP 혹은 Domain 이 됩니다. 그래서 가상머신에서 가상IP 을 이용해서 등록을 하게 될 경우 외부에서 Couchbase SDK 을 이용한 Client 연결이 불가능해질 수 있습니다.
이에 대한 해결 방법을 고민한 결과, 저는 hosts 파일을 모든 Client/Server 에 등록해서 연결하는 방식을 취하고 있습니다. IP 나 제대로된 DNS 을 이용할 경우 가상머신을 이용할 때에 꼬이게 되는 부분이 있어서 이렇게 처리했습니다. 혹시 더 좋은 방법이 있으신 분은 조언 부탁드립니다(zepinos@gmail.com).

또 다른 하나는, 실제 머신을 이용할 때입니다. 기업에서, 특히 저와 같이 게임 업계 쪽에서 Cloud 서비스을 이용하는 것은 바로 확장성입니다. Scale-Out 와 Scale-In(장비 줄이기) 가 매우 쉽기 때문입니다. 일반적으로 실제 머신을 이용하게 될 경우 IP 는 공인IP 을 직접 부여하는 경우가 많기 때문에 먼저와 같은 문제는 크게 고민거리가 안될 수 있습니다. 하지만, 실제 장비는 장비 추가가 급하게 이루어져야 할 때 크게 문제가 발생합니다. 장비의 도입까지는 서버 업체 및 사양 결정, 견적 요청, 납품 등의 프로세서를 거치는데 이 기간이 보통 수 주가 소비되는 경우가 많습니다. 서비스가 크게 흥행하게 될지 아닐지 모르는 상황에서 무턱대고 장비를 여러개 도입하기도 힘들고, 그렇다고 사양이 높다고 해서 성능이 올라가는 형태의 솔루션이 아니기 때문에 요청 숫자에 따른 장비 확보는 쉽지 않은 문제가 있습니다.
또한, Sharding 이 기본적으로 지원되어서 처리량을 늘려나갈 수 있는 장점이 존재하는 대신에 장비를 추가하거나 제거할 때에는 반드시 Rebalance 작업을 진행해야 합니다. 한 대의 장비에는 전체 문서(Document)의 1/N 만큼의 문서를 가지고 있고 해당 문서를 전담해서 처리한다고 생각하면 편한데, 서버를 제거할 경우에는 문서를 다시 1/(N-1) 만큼 나눠서 각 서버에게 재배치해야 하는 일이 발생한다는 것이죠. 그 작업을 Rebalance 라고 합니다. 아무리 메모리와 빠른 내부 네트워크를 이용해서 일을 처리한다고 해도 문서양이 많을 경우 수십분 이상 소요될 수 있는 작업이 됩니다. 물론 이러한 Rebalance 작업은 Live 환경에서 적용이 가능하기 때문에 작업 공지를 걸고 전체 서비스를 차단한 뒤 진행할 필요가 없어서 매우 좋긴 하지만 문제가 발생할 수 있다는 걱정 때문에 쉽사리 하지 못한다는 문제가 있습니다. 그리고, 각 서버는 Replica 라고 하는 백업 정보를 가지고 있는데 보통은 서버 대수보다 한 개 적게(N-1) 가지고 있습니다. 즉 1~3 번 서버가 존재한다면 Replica 는 2 개를 설정하는게 좋은데(Bucket 생성 시 선택할 수 있고, 언제든지 바꿀 수 있습니다) 1번 서버의 경우 메모리에는 자신에게 할당된 문서들을, Replica 에는 2 개의 백업(2, 3 번 서버에 할당된 문서)을 저장하게 되는 것입니다. 그래서 서버가 Rebalancing 없이 갑작스럽게 중지가 되어도 Replica 을 이용해서 문서 내용을 복구할 수 있습니다. 그리고 중지된 서버의 요청도 활성화된 서버가 Replica 의 내용을 메모리로 올려서 대신 제공해줍니다. 하지만, 실제 서버를 이용하게 될 경우 이런 불안한 상태를 장비 추가가 이루어질 때까지 불안하게 쳐다보고 있어야 한다는 단점이 있습니다. 게다가 Rebalance 에 대한 이해 없이 그냥 강제로 서버를 빼고 그냥 추가만 해버리면 데이터가 유실되는 끔찍한 사태를 겪을 수 있습니다.

그러므로 많은 노하우가 축적된 RDBMS 보다는 좀 더 신중하게 접근할 필요가 있으며 단순히 인터넷의 문서(Couchbase 공식 홈페이지에는 자세한 영문 문서가 제공됩니다)만 보고 작업했다가 실제 서비스 도중 재앙을 맞딱드릴 수 있으니 정식 지원 서비스에 가입을 하거나 정식 지원 서비스를 받은 적이 있는 엔지니어를 고용해서 서비스 하는 것을 권하고 싶습니다.



또다른 사용기는 다음 글에...

2014년 7월 10일 목요일

LG 스마트 TV 의 DLNA 사용은...그냥 그런 기능이 있다 수준으로만 생각하자구요...

제목 그대로입니다.

LG 스마트 TV 의 DLNA 사용은...그냥 그런 기능이 있다 수준으로만 생각하자구요...

얼마나 허접하냐면...

1. 최신의 펌웨어에선, REW/FF 작동 안합니다. 건너띄기만 작동하기 때문에 잠시 앞의 것을 보려면 1분 이상을 앞으로 가서 기다려야 합니다.

2. mkv 확장자 등을 이용한 멀티채널 음성을 지원 안합니다. 그래서 한글 더빙이 있는 동영상도 영어로 봐줘야 합니다. 다행이 자막은 지원을 하네요.

3. 1080p 동영상 재생 시 속도 저하로 인해 잦은 reload 혹은 음성 싱크 틀려지는 문제가 발생할 수 있습니다. 트랜스코딩 옵션을 켜면 고쳐질 수 있지만, DLNA Server 의 사양이 좋지 않을 경우 포기해야 합니다.

4. 업데이트는 죽어라 안합니다.

5. 그나마 된 업데이트가..위의 1~2 번 기능을 무려 "삭제" 한 업데이트랍니다.

본가에 있는 구형 LG 스마트 TV 는 1 번에 문제가 있을 수 있다는 경고와 함께 작동합니다. 그런데 인터넷을 뒤져보니 펌웨어 업그레이드 후 저 기능이 아예 막혔고, 2 번 역시 동일하다고 하는 글이 있네요.

그럴꺼면 왜 DLNA 를 재정하고 도입하려고 하는지 모르겠네요. 심지어 TV 에서 사용하라고 하는 PLEX Media Server 를 DLNA 서버로 썼는데도 말입니다.

아...물론 PLEX Media Server 의 재생앱에선 mkv 멀티음성 잘 지원합니다. 유료로 구입한 스마트폰 앱에서도 잘 되고 REW/FF 등도 잘 되고 트랜스코딩도 잘 됩니다.

당연히 TV 에 들어가는 칩이 x86 은 아닐꺼고 arm 도 아닐지도 모르고 더 열악한 개발환경을 제공하는 칩일 수 있고, 그러다보니 처음에 기능을 넣었다가 막을 수도 있겠지요. 하지만, 본가의 TV 만 해도 2010 년도 모델, 우리 집 TV 는 2012 년도 모델입니다. 심지어 TV 와 별개로 셋탑 형식으로도 판매되는 제품이 있던데...동일하지 않을까요? 이 기능 넣으면서 가격은 얼마나 비싸졌는데...

사실, DLNA 가 제대로만 구현된다면 나름 편한 점이 있습니다. 무엇보다 인트라넷에서 직접 정보를 가져오기 때문에 TV 에서 Server 까지 선으로 연결할 필요가 없죠. 그런 장점들 때문에 DLNA 지원을 확인하고 비싼 돈을 주고 구입했는데...LG 전자 페이스북을 포함해서...LG 전자의 응대도 개*이고...쩝...

다음에는 정말 삼성껄, 아니 중국 샤오미 이런걸 사야 할까요?

2014년 4월 16일 수요일

Couchbase 도입기 - 3

Couchbase 는 RHEL 이나 Ubuntu 계열에서 쉽게 설치가 가능합니다. 저의 경우 KT UcloudBiz 을 이용중이라 CentOS 6.5 을 사용중이고, yum install 로 Couchbase.com 에 있는 rpm 을 직접 설치하는 방식을 이용해서 설치하고 있습니다.

Couchbase 의 가장 편리한 점은 통상적으로 오픈소스 프로그램을 설치할 때 설정 파일을 열어 텍스트로 된 설정값을 수정하는 작업을 선행하는 형태의 작업이 필요없다는 것입니다. 상용으로도 제공되는 제품이다보니 설정이 굉장히 깔끔한 편입니다. yum 으로 install 한 뒤에 자동으로 couchbase-server 가 start 되어 있어서 바로 접속이 가능합니다.

첫번째 서버를 설치한 뒤 웹브라우저를 통해 8091 포트로 접속하면 설치 화면으로 접속이 가능합니다. 거기서 Admin 의 아이디와 비밀번호도 지정할 수 있고, 설치 위치도 지정할 수 있습니다. 그리고, 두번째 서버부터는 바로 첫번째 서버의 도메인을 지정하여 바로 연결할 수 있습니다.

이렇게 서버를 설치한 뒤 1 대 이상의 Couchbase 가 Clustering 이 되면 기본적으로 Data 을 분산하여 관리합니다(Sharding). Couchbase 내부의 알고리즘에 의해 데이터가 분산되어 저장되기 때문에 SDK 등으로 접속 시 원하는 자료를 불러오고 싶을 때 모든 서버를 뒤질 필요 없이 자료가 저장된 서버에서 가져오기 때문에 서버의 개수가 늘어날수록(Scale Out) 부하 분산이 되어서 속도가 느려지는 현상이 줄어듭니다. 일반적으로 Couchbase 는 서버의 사양을 올리는 것보다(물론 메모리는 크면 좋습니다) 이렇게 개수를 늘리는 쪽이 성능 향상에 도움이 되는 형태입니다.
그리고 이렇게 분산된 데이터는 각각 다른 서버의 Disk 에 Replica 로 저장이 되어 있기 때문에 장애가 발생해도 데이터가 유실되지 않습니다. 만약 하나의 서버에 장애가 발생한다면 해당 서버를 FailOver 처리를 한 뒤 Rebalacing 을 해주면 남아있는 서버에 남아있는 장애 서버의 자료의 Raplica 을 꺼내와 기존 서버의 메모리에 있는 자료들과 혼합하여 다시 분산 작업(Sharding) 을 진행하게 됩니다. 그리고 장애 서버는 Remove 할 수 있게 됩니다. 이 동작이 서버 중지 후 가능한 것이 아니라 서비스 도중 이루어지기 때문에 무중지 서버 운영이 가능하다는게 Couchbase 의 큰 장점 중 하나입니다. 그리고 장애가 발생한 서버를 고치거나 새로운 신규 서버를 투입한 뒤 다시 Rebalacing 을 할 때에도 마찬가지로 알고리즘에 의해 분산 저장(Sharding) 을 해서 서버는 항상 비슷한 양의 데이터를 분산 저장해서 응답 속도에 문제가 발생하지 않도록 구성되어 있습니다.

일반적인 운영에서 드러나는 가장 중요한 특징이 Sharding 와 Rebalacing 입니다. 그리고 장애 발생시 FailOver 처리와 Remove 처리 또한 이해가 필요한 작업입니다. 시간이 걸리는 작업인데 무턱대로 눌렀다가는 데이터 유실이 발생할 수도 있습니다(경험담). 서버를 추가한 뒤(yum 으로 설치 후 add server 을 이용해 매우 쉽게 추가 가능합니다) Rebalance 만 해주면 Scale Out 이 매우 손쉽게 된다는 것도 매우 매력적입니다.


이 다음 이야기는 다음 글에서 계속합니다...

2014년 4월 11일 금요일

Couchbase 도입기 - 2

Couchbase 을 도입하기로 마음 먹었습니다. 국내에 총판도 있어서 유사시 구입해서 지원을 받을 수 있는 환경이기도 했습니다. 활성화가 잘 되어 있다고는 할 수 없지만 네이버에 카페도 운영하고 있었습니다.

그런데, 도입 후 가격에 대해 문의를 했는데, 딸리는 영어 실력에 솔루션에 대한 이해가 떨어져서 도입 예상가를 제대로 판단하지 못한 문제가 발생했습니다.
처음 도입 시 1 대만 도입해도 되고, 24 시간 서비스 안받아도 되니 가장 저렴한 것으로 구입해도 되겠네...라는 생각을 가졌고, 본사에서 운영하는 사이트에서 제시된 2000 달러(2백만원 초반)면 상용 솔루션으로 전환도 가능하겠다고 생각했습니다.

하지만, Couchbase 는 1 대를 운영하는 것으로는 정상적인 운영이라고 부르기 힘든 제품입니다. 데이터에 대한 분산(Sharding)을 지원하고, 장애가 발생한 서버의 데이터를 재분산(Rebalancing)하는 특징이 있기 때문에, 최소 3 대 이상을 운영해야 제대로 된 구성이라고 할 수 있습니다.
그리고, 초기 도입 시 무조건 교육 패키지를 포함해야 합니다. 한국 총판에서는 (가격을 밝혀도 되는지 모르겠지만) 대략 프리미엄 급 제품 1 개의 가격만큼 책정을 해놓았더군요. 미국 본사의 방침이기도 하답니다.

결국 엔터프라이즈 급으로 도입하기 위해서는 최소 천만원 초중반의 비용이 소모된다는 결론에 도달하게 됩니다. 그래서, 아무 회사에서 엔터프라이즈로 바로 도입하는 건 무리라고 생각합니다. 물론 자료가 많아져서 커뮤니티 버젼으로도 운영 시 장애가 발생해도 해결하는데 큰 어려움이 없어진다면 커뮤니티로 도전하는 회사가 늘겠습니다만...사실 이걸 커뮤니티로 써도 될 정도의 자료가 있는 제품이라고 다른 분에게 권하기는 어렵겠더라구요. 자료를 유실해도 크게 문제가 없는 개인이 운영하는 커뮤니티나 조그만 포털 정도에서 쓰는 거면 몰라도요...

어쨌든 이런 비용 문제 때문에, 우리 회사도 일단은 커뮤니티 버젼으로 시작은 하기로 했습니다. 서비스 시작 후 수입이 괜찮을 것 같다면 바로 구입한다는 전제 조건 하에서요.



Couchbase 의 또 다른 특징은 Cloud 와 같이 공인 IP 을 하나만 쓰고 포트를 나워서 쓰는 환경에서는 쓰기가 쉽지 않다는 것입니다. 이는 모든 경우에 해당하는 것은 아닌데, SDK 을 이용해서 각 프로그램에서 접속을 할 때 귀찮은 일이 발생하게 됩니다. 사실 Couchbase 는 가상 머신이 아닌 실제 머신에서 운영하는 것을 권장합니다만...서버가 유동적으로 늘어나거나(Scale Out) 줄어들 수 있는(Scale In) 환경(대표적인게 게임 서버 쪽입니다)에서는 Cloud 서비스를 생각하게 됩니다. 요즘 많은 게임 회사들이 Cloud 쪽을 선호하는 이유이기도 합니다.
어쨌든...Couchbase 는 각 프로그래밍 언어을 위한 SDK 을 제공하는데, 사용하기 매우 편리합니다만, 접속 시에는 Clustering 방식 때문에 약간 독특한 방식을 취합니다. 가장 큰 문제는 여러 개의 연결된 Couchbase 중 하나의 서버에 접속하여 데이터를 처리하는 것이 아니라, 접속 목록을 SDK Client 에 제공하면 순서대로 접속을 시도한 뒤, 서버에서 사용 가능한 서버들의 도메인과 포트 정보를 보내준다는 것입니다. 그래서 Cloud 등에 들어있는 서버에 접속하기 위해서는 대표 서버 하나의 정보만을 이용해서 접속을 하도록 소스 상에 설정을 해둬야 합니다. 이를 자동화하지 않는다면 상황에 따라 서버 접속 정보를 바꿔줘야 하는 불편함이 발생하게 됩니다.
또한, 사용하는 포트 중 11210 이후 포트가 있는데(아마 Memcached 쪽 포트일 듯) 이게 우리 회사가 사용하는 KT UCloudbiz 의 예약 포트번호입니다. 그래서 이 포트를 열기 위해서는 게시판에 별도 요청을 해야 합니다. 이것도 나름 귀찮더군요.



이 다음 이야기는 다음 글에서 계속합니다...

2014년 4월 10일 목요일

Couchbase 도입기 - 1

Couchbase 는 NoSQL 제품 중 하나입니다.

Couchbase 는 상용이고, 커뮤니티 버젼이라는 무료 버젼도 제공하고 있습니다.
MySQL 등의 커뮤티니 버젼이 동일 버젼에 기능에 제약이 있거나 상용 버젼에 일부 코드가 튜닝되어 나온다는 등의 기능 차이가 있다면, Couchbase 는 (아직까지는)마이너 버젼 1 개 차이의 이전 버젼을 배포하는 것이 특징인 것 같습니다. 예를 들면, 2.2 버젼이 Enterprise 버젼(상용)의 최신 버젼이라면 Community 버젼은 2.1 을 제공하는 형태입니다. 이 글을 쓰는 지금은 2.5 가 최신 버젼이고, 2.2 에서 2.5 로 바로 건너띈 바람에 Community 버젼은 2.2 가 제공되고 있습니다.

Couchbase 는 Linux 배포판 중 Redhat, Debian 계열의 패키지인 rpm 와 deb 을 지원하고 있으며, 각각 yum 와 apt-get 을 통해 네트워크 설치를 지원합니다. 이런 패키지 관리자를 통해 설치할 경우 의존성이 있는 패키지를 동시에 설치해주므로 좀 더 편리한 설치가 가능합니다.


Couchbase 는 CouchDB 와 Memcached 을 섞어놓은 솔루션입니다. 그러므로, Couchbase 의 자료 뿐만 아니라 CouchDB 의 map/reduce 에 관한 자료나 Memcached 에 관한 자료를 참고하시면 도움이 많이 됩니다.





제가 Couchbase 을 도입하게 된 이유는 속도와 자동화된 기능 때문입니다.

게임 회사에 입사해서 게임 서버를 Java 로 개발하게 되었는데, 무료 위주의 솔루션으로 구축하자는 회사의 방침에 따라 정보 저장은 RDBMS 인 MySQL, 정확히는 MariaDB 를 사용하도록 일찌감치 낙점되었습니다. 그리고 Clustering 의 경우 MariaDB 에서 지원하는 Galera Cluster 을 쓰는 것으로 결정하였습니다. MySQL 의 NDB 클러스나 MMM, Master-Master Circular Replication 보다 사용하기 용이하고 완벽한 동기식 Cluster 라는 장점 때문이었습니다.
하지만, 이건 저의 착각이었습니다. Galera Cluster 의 경우 매우 좋은 성능을 보여주는 Cluster 임에는 분명했지만, Write 가 대량으로 발생하는 시스템에서는 그다지 좋은 성능을 보여주지 못하는 문제가 있었습니다. 한 서버에 Write 을 하게 되면 다른 모든 서버에 bin-log 을 복제하여 이를 적용하게 되고, 적용이 완료된 상태가 되어야 Write 작업이 마무리되게 되는데, 이 시간이 처리 속도의 관점에서 그리 빠르지 않다는 것이었습니다. 그래서 입력하는 서버에서 DeadLock 이 발생하는 것이 아니라 전파하는 속도 사이에 다른 요청이 들어와서 DeadLock 이 발생하는 문제가 생겼습니다. 이를 해결하기 위해서는 한 개의 MariaDB 에만 Write 을 하도록 하고, 나머지 서버에서는 Read-Only 상태로 사용해야 한다는 제약이 있다는 것을 알게 되었습니다.
일반적인 웹사이트에서는 Read 가 압도적으로 많기 때문에 이러한 구성이 문제가 없으나, 게임 서버는 그렇지 않습니다. 거의 1:1 의 Write/Read 가 발생하는 것이 정상적인 모습이기 때문입니다. 특히나 Log 형태의 데이터가 많아서 어떨 때에는 Write 비율이 더 많습니다.

그리고, KT UCloudBiz 을 이용하는데, KT UCloudbiz 에서만 제공한다고 알고 있는 "SSD" 서버의 성능은 압도적으로 좋은 퍼포먼스를 보여줍니다만, 그렇다고 해서 하루 수 천만 라인의 Write 가 이루어지는 게임 서버의 요구를 만족할 수는 없었습니다. SSD 서버의 경우 저의 테스트로는 초당 1만 건 정도의 트랜젝션을 처리할 수 있었습니다. 병렬로 늘리는(Scale Out) 작업이 불가능하다록 위에서 언급했기 때문에 프로그래밍 적으로 샤딩(Sharding)을 하지 않고서는 서비스를 할 수 없다는 결론이 나왔습니다.

그래서 최초로 생각한 것은 Redis 였습니다.

Redis 는 무료이며, Key-Value 방식의 간단한 구조를 가지고 있지만 매우 빠른 속도를 자랑하는 NoSQL 솔루션입니다. 단순 증가 필드도 지원해서 MySQL 계열에서 가지는 문제 중 하나인 auto increment(auto increment 필드로 지정해두면, 해당 테이블 추가시 Table Lock 이 발생한다!!!)를 해결할 수도 있었습니다.
하지만, 메모리를 이용하는 방식이라 데이터 유실에 대한 위험이 존재했고, 이를 보안하기 위한 하드디스크를 이용하게 될 경우 속도가 비극(?)적으로 느려진다는 보고가 보였습니다. 굉장히 꺼려지는 부분이었습니다.
거기다, 더 큰 문제가 발생했습니다. Clustering 이 원하는 형태대로 지원이 안되는 것이었습니다. 여러 개의 Redis 을 설치한 뒤 Sentinel 이라는 자체 솔루션을 이용해 Cluster 을 구성할 수 있었지만 수동으로 정상적인 서버의 위치를 알려줘야 했고, 이를 해결하기 위한 githup 의 몇몇 솔루션을 적용해봤으나 서비스 중단 시간이 수십초 씩 걸리는 문제가 발생했습니다.
게임에서 이런 중단 시간은 용납이 안됩니다.



그래서 찾아낸 것이 Couchbase 였습니다. 적극 권장하는 솔루션입니다...만...고생도 좀 했습니다.



이 다음 이야기는 다음 글에서 계속합니다...

2014년 3월 28일 금요일

STS/GGTS 에서 Runnable JAR file 로 Export 를 할 때 목록에 나타나지 않을 경우

Eclipse 의 문제이기도 한데, 너무 당연히 Eclipse 에서 이런 문제가 안생기는 통에 SSTS 에서 대단한 삽질을 했습니다.

Eclipse 계열에서 Export > Runnable JAR File 로 실행용 jar 파일을 만들 땐 꼭 Run As > Java Application 으로 한 번 실행해서 해당 실행 스크립트를 만든 뒤 시도해야 합니다.

특히 Groovy 프로젝트를 만든 뒤에는 Groovy 라는 이유로 Groovy Console 나 Groovy Shell 로 Run 을 시켜주는 경우가 있는데(제가 그랬습니다) 이런 경우 Runnable JAR File 실행 후 "Launch configuration" 에 항목이 뜨지 않습니다. 한시간 삽질했습니다. 에효...

그리고, 당연히 main() 이 있는 Class 에서 우측 버튼 눌러서 Run 하는 건 아시겠죠? 프로젝트 명에서 Run as... 실행하는 분들도 계시던데...당연히 바로 실행이 안됩니다. 실행할 main() 이 있는 클래스 이름에서 Run as 를 선택해서 실행하세요.

2014년 3월 11일 화요일

SimpleDateFormat 대신 FastDateFormat 사용하기

Java 에서 SimpleDateFormat(java.text.SimpleDateFormat) 을 이용해서 Date 개체의 날짜/시간 정보를 사람이 보기 좋은 형태로 변환할 수 있습니다.

하지만, 이 SimpleDateFormat 은 thread-safe 하지 않아 부하가 발생할 경우 오류가 발생할 수 있다고 합니다.

그래서 나온것이 FastDateFormat(org.apache.commons.lang.time.FastDateFormat) 입니다. SimpleDateFormat(java.text.DateFormat 을 상속) 와 마찬가지로 java.text.Format 을 상속한 개체로, apache commons-lang 에 포함된 라이브러리입니다.

특별히 문제가 발생하지 않는다면 SimpleDateFormat 을 사용해도 괜찮지만, 오류가 발생한다면 FastDateFormat 사용을 고려해보세요.

2014년 1월 6일 월요일

카카오팀의 MySQL 사용에 있어서 Linux Filesystem Cache 문제(메모리 먹는 하마2) 적용기

아래 내용을 적용해봤습니다.

http://kakaodbe.blogspot.kr/2013/09/mysql-linux-filesystem-cache-2.html



KT UCloudBiz 서비스를 이용중이고, CentOS 6.4 적용중입니다. 기본 서버 환경이기 때문에 몇 가지 프로그램과 라이브러리가 필요합니다.

$ yum install gcc perl-Inline perl-Parse-RecDescent




그리고 적용할 소스를 가져옵니다.

$ wget https://raw.github.com/yoshinorim/unmap_mysql_logs/master/unmap_mysql_logs

$ chmod +x unmap_mysql_logs

$ ./unmap_mysql_logs




unmap_mysql_logs 파일에 설정내용이 들어있으므로, 에러 발생 시 설정 내용을 변경해줘야 합니다.

예1)

readdir() attempted on invalid dirhandle DIR at ./unmap_mysql_logs line 36.

이 오류는 32 라인에서 $binlog_name 값을 shift 라고 정의하고 24 라인에서 디렉토리값을 추가로 지정해놔서 발생하는 오류입니다.

my @target_dirs = ( '/var/lib/mysql', '/var/lib/mysql/innodb_logs' );
...
my $binlog_name = shift;
...

위의 두 값을

my @target_dirs = ( '/var/lib/mysql' );
...
my $binlog_name = "logbin";
...

와 같이 변경해주면 됩니다. 저의 경우 my.cnf 에서 log-bin=galera 으로 설정해놓았기 때문에 아래 값은 logbin 이 아니라 galera 로 설정하였습니다.

2014년 1월 5일 일요일

Ubuntu 에 MariaDB 5.5 & Galera Cluster 설치

MariaDB 5.5 설치를 위한 사전 작업은 아래 링크를 참고합니다.

https://downloads.mariadb.org/mariadb/repositories/#mirror=kaist&distro=Ubuntu&distro_release=saucy&version=5.5

https://mariadb.com/kb/en/getting-started-with-mariadb-galera-cluster/





$ sudo apt-get install software-properties-common
$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
$ sudo add-apt-repository 'deb http://ftp.kaist.ac.kr/mariadb/mariadb-5.5.33/repo/ubuntu saucy main'


한국 미러는 kaist 서버 밖에 존재하지 않는 것 같습니다. 매우 고마운 서버이긴 하나 좀 느리다는게 단점이라면 단점입니다.

$ sudo apt-get update
$ sudo apt-get install mariadb-galera-server

mariadb-galera-server 를 설치합니다. mariadb-galera-server 에 mariadb-server 가 포함되어 있는 형태인 것 같습니다. CentOS 처럼 각각 설치하는 방식이 아닙니다. 설치 도중 MariaDB 에서 사용할 root 패스워드를 물어봅니다. CentOS 와는 달리 설치 스크립트에서 mysql_install_db 를 실행해서 DB 도 만들어둡니다. 별도의 디스크에 datadir 을 만들꺼라면 복사를 하거나 새로 mysql_install_db 을 실행해야 합니다.








insert 성능 향상을 위해 TokuDB 을 사용합니다. 5.5.34 이상의 버젼이라면 이미 포함되어 있으므로 아래 링크와 같이 별도 설치를 할 필요는 없습니다. 단지, /etc/mysql/conf.d/tokudb.cnf 에 있는 주석만 해제해주면 됩니다.

https://mariadb.com/kb/en/how-to-enable-tokudb-in-mariadb/








Multi-Thread 에서의 성능향상을 위해 jemalloc 을 설치하고 적용합니다. 이미 Ubuntu 버젼의 MariaDB 5.5 는 jemalloc 을 적용해서 complie 되어 있다고 합니다.

$ sudo apt-get install libjemalloc1

$ sudo vi /usr/bin/mysqld_safe

19 라인 정도에 위치한

mysqld_ld_preload=

에 jemalloc 라이브러리를 연결해줍니다.

mysqld_ld_preload=/usr/lib64/libjemalloc.so.1


mysql 을 재시작한 뒤 jemalloc 이 제대로 연동되었는지에 대한 확인은 아래와 같이 합니다.

$ sudo pmap `pidof mysqld` | grep jemalloc





2014년 1월 4일 토요일

CentOS 6.4 에서 jemalloc 설치 및 MariaDB 5.5 적용

yum 으로 간단하게 jemalloc 설치합니다. EPEL 저장소에 존재하므로 EPEL 저장소 연결은 먼저 해두어야 합니ㅏㄷ.

# yum install jemalloc



pmap 으로 jemalloc 이 적용되었는지 확인할 수 있습니다.

# pmap `pidof mysqld` | grep jemalloc

설치만 한 상태라면 아무런 결과가 나오지 않아야 정상입니다..




mysqld 실행 스크립트를 수정하여 mysqld 에만 jemalloc 이 이용되도록 수정합니다.

# vi /usr/bin/mysqld_safe

19 라인 정도에 위치한

mysqld_ld_preload=

에 jemalloc 라이브러리를 연결해줍니다.

mysqld_ld_preload=/usr/lib64/libjemalloc.so.1





# service mysql stop

# service mysql start --wsrep_cluster_address='gcomm://'

지금 MariaDB 5.5 에 Galera Cluster 을 연결해서 사용중인 서버이고, 메인 서버에 적용하는 것이라서 --wsrep_cluster_address 옵션을 이용해서 새로운 클러스터임을 알려줍니다. (필요없으면 지우고 실행)





pmap 으로 jemalloc 이 적용되었는지 다시 확인

# pmap `pidof mysqld` | grep jemalloc

뭔가 결과가 나와야 정상