MySQL 풀 텍스트(FULLTEXT) 검색하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

MySQL은 % 연산자를 사용하여 LIKE 패턴 연산을 지원할 뿐만 아니라, 단어 또는 구문에 대한 검색을 지원하며 이를  풀 텍스트(FULLTEXT) 검색이라고 부른다. MySQL은 3가지 종류의 FULLTEXT 검색 방식을 지원한다.

FULLTEXT 검색 방식

  • 자연어 검색(natural search)
    검색 문자열을 단어 단위로 분리한 후, 해당 단어 중 하나라도 포함되는 행을 찾는다.
  • 불린 모드 검색(boolean mode search)
    검색 문자열을 단어 단위로 분리한 후, 해당 단어가 포함되는 행을 찾는 규칙을 추가적으로 적용하여 해당 규칙에 매칭되는 행을 찾는다.
  • 쿼리 확장 검색(query extension search)
    2단계에 걸쳐서 검색을 수행한다. 첫 단계에서는 자연어 검색을 수행한 후, 첫 번째 검색의 결과에 매칭된 행을 기반으로 검색 문자열을 재구성하여 두 번째 검색을 수행한다. 이는 1단계 검색에서 사용한 단어와 연관성이 있는 단어가 1단계 검색에 매칭된 결과에 나타난다는 가정을 전제로 한다.

이 글에서는 자연어 검색과 불린 모드 검색만을 다루고자 한다. 그리고 영어 데이터가 아닌 한글 데이터를 기준으로 한다.

FULLTEXT 검색을 위한 주의사항

FULLTEXT 검색을 지원하기 위해서는 아래의 사항들을 주의해야 한다.

FULLTEXT 인덱스 생성

FULLTEXT 검색을 하려는 컬럼에 대해 FULLTEXT 인덱스를 생성해야 한다. FULLTEXT 인덱스는 MyISAM 엔진을 사용하는 테이블에 대해서만 생성할 수 있다. 또한 컬럼 데이터 타입은 반드시 Text, Binary Char, Varchar 타입을 가져야 한다. 또한 한글 데이터를 검색하려면 테이블 인코딩으로 utf8을 사용해야 한다.

FULL TEXT 인덱스는 테이블을 생성할 때 생성할 수도 있고, 또는 이미 만들어진 테이블에 대해서도 인덱스를 생성할 수 있다. 예를 들어 게시판 검색 기능을 만든다고 해보자. 게시글을 저장할 posts 테이블을 만들고, 여기에 게시글의 제목(gtitle), 본문(gdesc) 컬럼을 추가한다고 해보자. 만약 제목만을 FULLTEXT 검색을 하고자 한다면,

create table posts(
    id bigint(100) NOT NULL AUTO_INCREMENT,
    gtitle text NOT NULL,
    gdesc text NOT NULL,
    ....
    PRIMARY KEY (id),
    FULLTEXT KEY gtitle (gtitle)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

와 같이 테이블을 생성한다.

만약 이미 만들어진 테이블에 대해 FULLTEXT 인덱스를 생성해야 한다면,

alter table posts add FULLTEXT(gtitle);

와 같이 생성할 수 있다.

FULLTEXT 인덱스는 하나 이상의 컬럼에 대해서도 생성할 수 있다. 만약 제목 검색뿐만 아니라, 본문 검색까지 지원하려면 아래와 같이 게시글 제목과 본문에 대해서도 FULLTEXT 인덱스를 생성해야 한다.

alter table posts add FULLTEXT(gtitle, gdesc);

FULLTEXT 검색 엔진 설정하기

검색어가 너무 짧은 경우 아무런 검색결과도 나오지 않는다. 이때 짧다는 기준은 4글자 이하다. 만약 2글자의 검색어를 지원하려면 최소 검색어 길이 값을 2로 수정해야 한다. my.cnf 설정파일을 열어서 ft_min_word_len 변수 값을 기본값인 4에서 2로 변경한다.

# my.cnf 파일
ft_min_word_len=2

만약 FULLTEXT 인덱스를 생성한 경우라면 인덱스를 삭제한 후 재생성해야 한다. 또는 아래와 같이 인덱스를 갱신할 수 있다.

REPAIR TABLE posts QUICK;

이제 FULLTEXT 검색 본론으로 넘어가 보자.

자연어 검색

게시물의 제목과 본문에 “로고”라는 단어가 포함된 게시글을 검색하는 경우를 생각해 보자. FULLTEXT 검색은 아래와 같이 수행한다.

select P.gtitle, P.gdesc
from posts P
where match(gtitle, gdesc) against('로고') limit 10;

검색 결과는 다음과 같다.

mysql_fulltext_natural_search

무언가를 해낸듯한 기분이 들겠지만 약간의 문제가 있다. 이 부분은 조금 후에 불린 검색에서 다루기로 하고, 검색의 정확도를 수치로 보여주는 방법을 살펴보자.

select P.gtitle, P.gdesc,
       match(gtitle, gdesc) against('로고') as score
from posts P
where match(gtitle, gdesc) against('로고')
limit 10;

mysql_fulltext_natural_search_score

보는 바와 같이 검색의 정확도(score)에 따라 내림차순 정렬되어 결과가 표시됨을 알 수 있다. 물론 1단어뿐만 아니라 여러 단어로도 검색이 가능하다.

select P.gtitle, P.gdesc,
       match(gtitle, gdesc) against('귀여운 로고') as score
from posts P
where match(gtitle, gdesc) against('귀여운 로고')
limit 10;

mysql_fulltext_natural_search_multi_word

자연어 검색에서 여러 단어를 검색어로 사용한 경우, 먼저 구문을 단어 단위로 분할한 후, 해당 단어 중 1개라도 포함된 행을 검색한다. 따라서 6번째 결과와 같이 “예쁜 팔찌 만들어”와 같은 관련성이 낮은 게시글도 검색되게 된다.

불린 모드 검색

이제 불린 모드 검색을 이용하여 자연어 검색에서 부딪혔던 문제를 해결해 보자. 불린 검색이 자연어 검색와 크게 차이나는 점은 아래와 같다.

  • 검색의 정확도에 따라 결과가 정렬되지 않는다.
  • 구문 검색이 가능하다
  • 필수(+), 예외(-), 부분(*) 연산자를 사용할 수 있다

앞서 “귀여운 로고”를 단어 검색이 아닌 구문 검색, 즉 “귀여운 로고”가 그대로 포함된 게시글을 검색하고자 한다면, 아래와 같이

select P.gtitle, P.gdesc 
from posts P 
where match(gtitle, gdesc) against('"귀여운 로고"' in boolean mode);

구문을 쌍따옴펴(” “)로 묶은 후, 불린 모드(boolean mode)로 검색을 실행한다.

mysql_fulltext_boolean_mode

만약 검색된 데이터에서 맨 마지막의 여행영상 게시글을 검색에서 제외하려면 예외 연산자(-)를 사용할 수 있다.

select P.gtitle, P.gdesc 
from posts P 
where match(gtitle, gdesc) 
      against('"귀여운 로고" -여행영상' in boolean mode);

이제 부분 연산자()를 살펴보자. 앞서 자연어 검색 첫 번째 예제에서 “로고”를 검색한 결과를 보면, 모두 “로고” 단어가 독립적으로 존재한다. 다시 말해 “로고를”, “로고와” 등과 같은 단어는 검색되지 않는다. 이처럼 한글에서는 형태소를 잘라야만  인덱스가 제대로 구성되지만, 쉬운일은 아니다. 이러한 경우 검색할 때 부분 연산자를 사용하여 ‘로고‘와 같이 사용하면, 로고로 시작하는 모든 단어를 포함하는 행을 검색할 수 있다. 명확한 예를 위해 게시글 제목(gtitle)에 대해서만 FULLTEXT 검색을 실행해 보자. 먼저 아래의 자연어 검색 결과를 보자.

select P.id, P.gtitle 
from posts P 
where match(gtitle) against('로고를') limit 10;

위와 같이 검색하면,

mysql_fulltext_boolean_mode_exception

와 같이 “로고를”이 포함된 행이 매칭된다. 하지만 자연어 검색에서 아래와 같이 ‘로고’를 사용하면 해당 행이 검색되지 않는다.

select P.id, P.gtitle 
from posts P 
where match(gtitle) against('로고') 
and id = 911 
limit 10;

그러나 불린 검색에서 부분 검색 연산자를 사용하면 검색이 가능하다.

select P.id as id, P.gtitle 
from posts P 
where match(gtitle) against('로고*' in boolean mode) 
and id = 911 
limit 10;

메타 검색 기능 UI 구성

이제 FULLTEXT 검색 기능을 사용하여 서비스에 메타 검색 기능을 추가한다면, 아래와 같이 UI를 구성해볼 수 있다.

mysql_fulltext_meta_search_ui

일단 기본적으로 모든 검색은 불린 검색을 사용한다. 그리고 사용자가 입력한 단어는 구문 검색(” “)이 아닌 경우 공백을 기준으로 분리한 후, * 연산자를 추가한다. 아래는 입력 예다.

  • 1단어를 입력한 경우
    [로고*] 로 검색을 수행한다.
  • 2단어를 입력한 경우
    [귀여운* 로고*] 로 검색을 수행한다.
  • 구문 검색을 입력한 경우
    [“귀여운 로고”*] 로 검색을 수행한다.
  • 예외 연산자를 사용한 경우
    [“귀여운 로고”* -영상] 으로 검색을 수행한다.

크몽 재능

git 정말 필요한가?

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

이 글은 총 4부 중 마지막인, git이 필요한지에 대한 개인적인 의구심을 정리해 봤습니다.

요즘 git에 대해 이것저것 실험삼아 해보고, 자료를 보면서 드는 생각은

“Git이 정말 필요한가?”

이다. 서브버전과 비교하여 장단점을 비교하기에 앞서 git의 구조와 CI(Continuous Integration) 관점에서 전체 아키텍처를 한번 살펴보자. 이 글은 git을 쓰려고 시도한 후배님들과 대화한 내용을 중심으로 썼기에, 잘못된 부분이 있을 수도 있다.

프로젝트 공유

우선 2명의 개발자가 협업할 때 로컬 저장소(master)와 원격 저장소(remote repository)간의 구조와 처리 흐름은 다음과 같다.

git_share_project

  1. 개발자 A가 자신의 로컬 머신에서 git 프로젝트를 생성(init)한다.
  2. 그리고 몇가지 작업을 한 후, 프로젝트를 공유하기 위해 원격 서버에 프로젝트를 푸시한다.
  3. 개발자 B는 원격 저장소의 프로젝트를 자신의 로컬 저장소로 복제(clone)한다.

따라서 각 개발자는 자신만의 저장소(master)에서 변경작업을 하고 커밋을 하며, 로컬에서 작업 이력을 관리할 수 있게 된다. 여기에 git의 장점 2가지가 있다.

  • 빠르다
  • 네트워크가 안되더라도 작업 이력을 관리할 수 있다.

장점을 좀더 면밀히 검토해 보자. 우선 커밋이 로컬 머신에서 일어나므로, 빠를 수 밖에 없다. 네트워크 IO가 아니라 단순히 디스크 IO만 발생하기 때문이다. 하지만 서브버전을 쓰면서 느리다는 느낌을 받은 적은 거의 없다. 파일이 많으면 오래 걸릴 수도 있겠지만, 오히려 그 시간에 허리 한번 필 수 있으니 건강에는 도움이 되겠다. 즉 사용성 관점에서 크게 와닿지 않은 빠름일 뿐이다.

네트워크가 안된다? 북한도 인터넷이 되는 마당에, 네트워크는 어디를 가야 안되는지 모르겠다. 전혀 공감되는 장점이 아니다.

프로젝트 수정

그럼 이제 자신의 마스터 브랜치에서 프로그램을 수정한다고 해보자.

git_modify_project

프로젝트의 기능을 추가하거나 변경하는 경우 아래와 같은 흐름을 따르게 된다.

  • 마스터 브랜치에서 새로운 브랜치를 만든다.
  • 개발을 완료한 후 커밋을 한다.
  • 브랜치를 마스터 브랜치에 합친다.
  • 브랜치는 정리한다.
  • 변경된 내용을 중앙 저장소에 푸쉬한다.

유심히 볼 점은 중앙 저장소에 올리기 위해서는 2단계를 거친다는 점이다. 먼저 로컬 저장소에 커밋 한 후, 원격 저장소에 푸시한다는 점이다. 이 점이 중요한데, 이를 위해서는 전체 CI 구조를 이해해야 한다.

CI 관점에서 본 git

전체 CI 구조를 보면 다음과 같다.

git_as_ci

  • jenkins 서버(빌드 서버)에서 형상 서버(Git 서버)에서 소스 코드를 풀링한다.
  • 풀링된 코드를 빌드하여 실행 파일을 만든다.
  • 실행 파일을 운영 서버에 배포한다.

이처럼 CI 환경을 구성할 때 가장 어려운 점은 빌드시 2가지 문제가 흔히 발생한다는 점이다. 첫 번째는 컴파일 에러이며, 두번째는 개발이 완료되지 않아 배포하지 말아야 할 기능이 실수로 배포된다는 점이다.

이러한 문제가 발생하는 원인은 개발자가 완성되지 않은 프로그램을 형상 서버에 커밋하기 때문이다. 그러면 개발자는 완료되지도 않은 프로그램을 왜 형상 서버에 커밋하는가? 그 이유는 2가지다.

첫 번째는 자신의 로컬 환경에 장애가 발생할 수도 있으므로, 완성되지 않았더라도 백업하기를 원하기 때문이다. 즉 형상 성버는 백업의 공간으로 지금까지 활용되어 왔다. 두 번째는 이력을 관리하기 위해서다. 퇴근하기 전, 또는 사용자 스토리 중 하나의 기능이 완료가 되었을 때, 해당 시점의 프로그램에 대한 스냅샷을 저장하기 위해서다.

이러한 점에서 볼 때 git은 이 문제를 매끄럽게 해결한다. 자신의 로컬에 저장소를 따로 가지므로, 백업을 위한 공간인 동시에 로컬에서 이력을 관리할 수도 있게 된다.

사실 이러한 상황 뒤에는 커밋(commit)이 가지는 두 가지 의미가 이전까지는 제대로 정의되지 않아서라고 본다. 서브버전을 예로 들어보자. 서브버전에서 커밋이라는 행위에 2가지 의미가 내포된다. 첫 번째는 내가 완성한 프로그램을 운영서버에 배포하기 원한다는 뜻이며, 따라서 형상 서버에 올리겠다라는 행위다. 두 번째는 좀 전에도 얘기한 백업과 이력을 관리해 달라고 요청하는 것이다.

결국 서브버전을 CI 환경에 중심 형상 서버로 사용하게 되면, 개발자가 커밋한 행위가 배포를 요청한 것인지, 아니면 이력을 관리해달라고 요청한 것인지 구분이 불가능하다. 이로 인해 빌드하거나 운영 서버에 새로운 기능이 배포될 때 마다 늘 지옥문이 열리곤 한다.

git의 경우 커밋이 가지는 2가지 의미를 완전히 분리된 액션으로 만들었다. 즉 커밋은 자신의 로컬 저장소에만 요청하며, 배포는 원격 저장소에 푸시를 통해 요청하는 것이다. 사실 이러한 이해가 git의 사상에 맞는지는 제대로 활용한 경험이 없어 아직 모르겠다. 하지만 얼추 맞지 않을까?

한국 자바 직장인 개발자를 위한 내용

리눅스 머신에서 자바 개발을 하는 직장인 개발자를 본 적이 있는가? 결국 나처럼 윈도우에서 이클리스 기반으로 자바를 사용해 프로그래밍을 할 것이다. git이 윈도우를 공식적으로 지원하지 않기 때문에 윈도우 버전인 egit 이클립스 플러그인을 설치해서 개발을 해야 한다. 들은 얘기로 윈도우 64비트에서 egit이 제대로 동작하지 않는다. 이런 상황에서 꼮 git이어야만 할까? 잘 모르겠다.

크몽 재능

나도 git 좀 써보자 – 원격 서버 구축하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

이 글은 총 4부 중, 3번째 git 원격 서버 구축하기와 관련한 내용입니다.

일단 2명 이상의 개발자가 함께 프로젝트를 하려면 원격 저장소(remote repository)가 필요하다. 원격 저장소를 위한 서버는 직접 운영할 수도 있지만, 무료인 GitHub를 사용할 수도 있다.

원격 저장소는 일반적으로 아래와 같은 작업을 지원해야 한다.

  • 프로젝트를 원격 저장소에 업로드하기
  • 원격 저장소에서 로컬 저장소로 가져오기
  • 변경사항을 원격 저장소에 올리기
  • 다른 개발자가 올린 변경 내용을 로컬 저장소로 가져오기

이제 git에서 어떻게 하면 되는지 하나하나 살펴보려는 찰나, git 매뉴얼을 찾았다. 진작에 봤으면 삽질을 하는 시간이 줄었을텐데, 아쉬울 뿐이다. 대부분 한글로도 번역이 되어 있으므로, 상당히 도움이 된다.

어쨌뜬 서브버전을 쓰든, git을 쓰든 여러 사람과 협업하기 위해서는 원격 서버가 필요하다. Git 서버 매뉴얼에서 설명하는 내용을 따라서 서버를 구축하고 사용하는 법을 살펴보도록 하자.

원격 저장소는 작업 디렉토리(working directory)가 없는 bare 저장소다. 여기서 bare 저장소의 의미는 일반적인 git 프로젝트에서 .git 디렉토리만 있는 저장소라는 뜻이다. 원격 서버를 운영하려면 먼저 원격으로 접속할 프로토콜을 선택해야 한다.

프로토콜

git은 Local, SSH, Git, HTTP 프로토콜을 지원한다. HTTP 프로토콜을 제외한 나머지 방식에서는 모두 서버에 git이 설치되어 있어야 한다.

  • Local
    원격 저장소가 동일한 머신의 다른 디렉토리에 있을 때 사용한다. 즉 팀원이 모두 NFS와 같이 파일 시스템을 공유할 때 사용한다. 결국 쓸데 없을 듯…
  •  Git
    git에 포함된 데몬을 사용하는 방법으로 포트는 9418을 쓴다. 인증 메커니즘이 없으므로, 누구나 프로젝트에 푸시를 할 수 있다. 결국 쓸데 없다.
  •  SSH
    푸쉬를 할 수 있는 유일한 프로토콜이라고 보면 된다. HTTP/S에서도 푸쉬를 하도록 설정할 수 있지만, 잘 사용되지 않는다. 그리고 인증을 할 수 있으므로 보안에 안전하다. 하지만 익명으로는 read가 불가능하다.
  •  HTTP/S
    설정이 간단하다. 하지만 푸시를 설정하기가 까다로우며 거의 사용되지 않는다.

프로토콜을 조합해서 사용해도 되는데, 서버에 푸시를 할 때는 SSH를 사용하고, 익명으로 읽기 권한을 주고자 할 때는 Git 프로토콜을 쓰는 식이다.

서버를 설정하는게 복잡해 보이지만, 실제로도 복잡하다. 매뉴얼 보다가 한숨만 나왔다. Gitosis나 Gitolite를 사용하면 좀 더 간편히 설정할 수 있다고 한다. 현재 일하는 팀에서는 AWS에 Gitlab을 설치해서 사용중이다.

크몽 재능

나도 git 좀 써보자 – 사용하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

이 글은 총 4부 중, 2번째 git 사용하기와 관련한 내용입니다.

설치가 끝났으니 이제 프로젝트를 하나 만들어서 기본적인 활용법을 익혀보자.

저장소 만들기

서브버전을 사용해 왔다면 아마 저장소는 원격 서버에서 호스팅하고, 자신의 로컬 머신에는 복사본 또는 working copy를 유지했을 것이다. 반면 git에서는 복사본 또는 working tree뿐만 아니라, 저장소까지도 자신의 로컬 머신의 .git 디렉토리에 유지한다.

일단 비어 있는 프로젝트를 하나 만들자.

C:\Documents and Settings>mkdir my-project
C:\Documents and Settings>cd my-project
C:\Documents and Settings\my-project>git init
Initialized empty Git repository in C:/Documents and Settings/my-project/.git/

프로젝트 디렉토리 안에서 git init 명령어를 실행하면, git 저장소가 생성된다.

파일 추가하고 변경하기

비어 있는 프로젝트에 index.html 파일을 아래와 같이 만들어서 추가하자.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World
</body>
</html>

이제 프로젝트에 변경 사항이 생겼으므로, 즉 파일이 하나 추가되었으므로 git에 변경사항이 발생했음을 알려주자. 새로운 관리 대상이 생겼으므로, 대상 추가 작업 및 커밋 작업 2단계를 거쳐야 한다.

C:\Documents and Settings\my-project>git add index.html
C:\Documents and Settings\my-project>git commit -m "add new index.html"
[master (root-commit) 9bb9136] add new index.html
1 file changed, 9 insertions(+)
create mode 100644 index.html

커밋 로그를 보면,

C:\Documents and Settings\my-project>git log
commit 9bb9136e023cddf5db8457069be9c317bbc3ab2b
Author: socurites <socurites@gmail.com>
Date: Mon Jun 10 15:51:57 2013 +0900

add new index.html

와 같이 index.html 파일이 추가되었다는 기록을 확인할 수있다.

파일을 변경하기 전에, 현재 작업중인 working tree의 상태를 살펴보자.

C:\Documents and Settings\my-project>git status
# On branch master
nothing to commit, working directory clean

보다시피 working tree는 저장소와 현재 동기화 된 상태임을 알 수 있다. 이제 index.html을 아래와 같이 수정한 후,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World
Hello Changed World
</body>
</html>

working tree의 상태를 다시 살펴보면,

C:\Documents and Settings\my-project>git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.html
#
no changes added to commit (use "git add" and/or "git commit -a")

index.html 파일이 변경되었으며, 커밋을 하려면 스테이징이 필요하다는 메시지가 나온다.

git의 경우 파일을 세 군데에 저장한다.

  • 작업 트리(working tree)
    로컬에서 작업하는 공간으로, 서브버전에서는 working copy라고도 부른다.
  • 스테이징 영역(staging area)
    작업 트리와 저장소 사이의 버퍼 공간으로, 커밋할 대상을 올려두는 위치다.
  • 저장소(repository)
    실제 파일이 관리되는 공간이다.

git add 명령어를 사용하면, 작업 트리의 파일이 스테이징 영역으로 이동시킨다. 즉 파일을 스테이징하게 된다.

C:\Documents and Settings\my-project>git add index.html
C:\Documents and Settings\my-project>git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#

이제 파일을 저장소로 커밋하자.

C:\Documents and Settings\my-project>git commit -m "add body text" index.html
[master 0ca802d] add body text
1 file changed, 1 insertion(+)

C:\Documents and Settings\my-project>git status
# On branch master
nothing to commit, working directory clean

브랜치(branch) 만들기

이제 프로젝트의 스프린트가 마무리되었고, 릴리즈팀에서 릴리즈해야 한다고 해보자. 하지만 릴리즈와 돵시에프로젝트에 새로운 기능을 추가해야 한다고 해보자. 만약 새로운 기능을 추가할 때까지 릴리즈를 늦추어야 한다면, 사용자는 개발이 이미 완료된 기능을 다음 릴리즈까지 기다리게 하는 셈이다. 따라서 이번 이번 스프린트의 결과는 그대로 릴리즈하면서 동시에 새로운 기능을 개발하려고 할 때, 브랜치를 사용하면 효과적이다.

C:\Documents and Settings\my-project>git branch RB_1.0 master

git branch 명령어는 2개의 인자를 받는데, 첫 번째 인자는 브랜치명이며 두번째 인자는 브랜치할 프로젝트 명이다. 서브버전에서는 마스터 브랜치를 트렁크(trunk)라고 불렀다.

이제 릴리즈팀에서는 RB_1.0 브랜치에서 릴리즈를 하도록 내버려 두고, 개발팀은 마스터에서 새로운 기능을 추가한다. 예를 들어 index.html 파일을 수정해야한다고 해보자.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World
Hello Changed World
Hello New World
</body>
</html>

변경사항을 마스터 브랜치에 커밋한다.


C:\Documents and Settings\my-project>git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.html
#
no changes added to commit (use "git add" and/or "git commit -a")

C:\Documents and Settings\my-project>git commit -a -m "new world"
[master f8e64db] new world
1 file changed, 2 insertions(+)

C:\Documents and Settings\my-project>git status
# On branch master
nothing to commit, working directory clean

이와 동시에 릴리즈팀에서도 릴리즈 브랜치를 약간 수정할 작업이 생겼다. 작업 트리를 릴리즈 브랜치로 변경해 보자.

C:\Documents and Settings\my-project>git checkout RB_1.0
Switched to branch 'RB_1.0'

마스터에서 브랜치로 스위칭하면, 현재 수정한 index.html 파일의 내용이 변경 전의 내용으로 갱신된다. 왜냐하면 릴리즈 브랜치에서는 변경 작업이 발생하지 않았기 때문이다. 따라서 브랜치를 사용하면 릴리즈와 개발을 동시에 진행할 수 있게 된다.

이제 릴리즈 브랜치에서도 index.html을 약간 수정하자.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
Hello World
Hello Changed World
Hello Release World
</body>
</html>

그리고 변경사항을 커밋한다.

C:\Documents and Settings\my-project>git commit -a -m "release world"
[RB_1.0 d22029a] release world
1 file changed, 2 insertions(+)

릴리즈 태깅(tagging)하기

이제 릴리즈 준비가 끝난 브랜치에 태깅을 해보자. 태깅이란 거창한게 아니라 단순히 이름, 즉 태그를 붙여서 저장소 이력의 특정 지점을 알기 쉽게 표시하는 것이다.


C:\Documents and Settings\my-project>git tag my-project-1.0 RB_1.0
C:\Documents and Settings\my-project>git tag
my-project-1.0

릴리즈가 완료되면, 릴리즈 브랜치에서 변경된 내용을 마스터 브랜치에도 반영을 해야 하는데, 이러한 작업을 브랜치 병합(merge) 또는 합치기라고 부른다. 먼저 작업 트리를 마스터 브랜치로 변경한다.

C:\Documents and Settings\my-project>git checkout master
Switched to branch 'master'

브랜치를 마스터에 합친다.

C:\Documents and Settings\my-project>git rebase RB_1.0
First, rewinding head to replay your work on top of it...

근데 문제가 생겼다. 릴리즈 브랜치와 마스터 브랜치에서 동일한 라인을 수정했기 때문에, 자동으로 합치는게 불가능해졌다. 이런 경우에는 사람이 직접 개입을 할 수밖에 없다.

일단 동일한 파일의 동일한 라인을 2사람이 동시에 변경할 가능성이 적기 때문에, 이러한 긍정정 잠금(optimistic lock) 기능이 효과적이라고 하는 말에 개인적으로는 동의하지 않는다. 변경 가능성이 적더라도 언제나 충돌이 발생하기 마련이다. 특히 공통 파일 같은 경우 충돌이 발생하면, 정말이지 지옥의 문이 열리는 경우가 한두번이 아니기 때문이다.

어쨌든 충돌을 해결해 보자. 우선 마스터 브랜치에서 파일을 아래와 같이 정리하자.

C:\Documents and Settings\my-project>git commit -a -m "rebase conflict, merged by hand"
[detached HEAD 899bddf] rebase conflict, merged by hand
1 file changed, 2 insertions(+)

C:\Documents and Settings\my-project>git status
# HEAD detached from d22029a
# You are currently rebasing.
# (all conflicts fixed: run "git rebase --continue")
#
nothing to commit, working directory clean

일단 최신의 파일로 변경한 후 커밋했지만, 저장소의 상태는 문제가 있어 보인다. 그리고 rebase 명령어를 사용하는 경우, 나도 모르게 마스터 브랜치에서 릴리즈 브랜치로 이동한 상태가 되버렸다. 일단 이부분도 강제적으로 해결하자.

C:\Documents and Settings\my-project>git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

899bddf rebase conflict, merged by hand

If you want to keep them by creating a new branch, this may be a good timeto do so with:

git branch new_branch_name 899bddf

Switched to branch 'master'

C:\Documents and Settings\my-project>git status
# On branch master
# You are currently rebasing.
# (all conflicts fixed: run "git rebase --continue")
#
nothing to commit, working directory clean

C:\Documents and Settings\my-project>git commit -a -m "rebase conflict, merged by hand"
# On branch master
# You are currently rebasing.
# (all conflicts fixed: run "git rebase --continue")
#
nothing to commit, working directory clean

C:\Documents and Settings\my-project>git status
# On branch master
# You are currently rebasing.
# (all conflicts fixed: run "git rebase --continue")
#
nothing to commit, working directory clean

그럼 이제 불필요한 릴리즈 브랜치는 삭제하자. 릴리즈 브랜치는 태깅해두었기 때문에, 해당 브랜치에서 수정 작업이 필요하다면 태깅한 브랜치에서 얼마든지 다시 분기할 수 있다.

C:\Documents and Settings\my-project>git branch -d RB_1.0
error: The branch 'RB_1.0' is not fully merged.
If you are sure you want to delete it, run 'git branch -D RB_1.0'.

C:\Documents and Settings\my-project>git branch -D RB_1.0
Deleted branch RB_1.0 (was d22029a).

이제 my-project-1.0이라는 이름으로 태깅한 릴리즈를 압축하자.

C:\Documents and Settings\my-project>git archive --format=zip --prefix=my-project-1.0/ my-project-1.0 > mysite-1.0.zip

원격 저장소 사용하기

이제 개발팀에 새로운 팀원이 추가되었고, 프로젝트를 다른 팀원과 함께 개발해야 한다고 해보자. 그러면 지금까지 로컬 저장소에서 관리하던 프로젝트를 팀원과 공유해야 한다. 즉 원격 저장소가 필요하다.

원격 저장소를 만들었다면, 이제 원격 저장소에 지금가지 개발된 코드를 올린다. 그러면 새로운 팀원은 원격 저장소에서 코드를 복제한다. 이제 두명의 개발자가 동일한 프로젝트에서 작업하게 되었으며, 각각 자신만의 저장소를 가지게 되었다. 하지만 두 사람은 모두 변경된 사항을 원격에 푸시(push)해야만 서로간에 최신의 코드를 유지할 수 있다.

일단 원격 저장소 사용하는 법은 이어서 살펴보도록 하자.

크몽 재능

나도 git 좀 써 보자 – 설치하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

이 글은 총 4부로 구성됩니다.

CVS에서 SVN으로 넘어온지도 꽤 지났다. 그러면서 ant, hudson, jenkins, anthill.. 이제는 이름도 생각나지 않은 Cruise Control 등의 빌드 툴들을 사용해 봤다. 그렇게 시간이 지났고, 이제 git의 시대가 되었다.

관심 없었다. 서브버전(Subversion)으로도 충분히 큰 불편함이 없었기에. 이제 사람들이 모두 “짓허브”이 아니라 “깃허브”이라고 부르는 Github에 많은 프로젝트와 코드들이 쌓여간다.

이제는 더 뒤쳐질 수 없기에, 몇년 전에 사두었던 책, “Git, 분산 버전 관리 시스템”을 꺼내 들었다.

git_book

이제 나도 Github에서 단순히 ZIP 파일을 다운로드 하는게 아니라, 제대로 좀 써보자!!!!!!
는 생각으로 git 사용 이력을 여기에 남겨 본다.

먼저 git을 설치해야 한다. 맥북에는 이미 설치가 되어 있다. 이미 설치되었는지 궁금하다면, 버전을 확인해 보자.

island:~ socurites$ git --version
git version 1.8.1.2

윈도우에 git 설치하기

git은 리눅스를 기반으로 만들어졌기 때문에, 윈도우는 공식적으로 지원하지 않는다. 하지만 구글 코드에서 Git on MSys라는 이름의 프로젝트가 있다. Git on MSys는 git을 윈도우에 설치하여 쉽게 사용할 수 있도록 만들어졌다.

https://code.google.com/p/msysgit/‎에서 다운로드하여 쉽게 설치가 가능하다. 설치 과정에서 아래 창이 뜨면 2번째 옵션을 선택해야만, 커맨드 창에서도 git을 쉽게 이용할 수 있다.

git_window_install

이제 환경 설정을 해야 한다. 로컬 시스템의 전역 값 중에서 user.name과 user.email은 반드시 설정해야 한다.

island:~ socurites$ git config --global uer.name "socurites"
island:~ socurites$ git config --global user.name "socurites"
island:~ socurites$ git config --global user.email "socurites@gmail.com"
island:~ socurites$ git config --global --list
uer.name=socurites
user.name=socurites
user.email=socurites@gmail.com

잘못해서 오타가 났다. user.name을 입력해야 하는데, user.name을 입력했다. 불필요한 설정 값이므로 삭제하자.

island:~ socurites$ git config --global --unset uer.name
island:~ socurites$ git config --global --list
user.name=socurites
user.email=socurites@gmail.com

여기까지가 필수 전역 설정이다.

윈도우 사용자를 위한 추가 설정

git의 커밋 메시지의 기본 인코딩은 utf-8이다. 윈도우는 명령 프롬프트의 기본 인코딩이 cp949이므로, 커밋 메시지와 로그 메시지의 인코딩을 cp949로 변경해야 한다.

prompt>git config --global i18n.commitEncoding cp949
prompt>git config --global i18n.logOutputEncoding cp949

또한 mSysGit에서 로그 메시지를 콘솔로 출력할 때 less 명령어를 사용하는데, less 명령어가 한글을 제대로 보여주려면 마찬가지로 문자셋을 변경해 주어야 한다.

prompt> set LESSCHARSET=latin1

만약 환경 변수 값을 영구적으로 설정하고자 한다면, 시스템 환경 변수에 LESSCHARSET를 추가하고, 값으로는 latin1을 설정한다.

git_window_lesscharset

설정 파일은 사용자 홈디렉토리에 .gitconfig라는 이름으로로 저장된다.

크몽 재능

리눅스에서 mysql 사용하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

설치하기

mysql 서버와 클라이언트를 설치한다

$ sudo apt-get install mysql-server mysql-client

설치하는 중 root 사용자 패스워드를 입력하라는 화면이 나오면, 사용할 root 패스워드를 입력한다.

설치가 끝나면, mysql 설정파일(/etc/mysql/my.cnf)에서 bind-address 부분을 주석처리한다.

# bind-address = 127.0.0.1

데이터베이스 생성하기

create 명령어를 사용해서 데이터베이스를 생성한다. 여기에서는 springbook이라는 이름으로 데이터베이스를 생성한다.

$ mysqladmin -u root create springbook -p

데이터베이스에 접속하기

앞에서 생성한 데이터베이스에 접속한다.

$ mysql -u root -p springbook

현재 만들어진 테이블을 살펴본다. 아직 테이블을 만드지 않았으므로 아무런 테이블도 표시되지 않는다.

mysql> show tables;
Empty set (0.000 sec)

캐릭터 셋(Character Set) 설정하기

테이블을 생성하기에 앞서 클라이언트, 서버, 데이터베이스 등의 캐릭터 셋을 설정해야 한다.

지원되는 캐릭터 셋 확인하기

현재 머신에 설치된 mysql에서 사용가능한 Charater Set을 확인한다.

mysql> show character set;

현재 설정된 캐릭터 셋 확인하기

현재 설치된 캐릭터 셋을 확인한다.

mysql> show variables like 'char%';

mysql_charaterset

결과에서 보는 바와 같이, client, connection, database, result, server의 캐릭터 셋이 기본적으로 latin1로 되어 있음을 확인할 수 있다.

utf8로 캐릭터 셋 변경하기

캐릭터 셋을 변경하는 방법에는 여러가지가 있으나, mysql 데몬이 재시작된 후에도 캐릭터 셋 정보를 그대로 유지하려면 설정파일(my.cnf)을 편집해야 한다. 아래와 같이 utf8로 된 부분을 [client], [mysqld], [mysql] 영역에 추가한다.

port    = 3306
socket    = /var/run/mysqld/mysqld.sock

# character set to utf8 #####################################
default-character-set=utf8
###################################################
.....

[mysqld]
# character set to utf8 #####################################
init_connect=SET collation_connection = utf8_general_ci
init_connect=SET NAMES utf8
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_general_ci
###################################################
....

[mysql]
# character set to utf8 ###################################
default-character-set=utf8
###################################################

mysql 서버 데몬을 재시작한다.

$ sudo /etc/init.d/mysql restart

springbook 데이터베이스에 새로 접속해 보면, 아래와 같이 캐릭터 셋이 utf8로 모두 변경되었음을 확인할 수 있다.

mysql_characterset_utf8

테이블 생성하기

create table 문을 사용해서 새로운 테이블을 생성한다.

mysql> create table users (
id varchar(10) primary key,
name varchar(20) not null,
password varchar(10) not null
);

show tables 명령을 실행해보면 users 테이블이 생성되었음을 확인할 수 있다.

사용자 추가하기

사용자는 GRANT 명령어를 사용해서 추가할 수 있다. 여기에서는 아이디가 “spring”이고, 패스워드가 “book”인 사용자를 추가하고, 동시에 springbook 데이터베이스에 대한 권한을 모두 주고자 한다.

mysql> GRANT ALL PRIVILEGES ON springbook.* TO spring@localhost IDENTIFIED BY 'book' WITH GRANT OPTION;

데이터베이스를 mysql로 이동한다.

mysql> use mysql;

이제 user 테이블을 조회해보면 방금 등록한 spring 사용자가 등록되었음을 확인할 수 있다. root 계정도 함께 보이며, 패스워드는 암호화되어 저장되므로 조회 결과가 순식간에 스크롤된다.

mysql> select * from user;

크몽 재능

하둡 척와(Hadoop Chukwa) 초보 가이드 – 에이전트 영향도 분석

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

척와 초보자를 위한 가이드로, 총 3개로 구성되어 있습니다.

  1. 기본
  2. 설치하기
  3. 에이전트 영향도 분석

척와 에이전트의 경우, 로그를 수집할 대상 서버에 설치된다. 따라서 에이전트로 인해 해당 서버의 본래의 기능에 영향을 미쳐서는 안된다. 이를 위해 척와 에이전트가 설치되었을 때 로그 수집 대상 서버에 미치는 영향도를 분석하고자 한다.

준비사항

로그 생성 서버

테스트 목적으로 로그를 생성하는 데모 서버를 다운 받는다.

demo_loggers.jar

해당 서버를 실행하면, /tmp/ws_demo_log 디렉토리에 demo라는 이름의 로그를 생성한다.

척와 어댑터

데모 서버가 생성한 로그를 tailing할 어댑터를 initial_adaptors 설정 파일에 등록한다.

add filetailer.FileTailingAdaptor DaemonData /tmp/ws_demo_log/demo 0

성능 측정 스크립트

성능 측정 스크립트인 usage_ps.sh 스크립트를 아래와 같이 작성한다

pid=`cat /tmp/chukwa/pidDir/Agent.pid`
out_file="output_$1.txt"
rm -rf $out_file
echo "%CPU $MEM VSZ RSS" >> $out_file
while (true)
do
    sleep 3
ps aux | grep $pid | grep -v grep | awk '{print $3, $4, $5, %6 }' &>> $out_file
done

영향도 분석 시나라오

영향도 분석을 위한 시나리오는 다음과 같다.

  1. 척와 컬렉터, 척와 에이전트를 실행한다.
  2. 로그 생성 데몬 서버를 실행한다.
    java -cp ./demo_loggers.jar com.socurites.utils.web.server.demo.Main [number of Visitor]
    

    [number of Visitor]에는 실제 서버에서 발생하는 접속자 수 증가 등을 반영하기 위해 임의의 숫자를 입력한다. 여기에서는 3, 100, 1000을 사용했다.

  3. 성능 측정 스크립트를 실행한다.
    sh usage_ps.sh [number of Visitor]
    

    [number of Visitor]는 선택적인 옵션으로, 데모 서버를 실행할 때 사용했던 숫자와 동일한 숫자를 입력한다. 성능 결과는 현재 디렉토리에 output_[number of Visitor].txt 라는 이름으로 생성된다. 따라서 [number of Visitor]를 인자로 주지 않으면 output_.txt 라는 이름으로 생성되며, 여기에서는 옵션을 주지않고 실행했다.

 작업 과정

아래와 절차에 따라 작업을 수행했다.

[number of Visitor] = 3인 경우

시나리오 1번 과정, 3번 과정을 먼저 처리 한후, [number of Visitor]에 3을 설정한 후 그 결과를 수집했다. 이에 따른 데모 서버의 처리 결과는 다음과 같다.

===========================================
SUMMARY
===========================================
= Started At: 2011-11-29 20:14:30
= Ended At: 2011-11-29 20:15:20
= Size(bytes): " + fileSize); 84162
= Log Size/Time(Bytes/Sec): 1
===========================================

[number of Visitor] = 100인 경우

로그 데모 서버를 중지한 후, [number of Visitor]에 100을 설정해서 서버를 재실행하여 그 결과를 수집했다. 이에 따른 데모 서버의 처리 결과는 다음과 같다.

===========================================
SUMMARY
===========================================
= Started At: 2011-11-29 20:15:24
= Ended At: 2011-11-29 20:16:13
= Size(bytes): " + fileSize); 2754700
= Log Size/Time(Bytes/Sec): 55
===========================================
<p>

[number of Visitor] = 1000인 경우

로그 데모 서버를 중지한 후, [number of Visitor]에 1000을 설정해서 서버를 재실행하여 그 결과를 수집했다. 이에 따른 데모 서버의 처리 결과는 다음과 같다.

===========================================
SUMMARY
===========================================
= Started At: 2011-11-29 20:16:29
= Ended At: 2011-11-29 20:17:10
= Size(bytes): &quot; + fileSize); 21950227
= Log Size/Time(Bytes/Sec): 538
===========================================

서버 처리 결과에서 보는 바와 같이 로그 생성 속도는 선형적으로(1 -> 55 -> 538)로 증가함을 알 수 있다.

결과 분석

영향도를 측정한 결과 파일은 다음과 같다 (중간 부분은 일부 생략했다).

%CPU %MEM VSZ RSS
1.4 1.5 419024 27224
1.3 1.5 419024 27224
1.3 1.5 419024 27224
1.1 1.5 419024 27224
1.1 1.5 418928 27292
0.9 1.5 418928 27324

확인 결과 오히려 CPU와 메모리 사용률이 증가하지 않고, 적어지는 결과가 나왔다. 눈으로 보이는 결과만 봐서는 두 가지 결론을 내릴 수 있다.

  • 측정 방법에 문제가 있다.
  • 실제로 척와 에이전트가 로그 수집 대상 서버에는 영향을 미치지 않는다.

추가적인 분석

분석작업을 수행하면서 이와 동시에 척와 에이전트 로그를 tailing해서 실제로 에이전트가 어떻게 로그를 처리하고 있는지 함께 확인했다. 물론 정량적인인 분석은 아니며, 육안으로 확인할 결과다.

  • [number of Visitor]를 증가시켜 로그 생성 데모 서버를 실행하더라도, 척와 에이전트 로그의 생성 속도가 더 빨라지지 않았다. 이 현상을 통해 “로그 생성 속도가 빨라지더라도 척와 에이전트의 처리 속도가 그에 맞게 빨라지는게 아니라 정해진 속도를 따라 로그를 수집함”을 추정해볼 수 있다.
  • 앞의 두 작업([number of Visitor]가 3과 100이었던 경우)에서는 로그 데모 서버가 중지한 경우, 척와 에이전트 로그 또한 더 이상 로그가 쌓이지 않았다. 반면에 마지막 작업([number of Visitor]를 1000으로 지정한 경우)에서는 로그 데모 서버를 죽이고 나서도 척와 에이전트 로그가 한참동안 계속해서 쌓였다. 결국 “로그 생성 속도가 특정 값을 넘어서면 척와 에이전트의 로그 수집 속도가 따라가지 못하게 됨“을 추정해 볼 수 있다. 따라서 날짜가 바뀌는 경우 어떻게 처리할 것인지에 대한 문제가 숙제로 남았다.

참고자료

  • 클라우드 컴퓨팅 구현 기술 / 깅형준, 조준호, 안성화, 김병준 저 / 에이콘 출판사
  • 하둡 완벽 가이드 / 톰 화이트 지음 / 오라일리 출판사
  • Chukwa Documentation 4.0

크몽 재능

하둡 척와(Hadoop Chukwa) 초보 가이드 – 설치하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

 척와 초보자를 위한 가이드로, 총 3개로 구성되어 있습니다.

  1. 기본
  2. 설치하기
  3. 에이전트 영향도 분석

설치전 준비사항

척와를 설치하려면 아래와 같은 항목이 먼저 준비되어야 한다.

  • 리눅스 플랫폼을 사용한다.
  • 1.6 이상 버전의 자바가 설치되어 있어야 한다.
  • Hadoop 0.20.2 버전을 다운로드 받아야 한다.
  • 여기에서는 HICC를 설치하지 않을 것이므로 MySQL은 필요 없다.

척와 구성 요소

척와는 아래와 같은 요소로 구성된다. 따라서 척와를 설치하려면 하둡 클러스터, 척와 에이전트, 척와 컬렉터를 설치해야 한다.

chukwa_system_diagram

  • 데이터를 저장할 하둡 클러스터(척와 클러스터)
    여기에서는 하둡 파일 시스템을 의사 분산 모드로 설치했다고 가정한다. 자세한 내용은 의사 분산 모드로 하둡(Hadoop) 실행하기을 참고하라
  • 척와 에이전트
    로컬 머신에서 모니터링한 로그 데이터를 전송한다
  • 척오 컬렉터
    에이전트에서 수신한 데이터를 HDFS에 저장한다

예제 구성

여기에서는 아래와 같은 구성으로 척와를 구성하고자 한다.

chukwa_sample

두 대의 리눅스 머신 중에서 하나는 척와 에이전트를, 나머지 하나는 척와 컬렉터를 설치하고자 한다. 척와 컬렉터를 설치한 머신에는 하둡을 의사 분산 모드로 설치해서, 로그 데이터를 저장하는 역할까지 하도록 한다.

척와 설치 공통사항

아래의 사항은 에이전트와 컬렉트를 설치할 머신에서 공통적으로 설정해야 하는 작업이다.

척와 설치하기

척와를 척와 릴리즈 페이지에서 다운로드 받는다. 여기에서는 chukwa-0.4.0.tar.gz를 다운로드 받았다.

로컬 파일 시스템의 적당한 위치에 압축을 푼다. 이렇게 하둡이 설치된 디렉토리를 CHUKWA_HOME이라고 부르자.

$ tar xvf chukwa-0.4.0.tar.gz

척와 관련 명령어를 쉽게 실행하기 위해 척와 설치 디렉토리(CHUKWA_HOME)를 환경 변수에 설정하고, PATH를 설정한다(필수 사항은 아니다). 여기에서는 .bashrc 파일에 설정했다

#CHUKWA
export CHUKWA_HOME=척와가 설치된 경로
export PATH=$PATH:$CHUKWA_HOME/bin

척와 공통 정보 설정하기

척와 공통 정보를 conf/chukwa-env.sh에 설정한다 (에이전트와 컬렉터가 설치된 머신 모두에 설정해야 한다).

JAVA_HOME 환경변수를 설정한다. 시스템 환경변수(.bashrc)에 설정해도 상관 없지만, 여기에서는 conf/chukwa-env.sh에 설정한다.

export JAVA_HOME=/usr/lib/jvm/java-6-sun5

척와 콘솔 로그와 pid 로그를 저장할 디렉토리를 conf/chukwa-env.sh에 설정한다. 여기에서는 디폴트 값을 그대로 사용한다.

export CHUKWA_PID_DIR=/tmp/chukwa/pidDir
export CHUKWA_LOG_DIR=/tmp/chukwa/log

척와 콘솔 로그 파일에 이름을 붙일 때 사용할 CHUKWA_IDENT_STRING을 conf/chukwa-env.sh에서 설정한다. 여기에서는 디폴트 값을 그대로 사용한다.

export CHUKWA_IDENT_STRING=chukwa

척와 에이전트 설치하기

척와 에이전트를 설치 과정은 “1. 척와 에이전트 옵션 설정하기”, “2. 에이전트 등록하기”, “3. 컬렉터 등록하기”, “4. 어댑터 등록하기”, 총 4개의 작업으로 구성된다.

에이전트 옵션 설정하기

척와 에이전트는 conf/chukwa-agent-conf.xml에서 설정한다. 디폴트 그대로 사용해도 실행하는데 문제가 없으며, 필요에 따라 아래의 옵션을 설정한다.

  • chukwaAgent.tags
    척와 클러스터명으로, 모니터링하고 있는 노드에 대한 식별자다. 이 정보는 수집한 각 청크에 저장되므로, 해당 청크가 어느 머신에서 전송되었는지를 이 정보를 통해 구분할 수 있다. 여기에서는 디폴트 값 그대로 둔다.
  • chukwaAgent.checkpoint.dir
    컬렉터에 데이터를 전송하면서 장애가 발생했을 때, 마지막으로 전송한 청크의 오프셋 정보를 저장할 때 사용한다. 여기에서는 디폴트 값을 그대로 사용한다.

에이전트 등록하기

에이전트로 실행할 전체 에이전트 목록을 conf/agents에 설정한다. 여기에서는 에이전트가 로컬서버 한대이므로 localhost만 등록한다.

#agent
localhost

컬렉터 등록하기

데이터를 전송할 컬렉터를 conf/collectors에 등록한다. 척와는 이 파일에서 컬렉터를 임의로 골라서 해당 컬렉터로 데이터를 전송한다. 해당 컬렉터에 장애가 발생하면, 컬렉터 목록에서 다른 컬렉터를 선택하는 방식으로 로그 유실을 방지한다.

여기에서는 221번 서버가 컬렉터이므로, 이 컬렉터에 대한 정보를 등록한다. 실행할 전체 컬렉터 목록은 컬렉터가 설치된 머신의 conf/collectors에서 설정한다.

# collectors
http://33.33.211.221:8080

어댑터 등록하기

데이터를 수집할 어댑터를 conf/initial_adaptors에 등록한다. 이처럼 어댑터를 설정파일에 등록할 수도 있지만, 실행 중인 에이전트에 어댑터를 직접 추가할 수도 있다.

여기에서는 conf/initial_adaptors.template 파일을 참조해서 만든다. 템플릿 파일에 등록된 어댑터 중에서 Df, Top에 해당하는 어댑터 2개만 conf/initial_adpators에 등록한다.

add org.apache.hadoop.chukwa.datacollection.adaptor.ExecAdaptor Df 60 /bin/df -l 0
add org.apache.hadoop.chukwa.datacollection.adaptor.ExecAdaptor Top 60 /usr/bin/top -b -n 1 -c 0

척와 에이전트 관리하기

척와 에이전트는 아래의 명령어를 실행해서 데몬으로 실행할 수 있다.

$ bin/start-agents.sh

명령어를 실행하면 conf/agents에 나열단 각 머신에 ssh로 접속해서 에이전트를 실행한다. 이 경우 에이전트가 로컬호스트 하나 뿐이므로, 로컬호스트의 에이전트가 실행된다.

척와 에이전트를 중지하려면 아래의 명령어를 실행한다.

$ bin/stop-agents.sh

에이전트가 제대로 동작중인지는 에이전트 포트(디폴트로 9093을 사용한다)에 텔넷으로 접속해서 확인할 수 있다. 에이전트가 정상적으로 동작중이라면, 에이전트와 관련된 상태 메시지가 나온다.

척와 컬렉터 설치하기

하둡 설정하기

컬렉터에서 수집한 데이터를 저장해야 하므로, 하둡과 관련된 설정을 추가해야 한다. conf/chukwa-env.sh에 HADOOP_HOME과 HADOOP_CONF_DIR을 아래와 같이 설정한다.

export HADOOP_HOME="하둡이 설치된 위치"
export HADOOP_CONF_DIR="${HADOOP_HOME}/conf"

척와 옵션 설정하기

척와 컬렉터는 conf/chukwa-collector-conf.xml에서 옵션을 설정할 수 있다. 반드시 설정해야 하는 부분은 writer.hdfs.filesystem다. 여기에서는 의사 분산 모드로 설치한 하둡 파일 시스템을 설정한다.

<property>
    <name>writer.hdfs.filesystem</name>
    <value>hdfs://localhost:9000</value>
    <description>HDFS to dump to</description>
</property>

이 외에도 컬렉터에서는 아래와 같은 속성을 설정할 수 있다.

  • chukwaCollector.writerClass
    – 로그 레코드를 저장할 Writer 클래스
    – 디폴트: org.apache.hadoop.chukwa.datacollection.writer.PipelineStageWriter
  • chukwaCollector.pipeline
    – PipelineStageWriter에서 사용할 Writer 클래스. 콤마로 분리해서 설정한다.
    – 디폴트: org.apache.hadoop.chukwa.datacollection.writer.SocketTeeWriter, org.apache.hadoop.chukwa.datacollection.writer.SeqFileWriter
  • writer.hdfs.filesystem (필수)
    – 수집한 로그를 저장할 하둡 파일 시스템
  • chukwaCollector.outputDir
    – 수집한 로그(싱크 파일)를 저장할 하둡의 디렉토리
    – 디폴트: /chukwa/logs/
  • chukwaCollector.rotateInterval
    – 오픈한 파일을 close()하는 주기 (ms)
    – 디폴트: 300000
  • chukwaCollector.http.port
    – 컬렉터가 리스닝할 포트 번호
    – 디폴트: 8080

컬렉터 등록하기

실행할 컬렉터는 모두 conf/collectors에 등록한다. 여기에서는 221번 서버가 컬렉터이므로, 이 컬렉터에 대한 정보를 등록한다.

http://33.33.211.221:8080

척와 컬렉터 관리하기

척와 컬렉터는 아래의 명령어를 실행해서 데몬으로 실행할 수 있다.

$ bin/start-collectors.sh

그러면 conf/collectors에 나열된 각 머신에 ssh로 접속해서 컬렉터를 모두 실행한다.

척와 컬렉터를 중지하려면 아래의 명령어를 실행한다.

bin/stop-collectors.sh

컬렉터가 제대로 동작중인지 확인하려면 브라우저에서 http://collectorhost:collectorport/chukwa?ping=true 로 접속한다. 여기에서는 http://localhost:8080/chukwa?ping=true 로 접속해 보면 아래와 같이 컬렉터와 관련된 상태 정보를 확인할 수 있다.

Date:1322449269195
Now:1322449296866
numberHTTPConnection in time window:0
numberchunks in time window:0
lifetimechunks:0

마지막으로 데이터 처리 프로세스를 실행한다.

$ start-data-processors.sh

그러면 아카이빙, 디먹스, HICC용 데이터 프로세싱 작업이 실행되고 이를 통해 주기적으로 데이터를 처리하게 된다. 실제로 start-data-processors.sh를 열어서 보면 아래와 같이, archive, demux, dp를 차례대로 실행함을 알 수 있다.

# start data processors
"$bin"/chukwa-daemon.sh --config $CHUKWA_CONF_DIR start archive
"$bin"/chukwa-daemon.sh --config $CHUKWA_CONF_DIR start demux
"$bin"/chukwa-daemon.sh --config $CHUKWA_CONF_DIR start dp

실행과정 눈으로 확인하기

이렇게 설치가 끝났다면, 실제로 척와 관련 데몬을 실행해서 제대로 실행되는지 확인해 보자.

척와 실행하기

이렇게 설정을 다했다면 아래와 같은 구성으로 관련 데몬을 실행한다.

chukwa_sample_daemo

척와 에이전트 실행 확인하기

척와 에이전트가 설치된 머신에서 /tmp/chukwa/logs로 이동한다. 해당 디렉토리에는 agent.log가 아래와 같이 생성되어 있다.

HTTP post thread ChukwaHttpSender - collected 14 chunks for post_53
HTTP post thread ChukwaHttpSender - >>>>>> HTTP post_53 to http://33.33.211.211:8080/ length=18715
HTTP post thread ChukwaHttpSender - >>>>>> HTTP Got success back from http://33.33.211.211:8080/chukwa; response length 826
HTTP post thread ChukwaHttpSender - post_53 send 0 chunks, got back 14 acks

척와 컬렉터 실행 확인하기

척와 컬렉터가 설치된 머신에서 /tmp/chukwa/logs로 이동한다. 해당 디렉토리에는 collector.log가 생성되어 있으며, 컬렉터와 관련된 로그를 확인할 수 있다.

하둡 파일 시스템 확인하기

척와 컬렉터의 데이터 프로세스를 실행했다면, http://localhost:50070/ 로 접속해서 아래와 같이 척와 스토리지를 확인할 수 있다.

chukwa_hadoop_console

참고자료

  • 클라우드 컴퓨팅 구현 기술 / 깅형준, 조준호, 안성화, 김병준 저 / 에이콘 출판사
  • 하둡 완벽 가이드 / 톰 화이트 지음 / 오라일리 출판사
  • Chukwa Documentation 4.0

크몽 재능

하둡 척와(Hadoop Chukwa) 초보 가이드 – 기본

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

 척와 초보자를 위한 가이드로, 총 3개로 구성했습니다.

  1. 기본
  2. 설치하기
  3. 에이전트 영향도 분석

개요

하둡 척와(Chukwa)는 분산된 서버에서 로그 데이터를 수집하여 저장하며, 저장한 데이터를 분석하기 위해서 만들어졌다. 또한 하둡 클러스터의 로그, 서버의 상태 정보 등을 관리할 수 있는 기능도 포함되어 있다.

장점

  • 로그를 생성하는 응용 프로그램의 로그 저장 모듈을 수정하지 않고도 로그를 수집할 수 있다.
  • 수집된 로그 파일을 하둡 파일 시스템(HDFS)에 저장한다. 따라서 하둡 파일 시스템의 장점을 그대로 가진다.
  • 실시간 분석도 가능하다.

단점

  •  하둡 파일 시스템이 먼저 설치되어 있어야 한다. 하지만 하둡은 단순히 압축만 풀어서 설치할 수 있으므로 큰 문제는 아니다.

척와 시스템 구성

척와 시스템은 아래와 같이 구성된다.

chukwa_system_diagram

  • 척와 에이전트(agent)
    로그를 수집할 대상 서버(Monitored Source Node)에 설치한다. 에이전트는 해당 서버의 로그 파일이나 서버 정보를 컬렉터로 전송한다.
  • 척와 컬렉터(collector)
    여러 대의 에이전트로부터 로그 정보를 수신해서 하둡 파일 시스템에 저장한다.
  • 데이터 프로세싱(data processing)
    컬렉터가 수신한 데이터에 대해 아카이빙(archiving), 디먹스(demux) 등의 작업을 수행해서 처리한다.
  • HICC(Hadoop Infrastructure Care Center)
    하둡 클러스터의 로그 파일과 시스템 정보를 수집해서 분석한 후, 웹 UI를 통해 보여준다. 일반적인 로그 수집을 위한 용도가 아니라 하둡 클러스터 자체를 관리하는 기능이므로, 여기에서는 다루지 않겠다.

에이전트

척와 에이전트 자체에서 데이터를 직접 수집하지는 않고, 어댑터(adaptor)를 통해서 수집한다. 어댑터는 에이전트 프로세스 안에서 실행되며, 데이터를 실제로 수집하는 역할을 한다. 에이전트에 어댑터를 등록하는 방법에는 두 가지가 있다.

  • 에이전트가 시작할 때 읽어들이는 환경 설정 정보(conf/initial_adaptors)에 어댑터를 추가
  • 실행 중인 에이전트에 직접 어댑터를 추가

에이전트는 실행될 때 환경 설정 파일(conf/collectors)을 읽어들인 후, 이 중에서 하나의 컬렉터를 랜덤하게 선택해서 데이터를 전송한다. 선택한 컬렉터 서버에 장애가 생긴면, 설정 파일에 등록된 다른 컬렉터 서버에 데이터를 전송한다.

  • 에이전트 쪽 로그 유실 방지
    모든 컬렉터 서버에 장애가 있다면, 마지막으로 전송된 파일의 오프셋 정보(checkpoint)를 로컬 파일 시스템에 기록해 둔다. 이후에 컬렉터에 정상적으로 데이터를 전송할 수 있을 때가 되면, 해당 오프셋 이후의 데이터를 전송한다. 이러한 방식을 통해 로그 유실을 방지한다.

컬렉터

에이전트로부터 전송된 데이터를 주기적으로 하둡 파일 시스템에 저장한다. 이때 한 컬렉터는 여러 대의 에이전트 서버로부터 데이터를 전송받지만, 이를 하나의 파일에 저장한다. 이처럼 컬렉트가 저장하는 파일을 싱크(sink) 파일이라고 부르며, 하둡 파일 시스템의 SequenceFile 포맷으로 저장한다.

  • 컬렉터 쪽 로그 유실 방지
    하둡 파일 시스템은 파일을 저장할 때 특정 크기(64MB) 이상이 되지 않으면 close() 명령을 이용해서 파일을 닫지 않는 한 파일 내용이 보이지 않는다. 따라서 파일을 저장하는 클라이언트(이 경우 컬렉터)가 비정상 종료된 경우, 해당 데이터가 유실될 수 있다. 척와에서는 데이터가 유실되는 일을 방지하기 위해, 주기적으로 새로운 파일을 생성하고 에이전트에서 전송받은 데이터를 새로운 파일에 저장한 후 close()한다.

컬렉터는 로그 파일을 하둡 파일 시스템에 저장한다. 하지만 사용자 정의 Writer를 지정할 수도 있다. 예를 들어 척와에서 제공하는 PipelineStageWriter를 사용하면, 하나의 로그에 대해 여러 개의 Writer를 사용할 수 있다. 이를 통해 로그를 저장하는 동시에, 실시간으로 분석할 수도 있다. 실제로 척와에서는 디폴트로 PipelineSgateWriter를 사용한다.


// chukwa-collector-conf.xml 중에서

....

<property>

    <name>chukwaCollector.writerClass</name>

    <value>org.apache.hadoop.chukwa.datacollection.writer.PipelineStageWriter</value>

</property>

<property>

    <name>chukwaCollector.pipeline</name

    <value>org.apache.hadoop.chukwa.datacollection.writer.SocketTeeWriter,

org.apache.hadoop.chukwa.datacollection.writer.SeqFileWriter</value>

</property>

...

데이터 프로세싱

척와에서 로그 데이터를 처리하는 작업에는 아카이빙(archiving)과 디먹스(demux), 2가지 작업이 있다.

  • 아카이빙(archiving)
    아카이빙은 컬렉터가 저장한 로그 파일을 이용해서 시간 순서와 동일한 그룹으로 묶는 작업을 수행한다. 아카이빙에서는 데이터의 중복을 제거하고 정렬작업을 수행한 후, 하둡의 SequenceFile 포맷으로 저장한다.
  • 디먹스(demux)
    디먹스는 로그 레코드를 파싱해서 키-값 쌍으로 구성되는 ChukwaRecord를 만든 후, 하둡 파일 시스템에 다시 파일로 저장한다.

뿐만 아니라 맵리듀스(MapReduce)를 직접 만들어서, 아키이빙과 디먹스 작업이 완료된 데이터에 대해 맞춤형 분석 작업을 할 수도 있다. 척와 내부적으로도 PostProcessing이라는 작업을 수행한다. 디먹스가 완료된 데이터 중에서 하둡 클러스터의 시스템 메트릭 정보 등을 HICC에서 사용하는 데이터로 변환한 후, MySQL에 저장하는 과정이 PostProcessing 작업이다. PosteProcessing 코드를 참조하면, 로그 파일을 요구에 맞게 분삭하는 시스템을 구축할 수 있을 것으로 보인다.

척와 데이터 모델

척와 어댑터는 데이터를 청크(chunk) 단위로 전송한다. 청크란 일련의 바이트로 구성되며, 메타데이터가 일부 포함된다. 이러한 메타데이터는 다음과 같다. 이 중에서 Cluster와 Datatype은 사용자가 직접 설정해야 한다.

  • Source
    청크가 생성되는 호스트명
    자동으로 설정된다
  • Cluster
    호스트가 연결된 클러스터
    conf/chukwa-env.sh에 사용자가 설정한다.
  • Datatype
    출력 포맷
    어댑터를 구동할 때 사용자가 지정한다.
  • Sequence ID
    스트림에서 청크의 오프셋
    자동으로 설정되며, 초기 오프셋은 어댑터가 실행될데 설정된다.
  • Name
    데이터 소스 이름
    자동으로 설정되며, 어댑터가 선택한다.

장애가 발생했을 때 로그를 재전송하는 경우, 로그 데이터의 중복을 방지하기 위해서 이러한 메타데이터가 추가된다. 또한 로그의 데이터 타입별로 서로 다른 분석작업이 필요한 경우, 데이터 타입 정보를 이용할 수도 있다.

척와 스토리지 구조

척와에서 사용하는 하둡 파일 시스템의 구조

일반적으로 척와의 파일 시스템은 아래와 같이 구성된다.


/chukwa/

    archivesProcessing/

    dataSinkArchives/

    demuxProcessing/

    finalArchives/

    logs/

    postProcess/

    repos/

    rolling/

    temp/

척와 데이터 프로세싱 단계

척와 에이전트에서 전송한 데이터는 아래의 단계를 따라 처리된다.

  1. 청크 사이즈가 64MB가 될때까지, 또는 지정된 시간 간격이 지날 때까지는 청크를 logs/*.chukwa 파일에 저장한다.
  2. 컬렉터는 청크를 닫고, 청크를 *.done으로 이름을 변경한다.
  3. DemuxManager가 *.done 파일이 있는지 매 20초마다 검사한 후, 있으면 처리한다.
    – *.done 파일이 있으면, 해당 파일을 디먹스 프로세싱을 하기 위한 위치(demuxProcessing/mrInput)로 옮긴다.
    – demuxProcessing/mrInput에 있는 데이터에 대해 디먹스 MapReduce 잡이 실행하고, 그 결과를 출력 위치(demuxProcessing/mrOutput)에 저장한다.
    – 디먹스가 3번 시도하고, 성공하면 처리 완료된 파일을 아카이빙(dataSinkArchives/[yyyyMMdd]/*/*.done) 한다.
    – 디먹스가 실패하면 해당 파일을 에러 폴더(dataSinkArchives/InError/[yyyyMMdd]/*/*.done)로 옮긴다.
  4. HICC를 위한 데이터 프로세싱 작업이 주기적으로 실행된다 (자세한 내용은 생략한다).
  5. ChukwaArchiveManager가 30분마다 한번 정도로 실행되어, 맵리듀스를 사용해 아카이빙 처리를 한다. 아카이빙 처리가 되면서 dataSinkArchives에 있던 데이터를 삭제한다.
    dataSinkArchives/[yyyyMMdd]/*/*.done
    => archivesProcessing/mrInput
    => archivesProcessing/mrOutput
    => finalArchives/[yyyyMMdd]/*/chukwaArchive-part-*

이제 척와에 대한 개략적인 설명은 이 정도로 해 두고, 실제로 척와를 설치해 보자. 척와 설치와 관련해서는 “하둡 척와(Hadoop Chukwa) 초보 가이드 – 설치하기”에서 살펴보겠다.

참고자료

  • 클라우드 컴퓨팅 구현 기술 / 깅형준, 조준호, 안성화, 김병준 저 / 에이콘 출판사
  • 하둡 완벽 가이드 / 톰 화이트 지음 / 오라일리 출판사
  • Chukwa Documentation 4.0

크몽 재능

의사 분산 모드로 하둡(Hadoop) 실행하기

이 글은 크몽 재능인, socurites님이 원고를 기고하셨습니다.

이 글은 제 맥북에 하둡을 설치하여, 의사분산 모드로 실행한 작업 결과를 공유하기 위해서 정리한 글입니다.

설치하기

아파치 하둡 릴리즈 페이지에서 안정화된 배포판을 다운로드 받는다. 여기에서는 hadoop-0.20.2.tar.gz를 다운로드 받았다.

로컬 파일 시스템의 적당한 위치에 압축을 푼다.

$ tar xzf hadoop-0.20.2.tar.gz

이렇게 하둡이 설치된 디렉토리를 HADOOP_INSTALL이라고 부르자.

다음으로, HADOOP_INSTALL/conf/hadoop-env.sh 파일을 열어, JAVA_HOME 변수를 아래와 같이 설정한다.

export JAVA_HOME=/usr/lib/jvm/java-6-sun

필수사항은 아니지만 하둡 관련 명령어를 쉽게 실행하기 위해 하둡 설치 디렉토리(HADOOP_INSTALL)를 환경 변수에 설정하고, PATH를 설정한다. 여기에서는 .bashrc 파일에 설정했다.

#HADOOP
export HADOOP_INSTALL=하둡이 설치된 경로
export PATH=$PATH:$HADOOP_INSTALL/bin

설정한 환경 정보를 반영합니다.

$ source ~/.bashrc

아래와 같이 하둡 명령어를 실행해서 제대로 설치죄었는지 확인해 볼 수 있다.

$ hadoop version
Hadoop 0.20.2
Subversion https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.20 -r 911707
Compiled by chrisdo on Fri Feb 19 08:07:34 UTC 2010

환경 설정하기

하둡은 독립 실행 모드(Standalone Mode), 의사 분산 모드(Pseudo-Distributed Mode), 완전 분산 모드(Fully Distributed Mode)로 실행할 수 있다. 여기에서는 의사 분산 모드로 실행하고자 한다.

하둡은 XML 파일을 사용해서 설정하며, 설정할 파일은 총 3가지다.

  • conf/core-site.xml
    하둡 컴포넌트의 공통적인 속성을 정의한다.
  • conf/hdfs-site.xml
    하둡 파일 시스템과 관련된 설정을 한다.
  • conf/mapred-site.xml
    하둡 맵리듀스와 관련된 설정을 한다.

먼저 core-site.xml부터 설정하자.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
    <name>fs.default.name</name>
    <value>hdfs://localhost:9000</value>
</property>
</configuration>

fs.default.name에 하둡 파일 시스템의 네임노드의 호스트와 포트를 설정한다. 여기에서는 기본 포트인 8020이 아니라 9000을 포트로 설정했다.

다음으로 hdfs-site.xml을 설정한다.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
    <name>dfs.replication</name>
    <value>1</value>
</property>
</configuration>

의사 분산 모드로 설정하기 위해, 복사본을 1개를 만든다. 즉 dfs.replication를 1로 설정한다.

마지막으로 mapred-site.xml을 설정한다.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
    <name>mapred.job.tracker</name>
    <value>localhost:9001</value>
</property>
</configuration>

SSH 설정하기

의사 분산 모드/완전 분산 모드에서는 모두 데몬 프로세스를 실행하므로, 원격 서버의 명령을 수행할 수 있도록 ssh를 설정해야 한다. ssh가 설치되지 않았다면 먼저 ssh를 설치하도록 한다. ssh 명령어가 실행가능하더라도 ssh 데몬이 실행되어 있지 않으면 SSH을 설정할 수 없으므로, 아래와 같이 ssh를 다운받아서 설치한다.

$sudo apt-get install ssh

이제 아래와 같이 ssh 키를 생성한다.

$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

아래와 같은 명령어를 실행행서 성공한다면 제대로 설정한 것이다.

$ ssh localhost
Welcome to Ubuntu 11.10 (GNU/Linux 3.0.0-12-generic i686)
* Documentation: https://help.ubuntu.com/
Last login: Fri Nov 11 17:25:48 2011 from localhost

아래와 같이 22번 포트에 접속할 수 없다는 에러메시지가 나는 경우, sshd이 실행되어 있는지 확인한다.

ssh: connect to host localhost port 22: Connection refused
$ pgrep sshd

만약 아무런 결과도 나오지 않는다면 , sshd이 설치되지 않았거나, sshd 실행되지 않은 상태다.

실행하기

하둡 파일 시스템을 사용하려면 먼저 네임 노드를 포맷해야 한다.

$ hadoop namenode -format

하둡 파일 시스템과 맵리듀스 데몬을 아래와 같이 구동한다.

$ start-dfs.sh
$ start-mapred.sh

구동한 데몬을 중지하려면 아래의 명령어를 실행한다.

$ stop-dfs.sh
$ stop-mapred.sh

데몬이 제대로 실행되었는지 확인하는 방법에는 여러가지가 있다. 그 중에서도 웹 UI를 통해 모니터링하는 방법이 가장 편리하다. 네임노드는 http://localhost:50070/ 에서, 잡트래커는 http://localhost;50030/ 에서 확인할 수 있다.

크몽 재능