쉼터

'공부/opensource'에 해당되는 글 3건

  1. 2009.09.01 httpclient 사용시 CLOSE_WAIT, TIME_WAIT 문제 해결방안 2
  2. 2008.03.17 hbase 설치 2
  3. 2008.03.03 hadoop 설치
HTTP 통신할때 주로 httpclient를 이용해서 처리를 한다.

기본적인 httpclient 사용 방법은 다음과 같다.
여기서 주의할 점은
method.releaseConnection();
이렇게 connection을 끊어줘야한다.

근데 간혹 CLOSE_WAIT, TIME_WAIT이 누적되어서 FD가 빠지지 않는 경우가 있다.
(ESTABLISHED, CLOSE_WAIT, TIME_WAIT이 뭔지 모른다면 TCP 3-Way handshake부터 공부하면 된다.)
대충쓸때는 상관없지만 문제는 지속적으로 연결할때 CLOSE_WAIT, TIME_WAIT이 없어지지않고 계속해서 쌓이게될때가 있다.

일단 CLOSE_WAIT이 계속 누적해서 안빠진다면 httpclient를 잘못쓴 경우가 많다.
연결할때마다 계속해서 httpclient를 new해서 생성을 하면서 어느수준이상으로 연결을 시도할때 CLOSE_WAIT이 누적되어 안빠지게된다.
왜냐하면 httpclient는 default가 HTTP/1.1 방식이다.
어느정도 keepalive를 유지하기때문에
서버에서는 connectionTimeout이 지나면 연결을 종료시키지만
서버에서 연결종료된 상황을 클라이언트에서 서버로 다시 물어보기전에는 알 수가 없다.
그래서 완전히 종료가 안되고 CLOSE_WAIT 상태가 된다.
근데 이 상황에서 매번 httpclient를 생성하게되면 제대로 연결을 종료안되고
클라이언트 쪽에는 CLOSE_WAIT이 쌓이게된다.

해결책은 여러방법이 있다.
1. 클라이언트쪽에서 HTTP/1.0으로 연결하면된다.

method.getParams().setParameter(HttpMethodParams.PROTOCOL_VERSION, HttpVersion.HTTP_1_0);

1.0으로 연결을 한다는거는 keepalive를 유지안하고 매번 연결하고 끊고한다는거다.
이렇게 하면 CLOSE_WAIT이 누적은 안된다.
하지만 CLOSE_WAIT대신에 TIME_WAIT이 누적된다.
그리고 매번 연결을 끊고 연결하기때문에 throughput이 제대로 안나온다.

2. httpclient를 제한적으로 사용하는 방법이다.
httpclient를 wrapping하는 하나의 클래스를 만든다.
그리고 그 클래스를 싱글톤패턴을 이용해서 필요한곳에서 사용한다.
근데 문제는 스레드환경에서 한번에 여러군데 접속하고 싶을때는 문제가 발생한다.
그럴때는 MultiThreadedHttpConnectionManager를 이용하면된다.

MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(connectionManager);

이렇게만 해주면 알아서 pooling을 해준다.
MultiThreadedHttpConnectionManager에는 몇가지 옵션이 있는데
필요에 따라서 적절히 조절해주면된다.

이렇게 하면 CLOSE_WAIT 상태가 계속해서 누적되어 쌓이지 않는다.

3. IdleConnectionTimeoutThread를 이용해서 해결 할 수도 있다.

MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
IdleConnectionTimeoutThread idleConnectionTimeoutThread = new IdleConnectionTimeoutThread();
idleConnectionTimeoutThread.addConnectionManager(connectionManager);
HttpClient client = new HttpClient(connectionManager);
idleConnectionTimeoutThread.start();

이렇게 별도의 스레드를 생성해서 idle상태를 주기적으로 지워준다.

IdleConnectionTimeoutThread를 이용하지않고
connectionManager.closeIdleConnections(1000*10);
이걸 이용해서 주기적으로 지워줄 수 있다.

근데 3번째 방법은 CLOSE_WAIT를 해결하는 방법이라기보단
CLOSE_WAIT가 발생할때 더 이상 안늘어나게하는 사후처리 방법이다.

웬만하면 2번째처럼 통신할 수 있는 채널에 제약을 걸어서 많이 생성못하도록하는게 제일 좋은거 같다.

그리고 TIME_WAIT 상태가 누적되는거는 연결이 종료되는데 시간이 걸리기때문에
어쩔 수 없이 발생을 하게된다.
그래서 웬만하면 HTTP/1.1로 통신을 해야한다.
서버도 HTTP/1.1로 받을 수 있도록하고
클라이언트도 HTTP/1.1로 보내면서 keepalvie를 유지해서
나름 서로간에 전용통로를 만들어줘서 연결이 종료안되게 만들면된다.

여기서 중요한것은 MultiThreadedHttpConnectionManager 여기에
maxTotalConnections 이 값을 상황에 맞게 유지시키는거다.
내가 연결해야하는 connection수가 maxTotalConnections수를 넘어가게된다면
어쩔수 없이 기존 연결된 소켓을 끊고 새롭게 연결해야하기때문에
keepalive 상태를 유지못한다.

즉, TIME_WAIT이 안일어나게 하기 위해서는 연결 종료를 안하고
계속 그 통로를 통해서 통신을 하는건데
maxTotalConnections수를 적절히 조절해서 연결이 안끊기게
keepalive 상태를 유지하게하면된다.

자세한 사항은 httpclient wiki에 나와있다.
Posted by pchun

hbase 설치

2008. 3. 17. 21:51 : 공부/opensource
hbase는 Google의 Bigtable의 clone 프로젝트로 진행중에 있고
hadoop의 subproject로 진행중이다.

즉, hbase를 사용할려면 hadoop(0.16.0이상)을 다운 받으면된다.

$HADOOP_HOME/contrib/hbase 에 있다.

일단 $HBASE_HOME/conf/hbase-site.xml을 편집한다.

<configuration>
    <property>
        <name>hbase.master</name>
        <value>localhost:60000</value>
        <description>The host and port that the HBase master runs at.</description>
    </property>
  
<property>
        <name>hbase.rootdir</name>
        <value>hdfs://localhost:9000/hbase</value>
        <description>The directory shared by region servers.</description>
    </property>
</configuration>

일단 hbase.master, hbase.rootdir는 기본적으로 설정해줘야한다.

$HBASE_HOME/conf/regionservers 이 파일하고 $HADOOP_HOME/conf/slaves와 동일하게 해준다.

$HBASE_HOME/bin/start-hbase.sh(hbase 시작)
$HBASE_HOME/bin/stop-hbase.sh(hbase 종료)

항상 hadoop을 먼저 띄우고 hbase를 시작해야하고 hbase를 닫고 hadoop을 닫아줘야한다.

http://localhost:60010
정상적으로 hbase가 실행이 된다면 위 페이지가 나올것이다.

참조사이트(http://hadoop.apache.org/hbase/docs/current/api/overview-summary.html#overview_description)
Posted by pchun

hadoop 설치

2008. 3. 3. 23:18 : 공부/opensource
- ssh 설치
ssh를 이용해서 remote hadoop daemons을 관리하기 때문에 필수로 설치되어야한다.

- hadoop 다운로드
http://hadoop.apache.org/core/releases.html

- 압축을 풀고 나서 conf/hadoop-env.sh 파일에 JAVA_HOME 설정

- bin/hadoop 한번 실행

- conf/hadoop-site.xml 편집
<configuration>
  <property>
    <name>fs.default.name</name>
    <value>localhost:9000</value>
  </property>
  <property>
    <name>mapred.job.tracker</name>
    <value>localhost:9001</value>
  </property>
</configuration>

- ssh-keygen 실행(localhost도 ssh를 이용하기때문에 설정해야함)
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys


- DFS 포맷
bin/hadoop namenode -format


- example(그냥 싱글노드에서 동작)

bin/start-all.sh (hadoop daemon 실행)
bin/hadoop dfs -put conf input (conf 디렉토리에 있는 파일을 DFS에 input이라는 이름으로 copy)
bin/hadoop jar hadoop-*-examples.jar grep input output 'dfs[a-z.]+' (DFS input에 있는 파일 중에 'dfs[a-z.]+'에 매칭되는 문자열을 output에 저장)
bin/hadoop dfs -get output output  (DFS output에 있는 내용을 output 디렉토리에 저장)
cat outout/* (결과값 확인)
bin/stop-all.sh (hadoop daemon 중지)


참조 사이트(http://hadoop.apache.org/core/docs/current/quickstart.html)
Posted by pchun