<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    敏捷、分布式、ALM過程自動化、企業(yè)應(yīng)用架構(gòu)
    posts - 14, comments - 0, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    Hadoop實施已經(jīng)有快一個月了,對Hadoop的概念理解、使用,Linux與shell腳本,甚至mysql都有了更多的理解。


    項目背景:用于互聯(lián)網(wǎng)信息收集后的關(guān)鍵詞匹配與內(nèi)容提取。

    主要系統(tǒng)架構(gòu)分為互聯(lián)網(wǎng)爬蟲、分析、業(yè)務(wù)應(yīng)用三塊:

    簡單架構(gòu)描述

    由于我在當(dāng)中的角色主要負責(zé)分析架構(gòu)的搭建,所以其他兩塊都畫得簡單,下面也不會過多的描述。


    Hadoop理解:提到Hadoop都想到的是云、分布式計算,在一段時間的實施之后有了一些具體的理解。

    Hadoop的優(yōu)勢:

    針對性能指標,當(dāng)業(yè)務(wù)數(shù)據(jù)量總量或增速上升到一定級別,依靠關(guān)系型數(shù)據(jù)庫一定無法支持。對于非關(guān)系型數(shù)據(jù)庫,包括Nosql和Solr一類存儲方式,稍顯復(fù)雜,對于機器集群性能要求偏高(相對于文件系統(tǒng))。從數(shù)據(jù)使用模式上來講,目前海量數(shù)據(jù)的常常是不包含復(fù)雜邏輯的簡單統(tǒng)計整理(比如上述系統(tǒng)中的關(guān)鍵詞匹配)。這時候文件系統(tǒng)的優(yōu)勢反而比較明顯(結(jié)構(gòu)簡單,邏輯簡單)。

    如上述系統(tǒng)的應(yīng)用場景是怎么樣的呢,在一個強大的爬蟲系統(tǒng)之下,每個小時的數(shù)據(jù)增量在G到10G的級別,需要搜索所有的文件,獲取關(guān)鍵字的匹配,并且對匹配內(nèi)容進行摘要。很類似我們windows里面的搜索功能,需要解決的就是如何在這樣增幅的文件系統(tǒng)之下,如何滿足業(yè)務(wù)系統(tǒng)的需求。

    分析系統(tǒng)有什么要求呢?

    能夠建立集群,分布式的保存數(shù)據(jù)文件內(nèi)容(統(tǒng)一控制,可配置)。

    有一定的保護機制,保證數(shù)據(jù)或節(jié)點丟失不會影響系統(tǒng)使用。

    如果有一個任務(wù)腳本執(zhí)行框架機制就好了(用于并行計算)。

    能夠進行節(jié)點間的數(shù)據(jù)均衡。

    能夠簡單的查看所有的狀態(tài)與日志(web客戶端)

    可能主要是這些了。若自己實現(xiàn),確實是個復(fù)雜而龐大的工程,現(xiàn)在我們有了Hadoop。


    系統(tǒng)物理架構(gòu):

    我們使用了一臺服務(wù)器,利用虛擬化,安裝了7套64x位的CentOS。一個Namenode,6個Datanode,復(fù)制數(shù)設(shè)置為3。每個系統(tǒng)分配到一個cpu,2G內(nèi)存,Datanode掛載了500G的存儲空間。

    理想的Hadoop的搭建環(huán)境,參照《Best Practices for Selecting Apache Hadoop Hardware》(http://hortonworks.com/blog/best-practices-for-selecting-apache-hadoop-hardware/)一文,以及一些其他的文章。

    CPU:最好是雙CPU,8核左右。不用太高了。

    內(nèi)存:推薦48G,但是4G應(yīng)該就可以運行Hadoop了。

    硬盤:7200轉(zhuǎn)的SATA硬盤即可,Hadoop很占空間,所以盡量加。

    網(wǎng)絡(luò):內(nèi)部的數(shù)據(jù)交換要求非常高,內(nèi)網(wǎng)最好是千兆網(wǎng)卡,帶寬為1GB。

    理想與現(xiàn)實,有錢與沒錢,呵呵。


    系統(tǒng)軟件架構(gòu):

    Hadoop:版本使用的是1.0.3,再下來就是2了,為了盡量簡化應(yīng)用,所以不考慮2的新特性。對Hadoop沒有做太多的設(shè)置,基本基于默認。70為Namenode,71-76為Datanode。

    JDK:1.6.0_33 (64x)


    系統(tǒng)實施過程:

    HDFS部分:

    爬蟲抓取數(shù)據(jù),整理后存放在50文件服務(wù)器,70以外部掛載的形式讀取。網(wǎng)頁文件比較小,假如直接寫入Hadoop對Namenode負載過大,所以入庫前合并,將每小時網(wǎng)頁整合成為一個文件寫入HDFS,由于區(qū)分類別,所以每小時基本寫入10個文件左右,總量在5-8G,耗時在40-50分鐘。(這個過程中,由于爬蟲的IO過于頻繁,導(dǎo)致文件讀取困難,所以做了定時任務(wù),每小時啟動一次,將需要處理的文件先拷貝到臨時區(qū)域,合并入庫之后再刪除。此處應(yīng)該是受到單核cpu的限制,所有操作均是串行,包括拷貝(cp)和合并入庫(java),所以Namenode嚴重建議配置稍高。)

    此處沒有太多問題。

    MapReduce部分:

    寫入完成后,進行分析工作,MapReduce。此處的工作過程為:數(shù)據(jù)庫定時生成關(guān)鍵詞列表文件。Job執(zhí)行時會讀取列表文件,匹配指定范圍內(nèi)的HDFS文件(過去一小時),匹配出對應(yīng)的表達式與HTML,Map過程結(jié)束。在Reduce階段,會將Map的所有數(shù)據(jù)入數(shù)據(jù)庫(Mysql)。

    此處出現(xiàn)過一些問題,記錄下來。

    1. Reduce階段需要加載Mysql的第三方驅(qū)動包。我在三個環(huán)境測試過(公司、家里、發(fā)布環(huán)境),使用 -libjars 一定可以,有的地方不需要也可以。不明確,懷疑與HADOOP_HOME環(huán)境變量有關(guān)。

    2. MR過程中使用log4j打印日志,在Hadoop臨時目錄(如果你沒有配置dfs.name.dir,dfs.data.dir,mapred.local.dir.mapred.system.dir等目錄,這些都會在hadoop.tmp.dir當(dāng)中,我就偷懶都沒配置)mapred文件夾中查看一下。

    整個過程實際上還是比較簡單的,基本編碼量就在Job的部分,但是一個Java文件就夠了。在目前初級階段應(yīng)該還是比較好用的?,F(xiàn)在還沒有測試Job的執(zhí)行效率。完成后會繼續(xù)記錄下來。有什么問題可以提出。我想到什么也會在本文繼續(xù)更新。

    posted @ 2012-08-08 20:21 一酌散千憂 閱讀(585) | 評論 (0)編輯 收藏

    硬件資源:

    三臺CentOS5.6虛擬機(Vmware

    本機 windows7 64x

     

    基本資源配置:

    三臺虛擬機均是克隆自同一個鏡像

    已經(jīng)安裝了Java環(huán)境(jdk1.6.0_25

    Hadoop路徑在/usr/hadoop/hadoop-0.20.205.0

     

    操作步驟:

    1、機器名稱規(guī)范

    ip分別為128、129130,將128設(shè)置為master,其他設(shè)置為slave

    修改

    /etc/sysconfig/network

    /etc/hosts

    兩處配置,名稱分別為hadoop-master\hadoop-slave01\hadoop-slave02

    注意:此處名稱最好不用使用下劃線,有可能引發(fā)namenode的啟動異常。

     

    2、修改Hadoop配置 

    master節(jié)點的conf中修改masterslave文件,分別為機器的ip地址

     

    修改master節(jié)點的conf中:

    core-site.xml

    <property>

    <name>fs.default.name</name>

    <value>hdfs://ip-master:9000</value>

    </property>

     

    mapred-site.xml

    <property>

    <name>mapred.job.tracker</name>                                   

    <value>master:9001</value>                                

    </property>

     

    hdfs-site.xm

    <property>

    <name>dfs.replication</name>

    <value>2</value>

    </property>

    注意此處的端口號均為默認。

     

     

    3、建立m-s之間的ssh連接

    首先masterslave機器都需要進行ssh信任文件生成,執(zhí)行如下命令:

    $ ssh-keygen -t rsa

    中間需要輸入的地方直接回車,接受缺省值即可

     

    由于使用root用戶登錄,所以密鑰文件生成在 /root/.ssh/文件夾下,存有一對密鑰id_dsaid_dsa.pub。

    此處id_dsa(私鑰)必須為其他用戶不可讀,所以文件屬性應(yīng)當(dāng)是600

     

    master機器執(zhí)行:

    id_dsa.pub(公鑰)復(fù)制為 authorized_keys

    $ cp id_dsa.pub authorized_keys

    如果是多臺機器需要,無密碼登陸,則各自機器產(chǎn)生公鑰追加到authorized_keys即可.

     

    使用scp協(xié)議覆蓋slave端的密鑰文件夾,使得slave機器信任來自master的連接:

    $ scp /root/.ssh/* ip-slave:/root/.ssh

     

     

    4、啟動服務(wù) 

    建議將$HADOOP_HOME/bin下的所有文件給與執(zhí)行權(quán)限:

    $ chmod 777 bin

     

    master作為namenod需要執(zhí)行如下腳本:

    $HADOOP_HOME/bin/hadoop namenode –format

     

    完成后執(zhí)行 $HADOOP_HOME/bin/start-all.sh

     

    5、問題檢查

    Hadoop根目錄下的logs文件中,檢查各個服務(wù)日志的啟動情況

     

     

    6、其他情況說明:

    Q: $HADOOP_HOME is deprecated

    A: 基本不會產(chǎn)生任何影響。由于腳本啟動時設(shè)置了該環(huán)境變量,就會提示用戶原有環(huán)境變量失效??梢匀∠h(huán)境變量設(shè)置,或者直接去bin/hadoop中找到這句話,去掉即可

     

    Q: 無效的選項 -jvm / Unrecognized option: -jvm

    A: 在使用root用戶登錄時 bin/hadoop 腳本就會進行判斷,加上-jvm參數(shù)。此處是為了進入jsvchttp://commons.apache.org/daemon/jsvc.html),此處并不確定是否bug,也不再進行詳細的追溯,解決方法就是進入 bin/hadoop 腳本中 找到 jvm 參數(shù)并去掉。

     

     

     

     

     

     

     

    posted @ 2012-07-04 07:38 一酌散千憂 閱讀(589) | 評論 (0)編輯 收藏

    公司里有同事時常抱怨,項目的用戶體驗太差,常常挨領(lǐng)導(dǎo)的罵。大家都認為是在用戶體驗的設(shè)計方面,公司人員的能力和經(jīng)驗都不足引起的。發(fā)牢騷的時候也會說,如果公司能夠請得起“淘寶”的UI設(shè)計師,咱們的系統(tǒng)肯定會更上一層樓。我之前也一直認為如此,即我們的設(shè)計是影響項目體驗的重要原因。最近被領(lǐng)導(dǎo)調(diào)動去協(xié)助一個項目,產(chǎn)生了一些不一樣的體會。

    項目背景,一個新的產(chǎn)品,小型項目,純開發(fā)人員3-4人,2名熟練開發(fā)人員,1名新手,偶爾會有協(xié)助人員。沒有技術(shù)經(jīng)理,項目經(jīng)理身負多個項目,對項目進度關(guān)心不足,部門經(jīng)理會協(xié)助進行工作和進度管理??梢钥吹焦芾磉€是比較混亂。

    由于項目進度太慢,領(lǐng)導(dǎo)要求從我這邊調(diào)一個熟練人員協(xié)助開發(fā)。我也基本了解他們的項目狀況,為了不讓我的人進去抓瞎,我就和他一起去了解項目情況。

    項目狀況比較糟糕,介入項目時已經(jīng)開發(fā)了一段時間,保留的文檔只有兩份,一副數(shù)據(jù)庫說明,一份非常粗略的需求說明,而且還與開發(fā)進度不同步,就是沒有維護。

    我了解了一下項目目前的難度,開發(fā)人員和我反映一個是人員熟練程度的問題,二是需求變更的問題。我整體了解了一下項目目前的需求和設(shè)計,以及進度。就挑了一個模塊詢問他們的變更情況,這個模塊是一個關(guān)鍵詞匹配功能。結(jié)果是領(lǐng)導(dǎo)看了他們的頁面之后,嫌信息量太少,就要求提供一些更細化的數(shù)據(jù)展示。開發(fā)人員問我有什么意見,我就簡單講了一下頁面大概怎么構(gòu)建。其中有一個點,是用于變更數(shù)據(jù)范圍,即查詢的表變更,我一開始覺得使用下拉框就可以,產(chǎn)生了一些意見。有人建議分為不同子模塊,或者tab頁,或者分為多塊并列展示。我想了想,就給他們講了我認為幾種方案的優(yōu)點缺點及適用范圍。

     

    1.       多塊并行展示:

    多個不同范圍的數(shù)據(jù)在同一頁面中分為不同區(qū)域以相同形式展示。原因是由于多塊數(shù)據(jù)之間有一定的關(guān)聯(lián)因果關(guān)系,或值得對比。適用范圍:如購物網(wǎng)站中的多個物品比較。

    2.       Tab頁:

    同一個頁面的多個tab頁,表示多個tab頁中的數(shù)據(jù)可能在一定的領(lǐng)域概念之下有一定的關(guān)聯(lián),但關(guān)聯(lián)度不強。因為tab頁更重要的是強調(diào)一個同步工作的狀態(tài),即A tab頁查看一定信息,會打開B tab頁查看其他信息,中途還會切回A tab頁。適用范圍:如郵箱中,收件箱和草稿箱。

    3.       下拉框

    下拉框作為查詢條件的一部分,常用于有著常規(guī)或固定的可選擇內(nèi)容中(如性別,月份),更多是以過濾的形態(tài)出現(xiàn),即下拉框更適合針對某表的某個字段過濾,如果針對的是數(shù)據(jù)范圍或是對用戶需要直觀了解的重要業(yè)務(wù)條件則不太合適。適用范圍:如在考試成績中使用下拉框過濾“男女”或“及格不及格”。

    4.       單選框

    單選框與下拉框的作用范圍相似,但是不同之處在于將被選項全部展示,目的在于能夠讓用戶清楚的了解當(dāng)前數(shù)據(jù)顯示的實際范圍或條件,以及備選的其他范圍或條件。更適用于選項與實際業(yè)務(wù)及當(dāng)前展示數(shù)據(jù)關(guān)系重要,不同選項可能會引發(fā)用戶的不同行為。適用范圍:如銀行系統(tǒng)顯示了當(dāng)前用戶下綁定多個帳號時,使用單選框。

     

    經(jīng)過上述討論,我們仔細分析了這個模塊中用戶的實際需求,以及可能后續(xù)操作,最終選擇的單選框的方案。

    目前還沒有后續(xù),但是我想我們基于用戶真是需求的挖掘和后續(xù)操作的認真分析,會讓我們在與領(lǐng)導(dǎo)進行需求討論的時候有更加充分合理的依據(jù)。

    回來之后我又看了看淘寶的搜索頁面,比如就搜索“鞋子”來講,將品牌這欄設(shè)置為單選和下拉將是完全不同的效果,而確定方案的理由則是對于用戶的需求和實際行為的深入研究。這個應(yīng)該是需求分析和調(diào)研的結(jié)果。將搜索條件以tag的形式標注于頁面上,并且可以直接點擊X按鈕進行刪除,我覺得更加可以傾向為用戶體驗。滿足并充分考慮了用戶實際需求的是好的需求分析,能夠簡化并引導(dǎo)用戶行為的是好的用戶體驗。

    當(dāng)我們面臨的系統(tǒng)感覺非常難用的時候,往往這時候并非是用戶體驗差,我們應(yīng)該檢討的是我們對用戶需求有沒有好好挖掘,做出來的是不是用戶想要、用戶能用的系統(tǒng)。

    posted @ 2012-05-22 05:02 一酌散千憂 閱讀(265) | 評論 (0)編輯 收藏

    Zookeeper的核心概念:

    ZNode

    Znode就是核心結(jié)構(gòu),Zookeeper服務(wù)中是由大量的Znode構(gòu)成。Znode一般是由客戶端建立和修改,作為信息或標志的載體,甚至本身就是標志。

    Znode可以設(shè)置為持久(PERSISTENT)或臨時(EPHEMERAL),區(qū)別在于臨時的節(jié)點若斷開連接后就自動刪除。建立節(jié)點時可選擇是否使用序列號命名(SEQUENTIAL),若啟用則會自動在節(jié)點名后加入唯一序列編號。

    Session

    作為客戶端和Zookeeper服務(wù)之間交互的憑證。

    Watch

    當(dāng)客戶端對節(jié)點信息進行查詢操作之后,可以選擇是否設(shè)置一個Watch。其作用就是當(dāng)本次查詢的數(shù)據(jù)在服務(wù)器端發(fā)生變化之后,會對設(shè)置Watch的客戶端發(fā)送通知。一次發(fā)送之后,就將刪除該Watch,以后的變更或不再設(shè)置Watch則不會通知。

    ACLs

    節(jié)點的權(quán)限限制使用ACL,如增刪改查操作。

    Zookeeper的服務(wù)器安裝:

    1、下載對應(yīng)版本號的tar.gz文件

    2、使用 tar xzvf zookeeper-3.4.2.tar.gz -C ./ 解壓

    3、設(shè)置,將conf/zoo.example.cfg復(fù)制到conf/zoo.cfg或者手動建立一個新的。

    4、啟動Zookeeper服務(wù):bin/zkServer.sh start

    5、啟動客戶端連接:bin/zkCli.sh -server 127.0.0.1:2181(此處在本機,且使用了默認端口,且在Java環(huán)境中)

    6、使用命令:ls、get、set等。

    7、關(guān)閉Zookeeper服務(wù):bin/zkServer.sh stop

    Zookeeper代碼編寫:

    代碼編寫部分比較簡單,因為暴露的接口很少,主要復(fù)雜在于項目如何使用節(jié)點以及節(jié)點信息。

    啟動Zookeeper服務(wù)之后,客戶端代碼進行節(jié)點的增刪,Watch的設(shè)置,內(nèi)容的改查等。

    此處建議查看官方的《Programming with ZooKeeper - A basic tutorial》部分,當(dāng)中舉了兩個例子來模擬分布式系統(tǒng)的應(yīng)用。

    代碼基本沒有問題,唯一需要注意的就是:若之間按照原版進行調(diào)試時,有可能在調(diào)用

     Stat s = zk.exists(root, false);

    這句代碼時會出現(xiàn)一個異常,當(dāng)中包括“KeeperErrorCode = ConnectionLoss for”。

    這個問題引起的原因可以看一下代碼

                    System.out.println("Starting ZK:");
                    zk 
    = new ZooKeeper(address, 3000this);
                    mutex 
    = new Integer(-1);
                    System.out.println(
    "Finished starting ZK: " + zk);

    最后一行有打印出Zookeeper目前的信息,若未修改的原代碼,此處的State應(yīng)當(dāng)是CONECTING。連接中的時候去驗證是否存在節(jié)點會報錯。解決的方法也很簡單,就是等到Zookeeper客戶端以及完全連接上服務(wù)器,State為CONECTED之后再進行其他操作。給出代碼示例:

    // 使用了倒數(shù)計數(shù),只需要計數(shù)一次
    private CountDownLatch connectedSignal = new CountDownLatch(1); 
    SyncPrimitive(String address) {
        
    if(zk == null){
            
    try {
                System.out.println(
    "Starting ZK:");
                zk 
    = new ZooKeeper(address, 3000this);
                mutex 
    = new Integer(-1);
                connectedSignal.await(); 
    // 等待連接完成
                System.out.println("Finished starting ZK: " + zk);
            } 
    catch (IOException e) {
                System.out.println(e.toString());
                zk 
    = null;
            } 
    catch (InterruptedException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    //else mutex = new Integer(-1);
    }
    synchronized public void process(WatchedEvent event) {
        
    // 此處設(shè)立在Watch中會在狀態(tài)變化后觸發(fā)事件
        if (event.getState() == KeeperState.SyncConnected) {
            connectedSignal.countDown();
    // 倒數(shù)-1
        }
        
            
    synchronized (mutex) {
                
    //System.out.println("Process: " + event.getType());
                mutex.notify();
            }
    }

    這樣就可以正確運行代碼了。

    Zookeeper的應(yīng)用場景及方式:

    此處是為引用,原地址為(http://rdc.taobao.com/team/jm/archives/1232 

    ZooKeeper是一個高可用的分布式數(shù)據(jù)管理與系統(tǒng)協(xié)調(diào)框架?;趯axos算法的實現(xiàn),使該框架保證了分布式環(huán)境中數(shù)據(jù)的強一致性,也正是基于這樣的特性,使得zookeeper能夠應(yīng)用于很多場景。網(wǎng)上對zk的使用場景也有不少介紹,本文將結(jié)合作者身邊的項目例子,系統(tǒng)的對zk的使用場景進行歸類介紹。 值得注意的是,zk并不是生來就為這些場景設(shè)計,都是后來眾多開發(fā)者根據(jù)框架的特性,摸索出來的典型使用方法。因此,也非常歡迎你分享你在ZK使用上的奇技淫巧。

    場景類別

    典型場景描述(ZK特性,使用方法)

    應(yīng)用中的具體使用

    數(shù)據(jù)發(fā)布與訂閱

    發(fā)布與訂閱即所謂的配置管理,顧名思義就是將數(shù)據(jù)發(fā)布到zk節(jié)點上,供訂閱者動態(tài)獲取數(shù)據(jù),實現(xiàn)配置信息的集中式管理和動態(tài)更新。例如全局的配置信息,地址列表等就非常適合使用。

    1. 索引信息和集群中機器節(jié)點狀態(tài)存放在zk的一些指定節(jié)點,供各個客戶端訂閱使用。2. 系統(tǒng)日志(經(jīng)過處理后的)存儲,這些日志通常2-3天后被清除。 

    3. 應(yīng)用中用到的一些配置信息集中管理,在應(yīng)用啟動的時候主動來獲取一次,并且在節(jié)點上注冊一個Watcher,以后每次配置有更新,實時通知到應(yīng)用,獲取最新配置信息。

    4. 業(yè)務(wù)邏輯中需要用到的一些全局變量,比如一些消息中間件的消息隊列通常有個offset,這個offset存放在zk上,這樣集群中每個發(fā)送者都能知道當(dāng)前的發(fā)送進度。

    5. 系統(tǒng)中有些信息需要動態(tài)獲取,并且還會存在人工手動去修改這個信息。以前通常是暴露出接口,例如JMX接口,有了zk后,只要將這些信息存放到zk節(jié)點上即可。

    Name Service

    這個主要是作為分布式命名服務(wù),通過調(diào)用zk的create node api,能夠很容易創(chuàng)建一個全局唯一的path,這個path就可以作為一個名稱。

     

    分布通知/協(xié)調(diào)

    ZooKeeper中特有watcher注冊與異步通知機制,能夠很好的實現(xiàn)分布式環(huán)境下不同系統(tǒng)之間的通知與協(xié)調(diào),實現(xiàn)對數(shù)據(jù)變更的實時處理。使用方法通常是不同系統(tǒng)都對ZK上同一個znode進行注冊,監(jiān)聽znode的變化(包括znode本身內(nèi)容及子節(jié)點的),其中一個系統(tǒng)update了znode,那么另一個系統(tǒng)能夠收到通知,并作出相應(yīng)處理。

    1. 另一種心跳檢測機制:檢測系統(tǒng)和被檢測系統(tǒng)之間并不直接關(guān)聯(lián)起來,而是通過zk上某個節(jié)點關(guān)聯(lián),大大減少系統(tǒng)耦合。2. 另一種系統(tǒng)調(diào)度模式:某系統(tǒng)有控制臺和推送系統(tǒng)兩部分組成,控制臺的職責(zé)是控制推送系統(tǒng)進行相應(yīng)的推送工作。管理人員在控制臺作的一些操作,實際上是修改了ZK上某些節(jié)點的狀態(tài),而zk就把這些變化通知給他們注冊Watcher的客戶端,即推送系統(tǒng),于是,作出相應(yīng)的推送任務(wù)。 

    3. 另一種工作匯報模式:一些類似于任務(wù)分發(fā)系統(tǒng),子任務(wù)啟動后,到zk來注冊一個臨時節(jié)點,并且定時將自己的進度進行匯報(將進度寫回這個臨時節(jié)點),這樣任務(wù)管理者就能夠?qū)崟r知道任務(wù)進度。

    總之,使用zookeeper來進行分布式通知和協(xié)調(diào)能夠大大降低系統(tǒng)之間的耦合。

    分布式鎖

    分布式鎖,這個主要得益于ZooKeeper為我們保證了數(shù)據(jù)的強一致性,即用戶只要完全相信每時每刻,zk集群中任意節(jié)點(一個zk server)上的相同znode的數(shù)據(jù)是一定是相同的。鎖服務(wù)可以分為兩類,一個是保持獨占,另一個是控制時序。 

    所謂保持獨占,就是所有試圖來獲取這個鎖的客戶端,最終只有一個可以成功獲得這把鎖。通常的做法是把zk上的一個znode看作是一把鎖,通過create znode的方式來實現(xiàn)。所有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點,最終成功創(chuàng)建的那個客戶端也即擁有了這把鎖。

    控制時序,就是所有視圖來獲取這個鎖的客戶端,最終都是會被安排執(zhí)行,只是有個全局時序了。做法和上面基本類似,只是這里 /distribute_lock 已經(jīng)預(yù)先存在,客戶端在它下面創(chuàng)建臨時有序節(jié)點(這個可以通過節(jié)點的屬性控制:CreateMode.EPHEMERAL_SEQUENTIAL來指定)。Zk的父節(jié)點(/distribute_lock)維持一份sequence,保證子節(jié)點創(chuàng)建的時序性,從而也形成了每個客戶端的全局時序。

     

    集群管理

    1. 集群機器監(jiān)控:這通常用于那種對集群中機器狀態(tài),機器在線率有較高要求的場景,能夠快速對集群中機器變化作出響應(yīng)。這樣的場景中,往往有一個監(jiān)控系統(tǒng),實時檢測集群機器是否存活。過去的做法通常是:監(jiān)控系統(tǒng)通過某種手段(比如ping)定時檢測每個機器,或者每個機器自己定時向監(jiān)控系統(tǒng)匯報“我還活著”。 這種做法可行,但是存在兩個比較明顯的問題:1. 集群中機器有變動的時候,牽連修改的東西比較多。2. 有一定的延時。 

    利用ZooKeeper有兩個特性,就可以實時另一種集群機器存活性監(jiān)控系統(tǒng):a. 客戶端在節(jié)點 x 上注冊一個Watcher,那么如果 x 的子節(jié)點變化了,會通知該客戶端。b. 創(chuàng)建EPHEMERAL類型的節(jié)點,一旦客戶端和服務(wù)器的會話結(jié)束或過期,那么該節(jié)點就會消失。

    例如,監(jiān)控系統(tǒng)在 /clusterServers 節(jié)點上注冊一個Watcher,以后每動態(tài)加機器,那么就往 /clusterServers 下創(chuàng)建一個 EPHEMERAL類型的節(jié)點:/clusterServers/{hostname}. 這樣,監(jiān)控系統(tǒng)就能夠?qū)崟r知道機器的增減情況,至于后續(xù)處理就是監(jiān)控系統(tǒng)的業(yè)務(wù)了。
    2. Master選舉則是zookeeper中最為經(jīng)典的使用場景了。

    在分布式環(huán)境中,相同的業(yè)務(wù)應(yīng)用分布在不同的機器上,有些業(yè)務(wù)邏輯(例如一些耗時的計算,網(wǎng)絡(luò)I/O處理),往往只需要讓整個集群中的某一臺機器進行執(zhí)行,其余機器可以共享這個結(jié)果,這樣可以大大減少重復(fù)勞動,提高性能,于是這個master選舉便是這種場景下的碰到的主要問題。

    利用ZooKeeper的強一致性,能夠保證在分布式高并發(fā)情況下節(jié)點創(chuàng)建的全局唯一性,即:同時有多個客戶端請求創(chuàng)建 /currentMaster 節(jié)點,最終一定只有一個客戶端請求能夠創(chuàng)建成功。

    利用這個特性,就能很輕易的在分布式環(huán)境中進行集群選取了。

    另外,這種場景演化一下,就是動態(tài)Master選舉。這就要用到 EPHEMERAL_SEQUENTIAL類型節(jié)點的特性了。

    上文中提到,所有客戶端創(chuàng)建請求,最終只有一個能夠創(chuàng)建成功。在這里稍微變化下,就是允許所有請求都能夠創(chuàng)建成功,但是得有個創(chuàng)建順序,于是所有的請求最終在ZK上創(chuàng)建結(jié)果的一種可能情況是這樣: /currentMaster/{sessionId}-1 , /currentMaster/{sessionId}-2 , /currentMaster/{sessionId}-3 ….. 每次選取序列號最小的那個機器作為Master,如果這個機器掛了,由于他創(chuàng)建的節(jié)點會馬上小時,那么之后最小的那個機器就是Master了。

    1. 在搜索系統(tǒng)中,如果集群中每個機器都生成一份全量索引,不僅耗時,而且不能保證彼此之間索引數(shù)據(jù)一致。因此讓集群中的Master來進行全量索引的生成,然后同步到集群中其它機器。2. 另外,Master選舉的容災(zāi)措施是,可以隨時進行手動指定master,就是說應(yīng)用在zk在無法獲取master信息時,可以通過比如http方式,向一個地方獲取master。

    分布式隊列

    隊列方面,我目前感覺有兩種,一種是常規(guī)的先進先出隊列,另一種是要等到隊列成員聚齊之后的才統(tǒng)一按序執(zhí)行。對于第二種先進先出隊列,和分布式鎖服務(wù)中的控制時序場景基本原理一致,這里不再贅述。 

    第二種隊列其實是在FIFO隊列的基礎(chǔ)上作了一個增強。通??梢栽?nbsp;/queue 這個znode下預(yù)先建立一個/queue/num 節(jié)點,并且賦值為n(或者直接給/queue賦值n),表示隊列大小,之后每次有隊列成員加入后,就判斷下是否已經(jīng)到達隊列大小,決定是否可以開始執(zhí)行了。這種用法的典型場景是,分布式環(huán)境中,一個大任務(wù)Task A,需要在很多子任務(wù)完成(或條件就緒)情況下才能進行。這個時候,凡是其中一個子任務(wù)完成(就緒),那么就去 /taskList 下建立自己的臨時時序節(jié)點(CreateMode.EPHEMERAL_SEQUENTIAL),當(dāng) /taskList 發(fā)現(xiàn)自己下面的子節(jié)點滿足指定個數(shù),就可以進行下一步按序進行處理了。

     

    posted @ 2012-05-15 11:02 一酌散千憂 閱讀(4835) | 評論 (0)編輯 收藏

    MongoDB介紹

    當(dāng)今NoSQL領(lǐng)域中有很多有力的競爭者通過多種方式來處理海量數(shù)據(jù)問題。其中重要的解決方案之一就是MongoDB。MongoDB是面向文檔的弱結(jié)構(gòu)化存儲方案,使用JSON格式來展現(xiàn)、查詢和修改數(shù)據(jù)。

    MongoDB文檔相當(dāng)完備,擴展規(guī)模與安裝一樣簡單。它提供冗余、切片、索引以及map/reduce等概念支持。MongoDB的開源社區(qū)非常大且非常活躍。MongoDB在很多大型產(chǎn)品中被實際運用,如:Disney, Craigslist, Foursquare, Github 和SourceForge。MongoDB是一個開源項目,由10gen.com建立并維護,該公司由DoubleClick的前任執(zhí)行人員創(chuàng)立。同時,10gen也提供了極好的商業(yè)支持與參與建設(shè)。

    MongoDB NoSQL: 缺陷與優(yōu)勢

    MongoDB作為一個可用NoSQL方案具有很多優(yōu)勢。我剛開始接觸NoSQL數(shù)據(jù)庫了解了一系列基于Java的方案,并且花了大量的時間來弄懂什么是列家族,Hadoop與HBase的關(guān)系,ZooKeeper到底是什么。當(dāng)我終于全部清楚之后,發(fā)現(xiàn)Cassandra與HBase確實是對于NoSQL領(lǐng)域非常可靠、可信賴的解決方案。但與其他的解決方案相比,MongoDB讓我在能夠開始寫代碼之前,不用理解那么多的概念。

    與其他軟件相似,MongoDB也存在缺陷。經(jīng)過一段時間使用MongoDB,我列舉經(jīng)歷過并需要注意的一些事情,我成為“Gotchas”:

    • 不要按照關(guān)系型數(shù)據(jù)庫來思考。這很明顯,MongoDB使得構(gòu)建和執(zhí)行復(fù)雜查詢變得非常容易。當(dāng)實際使用的時候,你會主要關(guān)注于效率問題(像我一樣)。
    • MongoDB的索引是二進制的樹。如果你不是很熟悉B-tree,可能需要了解一下。這些都涉及到構(gòu)建符合提供查詢條件需求的建立索引的方式。
    • 小心的設(shè)計索引結(jié)構(gòu)。這涉及到上面提到的B-tree。剛開始我的索引包含文檔中的很多字段,以防我會使用到他們。不要犯同樣的錯誤。我有一個很小集合的索引(大約1千萬記錄)增長到超過17GB的空間,比集合本身還大。你應(yīng)該不會想要索引一個包含成百上千個實體的列表字段。
    • MongoDB采用了非常有意思的方式來實現(xiàn)NoSQL:采用BSON作為存儲,JSON作為展示,JavaScript用于管理和Map/Reduce。因此也引起了一些小問題比如這個 (破壞了Number和Long的相等操作),在MongoDB逐漸流行之后,可能會不斷的展示出來。

     

    MongoDB, 命令行與驅(qū)動

    MongoDB基本是使用JavaScript客戶端命令行程序來進行復(fù)雜任務(wù)管理的,如數(shù)據(jù)整合和簡單信息處理,編程都是完全使用JavaScript語言來的。本文中,我們會展示命令行的使用示例?,F(xiàn)在有大量的MongoDB客戶端產(chǎn)品提供,并且由MongoDB社區(qū)來支持驅(qū)動。通常每種編程語言都有驅(qū)動,并且所有流行的語言都有包括,一些不那么流行的也包含在內(nèi)。這篇文章展示了使用MongoDB的Java驅(qū)動,并使用一個ORM庫(MJORM)與之進行比較。

    介紹 MJORM: MongoDBORM方案

    在解決的眾多有意思的問題中,最近NoSQL數(shù)據(jù)存儲在開發(fā)者中主要的問題趨勢就是對象關(guān)系映射。對象關(guān)系映射就是將傳統(tǒng)中保存在關(guān)系型數(shù)據(jù)庫中的持久化數(shù)據(jù)映射為在應(yīng)用程序中使用的對象。這使得編程語言使用起來更加流暢和自然。

    MongoDB面向文檔的架構(gòu)使得它非常適合對象關(guān)系映射,因為文檔本身就是以對象形式存儲的??上]有太多的MongoDB的Java對象關(guān)系映射庫,但是還是有一些,如morphia-(A type-safe Java library for MongoDB), spring-data(SpringData項目的MongoDB實現(xiàn))

    這些ORM庫大量使用了注解,因為一些原因?qū)ξ也贿m合,其中最重要的就是這些被注解的對象在多個項目中的兼容性問題。這讓我開始了mongo-Java-orm 或者 "MJORM" (發(fā)音 me-yorm)項目,一個MongoDB的Java對象關(guān)系映射項目。MJORM是在MIT許可之下,并且在發(fā)布在了google code project。項目采用maven構(gòu)建,并且maven構(gòu)件倉庫托管于google code版本控制服務(wù)器。MJORM的最新可用發(fā)布版本為0.15,已經(jīng)由一些項目使用與生產(chǎn)環(huán)境中。

    開始使用ORM

    加入MJORM

    Maven的使用者首先應(yīng)當(dāng)在pom.xml中加入MJORM的maven倉庫,使得MJORM構(gòu)件可用。

    <repository>
             <id>mjorm-webdav-maven-repo</id>
             <name>mjorm maven repository</name>
             <url>http://mongo-Java-orm.googlecode.com/svn/maven/repo/</url>
             <layout>default</layout>
    </repository>

    然后加入依賴:

    <dependency>
             <groupId>com.googlecode</groupId>
             <artifactId>mongo-Java-orm</artifactId>
             <version>0.15</version>
    </dependency>

    這樣就可以在應(yīng)用中引入MJORM代碼。假如沒有使用maven,則你需要手動下載MJORM的pom.xml中列舉的所有依賴。

    建立 POJOs

    依賴已經(jīng)導(dǎo)入,可以開始編碼了。我們從POJO開始:

     
    class Author {
             private String firstName;
             private String lastName;
             // ... setters and getters ...
    }
     
    class Book {
             private String id;
             private String isbn;
             private String title;
             private String description;
             private Author author;
             // ... setters and getters ...
    }

    我們在這個對象模型中的描述是,作者有ID、姓和名,書有ID、ISNB、標題、描述和作者。

    你可能注意到書的id屬性是一個字符串,這是為了適應(yīng)MongoDB的對象ID類型。MongoDB的ID是一個12字節(jié)的二進制值顯示為一個十六進制的字符串。MongoDB要求集合中的每個文檔都必須有一個唯一id,但不要求一定要是ObjectId。目前MJORM只支持ObjectId,并且顯示為字符串。

    你也可能注意到了Author沒有id字段。這是因為Book是它的父文檔,因此不需要有id。記住,MongoDB只要求集合中的文檔在根級別的id。

    創(chuàng)建XML映射文件

    下一個步驟就是建立XML映射文件,MJORM能夠?qū)ongoDB文檔轉(zhuǎn)換為對象。我們?yōu)槊總€文檔創(chuàng)建一個對象作為示范,無論將所有的映射放在一個XML文件中還是分開都是可以的。

    Author.mjorm.xml:

    <?xml version="1.0"?>
    <descriptors>
             <object class="Author">
                     <property name="firstName" />
                     <property name="lastName" />
             </object>
    </descriptors>

    Book.mjorm.xml:

    <?xml version="1.0"?>
    <descriptors>
             <object class="Book">
                     <property name="id" id="true" auto="true" />
                     <property name="isbn" />
                     <property name="title" />
                     <property name="description" />
                     <property name="author" />
             </object>
    </descriptors>

     

    這些映射文件能夠很好的自解釋。descriptors 元素是根元素,必須包含在每個映射文件中。在它下面是object元素定義了文檔與之對應(yīng)的類。Object包含的property 元素主要用于描述POJO中的屬性以及這些屬性如何與MongoDB中的文檔想對應(yīng)。property 元素至少必須包含一個name 屬性,這個元素就是POJO和MongoDB的文檔中的屬性名稱。column 屬性則是可選的,用于特定一個在MongoDB文檔中的可選屬性名稱。

    property 元素當(dāng)中的id屬性應(yīng)該是對象的唯一識別。一個對象只能有一個property 元素包含id屬性。auto 的設(shè)置會使得MJORM在持久化時為該屬性自動生成一個值。

    可以在google code的MJORM項目主頁中查看XML映射文件的更多細節(jié)描述。

    整合POJOXML

    我們創(chuàng)建了數(shù)據(jù)模型以及映射文件,使得MJORM可以從MongoDB序列號以及反序列號POJO。我們可以進行一些有意思的事情了,首先打開MongoDB的鏈接:

    Mongo mongo = new Mongo(
             new MongoURI("mongodb://localhost/mjormIsFun")); // 10gen driver

    Mongo 對象是由10gen編寫的Java驅(qū)動提供的。示例中連接了一個本地的MongoDB實例中的mjormIsFun數(shù)據(jù)庫。接下來我們創(chuàng)建MJORM ObjectMapper 。目前ObjectMapper 在MJORM中的唯一實現(xiàn)就是XmlDescriptorObjectMapper,使用XML結(jié)構(gòu)描述信息??赡苤髸黾訉ψ⒔饣蚱渌Y(jié)構(gòu)定義的支持。

    XmlDescriptorObjectMapper objectMapper = new XmlDescriptorObjectMapper();
    mapper.addXmlObjectDescriptor(new File("Book.mjorm.xml"));
    mapper.addXmlObjectDescriptor(new File("Author.mjorm.xml"));

    建立好了XmlDescriptorObjectMapper 并且加入了映射文件。接下來建立由MJORM提供的MongoDao 對象的實例。

    DB db = mongo.getDB("mjormIsFun"); // 10gen driver
    MongoDao dao = new MongoDaoImpl(db, objectMapper);

    首先我們要獲得10gen驅(qū)動提供的DB對象實例。然后使用DB和ObjectMapper 建立MongoDao 。我們準備開始持久化數(shù)據(jù),建立一個Book 然后保存到MongoDB中。

    Book book = new Book();
    book.setIsbn("1594743061");
    book.setTitle("MongoDB is fun");
    book.setDescription("...");
     
    book = dao.createObject("books", book);
    System.out.println(book.getId()); // 4f96309f762dd76ece5a9595

    首先建立Book 對象并且填值,然后調(diào)用MongoDao 的 createObject 方法,將Book 對象傳入"books" 的集合中。MJORM會按照之前的xml映射文件將Book 轉(zhuǎn)換為DBObject (這是10gen的Java驅(qū)動使用的基本類型),并保存一個新的文檔進"books" 集合。MJORM返回Book對象時,id屬性會被填充。請注意,MongoDB默認是不需要在使用前建立數(shù)據(jù)庫或集合的,系統(tǒng)會在需要時自動創(chuàng)建,這可能會造成某些困擾。在MongoDB的命令行中查看Book對象大概如下:

    > db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()
    {
             "_id":          ObjectId("4f96309f762dd76ece5a9595"),
             "isbn":         "1594743061",
             "title":        "MongoDB is fun",
             "description": "..."
    }

     

    我們來看看假如不用MJORM而直接使用10gen的Java驅(qū)動,如何使用createObject 方法:

    Book book = new Book();
    book.setIsbn("1594743061");
    book.setTitle("MongoDB is fun");
    book.setDescription("...");
     
    DBObject bookObj = BasicDBObjectBuilder.start()
             .add("isbn",              book.getIsbn())
             .add("title",             book.getTitle())
             .add("description",       book.getDescription())
             .get();
     
    // 'db' is our DB object from earlier
    DBCollection col = db.getCollection("books");
    col.insert(bookObj);
     
    ObjectId id = ObjectId.class.cast(bookObj.get("_id"));
    System.out.println(id.toStringMongod()); // 4f96309f762dd76ece5a9595

     

    下面進行對象的查詢:

    Book book = dao.readObject("books", "4f96309f762dd76ece5a9595", Book.class);
    System.out.println(book.getTitle()); // "MongoDB is fun"

    readObject 方法根據(jù)給定文檔的id從指定的集合中讀取文檔,轉(zhuǎn)換為對象(再次使用映射文件)并返回。

    敏銳的讀者會注意到Book還沒有指定Author,仍然保存了。這歸咎于MongoDB的結(jié)構(gòu)不敏感的特性。我們不能要求集合中的文檔包含所有屬性(id屬性是必須的),所有在MongoDB中沒有Author的Book是可以的。我們現(xiàn)在為Book添加一個Author并且更新一下:

    Author author = new Author();
    author.setFirstName("Brian");
    author.setLastName("Dilley");
     
    book.setAuthor(author);
     
    dao.updateObject("books", "4f96309f762dd76ece5a9595", book);

    現(xiàn)在Book就包含了Author,并且在MongoDB中持久化了?,F(xiàn)在在命令行查看了Book:

    > db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()
    {
             "_id":          ObjectId("4f96309f762dd76ece5a9595"),
             "isbn":         "1594743061",
             "title":        "MongoDB is fun",
             "description": "..."
             "author": {
                 "firstName": "Brian",
                 "lastName": "Dilley"
             }
    }

    可以看到持久化的Book中已經(jīng)包含了author。不使用MJORM來操作一遍:

    Author author = new Author();
    author.setFirstName("Brian");
    author.setLastName("Dilley");
     
    book.setAuthor(author);
     
    DBObject bookObj = BasicDBObjectBuilder.start()
             .add("isbn",              book.getIsbn())
             .add("title",             book.getTitle())
             .add("description",       book.getDescription())
             .push("author")
                     .add("firstName",         author.getFirstName())
                     .add("lastName",  author.getLastName())
                     .pop()
             .get();
     
    DBCollection col = db.getCollection("books");
    col.update(new BasicDBObject("_id", bookObj.get("_id")), bookObj);
     

     

    對于MongoDao 方法的深入討論已經(jīng)超出了本文的范圍。對于將MJORM有興趣用于實際項目中的用戶強烈建議了解一下MJORM項目提供的相關(guān)文檔,或者MongoDao 接口提供的相關(guān)用法。

    總結(jié)

    希望這篇文章對MongoDB和MJORM的亮點有所展示。MongDB是一個優(yōu)秀的呃NoSQL數(shù)據(jù)存儲,有著大量優(yōu)秀的特性,會是NoSQL市場中長期競爭者。若你會在一個Java項目中使用MongoDB,希望你也能夠考慮使用MJORM作為你的ORM框架。十分歡迎大家提交特性需求、錯誤異常報告、文檔和源碼修正。

     

    作者 Bio

    Brian Dilley 是一個經(jīng)驗豐富的高級工程師以及項目領(lǐng)導(dǎo),在Java/Java EE /Spring Framework/Linux內(nèi)部結(jié)構(gòu)理解和管理有著超過13年的經(jīng)驗。Brian對于創(chuàng)業(yè)公司有很多經(jīng)驗,推向市場,構(gòu)建/維護產(chǎn)品等。他是IaascloudPHPLinux的專家,熟悉產(chǎn)品的采購、安裝及配置定義,以及公司的軟硬件架構(gòu)包括負載均衡、數(shù)據(jù)庫、微博等。可以follow Brian Twitter 。

    posted @ 2012-05-09 13:46 一酌散千憂 閱讀(1545) | 評論 (0)編輯 收藏

    “企業(yè)信息集成(EII):實用方式”于2005年發(fā)布,描述了一套集成不同數(shù)據(jù)源的方法論,利用了當(dāng)時的先進技術(shù),如面向服務(wù)架構(gòu)(SOA)、Web ServicesXML、資源描述架構(gòu)(RDF)、基于XML的元數(shù)據(jù)格式以及數(shù)據(jù)提取、轉(zhuǎn)換和加載(ETL)。EII能夠基本為關(guān)系型數(shù)據(jù)元素提供統(tǒng)一視角,但在性能效率上缺乏能夠替代數(shù)據(jù)倉庫和多維數(shù)據(jù)庫的能力。五年之后技術(shù)已經(jīng)得到了顯著提升,不僅在于對于分散數(shù)據(jù)的操作,還有簡化了單一容器下不同數(shù)據(jù)的整合,以及對數(shù)據(jù)深入挖掘的能力。

    轉(zhuǎn)變了數(shù)據(jù)管理方式的技術(shù)正是虛擬化。低成本存儲、云計算、NoSQL數(shù)據(jù)庫以及Hadoop。當(dāng)我們提起虛擬化時,已經(jīng)遠遠超出為一臺物理機器提供一套軟件實例這一概念。時至今日,我們可以虛擬化服務(wù)器、存儲以及網(wǎng)絡(luò)。所有這些虛擬化意味著我們不再被這些物理條件所限制,能夠迅速構(gòu)建物理環(huán)境以支持我們特定時刻的特定需求。當(dāng)面對Gb、Tb、Pb等級數(shù)據(jù)量的處理需求時,我們基本能擺脫結(jié)構(gòu)化的數(shù)據(jù)倉庫。我們不在需要僅僅為了發(fā)掘業(yè)務(wù)的某一方面而建立一個特殊的環(huán)境了。

    低成本存儲在業(yè)務(wù)的數(shù)據(jù)存儲方面節(jié)省了開支。高昂的存儲成本會使得企業(yè)尋找在限定規(guī)模的數(shù)據(jù)之上進行關(guān)鍵業(yè)務(wù)分析的方案,這樣使得如何選擇最重要的數(shù)據(jù)變得十分關(guān)鍵,而且還限制了系統(tǒng)能夠處理的數(shù)據(jù)的質(zhì)量。

    負面影響便是業(yè)務(wù)最終可能面臨很少的選擇,因為沒有足夠的歷史數(shù)據(jù)提供從而識別一個有效關(guān)鍵模式?;蛘咭驗楦甙旱耐度胧沟脴I(yè)務(wù)被停止,而使用常規(guī)慣例來識別模式。

    云計算為那些需要通過海量數(shù)據(jù)源在合理時間范圍內(nèi)產(chǎn)生結(jié)果的需求提供了一個可用的方式。海量數(shù)據(jù)處理需要兩點:彈性存儲,CPU。高速網(wǎng)絡(luò)很有幫助,但是待會我們會看到在發(fā)掘軟件在處理海量數(shù)據(jù)時,它并非是系統(tǒng)的瓶頸。彈性存儲意味著企業(yè)不會在期望操作的數(shù)據(jù)規(guī)?;蝾愋蜕鲜艿较拗?,降低了使用數(shù)據(jù)倉庫無法獲取最佳結(jié)果的風(fēng)險。更多的CPU使得結(jié)果能夠在期望的時間范圍內(nèi)更快的被交付。

    NoSQL提供了海量數(shù)據(jù)的支持,但與傳統(tǒng)的關(guān)系型數(shù)據(jù)庫沒有關(guān)聯(lián)。而且大部分NoSQL數(shù)據(jù)庫是開源的,無須支付購買證書等費用。NoSQL對于表結(jié)構(gòu)有著驚人的靈活性,無須隨著系統(tǒng)的改進而不斷修改完善定義。NoSQL可以支持不同數(shù)據(jù)源的合并查看,從而成為EII之后另一個備選方案,這或許是NoSQL最重要的方面了。

    NoSQL內(nèi)置了數(shù)據(jù)冗余與分布式數(shù)據(jù)存儲機制。海量數(shù)據(jù)的最大問題之一就是磁盤讀寫,NoSQL通過將數(shù)據(jù)分布至一系列節(jié)點來緩解這個問題。當(dāng)一個查詢請求發(fā)出時,這些節(jié)點能夠并行查詢自身節(jié)點,而不是僅僅依靠一塊磁盤,一個磁盤陣列或一條網(wǎng)絡(luò)連接等,數(shù)據(jù)查詢能夠在節(jié)省了讀寫開支之后變得更加迅速。

    最終,我們來討論Hadoop,集合了上述所有技術(shù)力量與一身的用于檢測和分析數(shù)據(jù)的框架。有些人可能認為Hadoop是一項NoSQL技術(shù),實際上Hadoop是一個分布組件的java框架,用于分解“吃大象”(此處也雙關(guān)Hadoop是以創(chuàng)立者的兒子給自己的一個大象玩具起的名字)的工作——每次一口。

    Hadoop自身實際上與待處理數(shù)據(jù)是各自獨立的。它將大型查詢?nèi)蝿?wù)分解為小的并行查詢?nèi)蝿?wù),然后收集結(jié)果,并整合出答案返回給用戶。Hadoop相對于NoSQL來說是一個并行查詢框架,通過云計算驅(qū)動節(jié)點,運行在低成本存儲及虛擬化技術(shù)之上。

    Kicking的知識回顧

    當(dāng)EII第一次作為最佳實踐出現(xiàn)于2003-2004年,關(guān)鍵要素就是無需再移動數(shù)據(jù)了。當(dāng)時大部分的數(shù)據(jù)中心仍然運行于低速網(wǎng)絡(luò)中,有限的空間用于復(fù)制數(shù)據(jù)。之后,EII成為了當(dāng)時可用技術(shù)和問題域中最優(yōu)秀的解決方案。EII的某些方面的優(yōu)秀即使在海量數(shù)據(jù)中也是很顯著的。

    EII的優(yōu)點之一就是將處理過程轉(zhuǎn)移到數(shù)據(jù)所在地。海量數(shù)據(jù)方案的關(guān)鍵架構(gòu)要素之一就是將處理過程轉(zhuǎn)移到數(shù)據(jù)所在地,而不是轉(zhuǎn)移數(shù)據(jù)。EII中的一個重要原則就是使用數(shù)據(jù)歸屬地的查詢功能。這項實踐就是構(gòu)建靠近數(shù)據(jù)源網(wǎng)絡(luò)的Web Service,能夠建立起通用查詢接口,但只針對本地數(shù)據(jù)庫進行查詢。我們通過開放的基于Web的接口解決了數(shù)據(jù)的專有格式的問題,從而使得多個數(shù)據(jù)子集能夠迅速的整合并以統(tǒng)一模式展示。

    有了低成本存儲和10G網(wǎng)絡(luò)之后,我們就不必那么擔(dān)心數(shù)據(jù)冗余與數(shù)據(jù)遷移,但還是有其他問題存在的,數(shù)據(jù)倉庫無法確保數(shù)據(jù)的原始性便是其中之一。在EII中,我們將從原始數(shù)據(jù)源獲取數(shù)據(jù)視為“黃金準則”,這樣就能夠保證信息未被修改過,且是準確的。

    Big Data要求數(shù)據(jù)必須轉(zhuǎn)移到新的物理位置,這樣可信任度又成為了問題。EII的那些獲取基線數(shù)據(jù)的最佳實踐仍然是相關(guān)而且重要的。實際上,那些為EII設(shè)計開發(fā)的Web Services接口最終在Big Data的啟用中扮演主要角色。

    當(dāng)然,討論數(shù)據(jù)管理不能不涉及到安全問題。EII在安全領(lǐng)域中還是超過了Big Data。技術(shù)上來說,Big Data在數(shù)據(jù)集成方面更加高效與敏捷,但是大部分缺少了固有的安全性,因為在設(shè)計上會加大處理的難度。所以,可能要由源系統(tǒng)來擔(dān)任起數(shù)據(jù)訪問安全方面的責(zé)任。因為EII直接在源系統(tǒng)中查詢數(shù)據(jù),所以必須要求有適當(dāng)?shù)氖跈?quán),否則查詢就將失敗。

    上述關(guān)于安全討論描述的是內(nèi)在的安全控制情況。將訪問權(quán)限控制列表集成進數(shù)據(jù)庫是非常合理的,這將確保安全能夠作為查詢的一部分進行維護。然后,一旦能夠直接查詢NoSQL數(shù)據(jù)源,就意味著能夠自由的訪問你所有的數(shù)據(jù)。

    總結(jié)

    引用老的Virginia Slims的廣告中的臺詞:“我們已經(jīng)歷很長的路途了,寶貝兒!”文中討論到的技術(shù)的發(fā)展已經(jīng)對21世紀第二個10年中的的數(shù)據(jù)解決方案產(chǎn)生了巨大的影響。商業(yè)化與小型化掃除了一些思想體系上的障礙,使得架構(gòu)師能夠?qū)W⒂趩栴}本身,而不是尋找一些實用及可實現(xiàn)的問題解決方案。構(gòu)建10000個節(jié)點的處理引擎,能夠在數(shù)秒內(nèi)處理Pb級別的數(shù)據(jù)量,卻只消耗每小時幾便士,這就是數(shù)據(jù)處理的美好前景。

    有了這些新工具,我們就要重新考慮如何推進數(shù)據(jù)管理。為何數(shù)據(jù)無法被很好地被維護整合,并且需要花費數(shù)萬美元。數(shù)據(jù)管理幾乎是每個大中型企業(yè)的心病。數(shù)據(jù)管理曾經(jīng)在存儲、管理、訪問、整合以及查詢上花費巨大,但是今后不再會是這樣了。

    關(guān)于作者

    JP Morgenthal 是在IT策略與云計算方面的世界級專家之一。他在企業(yè)復(fù)雜問題域的解決方案實施上有著25年的經(jīng)驗。JP Morgenthal以其在技術(shù)方面的深度和廣度,有利的支持他在企業(yè)問題域中的敏感度。他在集成、軟件開發(fā)和云計算是一位讓人尊敬的作者,同時也是InfoQ在引領(lǐng)云計算方面的編輯,并且參與了“云計算:評估風(fēng)險”項目。 

     

    原文接:http://www.infoq.com/articles/DataIntegrationFromEIItoBigData

    posted @ 2012-04-19 07:15 一酌散千憂 閱讀(289) | 評論 (0)編輯 收藏

    項目經(jīng)理(Project manager)是項目的支柱與核心,維基百科的定義:項目經(jīng)理是項目管理方面的專家,負責(zé)項目的策劃、執(zhí)行和結(jié)束,即整個生命周期過程。項目經(jīng)理手中的“干將莫邪”便是軟件開發(fā)過程方法(software development process/software development life cycle (SDLC)),可能采取的有RUPRational Unified Process),敏捷等。

    其實軟件開發(fā)區(qū)分階段已經(jīng)廣為大家接受,普遍的概念即需要區(qū)分為分析、設(shè)計、實施、測試、發(fā)布,過程中會產(chǎn)生若干產(chǎn)物,如需求說明書、概要設(shè)計、詳細設(shè)計等。若提及過程方法,如RUP的話,主要分為四大階段,先啟(Inception)、精華(Elaboration)、構(gòu)建(Construction)、交付(Transition)迭代的開發(fā)方式,而Scrum的核心概念則是Sprint。

     

    Maven在項目管理中有那些幫助呢?Maven能夠從一個信息中心為項目提供構(gòu)建,報告,文檔編制等工作。在Maven官方介紹《What is maven》中介紹了maven的項目目標(Objectives)(http://maven.apache.org/what-is-maven.html),如下:

    l         簡化構(gòu)建過程

    l         提供統(tǒng)一的構(gòu)建系統(tǒng)

    l         提供項目質(zhì)量信息

    l         提供對于開發(fā)最佳實踐的指導(dǎo)

    l         允許對于新特性的透明整合

     

    對于Maven影響最為深刻的就是它的構(gòu)建系統(tǒng),幾乎貫穿了整個實施階段。作為對比我們參考一下RUPConstruction階段,以及Scrum的單個Sprint過程。

     

    RUPConstruction階段的目標:

    這個階段的目標是澄清需求并基于架構(gòu)基線完成開發(fā)。

    l          通過優(yōu)化資源來縮減開支,并避免無意義的爭執(zhí)與返工。

    l          實用性與質(zhì)量兼具。

    l          盡快發(fā)布可用版本。

    l          完成對所有功能的分析、設(shè)計、開發(fā)、測試。

    l          采用增量迭代的模式完成開發(fā)并準備交付。

    l          檢查項目發(fā)布的所有資源是否已經(jīng)準備完全。

    l          形成項目組之間的并行開發(fā)。

     

    在《硝煙中的ScrumXP》一書中,介紹了作者實施Scrum的過程。在一個Sprint中,不是只有Sprint backlog、burn down chat等,實施過程中的敏捷思想也是其中的核心,我們來看看敏捷信奉的一部分最佳實踐:

    l          簡單設(shè)計(Simple Design

    l          結(jié)對編程(Pair Programming

    l          測試驅(qū)動(Test-Driven Development

    l          小規(guī)模發(fā)布(Small Releases

    l          持續(xù)集成(Continuous Integration

    l          集體擁有代碼(Collective Code Ownership

    l          編碼標準(Coding Standard

     

    Maven對于上述目標中的質(zhì)量(實用性與質(zhì)量,以測試驅(qū)動)、可用(可用版本,小規(guī)模)、資源管理等均能發(fā)揮較大的作用。主要是其定義了一套完整優(yōu)秀的構(gòu)建生命周期機制,其基本階段如下:

    l         validate驗證項目正確性及依賴有效性

    l         compile編譯項目源碼

    l         test使用合適的單元測試框架對編譯后的源碼進行測試,測試代碼不會被打包或發(fā)布

    l         package將編譯后的代碼以規(guī)定格式打包,如Jar

    l         integration-test將打包后的代碼放置于環(huán)境中進行集成測試

    l         verify檢查打包的有效性并驗證質(zhì)量標準

    l         install將包裝載入本地倉庫,以提供與其他項目的依賴

    l         deploy將包發(fā)布至遠程倉庫中

    其上每一個階段實際都分為前中后三個階段,用戶可以定義在每一個階段前后進行自定義的操作,打造自己的構(gòu)建流程(如在某個階段執(zhí)行前制定特殊的配置文件,完成后再改回默認)。對于階段的實際使用方式,如:validate可以項目所有依賴有效,test可以針對dao層進行單元測試,intergration-test可以對完整業(yè)務(wù)流程或服務(wù)層等進行集成測試。

     

    在項目中實際使用的經(jīng)驗,對于標簽的使用心得:

    1.<dependency> - 依賴標簽,最重要的標簽,也是Maven的基礎(chǔ)功能。

                  <dependency>

                         <groupId>junit</groupId>

                         <artifactId>junit</artifactId>

                         <version>4.8.1</version>

                         <scope>test</scope>

                  </dependency>

     

    2. <repository> - 資源倉庫,可以包含多個,常用的有Maven,Jboss等,如下是公司內(nèi)建的Nexus資源庫。

    <repository>

                         <id>Suntang's Maven Repository</id>

                         <name>Suntang Nexus Repository</name>

                         <url>http://10.10.10.33:8081/nexus/content/groups/public</url>

                  </repository>

    3. <profile> - 解釋為情景模式可能較為合適。可以有多個,在何種場景下會使用哪些屬性、插件等。如下例子便是當(dāng)缺失某個文件時激活。

    (感覺寫的不錯的一篇,http://blog.csdn.net/turkeyzhou/article/details/4894657

    <profile>

     <activation>

    <file>

    <missing>target/generated-sources/axistools/wsdl2java/org/apache/maven</missing>

    </file>

    </activation>

     </profile>

    4.<build> - 構(gòu)建過程。是進行整個項目管理的核心標簽。重點需要掌握的知識就是生命周期。

    http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference

    下面的例子就是制定了打包時的資源路徑,并且定義了最終打包的名稱。

     

           <build>

                  <resources>

                         <resource>

                                <directory>src/main/resources</directory>

                                <includes>

                                       <include>**/*</include>

                                </includes>

                         </resource>

                         <resource>

                                <directory>src/main/assembly</directory>

                                <includes>

                                       <include>**/*</include>

                                </includes>

                         </resource>

                  </resources>

     

                  <finalName>po</finalName>

           </build>

     

    4.< plugin > - 支持插件。如單元測試自動化,之前提到的Ant的插件等。若有某些功能覺得不順手,可以嘗試官網(wǎng)找一下有沒有合適的插件(http://maven.apache.org/plugins/index.html)。

    下面的例子就是在集成測試中,只運行后綴為TestSuitex.java的測試類

     

                         <plugin>

                                <groupId>org.apache.maven.plugins</groupId>

                                <artifactId>maven-surefire-plugin</artifactId>

                                <version>2.4.3</version>

                                <configuration>

                                       <junitArtifactName>junit:junit</junitArtifactName>

                                       <forkMode>once</forkMode>

                                </configuration>

                                <executions>

                                       <execution>

                                              <id>default-test</id>

                                              <phase>integration-test</phase>

                                              <goals>

                                                     <goal>test</goal>

                                              </goals>

                                              <configuration>

                                                     <skip>false</skip>

                                                     <includes>

                                                            <include>**/*TestSuitex.java</include>

                                                     </includes>

                                              </configuration>

                                       </execution>

                                </executions>

                         </plugin>

     

    posted @ 2012-04-06 14:48 一酌散千憂 閱讀(495) | 評論 (0)編輯 收藏

    環(huán)境背景:

    我作為項目經(jīng)理和技術(shù)架構(gòu)管理人員負責(zé)公司一條生產(chǎn)線。討論之后,首席架構(gòu)師希望我們能夠?qū)嵤?/span>TDD。在實施TDD的過程中,設(shè)計實施過程的整體思路就是:單元測試用例文檔 - 實施單元測試 - 實施業(yè)務(wù)代碼修改業(yè)務(wù)代碼邏輯。實施人員需要參與每個環(huán)節(jié),按照規(guī)范編寫單元測試用例文檔。單元測試我們按照模塊(模塊與人員基本沒有重合)劃分包(suite),保證實施起來不會產(chǎn)生干擾。。技術(shù)架構(gòu)決定采用:maven,junitsvn

     

    技術(shù)背景:

    技術(shù)架構(gòu)設(shè)計上,我們封裝了dao層的實現(xiàn),所以實施人員基本無需涉及dao層的開發(fā)。服務(wù)層我們采用了JAX-RS的服務(wù)規(guī)范,對外開發(fā)服務(wù)接口。

    在測試覆蓋率方面,我們基本不要求對dao層的單元測試,但要求在服務(wù)層的單元測試達到100%。由于服務(wù)層是Restful WS的模式,所以我們采用了模擬HTTP請求的方式在測試服務(wù)層。

    由于需要模擬HTTP的請求,所以我們在單元測試中采用了jetty作為內(nèi)嵌服務(wù)器,單元測試開始時同一啟動,完成后關(guān)閉。

     

    實施過程:

    開發(fā)過程中,實際實施的時候發(fā)現(xiàn)一個問題,對于測試數(shù)據(jù)的管理問題。即測試當(dāng)中需要一定的數(shù)據(jù)環(huán)境來驗證業(yè)務(wù)邏輯。這個數(shù)據(jù)環(huán)境如何建立?

     

    方案一,使用dbunithsqldb。在測試啟動時重建數(shù)據(jù)環(huán)境。

    否決,原因:

    1.與實際運行環(huán)境差異較大。

    2.反復(fù)重建數(shù)據(jù)環(huán)境,效率上有缺失。

    3.技術(shù)架構(gòu)增加,學(xué)習(xí)和維護曲線較大。

     

    討論后決定使用

    方案二,獨立出一套測試數(shù)據(jù)庫,完整數(shù)據(jù)環(huán)境??紤]到增刪改與查詢的沖突,制定默認規(guī)則,如id20之內(nèi)的不允許進行任何改動。以盡量隔離增刪改的影響。

     

    針對方案二,有一個較大的問題,如何在開發(fā)過程中自由的切換數(shù)據(jù)庫配置呢?由于我們還是用了Hudson作為CI服務(wù)器,還要考慮到打包的過程。整體考慮之后,有兩個步驟需要注意:

    一、開發(fā)過程。開發(fā)過程中,我們將配置直接指向測試數(shù)據(jù)庫。

    二、打包過程。使用了maven,存在單元測試配置與最終產(chǎn)品配置的沖突。

    所以最終問題的焦點集中在打包過程的maven配置方案。

     

    搜索之后比較好的資料有

    MAVEN:如何為開發(fā)和生產(chǎn)環(huán)境建立不同的配置文件 --我的簡潔方案

    http://www.tkk7.com/scud/archive/2010/10/27/336326.html

    這篇博客是介紹在maven 中使用mvn package -P test 這樣的自定義profile來實現(xiàn)的。這樣是可行的,但是在Hudson中無法實現(xiàn)一條命令切換兩套配置。

    于是繼續(xù)尋找,最終在maven的官方網(wǎng)站找到《Building For Different Environments with Maven 2》(http://maven.apache.org/guides/mini/guide-building-for-different-environments.html)看完文章之后發(fā)現(xiàn),實際maven提供了一個非常好的插件maven-antrun-plugin,以實現(xiàn)某些ant的功能。此處還需要了解的知識就是maven的構(gòu)建生命周期標準(http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)。基于上述兩個知識點,我們制定出如下方案,在項目中建立測試配置目錄及產(chǎn)品配置目錄,在mavenpackage階段開始前,都使用測試配置,運行集成測試,完成在package階段前將產(chǎn)品配置覆蓋至打包文件夾內(nèi),然后進行打包。思路就是這樣,下面貼出pom文件的關(guān)鍵部分。

     

     

    POM.xml

    <!—profile 節(jié)點定義覆蓋文件的方式內(nèi)容 -->

           <profiles>

                  <profile>

                         <id>product</id>

                         <build>

                                <plugins>

                                       <plugin>

                                              <artifactId>maven-antrun-plugin</artifactId>

                                              <executions>

                                                     <execution>

                                                            <id>pre_product</id>

                                                            <phase>prepare-package</phase>

                                                            <goals>

                                                                   <goal>run</goal>

                                                            </goals>

                                                            <configuration>

    <!—此處與ant的任務(wù)相似 -->

                                                                   <tasks>

                                                                          <delete file="${project.build.outputDirectory}/spring/dataSourceContext.xml" />

                                                                          <delete file="${project.build.outputDirectory}/log4j.properties" />

                                                                          <copy file="src/product/assembly/log4j.properties" tofile="${project.build.outputDirectory}/log4j.properties" />

                                                                          <copy file="src/product/assembly/spring/dataSourceContext.xml" tofile="${project.build.outputDirectory}/spring/dataSourceContext.xml" />

                                                                   </tasks>

                                                            </configuration>

                                                     </execution>

                                              </executions>

                                       </plugin>

                                </plugins>

                         </build>

                  </profile>

           </profiles>

     

    <!—構(gòu)建過程 -->

           <build>

    <!—指定資源目錄 -->

                  <resources>

                         <resource>

                                <directory>src/test/resources</directory>

                                <includes>

                                       <include>**/*</include>

                                </includes>

                         </resource>

                         <resource>

                                <directory>src/test/assembly</directory>

                                <includes>

                                       <include>**/*</include>

                                </includes>

                         </resource>

                  </resources>

     

                  <finalName>po</finalName>

     

    <!—指定集成測試配置 -->

                  <plugins>

                         <plugin>

                                <groupId>org.apache.maven.plugins</groupId>

                                <artifactId>maven-surefire-plugin</artifactId>

                                <version>2.4.3</version>

                                <configuration>

                                       <junitArtifactName>junit:junit</junitArtifactName>

                                       <forkMode>once</forkMode>

                                </configuration>

                                <executions>

                                       <execution>

                                              <id>default-test</id>

                                              <phase>integration-test</phase>

                                              <goals>

                                                     <goal>test</goal>

                                              </goals>

                                              <configuration>

                                                     <skip>false</skip>

                                                     <includes>

                                                            <include>**/*TestSuitex.java</include>

                                                     </includes>

                                              </configuration>

                                       </execution>

                                </executions>

                         </plugin>

                  </plugins>

           </build>

    posted @ 2012-04-05 11:26 一酌散千憂 閱讀(1751) | 評論 (0)編輯 收藏

         摘要: Nosql企業(yè)之道 http://www.infoq.com/articles/nosql-in-the-enterprise   介紹 作為一個企業(yè)架構(gòu)師的好處,就是我一直在找一些新的有希望的概念或想法,能夠幫助我的企業(yè)用戶處理不同垂直行業(yè)之間的問題。甚至在NoSQL這個詞被杜撰(錯誤的杜撰?此處作者認為NoSQL這個詞并不恰當(dāng),后面會提到)出來之前,因為上述的原因我曾持續(xù)...  閱讀全文

    posted @ 2012-04-04 21:41 一酌散千憂 閱讀(373) | 評論 (0)編輯 收藏

    《Hadoop in action》Manning出版,磕磕絆絆總算是看完了。書的內(nèi)容就不做介紹,主要講一下實踐的過程。并且在實踐過程中參考的書籍的部分也會簡單介紹。

    灰色背景部分為一些介紹,或過程中出現(xiàn)問題的描述,可以直接忽略。

    由于公司的業(yè)務(wù)需要,要在網(wǎng)絡(luò)收集網(wǎng)頁之后對網(wǎng)頁進行結(jié)構(gòu)化的解析,這個結(jié)構(gòu)化過程希望能夠基于HDFS并且使用MR算法實現(xiàn)。

    我虛擬了一個需求,針對http://hadoop.apache.org/common/releases.html 頁面,假設(shè)已經(jīng)下載了頁面并入庫。要求最終體現(xiàn)的數(shù)據(jù)是 “版本號+完整鏈接(即a標簽全部內(nèi)容)” 的結(jié)構(gòu)。

     

    偽分布式環(huán)境搭建在虛擬機上,操作系統(tǒng)是centos5.5,hadoop的版本是1.0.0.

     

    插入書中的一些環(huán)境搭建的介紹

    書中的2.1節(jié)中介紹了每個進程的作用。2.2節(jié)中的ssh設(shè)置也比較重要,否則好像會一直提示你輸入密碼。2.3.2節(jié)介紹了偽分布式的配置方式,對core-site.xml,mapred-site.xmlhdfs-site.xml進行配置之后,需要對namenode節(jié)點進行格式化。

    bin/hadoop namenode –format

     

    hadoop的根目錄為/usr/local/hadoop-1.0.0,直接啟動start-all.sh

     

    [root@localhost hadoop-1.0.0]# ./bin/start-all.sh

     

    啟動成功后使用jps命令

    jdk小工具jps介紹 

    jps(Java Virtual Machine Process Status Tool)JDK 1.5提供的一個顯示當(dāng)前所有java進程pid的命令,簡單實用,非常適合在linux/unix平臺上簡單察看當(dāng)前java進程的一些簡單情況。 jps存放在JAVA_HOME/bin/jps

     

    [root@localhost hadoop-1.0.0]# jps

    5694 SecondaryNameNode

    5461 NameNode

    5578 DataNode

    6027 Jps

    5784 JobTracker

    5905 TaskTracker

    這幾個進程是非常重要的。很多時候出現(xiàn)意外就是因為某項服務(wù)未啟動或異常??梢钥吹缴厦娴拿钌洗蛴〕鋈罩疚恢?。出現(xiàn)異常后可以在日志中查看詳細的堆棧信息。

     

    至此,hadoop已經(jīng)啟動,環(huán)境已經(jīng)準備就緒。

     

    下面準備我們的測試數(shù)據(jù),將目標頁面的html保存為news.txt,偽分布式也同樣支持hdfs,所以我們使用 fs –put news.txt存入hdfs中。

    [root@localhost hadoop-1.0.0]# ./bin/hadoop fs -put /mnt/hgfs/shared/news.txt /user/root

    [root@localhost hadoop-1.0.0]# ./bin/hadoop fs -lsr /userdrwxr-xr-x   - root supergroup          0 2012-04-01 11:22 /user/root

    -rw-r--r--   1 root supergroup       3935 2012-04-01 11:22 /user/root/news.txt

     

    實現(xiàn)的代碼在eclipse中使用maven打包,上傳至虛擬機。

    文件名com.suntang.analyse.hadoop-0.0.1.jar。
    使用hadoop的中的jar命令調(diào)用該jar文件。


    [root@localhost hadoop-1.0.0]# ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar com.suntang.analyse.hadoop.AnalyseJob /user/root/news.txt output_root_test

    12/04/01 14:40:04 INFO input.FileInputFormat: Total input paths to process : 1

    12/04/01 14:40:05 INFO mapred.JobClient: Running job: job_201204011420_0001

    12/04/01 14:40:06 INFO mapred.JobClient:  map 0% reduce 0%

    12/04/01 14:40:19 INFO mapred.JobClient:  map 100% reduce 0%

    12/04/01 14:40:31 INFO mapred.JobClient:  map 100% reduce 100%

    12/04/01 14:40:37 INFO mapred.JobClient: Job complete: job_201204011420_0001

     

     

    此處注意我犯的一個錯誤:

    [root@localhost hadoop-1.0.0]# ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar AnalyseJob -libjars hadoop-core-1.0.0.jar /user/root/news.txt output_root_test

    Exception in thread "main" java.lang.ClassNotFoundException: AnalyseJob

    提示找不到類,因為我忘了寫完整類名,命令應(yīng)該改為

    ./bin/hadoop jar com.suntang.analyse.hadoop-0.0.1.jar com.suntang.analyse.hadoop.AnalyseJob -libjars hadoop-core-1.0.0.jar /user/root/news.txt output_root_test 即可。

     

    此處運行可能出現(xiàn)另外一個錯誤。在命令行中出現(xiàn)

    12/04/01 14:01:38 INFO mapred.JobClient: Task Id : attempt_201204011356_0001_m_000001_0, Status : FAILED

    java.lang.Throwable: Child Error

            at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271)

    Caused by: java.io.IOException: Creation of symlink from /mnt/hgfs/shared/hadoop-1.0.0/libexec/../logs/userlogs/job_201204011356_0001/attempt_201204011356_0001_m_000001_0 to 。。。

    就不打全了,重點在與

    Creation of symlink,看詳細日志中hadoop-root-tasktracker-localhost.localdomain.log中提示org.apache.hadoop.fs.FileUtil: Command 'ln -s ....': Operation not supported,即ln操作不支持。google可知這個是由于vm中的共享區(qū)域的問題,解決方法就是將hadoop完全轉(zhuǎn)移至linux目錄中。本例中從/mnt/hgfs/shared/hadoop-1.0.0轉(zhuǎn)移至/usr/local/hadoop-1.0.0

     

    執(zhí)行完成后可在hdfs中查看結(jié)果,查看目錄結(jié)構(gòu)為

    -rw-r--r--   1 root supergroup          0 2012-04-01 14:40 /user/root/output_root_test/_SUCCESS

    drwxr-xr-x   - root supergroup          0 2012-04-01 14:40 /user/root/output_root_test/_logs

    drwxr-xr-x   - root supergroup          0 2012-04-01 14:40 /user/root/output_root_test/_logs/history

    -rw-r--r--   1 root supergroup      13634 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_1333262405103_root_ccAnalyseJob

    -rw-r--r--   1 root supergroup      20478 2012-04-01 14:40 /user/root/output_root_test/_logs/history/job_201204011420_0001_conf.xml

    -rw-r--r--   1 root supergroup       3580 2012-04-01 14:40 /user/root/output_root_test/part-r-00000

     

    /user/root/output_root_test/part-r-00000即為最終結(jié)果文件。

     

     =======================================================================

    附加AnalyseJob代碼

    package com.suntang.analyse.hadoop;

     

    import java.io.IOException;

     

    import org.apache.hadoop.conf.Configuration;

    import org.apache.hadoop.conf.Configured;

    import org.apache.hadoop.fs.Path;

    import org.apache.hadoop.io.LongWritable;

    import org.apache.hadoop.io.Text;

    import org.apache.hadoop.mapreduce.Job;

    import org.apache.hadoop.mapreduce.Mapper;

    import org.apache.hadoop.mapreduce.Reducer;

    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

    import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;

    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

    import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

    import org.apache.hadoop.util.Tool;

    import org.apache.hadoop.util.ToolRunner;

     

    public class AnalyseJob extends Configured implements Tool {

     

           public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {

     

                  @Override

                  protected void map(LongWritable key, Text value, Context context)

                                throws IOException, InterruptedException {

                        

                        

                         // TODO Auto-generated method stub

                         // super.map(key, value, context);

                         if (value.toString().matches("<a[^>]*>.*?release.*?</a>"))

                                context.write(

                                              new Text(value.toString().substring(

                                                            value.toString().indexOf("release") + 8,

                                                            value.toString().indexOf("available") - 1)),

                                              value);

                  }

     

           }

     

           public static class ReduceClass extends Reducer<Text, Text, Text, Text> {

     

                  @Override

                  protected void reduce(Text arg0, Iterable<Text> arg1, Context arg2)

                                throws IOException, InterruptedException {

                         // TODO Auto-generated method stub

                         // super.reduce(arg0, arg1, arg2);

                         arg2.write(arg0, arg1.iterator().next());

                  }

     

           }

     

           public int run(String[] args) throws Exception {

                  Configuration conf = getConf();

     

                  Job job = new Job(conf, "myAnalyseJob");

                  job.setJarByClass(getClass());

     

                  Path in = new Path(args[0]);

                  Path out = new Path(args[1]);

                  FileInputFormat.setInputPaths(job, in);

                  FileOutputFormat.setOutputPath(job, out);

     

                  job.setMapperClass(MapClass.class);

                  job.setReducerClass(ReduceClass.class);

     

                  job.setInputFormatClass(TextInputFormat.class);

                  job.setOutputFormatClass(TextOutputFormat.class);

                  job.setOutputKeyClass(Text.class);

                  job.setOutputValueClass(Text.class);

     

                  System.exit(job.waitForCompletion(true) ? 0 : 1);

     

                  return 0;

           }

     

           public static void main(String[] args) throws Exception {

                  int res = ToolRunner.run(new Configuration(), new AnalyseJob(), args);

                  System.exit(res);

           }

    }

    posted @ 2012-04-01 15:00 一酌散千憂 閱讀(916) | 評論 (0)編輯 收藏

    僅列出標題
    共2頁: 1 2 下一頁 
    主站蜘蛛池模板: 今天免费中文字幕视频| 免费无遮挡无码视频网站| 亚洲电影日韩精品 | 成年免费大片黄在线观看岛国 | 日韩在线永久免费播放| 亚洲色婷婷综合开心网| 亚洲人精品亚洲人成在线| 久草免费福利视频| 亚洲av区一区二区三| 亚洲综合偷自成人网第页色| 久久精品乱子伦免费| 亚洲国产精品一区二区第一页免 | 亚洲久热无码av中文字幕| 84pao强力永久免费高清| 国产综合精品久久亚洲| 国产成人不卡亚洲精品91| 免费精品国偷自产在线在线| 亚洲avav天堂av在线不卡| a毛片成人免费全部播放| 四虎永久成人免费| 国产AV旡码专区亚洲AV苍井空| 95老司机免费福利| 精品亚洲综合久久中文字幕| 污视频网站免费在线观看| 免费黄色一级毛片| 亚洲日韩国产精品乱-久| 无码乱肉视频免费大全合集| 亚洲黄色三级视频| 免费国产成人α片| 亚洲精品无码专区在线在线播放 | a级毛片高清免费视频就| 国产成人精品久久亚洲| 黄色一级免费网站| 四虎免费久久影院| 亚洲AV成人一区二区三区观看 | 亚洲最大成人网色| 久久这里只精品热免费99| 亚洲成AV人片在线观看ww| 免费久久人人爽人人爽av| 亚洲人成在线播放网站| 国产又黄又爽胸又大免费视频|