2012年2月21日 星期二

HBase-0.90.4 本機測試

上一篇takeshi談到如何在Hadoop上作本機測試,這次takeshi要談的是如何在HBase作本機測試,這也是takeshi目前專案正在使用的解決方案

此解決方案的採用,幫助團隊在複雜的mapReduce演算法研究和開發上,帶來相當大的效益;接下來,takeshi打算把原本相依於外部HBase環境和相關測試資料的功能性測試程式,重構成此解決方案的版本

 廢話不多說,接下來就介紹HBase本機測試的作法吧!

前提
1. 環境是HBase-0.90.4
2. 本解法參考的資料來源在這裡,此篇blog介紹了如何使用HBaseTestingUtility類別來初始local mini-cluster instance和使用ImportTsv類別來建構測試資料的方法;另外也參考了HBase的source code

準備工作
1. 誠如上一篇所講,如果是Windows環境的朋友,請先安裝cygwin

2. takeshi已把sample code整理成maven專案,檔案在這裡
2.1 要運行此專案需要使用maven, 請參考maven官網,或者也可以參考takeshi的文章ㄛ(打一下廣告^^)
2.2 假如朋友們要把maven專案 import到eclispe的話,要先在eclispe裝上m2eclispe plug-in

執行測試程式
把zip檔載下來後,解壓縮到你想放置的路徑(假設是$PROJECT_HOME),接著進入命令列模式(Command Line Interface, CLI),進入$PROJECT_HOME路徑執行mvn clean test,接著maven便會開始啟動HBase本機測試程式囉!

測試程式簡介
專案裡有三支測試程式,分別簡介如下...

AbstractHBaseMiniClusterTest
從名稱也看得出來,是一支抽象類別(Abstract Class),它把啟動和關閉HBaseTestingUtility類別的工作封裝在裡面,並另外提供一些工具方法(utility methods),另外兩支測試程式的super-class,程式碼如下...

public abstract class AbstractHBaseMiniClusterTest {

  //a static constant property for HBaseTestingUtility instance
  protected final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
 
  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    //start mini-cluster instance for 3 datanodes
    TEST_UTIL.startMiniCluster(3);
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    //shutdown mini-cluster instance
    TEST_UTIL.shutdownMiniCluster();
  }

  //following are utility methods...


FromClientSideTest
從HBase專案的測試程式借過來的,可以確認mini-cluster的可用性,這支測試程式提供了相當多的方法,如果在developer的本機環境都測過的話,表示mini-cluster是沒有問題的囉~


HBaseMiniClusterTest
這支測試程式是為了驗證ImportTsv類別的正確性所寫的,朋友們可以借由此測試程式來了解如何把測試資料倒入本機的mini-cluster,程式碼如下...

public class HBaseMiniClusterTest extends AbstractHBaseMiniClusterTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
    //start mini-cluster
    AbstractHBaseMiniClusterTest.setUpBeforeClass();
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
    //shutdown mini-cluster
    AbstractHBaseMiniClusterTest.tearDownAfterClass();
  }

  @Test //a test method for test data dumping
  public void testImportCompanyInfo() throws Exception {
    //prepare parameters
    //...
    //dump test data into mini-cluster
    importLocalFile2Table(conf, args, INPUT_FILE, INPUT_FILE_PATH);
    //...
    //validate the test data
    //...
  } 

心得分享
這次takeshi為了要找到本機測試解決方案,花了不少時間在trace HBase的source code,takeshi要跟大家分享的是,現在的opensource專案都遵守測試先行開發(Test Driven Development,TDD),除了對於開發團隊來說是程式品質的保證之外,對於takeshi這種「體制外的路人甲 XD」來說,這些測試程式也是「重要的文件ㄛ」!

例如,takeshi在研究HBaseTestingUtility和ImportTsv類別時,就是藉由它們的單元測試程式中的輸出入值和斷言(Assertion) ,來推導出它們的使用方法的,這也是takeshi提倡TDD的主要因素之一啦~

希望這些東東能幫助到正在看這篇文章的你/妳囉 ^^

2012年2月20日 星期一

Hadoop-0.20.x 本機測試

由於最近takeshi的專案主要是基於Hadoop和HBase平台上開發應用,所以不免俗地,我們需要對我們的應用作功能性上的測試;要執行我們的測試程式,必須要有以下步驟...

1. 必須要在環境中架一個Hadoop + HBase的cluster
2. 並且要在此cluster倒入事先定義好的測試資料
3. 接著在我們專案的maven pom檔中,把相關參數(Zookeeper的IP和port)設定好
4. 執行測試(也就是執行mvn clean verify)
5. 之後maven會幫我們執行所有的單元測試和整合測試,可以經過驗證輸出的值(assertion),來確認程式運作是否合乎我們預期

上述流程跑起來還算順暢,但仍有以下幾點會造成我們的困擾

1. 當其他團隊要參與我們的專案時,必須要跟我們索取測試資料(20GB... XD),並倒在HBase裡

2. 測試程式出錯時,很難debug!因為程式會被copy到參與工作的遠端節點再執行(分散式運算);所以developer在IDE中,對於想要debug的程式主要邏輯區塊下中斷點(breakpoint)時,往往都攔截不到執行緒(running thread),因為這些程式主要邏輯區塊都是在遠端節點執行的!

上述的第2點,是我們非常頭痛的issue,因為專案的商業邏輯越來越複雜,假如不能對這些程式主要邏輯區塊作debug的話,之後會嚴重拖慢開發進度>"<

也因此takeshi花了不少時間,看了相關書籍和網站,最後終於找到解法了!原來不論是Hadoop或是HBase,他們自己在開發的時候,也有相關的困擾,所以寫了一些類別,來專門在測試程式中起在本機跑的mini-cluster,因為是在同一個VM的instance,所以developer也有辦法對Hadoop或是HBase的cluster作debug囉!

不過這次takeshi先分享Hadoop的部分,之後再分享HBase的部分囉~

前提
1. 我們專案使用的環境是Hadoop-0.20.203.0
2. 本解法參考自書籍 Hadoop: The Definitive Guide, Second Edition,作者Tom White的sample code在這裡

準備工作
1.如果是windows環境的朋友,要請你們先安裝cygwin,載點在這裡
1.1 安裝完畢後,必須要把%CYGWIN_HOME% \bin路徑,加到PATH環境變數中
1.2 因為hadoop主要還是在unix-like的環境上執行,所以必須要在wnidows上模擬unix-like環境

2. 把作者的sample code import到IDE中(takeshi使用的是eclipse),並且把以下jar檔加入到build path裡

hadoop-0.20.2
hadoop-0.20.2-ant.jar
hadoop-0.20.2-core.jar
hadoop-0.20.2-examples.jar
hadoop-0.20.2-test.jar
hadoop-0.20.2-tools.jar

lib\commons-cli-1.2.jar
lib\commons-codec-1.3.jar
lib\commons-el-1.0.jar
lib\commons-httpclient-3.0.1.jar
lib\commons-logging-1.0.4.jar
lib\commons-logging-api-1.0.4.jar
lib\commons-net-1.4.1.jar
lib\core-3.1.1.jar
lib\hsqldb-1.8.0.10.jar
lib\jasper-compiler-5.5.12.jar
lib\jasper-runtime-5.5.12.jar
lib\jets3t-0.6.1.jar
lib\jetty-6.1.14.jar
lib\jetty-util-6.1.14.jar
lib\junit-3.8.1.jar
lib\kfs-0.2.2.jar
lib\log4j-1.2.15.jar
lib\mockito-all-1.8.0.jar
lib\oro-2.0.8.jar
lib\servlet-api-2.5-6.1.14.jar
lib\slf4j-api-1.4.3.jar
lib\slf4j-log4j12-1.4.3.jar
lib\xmlenc-0.52.jar

apache-tomcat-6.0.32
lib\jsp-api.jar
lib\servlet-api.jar

hamcrest-1.3.0RC2
hamcrest-all-1.3.0RC2.jar

以上的jar檔應該還可以再作刪減,或是應該可以再整理成maven pom檔, 但 takeshi很懶沒有做這個動作啦:p

眼明的朋友應該發現到為啥takeshi include的jar檔是hadoop-0.20.2,而不是hadoop-0.20.203.0,因為203的版本在windows上跑mini-cluster會出錯誤(不過討論網頁的連結在哪takeshi突然找不到了XD),所以takeshi是使用0.20.2來跑mini-cluster的;如果朋友們有其他的解,也請教一下takeshi喔

MiniDFSCluster
可以在本機起HDFS的mini-cluster instance,方便developer作本機debug,API doc在這邊,接著看看剛剛import的sample code專案中的ch03/src/main/java/路徑的CoherencyModelTest.java檔案,使用以下方式來啟動MiniDFSCluster類別

public class CoherencyModelTest {
  // use an in-process HDFS cluster for testing
  private MiniDFSCluster cluster;

  private FileSystem fs;

  @Before
  public void setUp() throws IOException {
    Configuration conf = new Configuration();
    //config parameters setting for test
    if (System.getProperty("test.build.data") == null) {
      System.setProperty("test.build.data", "/tmp");
    }
    cluster = new MiniDFSCluster(conf, 1, true, null);
    fs = cluster.getFileSystem();
  }
  
  @After
  public void tearDown() throws IOException {
    fs.close();
    //shutdown HDFS cluster
    cluster.shutdown();
  }

  //put your test codes below...

}


ClusterMapReduceTestCase
它是一個抽象測試類別,使用JUnit3的架構來啟動(當然JUnit4也可以使用囉),它預設會在本機起一個包含兩個節點的mini-cluster instance,方便developer作本機mapReduce 測試和debug,API doc在這邊,接著看看剛剛import的sample code專案中的ch05/src/main/java/v3/路徑的ClusterMapReduceTestCase.java檔案,使用以下方式來啟動此測試類別


// A test for MaxTemperatureDriver that runs in a "mini" HDFS and MapReduce cluster
public class MaxTemperatureDriverMiniTest extends ClusterMapReduceTestCase {
  
  @Override
  protected void setUp() throws Exception {
    //config setting for testcase
    if (System.getProperty("test.build.data") == null) {
      System.setProperty("test.build.data", "/tmp");
    }
    if (System.getProperty("hadoop.log.dir") == null) {
     System.setProperty("hadoop.log.dir", "/build/test/logs");
   }
    super.setUp();
  }

  //no need to extends the tearDown method due to the super-class handles it for you
  //protected void tearDown() throws Exception


  // Not marked with @Test since ClusterMapReduceTestCase is a JUnit 3 test case
  public void test() throws Exception {
    //...put your test code here
  }
}

細節的部分就請各位朋友去參考程式碼和書籍囉~

以下影片是takeshi在自己本機跑mini-cluster的情形,供大家參考囉~


最後takeshi在專案中採用的是使用HBase的解法(打算下一篇會寫),所以hadoop的source code就沒特別整理了,不過直接使用Tom White的source code,takeshi相信對大家的幫助更大唄~

2012年2月19日 星期日

實體關係圖與關聯式資料庫設計

本週takeshi跟公司同事分享了在專案經常用到的基本觀念,也就是我們要如何基於問題領域來設計資料庫模型,presentation如下...



3~5頁講解何謂抽象化,例子是takeshi跟李老師借來的,他是takeshi資料庫的啟蒙導師,takeshi在李老師身上學到很多,非常感謝Orz

12~24頁,是一個給大家熱身的案例,此案例是從資料庫的聖經「資料庫系統原理」借來的,takeshi嘗試一步一步地來引導大家,如何從ER-Model轉換成Relational Model

25~28頁,是一個貼近實務的案例,此案例是一個線上書店系統的類別圖(Class Diagram)(也是takeshi論文的一部分啦:p),其中有複雜的繼承和樹狀遞迴的概念,takeshi使用JPA(Java Persistence API),來把它們轉換成Relational Model

希望對有興趣的朋友有點幫助囉 ^^

2012年2月12日 星期日

雲端資料庫之設計與實作

這陣子takeshi在公司幫忙作雲端相關的案子,也應長官的要求在年前跟同事報告了相關資訊,所以takeshi作了以下ppt檔,放在這跟大家分享囉~




關於21頁的demo,是takeshi使用了VM Player作成的兩個節點,用來跟同事們demo如何使用hadoop和HBase,安裝規格如下...
 VM跑的Linux版本是:Fedora-15(不過官方已升級到16了啦...)
Hadoop版本:hadoop-0.20.203.0,安裝資訊在這裡
HBase版本:hbase-0.90.4,安裝資訊在這裡

關於24頁的demo,是takeshi使用最近opensource的專案JackHare,來操作HBase;因為JackHare目的是一個遵守JDBC 4.0規範的實作(目前支援HBase-0.90.4),所以takeshi是在同事面前demo了這些操作;關於JackHare的安裝步驟在這裡,有興趣的朋友可以試試看ㄛ ^^

最近takeshi在跟雲端"交朋友"的過程 ,也獲得了一些經驗,之後再跟朋友們分享囉 ^^