Language/NoSQL&JDBC

Hbase 설치하기

아르비스 2011. 8. 17. 15:07

사용환경
- Hadoop 0.20.2
- Hbase 0.20.6
- ext library : tableIndexed library for hbase0.20.6
- fully-distributed setup

1. hbase 설치
   http://hbase.apache.org 에서 0.20.6 버전을 다운로드 받아 설치한다.
   (현재 0.90.x가 나오고 있지만 아직 rc버전이다.)
   * 명심할것은 Hbase의 위치는 마스터또는 슬레이브서버 모두 동일해야 한다.
     서로 동일한 패스에 위치해야한다는 것을 명심하자.

2. /etc/host에 다음을 등록하자.
   * localhost에 127.0.0.1 같이 설정하지 마라
   * hostname에 - 같은 것을 쓰지마라. 인식을 할수 없다.
                              http://en.wikipedia.org/wiki/Hostname

192.168.0.202 localhost
192.168.0.203 hadoop.master
192.168.0.203 hadoop.slave

192.168.0.202 hbase.master
192.168.0.203 hbase.slave

    - hadoop.master : hadoop 마스터 서버의 위치
    - hadoop.slave : hadoop 슬레이브 서버의 위치

    - hbase.master : hbase 마스터 서버의 위치
    - hbase.slave: hbase 슬레이브 서버의 위치


3. 환경 설정 (마스터, 슬레이브 서버 공통)
 * hbase_env.sh 설정에 추가
  - jdk home path 설정 추가
 

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


  - table indexed 라이브러리를 사용하는 사람은 아래를 추가한다.
    (해당 외부 라이브러리 필요없으면 아래작업이 필요없다.)

export HBASE_HOME=/usr/local/hbase
export EXT_CLASSPATH=${HBASE_HOME}/lib/hbase-0.20.6-transactional.jar;
export HBASE_CLASSPATH=${EXT_CLASSPATH}


4. hbase-site 설정( Master, Slave 서버 공통)

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
<!-- Hadoop 의 Master 서버접속 url을 기록한다. -->
<property>
  <name>hbase.rootdir</name>
  <value>hdfs://hadoop.master:9000/hbase</value>
</property>

<!-- Hbase의 마스터 서버 위치를 설정한다. 현재 이서버가 해당된다. -->
<property>
  <name>hbase.master</name>
  <value>hbase.master:60000</value>
</property>

<property>
  <name>hbase.cluster.distributed</name>
  <value>true</value>
  <description>The mode the cluster will be in. Possible values are
    false: standalone and pseudo-distributed setups with managed Zookeeper
    true: fully-distributed with unmanaged Zookeeper Quorum (see hbase-env.sh)
  </description>
</property>
<!-- 아래는 indexed 외부 라이브러리가 필요한 사람만 추가로 등록한다. -->

<!--  Secondary Indexes in Habase. -->
        <property>
                <name>hbase.regionserver.class</name>
                <value>org.apache.hadoop.hbase.ipc.IndexedRegionInterface</value>
        </property>

        <property>
                <name>hbase.regionserver.impl</name>
                <value>org.apache.hadoop.hbase.regionserver.tableindexed.IndexedRegionServer</value>
        </property>


</configuration>



5. 마스터 서버에 추가 설정 (슬레이브 서버는 하지 않는다.)
   conf 폴더에 regionservers 파일을 생성하고
    hbase.master
    hbase.slave
   를 등록한다. 

6. 서비스 실행 
  이제 설정이 모두 완료되었다. 
마스터 서버에서 ./start-hbase.sh 를 하면 아래와 같이 자동적으로 Slave 서버까지 자동으로 구동될것이다. (마스터 서버에서만 실행하는것을 명심하자)

   * 마스터 서버에서 
     ./start-hbase.sh

    # jps로 확인시 아래와 같은 서비스가 구동되어 있으면 성공이다.
    - 마스터
      HRegionServer
      HQuorumPeer

     - 슬레이브
      HRegionServer
      
   
추가)
Hbase가 비록 BigTable같이 좋은 아키텍쳐를 지니고 있지만, 사용성 면에서는 많이 떨어지더군요. 그래서
http://code.google.com/p/hbase-jdo/  같은 오픈소스 프로젝트를 만들어 진행중입니다.  도움이 되었으면 하는군요. 이 프로젝트안에 있는 툴로 Hbase, Hadoop을 쉽게 조회 해볼 수 있으니 한번 사용해 보세요.


shell 실행
$ bin/hbase shell


7. Test

Test an Example Program
Original program source : http://hadoop.apache.org/hbase/docs/current/api/overview-summary.html#overview_description

sample/MyClient.java

package sample
import java.io.IOException;

import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Scanner;
import org.apache.hadoop.hbase.io.BatchUpdate;
import org.apache.hadoop.hbase.io.Cell;
import org.apache.hadoop.hbase.io.RowResult;

public class MyClient {

 public static void main(String[] args) throws IOException {
  // 클라이언트에서 어디로 접속할지 설정 객체에게 알려야 한다.
  // 기본으로 로컬 설정 파일에서 해당 정보를 가지고 오니 걱정하지는 말자.
  HBaseConfiguration config = new HBaseConfiguration();
  
  // 'myTable' 테이블에 접속하는 HTable 객체를 생성한다.
  HTable table = new HTable(config, "myTable");
  
  // row에 대한 모종의 업데이트를 수행하기 위해서는 BatchUpdate 객체를 사용한다.
  // BatchUpdate는 row 하나와 옵션으로 timestamp 값을 받는다.
  BatchUpdate batchUpdate = new BatchUpdate("myRow");
  
  // BatchUpdate의 put() 메소드는 값을 넣은 셀을 기술하는 텍스트와
  // 저장하고자 하는 값이 있는 byte 배열을 인자로 받는다.
  // 따라서 String이나 다른 primitives등을 저장하고자 한다면 getBytes()를 사용해야한다.
  batchUpdate.put("myColumnFamily:columnQualifier1", "columnQualifier1 value!".getBytes());
  
  // HBase에서는 삭제도 배치 작업이다.
  //batchUpdate.delete("myColumnFamily:cellWantDeleted");
  
  // 작업을 끝낸 뒤에는 결과를 commit 한다.
  // HTable#commit 메소드는 BatchUpdate 객체를 인자로 받아 배치작업을 수행한다.
  table.commit(batchUpdate);
  
  // 이제 방금 저장한 값들을 읽어보자. 리턴되는 값은 Cell 객체이다.
  // Cell은 byte 배열로 이루어진 값과 timestamp 값의 조합이다.
  Cell cell = table.get("myRow", "myColumnFamily:columnQualifier1");
  String valueStr = new String(cell.getValue());
  
  // 찾고자 하는 row를 모를 경우, Scanner를 사용한다. Scanner는 테이블의 내용에 대한
  // cursor 스타일의 인터페이스를 제공한다.
  Scanner scanner = table.getScanner(new String[]{"myColumnFamily:columnQualifier1"});
  
  // HBase 0.2에 있는 Scanner는 RowResult 객체를 리턴한다.
  // RowResult는 row key와 column들을 하나의 인터페이스로 묶어놓은 것과 같다.
  // RowResult#getRow는 row key를 리턴한다.
  // 또한 RowResult는 Map 인터페이스를 구현해두고 있기 때문에 column 결과에 쉽게 접근 가능하다.
  RowResult rowResult = scanner.next();
  while (rowResult != null) {
   System.out.println("Found row: " + new String(rowResult.getRow()) + " with value: " + rowResult.get("myColumnFamily:columnQualifier1".getBytes()));
   
   rowResult = scanner.next();
  }
  
  // iterable한 Scanner를 foreach로 탐색하는 방법도 있다.
  for (RowResult result : scanner) {
   System.out.println("Found row: " + new String(result.getRow()) + " with value: " + result.get("myColumnFamily:columnQualifier1".getBytes()));
  }
  
  // 작업이 끝나면 Scanner를 닫도록 한다.
  scanner.close();
 }
}

build.xml
<project name="MyClient">
 <property name="target.dir" value="build" />
 <property name="classes.dir" value="${target.dir}/classes" />
 
 <property name="source.dir" value="src" />
 <property name="lib.dir" value="lib" />
 
 <target name="init">
  <mkdir dir="${classes.dir}" />
  <path id="build.classpath">
   <fileset dir="${lib.dir}">
    <include name="**/**.jar" />
   </fileset>
  </path>
 </target>
  
 <target name="compile" depends="init">
  <javac
   srcdir="${source.dir}"
   destdir="${classes.dir}"
   classpathref="build.classpath"
   encoding="utf-8"
  />
 </target>
</project>
[hadoop@master example]$ ls
build.xml   lib   src
[hadoop@master example]$ ant compile
...
[hadoop@master example]$ ls
build    build.xml    lib    src
[hadoop@master example]$ cd build/classes
[hadoop@master example]$ ls
sample
[hadoop@master classes]$ export HBASE_HOME=/home/hadoop/hbase
[hadoop@master classes]$ $HBASE_HOME/bin/hbase sample.MyClient
Found row: myRow with value: timestamp=1217998267705, value=columnQualifier1 value!