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

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

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

    posts - 28, comments - 37, trackbacks - 0, articles - 0

    2011年7月3日


    淘寶招聘hadoop工程師若干, 面向在校生(2014年畢業(yè)),工作地點(diǎn):杭州或北京

    Hadoop研發(fā)工程師
    職位描述
    您將負(fù)責(zé):
    1.預(yù)研、開發(fā)、測(cè)試hdfs/mapreduce/hive/hbase的功能、性能和擴(kuò)展;
    2.對(duì)有助于提升集群處理能力/高可用性/高擴(kuò)展性的各種解決方案進(jìn)行跟蹤和落地;
    3.解決海量數(shù)據(jù)不斷增長(zhǎng)面臨的挑戰(zhàn),解決業(yè)務(wù)需求。

    您需要具備:
    1、熟練運(yùn)用java語(yǔ)言;
    2、熟悉jvm運(yùn)行機(jī)制、熟悉linux;
    3、至少熟悉hadoop、hbase、hive等軟件之一;

     

    有意者請(qǐng)發(fā)送郵件到 yuling.sh@taobao.com 

    posted @ 2013-09-15 18:21 俞靈 閱讀(962) | 評(píng)論 (1)編輯 收藏


    mapreduce,一個(gè)jobmap個(gè)數(shù), 每個(gè)map處理的數(shù)據(jù)量是如何決定的呢? 另外每個(gè)map又是如何讀取輸入文件的內(nèi)容呢? 用戶是否可以自己決定輸入方式, 決定map個(gè)數(shù)呢? 這篇文章將詳細(xì)講述hadoop中各種InputFormat的功能和如何編寫自定義的InputFormat.

     

    簡(jiǎn)介: mapreduce作業(yè)會(huì)根據(jù)輸入目錄產(chǎn)生多個(gè)map任務(wù), 通過(guò)多個(gè)map任務(wù)并行執(zhí)行來(lái)提高作業(yè)運(yùn)行速度, 但如果map數(shù)量過(guò)少, 并行量低, 作業(yè)執(zhí)行慢, 如果map數(shù)過(guò)多, 資源有限, 也會(huì)增加調(diào)度開銷. 因此, 根據(jù)輸入產(chǎn)生合理的map數(shù), 為每個(gè)map分配合適的數(shù)據(jù)量, 能有效的提升資源利用率, 并使作業(yè)運(yùn)行速度加快.

        mapreduce, 每個(gè)作業(yè)都會(huì)通過(guò) InputFormat來(lái)決定map數(shù)量. InputFormat是一個(gè)接口, 提供兩個(gè)方法:

    InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;

    RecordReader<K, V> getRecordReader(InputSplit split,

                                         JobConf job,

                                         Reporter reporter) throws IOException;

        其中getSplits方法會(huì)根據(jù)輸入目錄產(chǎn)生InputSplit數(shù)組, 每個(gè)InputSplit會(huì)相應(yīng)產(chǎn)生一個(gè)map任務(wù), map的輸入定義在InputSplit. getRecordReader方法返回一個(gè)RecordReader對(duì)象, RecordReader決定了map任務(wù)如何讀取輸入數(shù)據(jù), 例如一行一行的讀取還是一個(gè)字節(jié)一個(gè)字節(jié)的讀取, 等等.

        下圖是InputFormat的實(shí)現(xiàn)類:

           (暫時(shí)無(wú)法上傳)

        這理詳細(xì)介紹FileInputFormatCombineFileInputFormat, 其它不常用,有興趣的可以自己查看hadoop源碼.


     

    FileInputFormat(舊接口org.apache.hadoop.mapred)

     

    mapreduce默認(rèn)使用TextInputFormatTextInputFormat沒(méi)有實(shí)現(xiàn)自己的getSplits方法,繼承于FileInputFormat, 因此使用了FileInputFormat的.

    org.apache.hadoop.mapred.FileInputFormatgetSplits流程:

    兩個(gè)配置

    mapred.min.split.size        (一個(gè)map最小輸入長(zhǎng)度),

    mapred.map.tasks                (推薦map數(shù)量)

    如何決定每個(gè)map輸入長(zhǎng)度呢? 首先獲取輸入目錄下所有文件的長(zhǎng)度和, 除以mapred.map.tasks得到一個(gè)推薦長(zhǎng)度goalSize, 然后通過(guò)式子: Math.max(minSize, Math.min(goalSize, blockSize))決定map輸入長(zhǎng)度. 這里的minSizemapred.min.split.size, blockSize為相應(yīng)文件的block長(zhǎng)度. 這式子能保證一個(gè)map的輸入至少大于mapred.min.split.size, 對(duì)于推薦的map長(zhǎng)度,只有它的長(zhǎng)度小于blockSize且大于mapred.min.split.size才會(huì)有效果. 由于mapred.min.split.size默認(rèn)長(zhǎng)度為1, 因此通常情況下只要小于blockSize就有效果,否則使用blockSize做為map輸入長(zhǎng)度.

    因此, 如果想增加map數(shù), 可以把mapred.min.split.size調(diào)小(其實(shí)默認(rèn)值即可), 另外還需要把mapred.map.tasks設(shè)置大.

    如果需要減少map數(shù),可以把mapred.min.split.size調(diào)大, 另外把mapred.map.tasks調(diào)小.

    這里要特別指出的是FileInputFormat會(huì)讓每個(gè)輸入文件至少產(chǎn)生一個(gè)map任務(wù), 因此如果你的輸入目錄下有許多文件, 而每個(gè)文件都很小, 例如幾十kb, 那么每個(gè)文件都產(chǎn)生一個(gè)map會(huì)增加調(diào)度開銷. 作業(yè)變慢.

    那么如何防止這種問(wèn)題呢? CombineFileInputFormat能有效的減少map數(shù)量.


    FileInputFormat(新接口org.apache.hadoop.mapreduce.lib.input)

    Hadoop 0.20開始定義了一套新的mapreduce編程接口, 使用新的FileInputFormat, 它與舊接口下的FileInputFormat主要區(qū)別在于, 它不再使用mapred.map.tasks, 而使用mapred.max.split.size參數(shù)代替goalSize, 通過(guò)Math.max(minSize, Math.min(maxSize, blockSize))決定map輸入長(zhǎng)度, 一個(gè)map的輸入要大于minSize,小于

    Math.min(maxSize, blockSize).

        若需增加map數(shù),可以把mapred.min.split.size調(diào)小,mapred.max.split.size調(diào)大. 若需減少map數(shù), 可以把mapred.min.split.size調(diào)大, 并把mapred.max.split.size調(diào)小.


    CombineFileInputFormat

    顧名思義, CombineFileInputFormat的作用是把許多文件合并作為一個(gè)map的輸入.

    在它之前,可以使用MultiFileInputFormat,不過(guò)其功能太簡(jiǎn)單, 以文件為單位,一個(gè)文件至多分給一個(gè)map處理, 如果某個(gè)目錄下有許多小文件, 另外還有一個(gè)超大文件, 處理大文件的map會(huì)嚴(yán)重偏慢.

    CombineFileInputFormat是一個(gè)被推薦使用的InputFormat. 它有三個(gè)配置:

    mapred.min.split.size.per.node 一個(gè)節(jié)點(diǎn)上split的至少的大小

    mapred.min.split.size.per.rack   一個(gè)交換機(jī)下split至少的大小

    mapred.max.split.size             一個(gè)split最大的大小

    它的主要思路是把輸入目錄下的大文件分成多個(gè)map的輸入, 并合并小文件, 做為一個(gè)map的輸入. 具體的原理是下述三步:

    1.根據(jù)輸入目錄下的每個(gè)文件,如果其長(zhǎng)度超過(guò)mapred.max.split.size,block為單位分成多個(gè)split(一個(gè)split是一個(gè)map的輸入),每個(gè)split的長(zhǎng)度都大于mapred.max.split.size, 因?yàn)橐?/span>block為單位, 因此也會(huì)大于blockSize, 此文件剩下的長(zhǎng)度如果大于mapred.min.split.size.per.node, 則生成一個(gè)split, 否則先暫時(shí)保留.

    2. 現(xiàn)在剩下的都是一些長(zhǎng)度效短的碎片,把每個(gè)rack下碎片合并, 只要長(zhǎng)度超過(guò)mapred.max.split.size就合并成一個(gè)split, 最后如果剩下的碎片比mapred.min.split.size.per.rack, 就合并成一個(gè)split, 否則暫時(shí)保留.

    3. 把不同rack下的碎片合并, 只要長(zhǎng)度超過(guò)mapred.max.split.size就合并成一個(gè)split, 剩下的碎片無(wú)論長(zhǎng)度, 合并成一個(gè)split.

    舉例: mapred.max.split.size=1000

         mapred.min.split.size.per.node=300

          mapred.min.split.size.per.rack=100

    輸入目錄下五個(gè)文件,rack1下三個(gè)文件,長(zhǎng)度為2050,1499,10, rack2下兩個(gè)文件,長(zhǎng)度為1010,80. 另外blockSize500.

    經(jīng)過(guò)第一步, 生成五個(gè)split: 1000,1000,1000,499,1000. 剩下的碎片為rack1:50,10; rack210:80

    由于兩個(gè)rack下的碎片和都不超過(guò)100, 所以經(jīng)過(guò)第二步, split和碎片都沒(méi)有變化.

    第三步,合并四個(gè)碎片成一個(gè)split, 長(zhǎng)度為150.

     

    如果要減少map數(shù)量, 可以調(diào)大mapred.max.split.size, 否則調(diào)小即可.

    其特點(diǎn)是: 一個(gè)塊至多作為一個(gè)map的輸入,一個(gè)文件可能有多個(gè)塊,一個(gè)文件可能因?yàn)閴K多分給做為不同map的輸入, 一個(gè)map可能處理多個(gè)塊,可能處理多個(gè)文件。


    編寫自己的InputFormat

     

        待續(xù)


     

    posted @ 2012-07-03 22:17 俞靈 閱讀(16472) | 評(píng)論 (2)編輯 收藏

    Yarn做為hadoop下一代集群資源管理和調(diào)度平臺(tái), 其上能支持多種計(jì)算框架, 本文就簡(jiǎn)要介紹一下這些計(jì)算框架.


    1.       MapReduce

    首先是大家熟悉的mapreduce, MR2之前, hadoop包括HDFSmapreduce, 做為hadoop上唯一的分布式計(jì)算框架, 其優(yōu)點(diǎn)是用戶可以很方便的編寫分布式計(jì)算程序, 并支持許多的應(yīng)用, hive, mahout, pig. 但是其缺點(diǎn)是無(wú)法充分利用集群資源, 不支持DAG, 迭代式計(jì)算等. 為了解決這些問(wèn)題, yahoo提出了Yarn (next generation mapreduce), 一個(gè)分布式集群集群資源管理和調(diào)度平臺(tái). 這樣除了mapreduce, 還可以支持各種計(jì)算框架.

    2.       Spark

    Spark是一種與mapreduce相似的開源計(jì)算框架, 不同之處在于Spark在某些工作負(fù)載方面表現(xiàn)更優(yōu), 因?yàn)樗褂昧藘?nèi)存分布式數(shù)據(jù)集, 另外除了提供交互式查詢外, 它還可以優(yōu)化迭代工作負(fù)載.

    3.       Apache HAMA

    Apache Hama 是一個(gè)運(yùn)行在HDFS上的BSP(Bulk Synchronous Parallel大容量同步并行) 計(jì)算框架, 主要針對(duì)大規(guī)模科學(xué)計(jì)算,如矩陣, 圖像, 網(wǎng)絡(luò)算法等.當(dāng)前它有一下功能:

    • 作業(yè)提交和管理接口
    • 單節(jié)點(diǎn)上運(yùn)行多個(gè)任務(wù)
    • 輸入/輸出格式化
    • 備份恢復(fù)
    • 支持通過(guò)Apache Whirr運(yùn)行在云端
    • 支持與Yarn一起運(yùn)行

    4.       Apache Giraph

    圖像處理平臺(tái)上運(yùn)行這大型算法(page rank, shared connections, personalization-based popularity )已經(jīng)很流行, Giraph采用BSP模型(bulk-synchronous parallel model),可用于等迭代類算法。

    5.       Open MPI

    這是一個(gè)高性能計(jì)算函數(shù)庫(kù),通常在HPCHigh Performance Computing)中采用,與MapReduce相比,其性能更高,用戶可控性更強(qiáng),但編程復(fù)雜,容錯(cuò)性差,可以說(shuō),各有所長(zhǎng),在實(shí)際應(yīng)用中,針對(duì)不同 該應(yīng)用會(huì)采用MPI或者MapReduce

    6.       Apache HBase

    HBase是一個(gè)hadoop數(shù)據(jù)庫(kù), 其特點(diǎn)是分布式,可擴(kuò)展的,存儲(chǔ)大數(shù)據(jù)。當(dāng)有需要隨機(jī),實(shí)時(shí)讀寫的大數(shù)據(jù)時(shí), 使用HBase很適合.

    本文參考:

    http://wiki.apache.org/hadoop/PoweredByYarn
    http://www.oschina.net/p/open+mpi

    http://incubator.apache.org/hama/
    http://incubator.apache.org/giraph/

    http://hbase.apache.org/

    posted @ 2012-06-03 11:43 俞靈 閱讀(3663) | 評(píng)論 (0)編輯 收藏

    轉(zhuǎn)載
    http://fujun.sinaapp.com/2011/11/02/68.html

    第一步,打開終端,看看你的顯卡Ubuntu能認(rèn)出多少顯示分辨率設(shè)置,輸入命令

    wufujun@wufujun-VirtualBox:~$ xrandr

    系統(tǒng)給出的結(jié)果

    Screen 0: minimum 64 x 64, current 1024 x 768, maximum 32000 x 32000
    VBOX0 connected 1024×768+0+0 0mm x 0mm
    1024×768 60.0 + 60.0
    1600×1200 60.0
    1440×1050 60.0
    1280×960 60.0
    800×600 60.0
    640×480 60.0

    這里可以看到,沒(méi)有16:9的的分辨率設(shè)置

    第二步,用cvt命令測(cè)試1368×768是否可用

    wufujun@wufujun-VirtualBox:~$ cvt 1368 768

    顯示結(jié)果如下
    # 1368×768 59.88 Hz (CVT) hsync: 47.79 kHz; pclk: 85.86 MHz
    Modeline “1368x768_60.00″ 85.25 1368 1440 1576 1784 768 771 781 798 -hsync +vsync

    從這個(gè)結(jié)果里可以到,16:9的分辨率是可以用的

    第三步 輸入

    wufujun@wufujun-VirtualBox:~$ sudo xrandr --newmode "1368x768" 85.86 1368 1440 1576 1784 768 771 781 798 -hsync +vsync

    建立新的分辨率模式1368×768,把剛才cvt得到的數(shù)據(jù)寫進(jìn)參數(shù)

    第四步 繼續(xù)輸入

    sudo xrandr --addmode VBOX0 "1368x768"

    給當(dāng)前顯示器VBOX0增加1368×768分辨率設(shè)置

    做完以上操作后,可以在”顯示“設(shè)置里面看到顯示的分辨率列表中多了一個(gè) 1368×768(16:9)的選項(xiàng)。選中這個(gè)選項(xiàng),點(diǎn)擊應(yīng)用,完美的寬屏顯示回來(lái)了!

    經(jīng)過(guò)測(cè)試,上面的方法做完以后,每次注銷后就又變回了4:3的比例,而且會(huì)有的報(bào)錯(cuò),沒(méi)辦法,按上面的修改完畢后,還要再修改一下/etc/X11/xorg.conf這個(gè)文件,這個(gè)配置文件在現(xiàn)在的版里已經(jīng)取消了,所以需要我們新建一個(gè)


    $ sudo gedit /etc/X11/xorg.conf

    編輯內(nèi)容為:

    Section "Device"
    Identifier "Configured Video Device"
    EndSection

    Section "Monitor"
    Identifier "Configured Monitor"
    Modeline "1368x768_60.00" 85.86 1368 1440 1584 1800 768 769 772 795 -HSync +Vsync
    EndSection

    Section "Screen"
    Identifier "Default Screen"
    Monitor "Configured Monitor"
    Device "Configured Video Device"
    SubSection "Display"
    Modes "1368x768@60"
    EndSubSection
    EndSection

    其中 Modeline “1368x768_60.00″ 85.86 1368 1440 1584 1800 768 769 772 795 -HSync +Vsync 就是用$ cvt 1368 768得到的值。也可以用$ gtf 1368 768 60命令來(lái)得到這個(gè)Modeline的值,這個(gè)命令中,1368 768是分辨率 60為刷新率,用這個(gè)命令得到的值可能會(huì)更為準(zhǔn)確一些。

    SubSection "Display"
    Modes "1368x768@60"
    EndSubSection

    這段是設(shè)置默認(rèn)顯示最佳分辨率。

    注意這段文件中的一些規(guī)則

    Section “Device”區(qū)塊中,Identifier指定了顯卡的唯一名稱,這個(gè)名稱可以隨便取,但一定要與Section “Screen”區(qū)塊中的device選項(xiàng)中的名稱相同。在Section “Monitor”區(qū)塊中,Identifier指定了顯示器的唯一名稱,這個(gè)名稱可以隨便取,但一定要與Section “Screen”區(qū)塊中的Monitor選項(xiàng)中所指定的名稱相同。Section “Screen”區(qū)塊中的Identifier選項(xiàng),指定了這個(gè)顯卡與顯示器相結(jié)合的唯一名稱。這個(gè)名稱也可以隨便取的。這個(gè)名稱需要與Section “ServerLayout” 區(qū)塊中的名稱相同。這個(gè)Section “ServerLayout” 區(qū)塊我們一般不必編寫

    posted @ 2012-05-24 14:46 俞靈 閱讀(2886) | 評(píng)論 (0)編輯 收藏

         摘要:      最近這些天學(xué)習(xí)了classLoader的原理, 原因是因?yàn)榉?wù)器上的一個(gè)java進(jìn)程啟動(dòng)時(shí)加載兩個(gè)不同版本的jar包, 含有相同名字的類, 而且服務(wù)端的jar包排在前面, 我上傳的jar包排在后面, 于是每次都使用服務(wù)端的jar包, 我的jar包便無(wú)法生效, 因此希望修改classLader, 讓它按相反的順序加載jar包.  ...  閱讀全文

    posted @ 2012-05-20 19:43 俞靈 閱讀(5666) | 評(píng)論 (1)編輯 收藏

         摘要: High Availability for the HDFS Namenode Sanjay Radia, Suresh Srinivas Yahoo! Inc  (本文為namdnoe HA的設(shè)計(jì)文檔翻譯) 1.       問(wèn)題闡述 有許多方法可以改善HDFS Namednoe(NN)的可用性,包括減少啟動(dòng)時(shí)間,更...  閱讀全文

    posted @ 2012-03-24 21:38 俞靈 閱讀(3212) | 評(píng)論 (2)編輯 收藏

    本文轉(zhuǎn)自:
    http://blog.csdn.net/zhouysh/article/details/304767

    JAVA代碼編寫的30條建議
    (1) 類名首字母應(yīng)該大寫。字段、方法以及對(duì)象(句柄)的首字母應(yīng)小寫。對(duì)于所有標(biāo)識(shí)符,其中包含的所有單詞都應(yīng)緊靠在一起,而且大寫中間單詞的首字母。例如:
    ThisIsAClassName
    thisIsMethodOrFieldName
    若在定義中出現(xiàn)了常數(shù)初始化字符,則大寫static final基本類型標(biāo)識(shí)符中的所有字母。這樣便可標(biāo)志出它們屬于編譯期的常數(shù)。
    Java包(Package)屬于一種特殊情況:它們?nèi)际切懽帜福幢阒虚g的單詞亦是如此。對(duì)于域名擴(kuò)展名稱,如com,org,net或者edu等,全部都應(yīng)小寫(這也是Java 1.1和Java 1.2的區(qū)別之一)。

    (2) 為了常規(guī)用途而創(chuàng)建一個(gè)類時(shí),請(qǐng)采取"經(jīng)典形式",并包含對(duì)下述元素的定義:

    equals()
    hashCode()
    toString()
    clone()(implement Cloneable)
    implement Serializable

    (3) 對(duì)于自己創(chuàng)建的每一個(gè)類,都考慮置入一個(gè)main(),其中包含了用于測(cè)試那個(gè)類的代碼。為使用一個(gè)項(xiàng)目中的類,我們沒(méi)必要?jiǎng)h除測(cè)試代碼。若進(jìn)行了任何形式的改動(dòng),可方便地返回測(cè)試。這些代碼也可作為如何使用類的一個(gè)示例使用。

    (4) 應(yīng)將方法設(shè)計(jì)成簡(jiǎn)要的、功能性單元,用它描述和實(shí)現(xiàn)一個(gè)不連續(xù)的類接口部分。理想情況下,方法應(yīng)簡(jiǎn)明扼要。若長(zhǎng)度很大,可考慮通過(guò)某種方式將其分割成較短的幾個(gè)方法。這樣做也便于類內(nèi)代碼的重復(fù)使用(有些時(shí)候,方法必須非常大,但它們?nèi)詰?yīng)只做同樣的一件事情)。

    (5) 設(shè)計(jì)一個(gè)類時(shí),請(qǐng)?jiān)O(shè)身處地為客戶程序員考慮一下(類的使用方法應(yīng)該是非常明確的)。然后,再設(shè)身處地為管理代碼的人考慮一下(預(yù)計(jì)有可能進(jìn)行哪些形式的修改,想想用什么方法可把它們變得更簡(jiǎn)單)。
    (6) 使類盡可能短小精悍,而且只解決一個(gè)特定的問(wèn)題。下面是對(duì)類設(shè)計(jì)的一些建議:
    ■一個(gè)復(fù)雜的開關(guān)語(yǔ)句:考慮采用"多形"機(jī)制
    ■數(shù)量眾多的方法涉及到類型差別極大的操作:考慮用幾個(gè)類來(lái)分別實(shí)現(xiàn)
    ■許多成員變量在特征上有很大的差別:考慮使用幾個(gè)類

    (7) 讓一切東西都盡可能地"私有"--private。可使庫(kù)的某一部分"公共化"(一個(gè)方法、類或者一個(gè)字段等等),就永遠(yuǎn)不能把它拿出。若強(qiáng)行拿出,就可 能破壞其他人現(xiàn)有的代碼,使他們不得不重新編寫和設(shè)計(jì)。若只公布自己必須公布的,就可放心大膽地改變其他任何東西。在多線程環(huán)境中,隱私是特別重要的一個(gè) 因素--只有private字段才能在非同步使用的情況下受到保護(hù)。

    (8) 謹(jǐn)惕"巨大對(duì)象綜合癥"。對(duì)一些習(xí)慣于順序編程思維、且初涉OOP領(lǐng)域的新手,往往喜歡先寫一個(gè)順序執(zhí)行的程序,再把它嵌入一個(gè)或兩個(gè)巨大的對(duì)象里。根據(jù)編程原理,對(duì)象表達(dá)的應(yīng)該是應(yīng)用程序的概念,而非應(yīng)用程序本身。

    (9) 若不得已進(jìn)行一些不太雅觀的編程,至少應(yīng)該把那些代碼置于一個(gè)類的內(nèi)部。

    (10) 任何時(shí)候只要發(fā)現(xiàn)類與類之間結(jié)合得非常緊密,就需要考慮是否采用內(nèi)部類,從而改善編碼及維護(hù)工作(參見(jiàn)第14章14.1.2小節(jié)的"用內(nèi)部類改進(jìn)代碼")。

    (11) 盡可能細(xì)致地加上注釋,并用javadoc注釋文檔語(yǔ)法生成自己的程序文檔。

    (12) 避免使用"魔術(shù)數(shù)字",這些數(shù)字很難與代碼很好地配合。如以后需要修改它,無(wú)疑會(huì)成為一場(chǎng)噩夢(mèng),因?yàn)楦静恢?100"到底是指"數(shù)組大小"還是"其他 全然不同的東西"。所以,我們應(yīng)創(chuàng)建一個(gè)常數(shù),并為其使用具有說(shuō)服力的描述性名稱,并在整個(gè)程序中都采用常數(shù)標(biāo)識(shí)符。這樣可使程序更易理解以及更易維護(hù)。

    (13) 涉及構(gòu)建器和異常的時(shí)候,通常希望重新丟棄在構(gòu)建器中捕獲的任何異常--如果它造成了那個(gè)對(duì)象的創(chuàng)建失敗。這樣一來(lái),調(diào)用者就不會(huì)以為那個(gè)對(duì)象已正確地創(chuàng)建,從而盲目地繼續(xù)。

    (14) 當(dāng)客戶程序員用完對(duì)象以后,若你的類要求進(jìn)行任何清除工作,可考慮將清除代碼置于一個(gè)良好定義的方法里,采用類似于cleanup()這樣的名字,明確表 明自己的用途。除此以外,可在類內(nèi)放置一個(gè)boolean(布爾)標(biāo)記,指出對(duì)象是否已被清除。在類的finalize()方法里,請(qǐng)確定對(duì)象已被清除, 并已丟棄了從RuntimeException繼承的一個(gè)類(如果還沒(méi)有的話),從而指出一個(gè)編程錯(cuò)誤。在采取象這樣的方案之前,請(qǐng)確定 finalize()能夠在自己的系統(tǒng)中工作(可能需要調(diào)用System.runFinalizersOnExit(true),從而確保這一行為)。

    (15) 在一個(gè)特定的作用域內(nèi),若一個(gè)對(duì)象必須清除(非由垃圾收集機(jī)制處理),請(qǐng)采用下述方法:初始化對(duì)象;若成功,則立即進(jìn)入一個(gè)含有finally從句的try塊,開始清除工作。

    (16) 若在初始化過(guò)程中需要覆蓋(取消)finalize(),請(qǐng)記住調(diào)用super.finalize()(若Object屬于我們的直接超類,則無(wú)此必 要)。在對(duì)finalize()進(jìn)行覆蓋的過(guò)程中,對(duì)super.finalize()的調(diào)用應(yīng)屬于最后一個(gè)行動(dòng),而不應(yīng)是第一個(gè)行動(dòng),這樣可確保在需要 基礎(chǔ)類組件的時(shí)候它們依然有效。

    (17) 創(chuàng)建大小固定的對(duì)象集合時(shí),請(qǐng)將它們傳輸至一個(gè)數(shù)組(若準(zhǔn)備從一個(gè)方法里返回這個(gè)集合,更應(yīng)如此操作)。這樣一來(lái),我們就可享受到數(shù)組在編譯期進(jìn)行類型檢查的好處。此外,為使用它們,數(shù)組的接收者也許并不需要將對(duì)象"造型"到數(shù)組里。

    (18) 盡量使用interfaces,不要使用abstract類。若已知某樣?xùn)|西準(zhǔn)備成為一個(gè)基礎(chǔ)類,那么第一個(gè)選擇應(yīng)是將其變成一個(gè)interface(接 口)。只有在不得不使用方法定義或者成員變量的時(shí)候,才需要將其變成一個(gè)abstract(抽象)類。接口主要描述了客戶希望做什么事情,而一個(gè)類則致力 于(或允許)具體的實(shí)施細(xì)節(jié)。

    (19) 在構(gòu)建器內(nèi)部,只進(jìn)行那些將對(duì)象設(shè)為正確狀態(tài)所需的工作。盡可能地避免調(diào)用其他方法,因?yàn)槟切┓椒赡鼙黄渌烁采w或取消,從而在構(gòu)建過(guò)程中產(chǎn)生不可預(yù)知的結(jié)果(參見(jiàn)第7章的詳細(xì)說(shuō)明)。

    (20) 對(duì)象不應(yīng)只是簡(jiǎn)單地容納一些數(shù)據(jù);它們的行為也應(yīng)得到良好的定義。

    (21) 在現(xiàn)成類的基礎(chǔ)上創(chuàng)建新類時(shí),請(qǐng)首先選擇"新建"或"創(chuàng)作"。只有自己的設(shè)計(jì)要求必須繼承時(shí),才應(yīng)考慮這方面的問(wèn)題。若在本來(lái)允許新建的場(chǎng)合使用了繼承,則整個(gè)設(shè)計(jì)會(huì)變得沒(méi)有必要地復(fù)雜。

    (22) 用繼承及方法覆蓋來(lái)表示行為間的差異,而用字段表示狀態(tài)間的區(qū)別。一個(gè)非常極端的例子是通過(guò)對(duì)不同類的繼承來(lái)表示顏色,這是絕對(duì)應(yīng)該避免的:應(yīng)直接使用一個(gè)"顏色"字段。

    (23) 為避免編程時(shí)遇到麻煩,請(qǐng)保證在自己類路徑指到的任何地方,每個(gè)名字都僅對(duì)應(yīng)一個(gè)類。否則,編譯器可能先找到同名的另一個(gè)類,并報(bào)告出錯(cuò)消息。若懷疑自己碰到了類路徑問(wèn)題,請(qǐng)?jiān)囋囋陬惵窂降拿恳粋€(gè)起點(diǎn),搜索一下同名的.class文件。

    (24) 在Java 1.1 AWT中使用事件"適配器"時(shí),特別容易碰到一個(gè)陷阱。若覆蓋了某個(gè)適配器方法,同時(shí)拼寫方法沒(méi)有特別講究,最后的結(jié)果就是新添加一個(gè)方法,而不是覆蓋現(xiàn) 成方法。然而,由于這樣做是完全合法的,所以不會(huì)從編譯器或運(yùn)行期系統(tǒng)獲得任何出錯(cuò)提示--只不過(guò)代碼的工作就變得不正常了。

    (25) 用合理的設(shè)計(jì)方案消除"偽功能"。也就是說(shuō),假若只需要?jiǎng)?chuàng)建類的一個(gè)對(duì)象,就不要提前限制自己使用應(yīng)用程序,并加上一條"只生成其中一個(gè)"注釋。請(qǐng)考慮將 其封裝成一個(gè)"獨(dú)生子"的形式。若在主程序里有大量散亂的代碼,用于創(chuàng)建自己的對(duì)象,請(qǐng)考慮采納一種創(chuàng)造性的方案,將些代碼封裝起來(lái)。

    (26) 警惕"分析癱瘓"。請(qǐng)記住,無(wú)論如何都要提前了解整個(gè)項(xiàng)目的狀況,再去考察其中的細(xì)節(jié)。由于把握了全局,可快速認(rèn)識(shí)自己未知的一些因素,防止在考察細(xì)節(jié)的時(shí)候陷入"死邏輯"中。

    (27) 警惕"過(guò)早優(yōu)化"。首先讓它運(yùn)行起來(lái),再考慮變得更快--但只有在自己必須這樣做、而且經(jīng)證實(shí)在某部分代碼中的確存在一個(gè)性能瓶頸的時(shí)候,才應(yīng)進(jìn)行優(yōu)化。 除非用專門的工具分析瓶頸,否則很有可能是在浪費(fèi)自己的時(shí)間。性能提升的隱含代價(jià)是自己的代碼變得難于理解,而且難于維護(hù)。

    (28) 請(qǐng)記住,閱讀代碼的時(shí)間比寫代碼的時(shí)間多得多。思路清晰的設(shè)計(jì)可獲得易于理解的程序,但注釋、細(xì)致的解釋以及一些示例往往具有不可估量的價(jià)值。無(wú)論對(duì)你自 己,還是對(duì)后來(lái)的人,它們都是相當(dāng)重要的。如對(duì)此仍有懷疑,那么請(qǐng)?jiān)囅胱约涸噲D從聯(lián)機(jī)Java文檔里找出有用信息時(shí)碰到的挫折,這樣或許能將你說(shuō)服。

    (29) 如認(rèn)為自己已進(jìn)行了良好的分析、設(shè)計(jì)或者實(shí)施,那么請(qǐng)稍微更換一下思維角度。試試邀請(qǐng)一些外來(lái)人士--并不一定是專家,但可以是來(lái)自本公司其他部門的人。 請(qǐng)他們用完全新鮮的眼光考察你的工作,看看是否能找出你一度熟視無(wú)睹的問(wèn)題。采取這種方式,往往能在最適合修改的階段找出一些關(guān)鍵性的問(wèn)題,避免產(chǎn)品發(fā)行 后再解決問(wèn)題而造成的金錢及精力方面的損失。

    (30) 良好的設(shè)計(jì)能帶來(lái)最大的回報(bào)。簡(jiǎn)言之,對(duì)于一個(gè)特定的問(wèn)題,通常會(huì)花較長(zhǎng)的時(shí)間才能找到一種最恰當(dāng)?shù)慕鉀Q方案。但一旦找到了正確的方法,以后的工作就輕松 多了,再也不用經(jīng)歷數(shù)小時(shí)、數(shù)天或者數(shù)月的痛苦掙扎。我們的努力工作會(huì)帶來(lái)最大的回報(bào)(甚至無(wú)可估量)。而且由于自己傾注了大量心血,最終獲得一個(gè)出色的 設(shè)計(jì)方案,成功的快感也是令人心動(dòng)的。堅(jiān)持抵制草草完工的誘惑--那樣做往往得不償失

    posted @ 2011-11-28 14:34 俞靈 閱讀(594) | 評(píng)論 (0)編輯 收藏

    本文轉(zhuǎn)自it186云計(jì)算頻道,原文地址:cloud.it168.com

    在互聯(lián)網(wǎng)這個(gè)領(lǐng)域一直有這樣的說(shuō)法:“如果老二無(wú)法戰(zhàn)勝老大,那么就把老大賴以生存的東西開源吧”。當(dāng)年Yahoo!與Google還是處在 強(qiáng)烈競(jìng)爭(zhēng)關(guān)系時(shí)候,招聘了Doug(Hadoop創(chuàng)始人),把Google老大賴以生存的DFS與Map-Reduce開源了,開始了Hadoop的童年 時(shí)期。差不多在2008年的時(shí)候,Hadoop才算逐漸成熟。

    從初創(chuàng)到現(xiàn)在,Hadoop經(jīng)過(guò)了至少7年的積累,現(xiàn)在的Hadoop不僅是當(dāng)年的老二Yahoo的專用產(chǎn)品了,從Hadoop長(zhǎng)長(zhǎng)的用戶名單中, 可以看到Facebook、Linkedin、Amazon,可以看到EMC、eBay、Twitter、IBM、Microsoft,、Apple、 HP…國(guó)內(nèi)的公司有淘寶、百度等等。

    本文將對(duì)Hadoop七年(2004-2011)的發(fā)展歷程進(jìn) 行梳理。讀完本文后,將不難看出,Hadoop的發(fā)展基本上經(jīng)歷了這樣一個(gè)過(guò)程:從一個(gè)開源的Apache基金會(huì)項(xiàng)目,隨著越來(lái)越多的用戶的加入,不斷地 使用、貢獻(xiàn)和完善,形成一個(gè)強(qiáng)大的生態(tài)系統(tǒng),從2009年開始,隨著云計(jì)算和大數(shù)據(jù)的發(fā)展,Hadoop作為海量數(shù)據(jù)分析的最佳解決方案,開始受到許多 IT廠商的關(guān)注,從而出現(xiàn)了許多Hadoop的商業(yè)版以及支持Hadoop的產(chǎn)品,包括軟件和硬件。

    • 2004年,Google發(fā)表論文,向全世界介紹了MapReduce。
    • 2005年初,為了支持Nutch搜索引擎項(xiàng)目,Nutch的開發(fā)者基于Google發(fā)布的MapReduce報(bào)告,在Nutch上開發(fā)了一個(gè)可工作的MapReduce應(yīng)用。
    • 2005年年中,所有主要的Nutch算法被移植到使用MapReduce和NDFS(Nutch Distributed File System )來(lái)運(yùn)行。
    • 2006年1月,Doug Cutting加入雅虎,Yahoo!提供一個(gè)專門的團(tuán)隊(duì)和資源將Hadoop發(fā)展成一個(gè)可在網(wǎng)絡(luò)上運(yùn)行的系統(tǒng)。
    • 2006年2月,Apache Hadoop項(xiàng)目正式啟動(dòng)以支持MapReduce和HDFS的獨(dú)立發(fā)展。
    • 2007年,百度開始使用Hadoop做離線處理,目前差不多80%的Hadoop集群用作日志處理。
    • 2007年,中國(guó)移動(dòng)開始在“大云”研究中使用Hadoop技術(shù),規(guī)模超過(guò)1000臺(tái)。
    • 2008年,淘寶開始投入研究基于Hadoop的系統(tǒng)——云梯,并將其用于處理電子商務(wù)相關(guān)數(shù)據(jù)。云梯1的總?cè)萘看蟾艦?.3PB,包含了1100臺(tái)機(jī)器,每天處理約18000道作業(yè),掃描500TB數(shù)據(jù)。
    • 2008年1月,Hadoop成為Apache頂級(jí)項(xiàng)目。
    • 2008年2月,Yahoo!宣布其搜索引擎產(chǎn)品部署在一個(gè)擁有1萬(wàn)個(gè)內(nèi)核的Hadoop集群上。
    • 2008年7月,Hadoop打破1TB數(shù)據(jù)排序基準(zhǔn)測(cè)試記錄。Yahoo!的一個(gè)Hadoop集群用209秒完成1TB數(shù)據(jù)的排序 ,比上一年的紀(jì)錄保持者保持的297秒快了將近90秒。
    • 2009 年 3 月,Cloudera推出CDH(Cloudera’s Distribution including Apache Hadoop)平臺(tái),完全由開放源碼軟件組成,目前已經(jīng)進(jìn)入第3版。
    • 2009年5月,Yahoo的團(tuán)隊(duì)使用Hadoop對(duì)1 TB的數(shù)據(jù)進(jìn)行排序只花了62秒時(shí)間。
    • 2009年7月 ,Hadoop Core項(xiàng)目更名為Hadoop Common;
    • 2009年7月 ,MapReduce 和 Hadoop Distributed File System (HDFS) 成為Hadoop項(xiàng)目的獨(dú)立子項(xiàng)目。
    • 2009年7月 ,Avro 和 Chukwa 成為Hadoop新的子項(xiàng)目。
    • 2010年5月 ,Avro脫離Hadoop項(xiàng)目,成為Apache頂級(jí)項(xiàng)目。
    • 2010年5月 ,HBase脫離Hadoop項(xiàng)目,成為Apache頂級(jí)項(xiàng)目。
    • 2010年5月,IBM提供了基于Hadoop 的大數(shù)據(jù)分析軟件——InfoSphere BigInsights,包括基礎(chǔ)版和企業(yè)版。
    • 2010年9月,Hive( Facebook) 脫離Hadoop,成為Apache頂級(jí)項(xiàng)目。
    • 2010年9月,Pig脫離Hadoop,成為Apache頂級(jí)項(xiàng)目。
    • 2011年1月,ZooKeeper 脫離Hadoop,成為Apache頂級(jí)項(xiàng)目。
    • 2011年3月,Apache Hadoop獲得Media Guardian Innovation Awards 。
    • 2011年3月, Platform Computing 宣布在它的Symphony軟件中支持Hadoop MapReduce API。
    • 2011年5月,Mapr Technologies公司推出分布式文件系統(tǒng)和MapReduce引擎——MapR Distribution for Apache Hadoop。
    • 2011年5月,HCatalog 1.0發(fā)布。該項(xiàng)目由Hortonworks 在2010年3月份提出,HCatalog主要用于解決數(shù)據(jù)存儲(chǔ)、元數(shù)據(jù)的問(wèn)題,主要解決HDFS的瓶頸,它提供了一個(gè)地方來(lái)存儲(chǔ)數(shù)據(jù)的狀態(tài)信息,這使得 數(shù)據(jù)清理和歸檔工具可以很容易的進(jìn)行處理。
    • 2011年4月,SGI( Silicon Graphics International )基于SGI Rackable和CloudRack服務(wù)器產(chǎn)品線提供Hadoop優(yōu)化的解決方案。
    • 2011年5月,EMC為客戶推出一種新的基于開源Hadoop解決方案的數(shù)據(jù)中心設(shè)備——GreenPlum HD,以助其滿足客戶日益增長(zhǎng)的數(shù)據(jù)分析需求并加快利用開源數(shù)據(jù)分析軟件。Greenplum是EMC在2010年7月收購(gòu)的一家開源數(shù)據(jù)倉(cāng)庫(kù)公司。
    • 2011年5月,在收購(gòu)了Engenio之后, NetApp推出與Hadoop應(yīng)用結(jié)合的產(chǎn)品E5400存儲(chǔ)系統(tǒng)。
    • 2011年6月,Calxeda公司(之前公司的名字是Smooth-Stone)發(fā)起了“開拓者行動(dòng)”,一個(gè)由10家軟件公司組成的團(tuán)隊(duì)將為基于Calxeda即將推出的ARM系統(tǒng)上芯片設(shè)計(jì)的服務(wù)器提供支持。并為Hadoop提供低功耗服務(wù)器技術(shù)。
    • 2011年6月,數(shù)據(jù)集成供應(yīng)商Informatica發(fā)布了其旗艦產(chǎn)品,產(chǎn)品設(shè)計(jì)初衷是處理當(dāng)今事務(wù)和社會(huì)媒體所產(chǎn)生的海量數(shù)據(jù),同時(shí)支持Hadoop。
    • 2011年7月,Yahoo!和硅谷風(fēng)險(xiǎn)投資公司 Benchmark Capital創(chuàng)建了Hortonworks 公司,旨在讓Hadoop更加魯棒(可靠),并讓企業(yè)用戶更容易安裝、管理和使用Hadoop。
    • 2011年8月,Cloudera公布了一項(xiàng)有益于合作伙伴生態(tài)系統(tǒng)的計(jì)劃——創(chuàng)建一個(gè)生態(tài)系統(tǒng),以便硬件供應(yīng)商、軟件供應(yīng)商以及系統(tǒng)集成商可以一起探索如何使用Hadoop更好的洞察數(shù)據(jù)。
    • 2011年8月,Dell與Cloudera聯(lián)合推出Hadoop解決方案——Cloudera Enterprise。Cloudera Enterprise基于Dell PowerEdge C2100機(jī)架服務(wù)器以及Dell PowerConnect 6248以太網(wǎng)交換機(jī)

    在梳理的過(guò)程中,筆者發(fā)現(xiàn)了上圖,它很好地展現(xiàn)了Hadoop生態(tài)系統(tǒng)是如何在使用中一步一步成長(zhǎng)起來(lái)的。

    posted @ 2011-11-21 09:04 俞靈 閱讀(506) | 評(píng)論 (0)編輯 收藏

    本文轉(zhuǎn)自:
    http://linuxtoy.org/archives/bash-shortcuts.html

    生活在 Bash shell 中,熟記以下快捷鍵,將極大的提高你的命令行操作效率。

    編輯命令

    • Ctrl + a :移到命令行首
    • Ctrl + e :移到命令行尾
    • Ctrl + f :按字符前移(右向)
    • Ctrl + b :按字符后移(左向)
    • Alt + f :按單詞前移(右向)
    • Alt + b :按單詞后移(左向)
    • Ctrl + xx:在命令行首和光標(biāo)之間移動(dòng)
    • Ctrl + u :從光標(biāo)處刪除至命令行首
    • Ctrl + k :從光標(biāo)處刪除至命令行尾
    • Ctrl + w :從光標(biāo)處刪除至字首
    • Alt + d :從光標(biāo)處刪除至字尾
    • Ctrl + d :刪除光標(biāo)處的字符
    • Ctrl + h :刪除光標(biāo)前的字符
    • Ctrl + y :粘貼至光標(biāo)后
    • Alt + c :從光標(biāo)處更改為首字母大寫的單詞
    • Alt + u :從光標(biāo)處更改為全部大寫的單詞
    • Alt + l :從光標(biāo)處更改為全部小寫的單詞
    • Ctrl + t :交換光標(biāo)處和之前的字符
    • Alt + t :交換光標(biāo)處和之前的單詞
    • Alt + Backspace:與 Ctrl + w 相同類似,分隔符有些差別 [感謝 rezilla 指正]

    重新執(zhí)行命令

    • Ctrl + r:逆向搜索命令歷史
    • Ctrl + g:從歷史搜索模式退出
    • Ctrl + p:歷史中的上一條命令
    • Ctrl + n:歷史中的下一條命令
    • Alt + .:使用上一條命令的最后一個(gè)參數(shù)

    控制命令

    • Ctrl + l:清屏
    • Ctrl + o:執(zhí)行當(dāng)前命令,并選擇上一條命令
    • Ctrl + s:阻止屏幕輸出
    • Ctrl + q:允許屏幕輸出
    • Ctrl + c:終止命令
    • Ctrl + z:掛起命令

    Bang (!) 命令

    • !!:執(zhí)行上一條命令
    • !blah:執(zhí)行最近的以 blah 開頭的命令,如 !ls
    • !blah:p:僅打印輸出,而不執(zhí)行
    • !$:上一條命令的最后一個(gè)參數(shù),與 Alt + . 相同
    • !$:p:打印輸出 !$ 的內(nèi)容
    • !*:上一條命令的所有參數(shù)
    • !*:p:打印輸出 !* 的內(nèi)容
    • ^blah:刪除上一條命令中的 blah
    • ^blah^foo:將上一條命令中的 blah 替換為 foo
    • ^blah^foo^:將上一條命令中所有的 blah 都替換為 foo

    友情提示

    1. 以上介紹的大多數(shù) Bash 快捷鍵僅當(dāng)在 emacs 編輯模式時(shí)有效,若你將 Bash 配置為 vi 編輯模式,那將遵循 vi 的按鍵綁定。Bash 默認(rèn)為 emacs 編輯模式。如果你的 Bash 不在 emacs 編輯模式,可通過(guò) set -o emacs 設(shè)置。
    2. ^S、^Q、^C、^Z 是由終端設(shè)備處理的,可用 stty 命令設(shè)置。

    posted @ 2011-11-15 10:04 俞靈 閱讀(602) | 評(píng)論 (0)編輯 收藏


    希望大家喜歡,自己留個(gè)備份,沒(méi)事逛逛!!

    http://www.javaalmanac.com - Java開發(fā)者年鑒一書的在線版本. 要想快速查到某種Java技巧的用法及示例代碼, 這是一個(gè)不錯(cuò)的去處.
    http://www.onjava.com - O'Reilly的Java網(wǎng)站. 每周都有新文章.
    http://java.sun.com - 官方的Java開發(fā)者網(wǎng)站 - 每周都有新文章發(fā)表.
    http://www.developer.com/java - 由Gamelan.com 維護(hù)的Java技術(shù)文章網(wǎng)站.
    http://www.java.net - Sun公司維護(hù)的一個(gè)Java社區(qū)網(wǎng)站.
    http://www.builder.com - Cnet的Builder.com網(wǎng)站 - 所有的技術(shù)文章, 以Java為主.
    http://www.ibm.com/developerworks/java - IBM的Developerworks技術(shù)網(wǎng)站; 這是其中的Java技術(shù)主頁(yè).
    http://www.javaworld.com - 最早的一個(gè)Java站點(diǎn). 每周更新Java技術(shù)文章.
    http://www.devx.com/java - DevX維護(hù)的一個(gè)Java技術(shù)文章網(wǎng)站.
    http://www.fawcette.com/javapro - JavaPro在線雜志網(wǎng)站.
    http://www.sys-con.com/java - Java Developers Journal的在線雜志網(wǎng)站.
    http://www.javadesktop.org - 位于Java.net的一個(gè)Java桌面技術(shù)社區(qū)網(wǎng)站.
    http://www.theserverside.com - 這是一個(gè)討論所有Java服務(wù)器端技術(shù)的網(wǎng)站.
    http://www.jars.com - 提供Java評(píng)論服務(wù). 包括各種framework和應(yīng)用程序.
    http://www.jguru.com - 一個(gè)非常棒的采用Q&A形式的Java技術(shù)資源社區(qū).
    http://www.javaranch.com - 一個(gè)論壇,得到Java問(wèn)題答案的地方,初學(xué)者的好去處。
    http://www.ibiblio.org/javafaq/javafaq.html - comp.lang.java的FAQ站點(diǎn) - 收集了來(lái)自comp.lang.java新聞組的問(wèn)題和答案的分類目錄.
    http://java.sun.com/docs/books/tutorial/ - 來(lái)自SUN公司的官方Java指南 - 對(duì)于了解幾乎所有的java技術(shù)特性非常有幫助.
    http://www.javablogs.com - 互聯(lián)網(wǎng)上最活躍的一個(gè)Java Blog網(wǎng)站.
    http://java.about.com/ - 來(lái)自About.com的Java新聞和技術(shù)文章網(wǎng)站.

    posted @ 2011-11-15 09:45 俞靈 閱讀(601) | 評(píng)論 (0)編輯 收藏

    本文轉(zhuǎn)自

    http://trinea.iteye.com/blog/1196400

     

    1、jps的作用

    jps類似linux的ps命令,不同的是ps是用來(lái)顯示進(jìn)程,而jps只顯示java進(jìn)程,準(zhǔn)確的說(shuō)是當(dāng)前用戶已啟動(dòng)的部分java進(jìn)程信息,信息包括進(jìn)程號(hào)和簡(jiǎn)短的進(jìn)程command。

     

    2、某個(gè)java進(jìn)程已經(jīng)啟動(dòng),用jps卻顯示不了該進(jìn)程進(jìn)程號(hào)

    這個(gè)問(wèn)題已經(jīng)碰到過(guò)兩次了,所以在這里總結(jié)下。

    現(xiàn)象:

    用ps -ef|grep java能看到啟動(dòng)的java進(jìn)程,但是用jps查看卻不存在該進(jìn)程的id。待會(huì)兒解釋過(guò)之后就能知道在該情況下,jconsole、jvisualvm可能無(wú)法監(jiān)控該進(jìn)程,其他java自帶工具也可能無(wú)法使用

     

    分析:

    java程序啟動(dòng)后,默認(rèn)(請(qǐng)注意是默認(rèn))會(huì)在/tmp/hsperfdata_userName目錄下以該進(jìn)程的id為文件名新建文件,并在該文件中存儲(chǔ)jvm運(yùn)行的相關(guān)信息,其中的userName為當(dāng)前的用戶名,/tmp/hsperfdata_userName目錄會(huì)存放該用戶所有已經(jīng)啟動(dòng)的java進(jìn)程信息。對(duì)于windows機(jī)器/tmp用Windows存放臨時(shí)文件目錄代替。

     

    而jps、jconsole、jvisualvm等工具的數(shù)據(jù)來(lái)源就是這個(gè)文件(/tmp/hsperfdata_userName/pid)。所以當(dāng)該文件不存在或是無(wú)法讀取時(shí)就會(huì)出現(xiàn)jps無(wú)法查看該進(jìn)程號(hào),jconsole無(wú)法監(jiān)控等問(wèn)題

     

    原因:

    (1)、磁盤讀寫、目錄權(quán)限問(wèn)題

    若該用戶沒(méi)有權(quán)限寫/tmp目錄或是磁盤已滿,則無(wú)法創(chuàng)建/tmp/hsperfdata_userName/pid文件。或該文件已經(jīng)生成,但用戶沒(méi)有讀權(quán)限

     

    (2)、臨時(shí)文件丟失,被刪除或是定期清理

    對(duì)于linux機(jī)器,一般都會(huì)存在定時(shí)任務(wù)對(duì)臨時(shí)文件夾進(jìn)行清理,導(dǎo)致/tmp目錄被清空。這也是我第一次碰到該現(xiàn)象的原因

    這個(gè)導(dǎo)致的現(xiàn)象可能會(huì)是這樣,用jconsole監(jiān)控進(jìn)程,發(fā)現(xiàn)在某一時(shí)段后進(jìn)程仍然存在,但是卻沒(méi)有監(jiān)控信息了。

     

    (3)、java進(jìn)程信息文件存儲(chǔ)地址被設(shè)置,不在/tmp目錄下

    上面我們?cè)诮榻B時(shí)說(shuō)默認(rèn)會(huì)在/tmp/hsperfdata_userName目錄保存進(jìn)程信息,但由于以上1、2所述原因,可能導(dǎo)致該文件無(wú)法生成或是丟失,所以java啟動(dòng)時(shí)提供了參數(shù),可以對(duì)這個(gè)文件的位置進(jìn)行設(shè)置,而jps、jconsole都只會(huì)從/tmp目錄讀取,而無(wú)法從設(shè)置后的目錄讀物信息,

             這個(gè)問(wèn)題只會(huì)在jdk 6u23和6u24上出現(xiàn),在6u23和6u24上,進(jìn)程信息會(huì)保存在-Djava.io.tmpdir下, 因此如果它被設(shè)置為非/tmp目錄則會(huì)導(dǎo)致 jps,jconsole等無(wú)法讀取的現(xiàn)象, 但在其他版本的jdk上,即使設(shè)置-Djava.io.tmpdir為非/tmp,  也會(huì)在/tmp/hsperfdata_userName下保存java進(jìn)程信息.因此可以說(shuō)這是6u23和6u24的bug,

             以下是jdk對(duì)該bug的描述地址:

    bug描述:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7021676
    bug的修復(fù)描述:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7009828
    bug修改代碼:
    http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/34d64ad817f4

     

     

    關(guān)于設(shè)置該文件位置的參數(shù)為-Djava.io.tmpdir

    posted @ 2011-11-14 16:15 俞靈 閱讀(5956) | 評(píng)論 (0)編輯 收藏

    1.       根據(jù)上一章配好的集群,現(xiàn)為Myhost1配置backupNodeSecondaryNamenode, 由于機(jī)器有限,這里就不為Myhost2配置backupNodeSecondaryNamenode,但是方法相同.

    2.       我們選定Myhost4SecondaryNamenode, Myhost5backupNode.

    配置并啟動(dòng)SecondaryNamenode:

    1.       配置:Myhost1 hdfs-site.xml 加入如下配置,指定SecondaryNamenode.

      <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value> Myhost4:9001</value>
      </property>

    2.       Myhost4hdfs-site.xml 加入如下配置,指定nnurl和本地的checkpoint.dir.

      <property>
        <name>dfs.federation.nameservice.id</name>
        <value> Myhost1:50070</value>
      </property>

      <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>/home/yuling.sh/checkpoint-data</value>
      </property>

    3.       啟動(dòng)SecondaryNamenode. Myhost1上運(yùn)行命令:sbin/star-dfs.sh或者在Myhost4上運(yùn)行sbin/hadoop-daemo.sh start SecondaryNamenode 即可以啟動(dòng)SecondaryNamenode. 可以通過(guò)log或者網(wǎng)頁(yè)Myhost4:50090查看其狀態(tài). 另外在checkpoint.dir下會(huì)有元數(shù)據(jù)信息.

     

    配置并啟動(dòng)backupNode:

    1.       配置Myhost5hdfs-site.xml, 加入如下配置信息:

      <property>
        <name>dfs.namenode.backup.address</name>
        <value> Myhost5:9002</value>
      </property>
      <property>
        <name>dfs.namenode.backup.http-address</name>
        <value> Myhost5:9003</value>
      </property>
      <property>
        <name>dfs.namenode.http-address</name>
        <value> Myhost1:50070</value>
      </property>

      <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/yuling.sh/ backup-data</value>
      </property>

    2.       啟動(dòng)backupNode, Myhost5上運(yùn)行bin/hdfs namenode –backup &

    3.       dfs.namenode.name.dir下查看元數(shù)據(jù)信息.


    下一篇博客將講述如何搭建hadoop 0.23 的mapreduce

    posted @ 2011-11-11 14:59 俞靈 閱讀(3633) | 評(píng)論 (2)編輯 收藏

    使用hadoop-0.23 搭建hdfs,  namenode + datanode

    1.       HDFS-1052引入了多namenode, HDFS架構(gòu)變化較大, 可以參考hortonworks的文章: http://hortonworks.com/an-introduction-to-hdfs-federation/.

    我將在接下來(lái)的博客里把此文章翻譯一下(另外還有: http://developer.yahoo.com/blogs/hadoop/posts/2011/03/mapreduce-nextgen-scheduler/).

    所有namenode共享datanode, 各個(gè)namenode相互獨(dú)立, 互不影響, 每個(gè)namenode都有一個(gè)backupNodeSecondaryNamenode,提供主備切換功能和備份元數(shù)據(jù)的功能.

    下文的配置信息主要參考HDFS-2471.

    2.       環(huán)境:

    a)         五臺(tái)機(jī)器 ,linux系統(tǒng),

    b)         互相添加ssh-key,后應(yīng)該可以不用密碼互連

    c)         編譯好的0.23版本的包: hadoop-0.23.0-SNAPSHOT.tar.gz

    d)         每臺(tái)機(jī)器需要安裝java1.6或以上版本.并把JAVA_HOME加到$PATH.

    e)         最好加上psshpscp工具.

    這里把五臺(tái)機(jī)器命名為:

     Myhost1

          Myhost2

          Myhost3

    Myhost4

          Myhost5

         假設(shè)我們需要搭建如下集群:

    Myhost1Myhost2開啟 namenode, 另外三臺(tái)機(jī)器啟動(dòng)datanode服務(wù).

    3.       首先把分配到五臺(tái)機(jī)器上,然后解壓.(推薦使用pscp, pssh命令)

    4.       然后在五臺(tái)機(jī)器上安裝java,并把JAVA_HOME加到$PATH

    5.       進(jìn)入解壓后的hadoop目錄, 編輯 etc/hadoop/hdfs-site.xml

    a)         Myhost1的配置如下(其中hadoop存放在/home/yuling.sh/目錄下):

     <property>
        <name>fs.defaultFS</name>
        <value>hdfs:// Myhost1:9000</value>
      </property>

      <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/yuling.sh/cluster-data</value>
      </property>

    b)         Myhost2的配置如下(其中hadoop存放在/home/yuling.sh/目錄下):

     <property>
        <name>fs.defaultFS</name>
        <value>hdfs:// Myhost2:9000</value>
      </property>

      <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/yuling.sh/cluster-data</value>
      </property>

     

    c) 這里把Myhost1集群起名ns1, Myhost1集群起名ns2, 三臺(tái)slavaetc/hadoop/hdfs-site.xml配置如下:

     <property>
        <name>dfs.federation.nameservices</name>
        <value>ns1,ns2</value>
      </property>


      <property>
        <name>dfs.namenode.rpc-address.ns1</name>
        <value>hdfs:// Myhost1:9000</value>
      </property>


      <property>
        <name>dfs.namenode.http-address.ns1</name>
        <value> Myhost1:50070</value>
      </property>

      <property>
        <name>dfs.namenode.rpc-address.ns2</name>
        <value>hdfs:// Myhost2:9000</value>
      </property>
      <property>
        <name>dfs.namenode.http-address.ns1</name>
        <value> Myhost2:50070</value>
      </property>

      <property>
        <name>dfs.datanode.data.dir</name>
        <value>/home/yuling.sh/datanode</value>
      </property>  

    d) 解釋:namenode需要指定兩個(gè)參數(shù), 用于存放元數(shù)據(jù)和文件系統(tǒng)的URL. Datanode需指定要連接的namenode rpc-addresshttp-address. 以及數(shù)據(jù)存放位置dfs.datanode.data.dir.

    6.       然后編輯兩臺(tái)namenodehadoop目錄下 etc/hadoop/slaves文件. 加入三臺(tái)slave機(jī)器名:

    Myhost3

    Myhost4

          Myhost5

     

    7.       現(xiàn)在需要格式化namenode, 由于namenode共享datanode, 因此它們的clusterid需要有相同的名字.這里我們把名字設(shè)為 yuling .命令如下:

    bin/hdfs namenode –format –clusterid yuling

    兩臺(tái)機(jī)器格式話之后會(huì)在/home/yuling.sh/cluster-data下生成元數(shù)據(jù)目錄.

    8.       啟動(dòng)Myhost1Myhost2上的namenodeslavedatanode服務(wù). 命令如下:

       sbin/start-hdfs.sh

    分別在Myhost1Myhost2下運(yùn)行.

    9.       啟動(dòng)之后打開瀏覽器, 分別查看兩namenode啟動(dòng)后狀態(tài). URL:

    Myhost1:50070Myhost2:50070

    10.   這期間可能會(huì)遇到許多問(wèn)題, 但是可以根據(jù)拋出的異常自己解決, 我這里就不多說(shuō)了.

    下一篇博客將講述如何啟動(dòng)backupNodeSecondaryNamenode

     

    posted @ 2011-11-10 21:29 俞靈 閱讀(3077) | 評(píng)論 (3)編輯 收藏

    編譯(環(huán)境linux, 需要聯(lián)網(wǎng))

    1.       首先下載hadoop 0.23版本

    svn checkout http://svn.apache.org/repos/asf/hadoop/common/tags/release-0.23.0-rc0/

    2.       進(jìn)入release-0.23.0-rc0目錄下能看到INSTALL.TXT文件, 這里有編譯hadoop 0.23的教程.

    編譯前的準(zhǔn)備:.

    a)         * Unix System

    b)         * JDK 1.6

    c)         * Maven 3.0

    d)         * Forrest 0.8 (if generating docs)

    e)         * Findbugs 1.3.9 (if running findbugs)

    f)          * ProtocolBuffer 2.4.1+ (for MapReduce)

    g)         * Autotools (if compiling native code)

    h)         * Internet connection for first build (to fetch all Maven and Hadoop dependencies)

    可以根據(jù)需要安裝全部或部分的工具,然后把它們加入到$PATH. 這里介紹一下ProtocolBuffer的安裝方法:下載2.4.1版本后解壓,進(jìn)入目錄,運(yùn)行如下命令即可.

    $ ./configure --prefile=/usr/local

    $ make

    $ sudo make install

    3.       經(jīng)過(guò)第二步準(zhǔn)備之后,由于從hadoop0.23開始使用Maven編譯,因此必需聯(lián)網(wǎng),命令如下:

    mvn package [-Pdist][-Pdocs][-Psrc][-Pnative][-Dtar]

    建議先運(yùn)行命令: mvn package -Pdist -DskipTests –Dtar (前提Maven 3.0ProtocolBuffer2.4.1以上), 此命令成功之后會(huì)在release-0.23.0-rc0/下生成 hadoop-dist/target/hadoop-0.23.0-SNAPSHOT.tar.gz. 可以使用這個(gè)包搭建集群.

    使用-Pdocs選項(xiàng)可以生成文檔,當(dāng)然前提是安裝了Forrest 0.8Findbugs 1.3.9. 可以參考如下命令手動(dòng)指定:FORREST_HOMEFINDBUGS_HOME.

    mvn package -Pdocs -DskipTests -Dtar -Dmaven.test.skip -Denv.FORREST_HOME=/usr/local/apache-forrest-0.9  -Denv.FINDBUGS_HOME=/usr/local/findbugs-1.3.9

    生成的文檔在各自的target/site目錄下.

    經(jīng)過(guò)以上步驟,我們已經(jīng)編譯好了hadoop-0.23,現(xiàn)在可以使用hadoop-0.23.0-SNAPSHOT.tar.gz來(lái)搭建集群了.

     

    下一篇博客將講述如何使用hadoop-0.23 搭建hdfs集群

    posted @ 2011-11-10 21:26 俞靈 閱讀(3440) | 評(píng)論 (6)編輯 收藏

    本周末學(xué)習(xí)zookeeper,原理和安裝配置

    本文參考: http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

    http://zookeeper.apache.org/

     

    Zookeeper 作為一個(gè)分布式的服務(wù)框架,主要用來(lái)解決分布式集群中應(yīng)用系統(tǒng)的一致性問(wèn)題,它能提供基于類似于文件系統(tǒng)的目錄節(jié)點(diǎn)樹方式的數(shù)據(jù)存儲(chǔ),但是 Zookeeper 并不是用來(lái)專門存儲(chǔ)數(shù)據(jù)的,它的作用主要是用來(lái)維護(hù)和監(jiān)控你存儲(chǔ)的數(shù)據(jù)的狀態(tài)變化。通過(guò)監(jiān)控這些數(shù)據(jù)狀態(tài)的變化,從而可以達(dá)到基于數(shù)據(jù)的集群管理。

    Zookeeper安裝和配置比較簡(jiǎn)單,可以參考官網(wǎng).

    數(shù)據(jù)模型

    Zookeeper 會(huì)維護(hù)一個(gè)具有層次關(guān)系的數(shù)據(jù)結(jié)構(gòu),它非常類似于一個(gè)標(biāo)準(zhǔn)的文件系統(tǒng),如圖 1 所示:


    1 Zookeeper 數(shù)據(jù)結(jié)構(gòu)

    Zookeeper 這種數(shù)據(jù)結(jié)構(gòu)有如下這些特點(diǎn):

    1. 每個(gè)子目錄項(xiàng)如 NameService 都被稱作為 znode,這個(gè) znode 是被它所在的路徑唯一標(biāo)識(shí),如 Server1 這個(gè) znode 的標(biāo)識(shí)為 /NameService/Server1
    2. znode 可以有子節(jié)點(diǎn)目錄,并且每個(gè) znode 可以存儲(chǔ)數(shù)據(jù),注意 EPHEMERAL 類型的目錄節(jié)點(diǎn)不能有子節(jié)點(diǎn)目錄
    3. znode 是有版本的,每個(gè) znode 中存儲(chǔ)的數(shù)據(jù)可以有多個(gè)版本,也就是一個(gè)訪問(wèn)路徑中可以存儲(chǔ)多份數(shù)據(jù)
    4. znode 可以是臨時(shí)節(jié)點(diǎn),一旦創(chuàng)建這個(gè) znode 的客戶端與服務(wù)器失去聯(lián)系,這個(gè) znode 也將自動(dòng)刪除,Zookeeper 的客戶端和服務(wù)器通信采用長(zhǎng)連接方式,每個(gè)客戶端和服務(wù)器通過(guò)心跳來(lái)保持連接,這個(gè)連接狀態(tài)稱為 session,如果 znode 是臨時(shí)節(jié)點(diǎn),這個(gè) session 失效,znode 也就刪除了
    5. znode 的目錄名可以自動(dòng)編號(hào),如 App1 已經(jīng)存在,再創(chuàng)建的話,將會(huì)自動(dòng)命名為 App2
    6. znode 可以被監(jiān)控,包括這個(gè)目錄節(jié)點(diǎn)中存儲(chǔ)的數(shù)據(jù)的修改,子節(jié)點(diǎn)目錄的變化等,一旦變化可以通知設(shè)置監(jiān)控的客戶端,這個(gè)是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于這個(gè)特性實(shí)現(xiàn)的,后面在典型的應(yīng)用場(chǎng)景中會(huì)有實(shí)例介紹

     

    ZooKeeper 典型的應(yīng)用場(chǎng)景

    Zookeeper 從設(shè)計(jì)模式角度來(lái)看,是一個(gè)基于觀察者模式設(shè)計(jì)的分布式服務(wù)管理框架,它負(fù)責(zé)存儲(chǔ)和管理大家都關(guān)心的數(shù)據(jù),然后接受觀察者的注冊(cè),一旦這些數(shù)據(jù)的狀態(tài)發(fā)生 變化,Zookeeper 就將負(fù)責(zé)通知已經(jīng)在 Zookeeper 上注冊(cè)的那些觀察者做出相應(yīng)的反應(yīng),從而實(shí)現(xiàn)集群中類似 Master/Slave 管理模式,關(guān)于 Zookeeper 的詳細(xì)架構(gòu)等內(nèi)部細(xì)節(jié)可以閱讀 Zookeeper 的源碼

    下面詳細(xì)介紹這些典型的應(yīng)用場(chǎng)景,也就是 Zookeeper 到底能幫我們解決那些問(wèn)題?下面將給出答案。

    統(tǒng)一命名服務(wù)(Name Service)

    分布式應(yīng)用中,通常需要有一套完整的命名規(guī)則,既能夠產(chǎn)生唯一的名稱又便于人識(shí)別和記住,通常情況下用樹形的名稱結(jié)構(gòu)是一個(gè)理想的選擇,樹形 的名稱結(jié)構(gòu)是一個(gè)有層次的目錄結(jié)構(gòu),既對(duì)人友好又不會(huì)重復(fù)。說(shuō)到這里你可能想到了 JNDI(Java Naming and Directory Interface,Java命名和目錄接口,是一組在Java應(yīng)用中訪問(wèn)命名和目錄服務(wù)的API),沒(méi)錯(cuò) Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結(jié)構(gòu)關(guān)聯(lián)到一定資源上,但是 Zookeeper 的 Name Service 更加是廣泛意義上的關(guān)聯(lián),也許你并不需要將名稱關(guān)聯(lián)到特定資源上,你可能只需要一個(gè)不會(huì)重復(fù)名稱,就像數(shù)據(jù)庫(kù)中產(chǎn)生一個(gè)唯一的數(shù)字主鍵一樣。

    Name Service 已經(jīng)是 Zookeeper 內(nèi)置的功能,你只要調(diào)用 Zookeeper 的 API 就能實(shí)現(xiàn)。如調(diào)用 create 接口就可以很容易創(chuàng)建一個(gè)目錄節(jié)點(diǎn)。

    配置管理(Configuration Management

    配置的管理在分布式應(yīng)用環(huán)境中很常見(jiàn),例如同一個(gè)應(yīng)用系統(tǒng)需要多臺(tái) PC Server 運(yùn)行,但是它們運(yùn)行的應(yīng)用系統(tǒng)的某些配置項(xiàng)是相同的,如果要修改這些相同的配置項(xiàng),那么就必須同時(shí)修改每臺(tái)運(yùn)行這個(gè)應(yīng)用系統(tǒng)的 PC Server,這樣非常麻煩而且容易出錯(cuò)。

    像這樣的配置信息完全可以交給 Zookeeper 來(lái)管理,將配置信息保存在 Zookeeper 的某個(gè)目錄節(jié)點(diǎn)中,然后將所有需要修改的應(yīng)用機(jī)器監(jiān)控配置信息的狀態(tài),一旦配置信息發(fā)生變化,每臺(tái)應(yīng)用機(jī)器就會(huì)收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應(yīng)用到系統(tǒng)中。


    2. 配置管理結(jié)構(gòu)圖

    集群管理(Group Membership

    Zookeeper 能夠很容易的實(shí)現(xiàn)集群管理的功能,如有多臺(tái) Server 組成一個(gè)服務(wù)集群,那么必須要一個(gè)“總管”知道當(dāng)前集群中每臺(tái)機(jī)器的服務(wù)狀態(tài),一旦有機(jī)器不能提供服務(wù),集群中其它集群必須知道,從而做出調(diào)整重新分配服 務(wù)策略。同樣當(dāng)增加集群的服務(wù)能力時(shí),就會(huì)增加一臺(tái)或多臺(tái) Server,同樣也必須讓“總管”知道。

    Zookeeper 不僅能夠幫你維護(hù)當(dāng)前的集群中機(jī)器的服務(wù)狀態(tài),而且能夠幫你選出一個(gè)“總管”,讓這個(gè)總管來(lái)管理集群,這就是 Zookeeper 的另一個(gè)功能 Leader Election。

    它們的實(shí)現(xiàn)方式都是在 Zookeeper 上創(chuàng)建一個(gè) EPHEMERAL 類型的目錄節(jié)點(diǎn),然后每個(gè) Server 在它們創(chuàng)建目錄節(jié)點(diǎn)的父目錄節(jié)點(diǎn)上調(diào)用 getChildren(String path, boolean watch) 方法并設(shè)置 watch 為 true,由于是 EPHEMERAL 目錄節(jié)點(diǎn),當(dāng)創(chuàng)建它的 Server 死去,這個(gè)目錄節(jié)點(diǎn)也隨之被刪除,所以 Children 將會(huì)變化,這時(shí) getChildren上的 Watch 將會(huì)被調(diào)用,所以其它 Server 就知道已經(jīng)有某臺(tái) Server 死去了。新增 Server 也是同樣的原理。

    Zookeeper 如何實(shí)現(xiàn) Leader Election,也就是選出一個(gè) Master Server。和前面的一樣每臺(tái) Server 創(chuàng)建一個(gè) EPHEMERAL 目錄節(jié)點(diǎn),不同的是它還是一個(gè) SEQUENTIAL 目錄節(jié)點(diǎn),所以它是個(gè) EPHEMERAL_SEQUENTIAL 目錄節(jié)點(diǎn)。之所以它是 EPHEMERAL_SEQUENTIAL 目錄節(jié)點(diǎn),是因?yàn)槲覀兛梢越o每臺(tái) Server 編號(hào),我們可以選擇當(dāng)前是最小編號(hào)的 Server 為 Master,假如這個(gè)最小編號(hào)的 Server 死去,由于是 EPHEMERAL 節(jié)點(diǎn),死去的 Server 對(duì)應(yīng)的節(jié)點(diǎn)也被刪除,所以當(dāng)前的節(jié)點(diǎn)列表中又出現(xiàn)一個(gè)最小編號(hào)的節(jié)點(diǎn),我們就選擇這個(gè)節(jié)點(diǎn)為當(dāng)前 Master。這樣就實(shí)現(xiàn)了動(dòng)態(tài)選擇 Master,避免了傳統(tǒng)意義上單 Master 容易出現(xiàn)單點(diǎn)故障的問(wèn)題。


    3. 集群管理結(jié)構(gòu)圖

    這部分的示例代碼如下,完整的代碼請(qǐng)看源代碼:


    清單 3. Leader Election 關(guān)鍵代碼

                                   
     void findLeader() throws InterruptedException { 
            byte[] leader = null; 
            try { 
                leader = zk.getData(root + "/leader", true, null); 
            } catch (Exception e) { 
                logger.error(e); 
            } 
            if (leader != null) { 
                following(); 
            } else { 
                String newLeader = null; 
                try { 
                    byte[] localhost = InetAddress.getLocalHost().getAddress(); 
                    newLeader = zk.create(root + "/leader", localhost, 
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 
                } catch (Exception e) { 
                    logger.error(e); 
                } 
                if (newLeader != null) { 
                    leading(); 
                } else { 
                    mutex.wait(); 
                } 
            } 
        } 

     

    共享鎖(Locks)

    共享鎖在同一個(gè)進(jìn)程中很容易實(shí)現(xiàn),但是在跨進(jìn)程或者在不同 Server 之間就不好實(shí)現(xiàn)了。Zookeeper 卻很容易實(shí)現(xiàn)這個(gè)功能,實(shí)現(xiàn)方式也是需要獲得鎖的 Server 創(chuàng)建一個(gè) EPHEMERAL_SEQUENTIAL 目錄節(jié)點(diǎn),然后調(diào)用 getChildren方法獲取當(dāng)前的目錄節(jié)點(diǎn)列表中最小的目錄節(jié)點(diǎn)是不是就是自己創(chuàng)建的目錄節(jié)點(diǎn),如果正是自己創(chuàng)建的,那么它就獲得了這個(gè)鎖,如果不是那么它就調(diào)用 exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點(diǎn)列表的變化,一直到自己創(chuàng)建的節(jié)點(diǎn)是列表中最小編號(hào)的目錄節(jié)點(diǎn),從而獲得鎖,釋放鎖很簡(jiǎn)單,只要?jiǎng)h除前面它自己所創(chuàng)建的目錄節(jié)點(diǎn)就行了。


    4. Zookeeper 實(shí)現(xiàn) Locks 的流程圖

    同步鎖的實(shí)現(xiàn)代碼如下,完整的代碼請(qǐng)看源代碼:


    清單 4. 同步鎖的關(guān)鍵代碼

                                   
     void getLock() throws KeeperException, InterruptedException{ 
            List<String> list = zk.getChildren(root, false); 
            String[] nodes = list.toArray(new String[list.size()]); 
            Arrays.sort(nodes); 
            if(myZnode.equals(root+"/"+nodes[0])){ 
                doAction(); 
            } 
            else{ 
                waitForLock(nodes[0]); 
            } 
        } 
        void waitForLock(String lower) throws InterruptedException, KeeperException {
            Stat stat = zk.exists(root + "/" + lower,true); 
            if(stat != null){ 
                mutex.wait(); 
            } 
            else{ 
                getLock(); 
            } 
        } 

     

    隊(duì)列管理

    Zookeeper 可以處理兩種類型的隊(duì)列:

    1. 當(dāng)一個(gè)隊(duì)列的成員都聚齊時(shí),這個(gè)隊(duì)列才可用,否則一直等待所有成員到達(dá),這種是同步隊(duì)列。
    2. 隊(duì)列按照 FIFO 方式進(jìn)行入隊(duì)和出隊(duì)操作,例如實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者模型。

    同步隊(duì)列用 Zookeeper 實(shí)現(xiàn)的實(shí)現(xiàn)思路如下:

    創(chuàng)建一個(gè)父目錄 /synchronizing,每個(gè)成員都監(jiān)控標(biāo)志(Set Watch)位目錄 /synchronizing/start 是否存在,然后每個(gè)成員都加入這個(gè)隊(duì)列,加入隊(duì)列的方式就是創(chuàng)建 /synchronizing/member_i 的臨時(shí)目錄節(jié)點(diǎn),然后每個(gè)成員獲取 / synchronizing 目錄的所有目錄節(jié)點(diǎn),也就是 member_i。判斷 i 的值是否已經(jīng)是成員的個(gè)數(shù),如果小于成員個(gè)數(shù)等待 /synchronizing/start 的出現(xiàn),如果已經(jīng)相等就創(chuàng)建 /synchronizing/start。

    用下面的流程圖更容易理解:


    5. 同步隊(duì)列流程圖

    同步隊(duì)列的關(guān)鍵代碼如下,完整的代碼請(qǐng)看附件:


    清單 5. 同步隊(duì)列

                                   
     void addQueue() throws KeeperException, InterruptedException{ 
            zk.exists(root + "/start",true); 
            zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE, 
            CreateMode.EPHEMERAL_SEQUENTIAL); 
            synchronized (mutex) { 
                List<String> list = zk.getChildren(root, false); 
                if (list.size() < size) { 
                    mutex.wait(); 
                } else { 
                    zk.create(root + "/start", new byte[0], Ids.OPEN_ACL_UNSAFE,
                     CreateMode.PERSISTENT); 
                } 
            } 
     } 

     

    當(dāng)隊(duì)列沒(méi)滿是進(jìn)入 wait(),然后會(huì)一直等待 Watch 的通知,Watch 的代碼如下:

     public void process(WatchedEvent event) { 
            if(event.getPath().equals(root + "/start") &&
             event.getType() == Event.EventType.NodeCreated){ 
                System.out.println("得到通知"); 
                super.process(event); 
                doAction(); 
            } 
        } 

     

    FIFO 隊(duì)列用 Zookeeper 實(shí)現(xiàn)思路如下:

    實(shí)現(xiàn)的思路也非常簡(jiǎn)單,就是在特定的目錄下創(chuàng)建 SEQUENTIAL 類型的子目錄 /queue_i,這樣就能保證所有成員加入隊(duì)列時(shí)都是有編號(hào)的,出隊(duì)列時(shí)通過(guò) getChildren( ) 方法可以返回當(dāng)前所有的隊(duì)列中的元素,然后消費(fèi)其中最小的一個(gè),這樣就能保證 FIFO

    下面是生產(chǎn)者和消費(fèi)者這種隊(duì)列形式的示例代碼,完整的代碼請(qǐng)看附件:


    清單 6. 生產(chǎn)者代碼

                                   
     boolean produce(int i) throws KeeperException, InterruptedException{ 
            ByteBuffer b = ByteBuffer.allocate(4); 
            byte[] value; 
            b.putInt(i); 
            value = b.array(); 
            zk.create(root + "/element", value, ZooDefs.Ids.OPEN_ACL_UNSAFE, 
                        CreateMode.PERSISTENT_SEQUENTIAL); 
            return true; 
        } 



    清單 7. 消費(fèi)者代碼

                                   
     int consume() throws KeeperException, InterruptedException{ 
            int retvalue = -1; 
            Stat stat = null; 
            while (true) { 
                synchronized (mutex) { 
                    List<String> list = zk.getChildren(root, true); 
                    if (list.size() == 0) { 
                        mutex.wait(); 
                    } else { 
                        Integer min = new Integer(list.get(0).substring(7)); 
                        for(String s : list){ 
                            Integer tempValue = new Integer(s.substring(7)); 
                            if(tempValue < min) min = tempValue; 
                        } 
                        byte[] b = zk.getData(root + "/element" + min,false, stat); 
                        zk.delete(root + "/element" + min, 0); 
                        ByteBuffer buffer = ByteBuffer.wrap(b); 
                        retvalue = buffer.getInt(); 
                        return retvalue; 
                    } 
                } 
            } 
     } 

     

    總結(jié)

    Zookeeper 作為 Hadoop 項(xiàng)目中的一個(gè)子項(xiàng)目,是 Hadoop 集群管理的一個(gè)必不可少的模塊,它主要用來(lái)控制集群中的數(shù)據(jù),如它管理 Hadoop 集群中的 NameNode,還有 Hbase 中 Master Election、Server 之間狀態(tài)同步等。

    本文介紹的 Zookeeper 的基本知識(shí),以及介紹了幾個(gè)典型的應(yīng)用場(chǎng)景。這些都是 Zookeeper 的基本功能,最重要的是 Zoopkeeper 提供了一套很好的分布式集群管理的機(jī)制,就是它這種基于層次型的目錄樹的數(shù)據(jù)結(jié)構(gòu),并對(duì)樹中的節(jié)點(diǎn)進(jìn)行有效管理,從而可以設(shè)計(jì)出多種多樣的分布式的數(shù)據(jù)管 理模型,而不僅僅局限于上面提到的幾個(gè)常用應(yīng)用場(chǎng)景。


    posted @ 2011-10-29 20:18 俞靈 閱讀(5213) | 評(píng)論 (1)編輯 收藏

    使用 Linux 系統(tǒng)總是免不了要接觸包管理工具。比如,Debian/Ubuntu 的 apt、openSUSE 的 zypp、Fedora 的 yum、Mandriva 的 urpmi、Slackware 的 slackpkg、Archlinux 的 pacman、Gentoo 的 emerge、Foresight 的 conary、Pardus 的 pisi,等等。DistroWatch 針對(duì)上述包管理器的主要用法進(jìn)行了總結(jié),對(duì)各位 Linux 用戶來(lái)說(shuō)具有很好的參考作用。這個(gè)總結(jié)還是有一點(diǎn)不足,有空給大家整理一個(gè)更全面的版本。

    任務(wù) apt
    Debian, Ubuntu
    zypp
    openSUSE
    yum
    Fedora, CentOS
    安裝包 apt-get install <pkg> zypper install <pkg> yum install <pkg>
    移除包 apt-get remove <pkg> zypper remove <pkg> yum erase <pkg>
    更新包列表 apt-get update zypper refresh yum check-update
    更新系統(tǒng) apt-get upgrade zypper update yum update
    列出源 cat /etc/apt/sources.list zypper repos yum repolist
    添加源 (edit /etc/apt/sources.list) zypper addrepo <path> <name> (add <repo> to /etc/yum.repos.d/)
    移除源 (edit /etc/apt/sources.list) zypper removerepo <name> (remove <repo> from /etc/yum.repos.d/)
    搜索包 apt-cache search <pkg> zypper search <pkg> yum search <pkg>
    列出已安裝的包 dpkg -l rpm -qa rpm -qa
    任務(wù) urpmi
    Mandriva
    slackpkg
    Slackware
    pacman
    Arch
    安裝包 urpmi <pkg> slackpkg install <pkg> pacman -S <pkg>
    移除包 urpme <pkg> slackpkg remove <pkg> pacman -R <pkg>
    更新包列表 urpmi.update -a slackpkg update pacman -Sy
    更新系統(tǒng) urpmi --auto-select slackpkg upgrade-all pacman -Su
    列出源 urpmq --list-media cat /etc/slackpkg/mirrors cat /etc/pacman.conf
    添加源 urpmi.addmedia <name> <path> (edit /etc/slackpkg/mirrors) (edit /etc/pacman.conf)
    移除源 urpmi.removemedia <media> (edit /etc/slackpkg/mirrors) (edit /etc/pacman.conf)
    搜索包 urpmf <pkg> -- pacman -Qs <pkg>
    列出已安裝的包 rpm -qa ls /var/log/packages/ pacman -Qii
    任務(wù) conary
    rPath, Foresight
    pisi
    Pardus
    emerge
    Gentoo
    安裝包 conary update <pkg> pisi install <pkg> emerge <pkg>
    移除包 conary erase <pkg> pisi remove <pkg> emerge -C <pkg>
    更新包列表   pisi update-repo emerge --sync | layman -S [for added repositories]
    更新系統(tǒng) conary updateall pisi upgrade emerge -NuDa world
    列出源   pisi list-repo layman -L
    添加源   pisi add-repo <name> <path> layman -a
    移除源   pisi remove-repo <name> layman -d
    搜索包 conary query <pkg> pisi search <pkg> emerge --search
    列出已安裝的包 conary query pisi list-installed cat /var/lib/portage | more
    本文轉(zhuǎn)自
    http://linuxtoy.org/archives/linux-package-management-cheatsheet.html

    posted @ 2011-10-22 15:02 俞靈 閱讀(428) | 評(píng)論 (0)編輯 收藏

    -Xms256m
    -Xmx512m
    -Xmn128m
    -XX:PermSize=96m
    -XX:MaxPermSize=96m
    -Xverify:none
    -Xnoclassgc
    -XX:UseParNewGC
    -XX:+UseConcMarkSweepGC
    -XX:CMSInitiatingOccupancyFraction=85
    加入以上參數(shù)能使eclipse啟動(dòng)速度得到加快.至于各個(gè)參數(shù)的意義可以在網(wǎng)上查找到,這里不詳細(xì)贅述.

    posted @ 2011-10-16 13:10 俞靈 閱讀(1801) | 評(píng)論 (2)編輯 收藏

    Eclipse插件開發(fā)

    1. 下載并安裝jdkeclipse
      
    這里強(qiáng)調(diào)一下: 需要下載Eclipse for RCP and RAP Developers, 否則無(wú)法新建Plug-in Development 項(xiàng)目.
    2.
    新建項(xiàng)目
      
    安裝好之后打開eclipse, 點(diǎn)擊 File->NewProject。選擇Plug-in Project,點(diǎn)擊Next。新建一個(gè)名為com.developer.showtime的項(xiàng)目,所有參數(shù)采用默認(rèn)值.

    3. com.developer.showtime項(xiàng)目的src下新建一個(gè)類: ShowTime,代碼如下:

     

    package com.developer.showtime;

    import org.eclipse.jface.dialogs.MessageDialog;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    import org.eclipse.ui.IStartup;

    public class ShowTime implements IStartup {
        
    public void earlyStartup() {
            Display.getDefault().syncExec(
    new Runnable() {
                
    public void run(){
                    
    long eclipseStartTime = Long.parseLong(System.getProperty("eclipse.startTime"));
                    
    long costTime = System.currentTimeMillis() - eclipseStartTime;
                    Shell shell 
    = Display.getDefault().getActiveShell();
                    String message 
    = "Eclipse start in " + costTime + "ms";
                    MessageDialog.openInformation(shell, 
    "Information", message);
                }
            });
        }
    }

    4. 修改plugin.xml文件如下:


    <?xml version="1.0" encoding="UTF-8"?>

    <?eclipse version="3.4"?>

    <plugin>
       
    <extension

             point
    ="org.eclipse.ui.startup">

             
    <startup class="com.developer.showtime.ShowTime"/>

       
    </extension>

    </plugin>

    5. 試運(yùn)行

    右鍵點(diǎn)擊Run as -> Eclipse Application. 此時(shí)會(huì)運(yùn)行一個(gè)eclipse, 啟動(dòng)之后就能顯示啟動(dòng)所需時(shí)間.

    6. 導(dǎo)出插件.

    右鍵Export -> Deployable plug-ins and fragments. Directory中輸入需要導(dǎo)出的路徑, 點(diǎn)擊finish后會(huì)在該目錄下產(chǎn)生一個(gè)plugins的目錄, 里面就是插件包: com.developer.showTime_1.0.0.201110161216.jar. 把這個(gè)包復(fù)制到eclipse目錄下的plugin目錄下. 然后再啟動(dòng)eclipse 便可以看到eclipse啟動(dòng)所花的時(shí)間.

    posted @ 2011-10-16 13:07 俞靈 閱讀(7125) | 評(píng)論 (2)編輯 收藏

    本周學(xué)習(xí)了mapreduce-64,對(duì)map端的spill有了較為深入的了解.
    附件描述了修改前后sort的原理.mapreduce-64前spill原理較為簡(jiǎn)單,打上mapreduce-64后主要流程也不難,需要了解各個(gè)參數(shù)的意義.


    posted @ 2011-09-18 15:47 俞靈 閱讀(3272) | 評(píng)論 (7)編輯 收藏

    下文翻譯自yahoo博客:
    http://developer.yahoo.com/blogs/hadoop/posts/2011/02/mapreduce-nextgen/

    Hadoop的下一代mapreduce

    概述

    在大數(shù)據(jù)商業(yè)領(lǐng)域中,運(yùn)行個(gè)數(shù)少但較大的集群比運(yùn)行多個(gè)小集群更劃算,大集群還可以處理更大的數(shù)據(jù)集并支持更多的作業(yè)和用戶.

    Apache Hadoop MapReduce框架已經(jīng)達(dá)到4000臺(tái)機(jī)器的擴(kuò)展極限,我們正在發(fā)展下一代MapReduce,使其成為一個(gè)通用資源管理,單作業(yè),用戶自定義組件,管理著應(yīng)用程序執(zhí)行的框架. 由于停機(jī)成本更大,高可用必需從一開始就得建立,就如安全性和多用戶組,用以支持更多用戶使用更大的集群,新的構(gòu)架在許多地方進(jìn)行了創(chuàng)新,增加了敏捷性和機(jī)器利用率.

    背景

    當(dāng)前Apache Hadoop MapReduce的接口會(huì)顯示其年齡.

    由于集群大小和工作負(fù)載的變化趨勢(shì), MapReduceJobTracker需要徹底的改革以解決其可擴(kuò)展性,內(nèi)存消耗,線程模型,可靠性和性能上的不足. 過(guò)去五年,我們做了一些小的修復(fù),然而最近,修改框架的的成本越來(lái)越高. 結(jié)構(gòu)的缺陷和糾正措施都很好理解,甚至早在2007,當(dāng)我們記錄下修復(fù)建議: https://issues.apache.org/jira/browse/MAPREDUCE-278.

    從運(yùn)營(yíng)的角度看,目前的Hadoop MapReduce框架面臨系統(tǒng)級(jí)別的升級(jí),以解決例如bug修復(fù),性能改善和功能的需求. 更糟糕的是,它迫使每個(gè)用戶也需要同時(shí)升級(jí),不顧其利益;這使用戶使用新版本的周期變長(zhǎng).

    需求

    我們考慮改善Hadoop MapReduce框架的方法,重要的是記住最迫切的需求,下一代Hadoop MapReduce框架最迫切的需求是:

    • 可靠性
    • 可用性
    • 可擴(kuò)展性 - 10000臺(tái)機(jī)器,200000核,或者更多
    • 向后兼容性 - 確保用戶的MapReduce應(yīng)用程序在下一代框架下不需要改變
    • 進(jìn)展 – 客戶端可以控制hadoop軟件堆棧的升級(jí).
    • 可預(yù)測(cè)的延遲 – 用戶很關(guān)注的一點(diǎn).
    • 集群利用率

    第二層次需求:

    • 使MapReduce支持備用編程范式
    • 支持短時(shí)間的服務(wù)

    鑒于以上需求,顯然我們需要重新考慮使用hadoop成為數(shù)據(jù)處理的基礎(chǔ)設(shè)施. 事實(shí)上,當(dāng)前MapReduce結(jié)構(gòu)無(wú)法滿足我們的需求,因此需要新的創(chuàng)新,這在hadoop社區(qū)這已成為共識(shí),查看2008年一月的一個(gè)提議,在jira: https://issues.apache.org/jira/browse/MAPREDUCE-279.

    下一代MapReduce

    重構(gòu)的基本思想是把jobtracker的兩大功能分開,使資源管理和作業(yè)分配/監(jiān)控成為兩個(gè)部件.新的資源管理器管理提供給應(yīng)用(一個(gè)或多個(gè))的計(jì)算資源,應(yīng)用管理中心管理應(yīng)用程序的調(diào)度和協(xié)調(diào),應(yīng)用程序既是一個(gè)經(jīng)典MapReduce作業(yè)也是這類作業(yè)的DAG. 資源管理器和每臺(tái)機(jī)器的NodeManager服務(wù),管理該機(jī)上的用戶進(jìn)程,形成計(jì)算結(jié)構(gòu). 每個(gè)應(yīng)用程序的ApplicationMaster是一個(gè)具體庫(kù)的架構(gòu),負(fù)責(zé)從資源管理器請(qǐng)求資源,并和NodeManager協(xié)同執(zhí)行和監(jiān)控任務(wù).

    資源管理器支持應(yīng)用程序的分組,這些組保證使用一定比例集群資源. 它是純粹的調(diào)度,也就是,它運(yùn)行時(shí)并不監(jiān)控和追蹤應(yīng)用的狀態(tài). 此外,它不保證重新啟動(dòng)失敗的任務(wù),無(wú)論是應(yīng)用程序或硬件導(dǎo)致的失敗.

    資源管理器執(zhí)行調(diào)度功能是基于應(yīng)用的資源需求,每個(gè)應(yīng)用需要多種資源需求,代表對(duì)對(duì)容器所需的資源,資源需求包括內(nèi)存,cpu,硬盤,網(wǎng)絡(luò)等,注意這與當(dāng)前使用slot模型的MapReduce有很大的不同,slot模型導(dǎo)致集群利用率不高,資源管理器有一個(gè)調(diào)度策略插件,負(fù)責(zé)分把集群資源分給各個(gè)組,應(yīng)用等.有基礎(chǔ)的調(diào)度插件,例如:當(dāng)前的CapacityScheduler FairScheduler.

    NodeManager是每臺(tái)機(jī)器的框架代理,負(fù)責(zé)提交應(yīng)用程序的容器,監(jiān)控他們的資源利用率(cpu,內(nèi)存,硬盤,網(wǎng)絡(luò)),并且報(bào)告給調(diào)度器.

    每個(gè)應(yīng)用程序的ApplicationMaster負(fù)責(zé)與調(diào)度器請(qǐng)求適當(dāng)?shù)馁Y源容器,提交作業(yè),追蹤其狀態(tài),監(jiān)控進(jìn)度和處理失敗任務(wù).

    結(jié)構(gòu)


    改進(jìn)當(dāng)前實(shí)現(xiàn)面對(duì)面的Hadoop MapReduce

    可擴(kuò)展性

    在集群中把資源管理從集群管理器的整個(gè)生命周期和他們的部件中分離出來(lái)后形成的架構(gòu):擴(kuò)展性更好并且更優(yōu)雅, Hadoop MapReduceJobTracker花費(fèi)很大一部分時(shí)間和精力管理應(yīng)用程序的生命周期,這是導(dǎo)致軟件災(zāi)難的原因.把它移到應(yīng)用指定的實(shí)體是一個(gè)重大的勝利.

    可擴(kuò)展性在當(dāng)前硬件趨勢(shì)下更加重要,當(dāng)前hadoopMapReduce已經(jīng)發(fā)展到4000臺(tái)機(jī)器,然而4000臺(tái)機(jī)器在2009(:8core,16G RAM,4TB硬盤)只有2011400臺(tái)機(jī)器的一半(16core,48G RAM, 24TB硬盤). 并且,運(yùn)營(yíng)成本的因素有助于迫使和鞏固我們使用更大的集群:6000臺(tái)機(jī)器或者更多.

    可用性

    • 資源管理器使用 Apache ZooKeeper 用于故障轉(zhuǎn)移. 當(dāng)資源管理器發(fā)生故障,另外一個(gè)可以迅速恢復(fù),這是由于集群狀態(tài)保存在ZooKeeper中. 資源管理器失敗后,重啟所有組和正在運(yùn)行的應(yīng)用程序.
    • 應(yīng)用中心 - 下一代MapReduce支持應(yīng)用特殊點(diǎn)的檢查功能 ,依靠其把自身狀態(tài)存儲(chǔ)在hdfs上的功能,MapReduce 應(yīng)用中心可以從失敗中恢復(fù),

    兼容性

    下一代MapReduce使用線兼容協(xié)議以允許不同版本的服務(wù)端和客戶端相互通信,在將來(lái)的releases版本,這將使集群滾動(dòng)升級(jí),一個(gè)重要的可操作性便成功了.

    創(chuàng)新和敏捷性

    提出的構(gòu)架一個(gè)主要優(yōu)點(diǎn)是MapReduce將更有效,成為user-land library. 計(jì)算框架(資源管理器和節(jié)點(diǎn)管理器)完全通用并在MapReduce看來(lái)是透明的.

    這使最終客戶在同一個(gè)集群使用可用不同版本的MapReduce, 這是微不足道的支持,因?yàn)?/span>MapReduce的應(yīng)用中心和運(yùn)行時(shí)的多版本可用于不同的應(yīng)用. 這為應(yīng)用提供顯著的靈活性,因?yàn)檎麄€(gè)集群沒(méi)必要升級(jí),如修復(fù)bug,改進(jìn)和新功能的應(yīng)用. 它也允許終端用戶根據(jù)他們自己的安排升級(jí)其應(yīng)用到MapReduce版本,這大大提高了集群的可操作性.

     

    允許用戶自定義的Map-Reduce版本的創(chuàng)新不會(huì)影響軟件的穩(wěn)定性. 這是微不足道的,就像hadoop在線原型進(jìn)入用戶MapReduce版本而不影響其他用戶.( It will be trivial to incorporate features such as the Hadoop Online Prototype into the user’s version of MapReduce without affecting other users.)

    集群利用率

    下一代MapReduce資源管理器使用通用概念,用于調(diào)度和分配給單獨(dú)的個(gè)體.

    集群中的每個(gè)機(jī)器資源是概念性的,例如內(nèi)存,cpu,I/O帶寬等. 每個(gè)機(jī)器都是可替代的,分配給應(yīng)用程序就像基于應(yīng)用指定需求資源的容器.每個(gè)容器包括一些處理器,并和其他容器邏輯隔離,提供強(qiáng)有利的多租戶支持.

    它刪除了當(dāng)前hadoop  MapReducemapreduce slots概念. Slot會(huì)影響集群的利用率,因?yàn)樵谌魏螘r(shí)候,無(wú)論mapreduce都是稀缺的.

    支持MapReduce編程范式

    下一代MapReduce提供一個(gè)完全通用的計(jì)算框架以支持MapReduce和其他的范例.

    架構(gòu)允許終端用戶實(shí)現(xiàn)應(yīng)用指定的框架,通過(guò)實(shí)現(xiàn)用戶的ApplicationMaster,可以向資源管理器請(qǐng)求資源并利用他們,因?yàn)樗麄兺ㄟ^(guò)隔離并保證資源的情況下看起來(lái)是適合的.

    因此,在同一個(gè)hadoop集群下支持多種編程范式,例如MapReduce, MPI, Master-Worker和迭代模型,并允許為每個(gè)應(yīng)用使用適當(dāng)?shù)目蚣?/span>.這對(duì)自定義框架順序執(zhí)行一定數(shù)目的MapReduc應(yīng)用程序(: K-Means, Page-Rank)很重要.

    結(jié)論

    Apache Hadoop和特定的Hadoop MapReduce,是一個(gè)用于處理大數(shù)據(jù)集的成功開源項(xiàng)目. 我們建議Hadoop MapReduce重構(gòu)以提供高可用性,增加集群利用率,提供編程范例的支持以加快發(fā)展.

    我們認(rèn)為,在已存在的選項(xiàng)中如Torque, Condor, Mesos ,沒(méi)有一個(gè)用于設(shè)計(jì)解決MapReduce集群規(guī)模的問(wèn)題, 某些功能很新且不成熟, 另外一些沒(méi)有解決關(guān)鍵問(wèn)題,如調(diào)度在上十萬(wàn)個(gè)task,規(guī)模的性能,安全和多用戶等.

    我們將與Apache Hadoop社區(qū)合作,為實(shí)現(xiàn)這以提升Apache Hadoop以適應(yīng)下一代大數(shù)據(jù)空間.


    0.23的調(diào)度方法: http://developer.yahoo.com/blogs/hadoop/posts/2011/03/mapreduce-nextgen-scheduler/

    posted @ 2011-09-12 16:28 俞靈 閱讀(2357) | 評(píng)論 (1)編輯 收藏

    周末無(wú)事,故翻譯sheepdog design.

    原文地址: https://github.com/collie/sheepdog/wiki/Sheepdog-Design

    Sheepdog 設(shè)計(jì)

    Sheeepdog采用完全對(duì)稱的結(jié)構(gòu),沒(méi)有類似元數(shù)據(jù)服務(wù)的中心節(jié)點(diǎn). 這種設(shè)計(jì)有以下的特點(diǎn).

    1)       性能于容量的線性的可擴(kuò)展性.

    當(dāng)需要提升性能或容量時(shí),只需向集群中增加新的機(jī)器便能使Sheeepdog線性成長(zhǎng).

    2)       沒(méi)有單點(diǎn)故障

    即使某臺(tái)機(jī)器發(fā)生故障,依然可以通過(guò)其他機(jī)器訪問(wèn)數(shù)據(jù).

    3)       容易管理

    不需要配置機(jī)器角色,當(dāng)管理員在新增的機(jī)器開啟Sheepdog守護(hù)進(jìn)程時(shí), Sheepdog會(huì)自動(dòng)檢測(cè)新加入的機(jī)器并配置它成為存儲(chǔ)系統(tǒng)中的一員.

    結(jié)構(gòu)概述



    Sheepdog是一個(gè)分布式存儲(chǔ)系統(tǒng).Sheepdog客戶端(QEMU的塊驅(qū)動(dòng)程序)提供對(duì)象存儲(chǔ)(類似于簡(jiǎn)單的鍵值對(duì)). 接下來(lái)幾章將更加詳細(xì)的闡述Sheepdog各個(gè)部分.

    1)       對(duì)象存儲(chǔ)(Object對(duì)象存儲(chǔ)(Object Storage)

    2)       )

    Sheepdog不同于一般的文件系統(tǒng), Sheepdog進(jìn)程為QEMU(Sheepdog進(jìn)程名)創(chuàng)建一個(gè)分布式對(duì)象存儲(chǔ)系統(tǒng),它可以存儲(chǔ)對(duì)象”.這里的對(duì)象數(shù)據(jù)大小可變,并有唯一的標(biāo)識(shí),通過(guò)標(biāo)識(shí)可以進(jìn)行讀//創(chuàng)建/刪除操作.對(duì)象存儲(chǔ)組成網(wǎng)關(guān)對(duì)象管理器”.

    3)       網(wǎng)關(guān)(getway)

    Getway接收QEMU塊驅(qū)動(dòng)的I/O請(qǐng)求(對(duì)象id,偏移,長(zhǎng)度和操作類型),通過(guò)一直散列算法獲得目標(biāo)節(jié)點(diǎn),然后轉(zhuǎn)發(fā)I/O請(qǐng)求至該節(jié)點(diǎn).

    4)       對(duì)象管理器(Object manager)

    對(duì)象管理器接收getway轉(zhuǎn)發(fā)過(guò)來(lái)的I/O請(qǐng)求,然后對(duì)磁盤執(zhí)行讀/寫操作.

    5)       集群管理器(Cluster manager)

    集群管理器管理管理節(jié)點(diǎn)成員(探測(cè)失敗/新增節(jié)點(diǎn)并報(bào)告節(jié)點(diǎn)成員的變化),以及一些需要節(jié)點(diǎn)一致的操作(vdi 創(chuàng)建, 快照 vdi).當(dāng)前集群管理器使用corosync集群引擎.

    6)       QEMU 塊驅(qū)動(dòng)

    QEMU塊驅(qū)動(dòng)把VM image分為固定大小(默認(rèn)4M),并通過(guò)其getway存儲(chǔ)到對(duì)象存儲(chǔ)中

    對(duì)象存儲(chǔ)(Object Storage)

    每個(gè)對(duì)象使用一個(gè)64bit的整數(shù)作為全局標(biāo)識(shí),并在多臺(tái)機(jī)器存有備份,QEMU塊驅(qū)動(dòng)并不關(guān)心存儲(chǔ)的位置,對(duì)象存儲(chǔ)系統(tǒng)負(fù)責(zé)管理存儲(chǔ)的位置.

    對(duì)象類型(object types)

    Sheepdog的對(duì)象分為以下四種:

    1)       數(shù)據(jù)類型(data object)

    它包括虛擬磁盤映射的真實(shí)數(shù)據(jù),虛擬磁盤映射分為固定大小的數(shù)據(jù)對(duì)象, Sheepdog客戶端訪問(wèn)這個(gè)對(duì)象.

    2)       vdi object

    它包括虛擬磁盤映射的元數(shù)據(jù)(:映射名,磁盤大小,創(chuàng)建時(shí)間,vdi的數(shù)據(jù)對(duì)象ID).

    3)       vmstate object

    它存儲(chǔ)運(yùn)行中的VM狀態(tài)映射.管理員通過(guò)它獲取實(shí)時(shí)快照信息.

    4)       vdi attr object

    使用它存儲(chǔ)各個(gè)vdi的屬性,屬性為鍵值對(duì)類型,類似于普通文件的擴(kuò)展信息.

    對(duì)象ID規(guī)則(object ID rules)

    1) 0 - 31 (32 bits): 對(duì)象類型詳細(xì)信息

    2) 32 - 55 (24 bits): vdi id

    3) 56 - 59 ( 4 bits): 預(yù)留

    4) 60 - 63 ( 4 bits): 對(duì)象類型標(biāo)識(shí)符

    每個(gè)VDI有一個(gè)全局唯一的ID(vdi id), 通過(guò)VDI名求得的散列值,低三十二位使用如下:

    對(duì)象類型

    32位的作用

    數(shù)據(jù)類型

    虛擬磁盤映射的索引號(hào)

    Vdi對(duì)象

    未使用(0)

    Vm狀態(tài)對(duì)象

    Vm狀態(tài)映射索引

    Vdi屬性對(duì)象

    鍵名的散列值

     

    對(duì)象格式(object format)

    1)       數(shù)據(jù)對(duì)象

    虛擬磁盤映射的塊

    2)       Vdi對(duì)象

     

     1  struct sheepdog_inode {
     2      char name[SD_MAX_VDI_LEN];               /* the name of this VDI*/
     3      char tag[SD_MAX_VDI_TAG_LEN];           /* the snapshot tag name */
     4      uint64_t ctime;                                    /* creation time of this VDI */
     5      uint64_t snap_ctime;                            /* the time snapshot is taken */
     6      uint64_t vm_clock_nsec;                       /* vm clock (used for live snapshot) */
     7      uint64_t vdi_size;                                 /* the size of VDI */
     8      uint64_t vm_state_size;                        /* the size of vm state (used for live snapshot) */
     9      uint16_t copy_policy;                           /* reserved */
    10      uint8_t  nr_copies;                              /* the number of object redundancy */
    11      uint8_t  block_size_shift;                      /* info about the size of the data object */
    12      uint32_t snap_id;                                /* the snapshot id */
    13      uint32_t vdi_id;                                  /* the vdi id */
    14      uint32_t parent_vdi_id;                        /* the parent snapshot vdi id of this VDI */
    15      uint32_t child_vdi_id[MAX_CHILDREN];    /* the children VDIs of this VDI */
    16      uint32_t data_vdi_id[MAX_DATA_OBJS];   /* the data object IDs this VDI contains*/
    17  };

    3)       Vm狀態(tài)對(duì)象

    Vm狀態(tài)映射塊

    4)       Vdi屬性對(duì)象

    SD_MAX_VDI_ATTR_KEY_LEN(256)為屬性的鍵名,余下的是屬性指.

    只讀/可寫對(duì)象(read-only/writable objects)

    從如何訪問(wèn)對(duì)象的角度,我們還可以把Sheepdog對(duì)象分為以下兩類.

    1)       只讀對(duì)象(:VDI快照數(shù)據(jù)對(duì)象)

    只允許一個(gè)VM對(duì)其讀寫,其他vm無(wú)法訪問(wèn)

    2)       可寫對(duì)象

    不允許任何VM對(duì)其寫,所有VM都可讀

    其他功能(other features)

    Sheepdog對(duì)象存儲(chǔ)可接收正在寫時(shí)復(fù)制(copy-on-write)的請(qǐng)求.當(dāng)一個(gè)客戶端發(fā)送一個(gè)創(chuàng)建和寫的請(qǐng)求時(shí),同時(shí)可以指定基本對(duì)象(CoW操作的來(lái)源),這用于快照和克隆操作.

    網(wǎng)關(guān)(Gateway)

    對(duì)象存在哪(where to store objects)

    Sheepdog使用一致性哈希算法決定存放對(duì)象的位置,一致性哈希算法提供哈希表,而且增加或介紹節(jié)點(diǎn)不回顯著的改變對(duì)象映射,通過(guò)哈希表能使I/O負(fù)載均衡.

    副本(replication)

    Sheepdog的數(shù)據(jù)副本很簡(jiǎn)單,我們假設(shè)只有一個(gè)寫,所以寫沖突不會(huì)發(fā)生,客戶端可以并行發(fā)生請(qǐng)求到目標(biāo)節(jié)點(diǎn),發(fā)生讀請(qǐng)求到一個(gè)目標(biāo)節(jié)點(diǎn)如果客戶端自己處理I/O請(qǐng)求順序.

    I/O(write I/O flow)

    Getway使用一致性哈希算法計(jì)算目標(biāo)節(jié)點(diǎn)并發(fā)送寫請(qǐng)求到所有目標(biāo)節(jié)點(diǎn),只有所有副本均更新成功寫請(qǐng)求才會(huì)成功,這是因?yàn)槿绻粋€(gè)副本未更新,getway有可能從未更新的節(jié)點(diǎn)讀取舊數(shù)據(jù).

    I/O(read I/O flow)

    Getway使用一致性哈希算法計(jì)算目標(biāo)節(jié)點(diǎn),并發(fā)送讀請(qǐng)求到一個(gè)目標(biāo)節(jié)點(diǎn).

    1)       修復(fù)對(duì)象一致性

    當(dāng)某節(jié)點(diǎn)在轉(zhuǎn)發(fā)I/O請(qǐng)求時(shí)crash,有可能破壞副本的一致性,所以當(dāng)getway第一次讀取對(duì)象時(shí)會(huì)試圖修復(fù)其一致性,從一節(jié)點(diǎn)讀取整個(gè)對(duì)象并用它覆蓋所有副本.

    重試I/O請(qǐng)求(retrying I/O requests)

    Sheepdog存儲(chǔ)所有成員節(jié)點(diǎn)的歷史信息,我們把歷史版本號(hào)叫做”epoch”(詳見(jiàn)章節(jié)對(duì)象恢復(fù)’). 如果getway轉(zhuǎn)發(fā)I/O請(qǐng)求至目標(biāo)節(jié)點(diǎn)并且getway與目標(biāo)節(jié)點(diǎn)epoch號(hào)不相符,I/O請(qǐng)求失敗且getway重試請(qǐng)求直到epcho號(hào)相符,這就需要保持副本強(qiáng)一致性.

    I/O重試也可能發(fā)生在目標(biāo)節(jié)點(diǎn)掛了導(dǎo)致無(wú)法完成I/O操作.

    對(duì)象管理器(Object Manager)

    對(duì)象管理器把對(duì)象存儲(chǔ)到本地磁盤,當(dāng)前把每個(gè)對(duì)象存儲(chǔ)為一個(gè)文件,這中方法簡(jiǎn)單.我們也可以使用DBMS(: BerkeleyDB, Tokyo Cabinet) 作為對(duì)象存儲(chǔ)器,但還不支持.

    路徑命名規(guī)則(path name rule)

    對(duì)象存儲(chǔ)成如下路徑:

            /store_dir/obj/[epoch number]/[object ID]

    所有對(duì)象文件有一個(gè)擴(kuò)展屬性: 副本數(shù)(sheepdog.copies),

    寫日志(write journaling)

    當(dāng)sheep進(jìn)程在寫操作過(guò)程中失敗,對(duì)象有可能至少部分更新,一般情況這不會(huì)有問(wèn)題,因?yàn)槿绻?/span>VM未接收成功消息,不保證所寫部分的內(nèi)容.然而對(duì)于vdi對(duì)象,我們必須整體更新或整體未更新,因?yàn)槿绻?/span>vdi對(duì)象只是部分更新,VDI的元數(shù)據(jù)有可能被破壞. 為例防止這個(gè)問(wèn)題,我們使用日志記錄對(duì)vdi對(duì)象的寫操作. 日志過(guò)程很簡(jiǎn)單:

    1)       創(chuàng)建日志文件"/store_dir/journal/[epoch]/[vdi object id]"

    2)       首先寫數(shù)據(jù)到日志文件

    3)       寫一個(gè)數(shù)據(jù)到vdi對(duì)象

    4)       刪除日志文件

    集群管理器(Cluster Manager)

    大多情況, Sheepdo客戶端單獨(dú)訪問(wèn)它們的映射因?yàn)槲覀儾辉试S兩個(gè)客戶端同時(shí)訪問(wèn)一個(gè)映射,但是某些VDI操作(:克隆VDI,創(chuàng)建VDI)必須做,因?yàn)檫@些操作更新全局信息,我們使用Corosync集群引擎完成而不是中心服務(wù)器.

    我們將擴(kuò)展Sheepdog以支持其他集群管理系統(tǒng).

    本章正在編輯

    QEMU 塊驅(qū)動(dòng)(QEMU Block Driver)

    Sheepdog卷被分為4M的數(shù)據(jù)對(duì)象,剛創(chuàng)建的對(duì)象未分配,也就是說(shuō),只有寫對(duì)象被分配.

    Open

    首先QEMU塊驅(qū)動(dòng)通過(guò)getwaybdrv_open()從對(duì)象存儲(chǔ)讀取vdi

    /(read/write)

    塊驅(qū)動(dòng)通過(guò)請(qǐng)求的部分偏移量和大小計(jì)算數(shù)據(jù)對(duì)象id, 并向getway發(fā)送請(qǐng)求. 當(dāng)塊驅(qū)動(dòng)發(fā)送寫請(qǐng)求到那些不屬于其當(dāng)前vdi的數(shù)據(jù)對(duì)象是,塊驅(qū)動(dòng)發(fā)送CoW請(qǐng)求分配一個(gè)新的數(shù)據(jù)對(duì)象.

    寫入快照vdi(write to snapshot vdi)

    我們可以把快照VDI附加到QEMU, 當(dāng)塊驅(qū)動(dòng)第一次發(fā)送寫請(qǐng)求到快照VDI, 塊驅(qū)動(dòng)創(chuàng)建一個(gè)新的可寫VDI作為子快照,并發(fā)送請(qǐng)求到新的VDI.

    VDI操作(VDI Operations)

    查找(lookup)

    當(dāng)查找VDI對(duì)象時(shí):

    1)       通過(guò)求vdi名的哈希值得到vdi id

    2)       通過(guò)vdi id計(jì)算di對(duì)象

    3)       發(fā)送讀請(qǐng)求到vdi對(duì)象

    4)       如果此vdi不是請(qǐng)求的那個(gè),增加vdi id并重試發(fā)送讀請(qǐng)求

    快照,克隆(snapshot, cloning)

    快照可克隆操作很簡(jiǎn)單,

    1)       讀目標(biāo)VDI

    2)       創(chuàng)建一個(gè)與目標(biāo)一樣的新VDI

    3)       把新vdi‘'parent_vdi_id''設(shè)為目標(biāo)VDIid

    4)       設(shè)置目標(biāo)vdi''child_vdi_id''為新vdiid.

    5)       設(shè)置目標(biāo)vdi''snap_ctime''為當(dāng)前時(shí)間, vdi變?yōu)楫?dāng)前vdi對(duì)象

    刪除(delete)

    TODO:當(dāng)前,回收未使用的數(shù)據(jù)對(duì)象是不會(huì)被執(zhí)行,直到所有相關(guān)VDI對(duì)象(相關(guān)的快照VDI和克隆VDI)被刪除.

    所有相關(guān)VDI被刪除后, Sheepdog刪除所有此VDI的數(shù)據(jù)對(duì)象,設(shè)置此VDI對(duì)象名為空字符串.

    對(duì)象恢復(fù)(Object Recovery)

    epoch

    Sheepdog把成員節(jié)點(diǎn)歷史存儲(chǔ)在存儲(chǔ)路徑, 路徑名如下:

            /store_dir/epoch/[epoch number]

    每個(gè)文件包括節(jié)點(diǎn)在epoch的列表信息(IP地址,端口,虛擬節(jié)點(diǎn)個(gè)數(shù)).

    恢復(fù)過(guò)程(recovery process)

    1)       從所有節(jié)點(diǎn)接收存儲(chǔ)對(duì)象ID

    2)       計(jì)算選擇那個(gè)對(duì)象

    3)       創(chuàng)建對(duì)象ID list文件"/store_dir/obj/[the current epoch]/list"

    4)       發(fā)送一個(gè)讀請(qǐng)求以獲取id存在于list文件的對(duì)象. 這個(gè)請(qǐng)求被發(fā)送到包含前一次epoch的對(duì)象的節(jié)點(diǎn).( The requests are sent to the node which had the object at the previous epoch.)

    5)       把對(duì)象存到當(dāng)前epoch路徑.

    沖突的I/O(conflicts I/Os)

    如果QEMU發(fā)送I/O請(qǐng)求到某些未恢復(fù)的對(duì)象, Sheepdog阻塞此請(qǐng)求并優(yōu)先恢復(fù)對(duì)象.

    協(xié)議(Protocol)

    Sheepdog的所有請(qǐng)求包含固定大小的頭部(48)和固定大小的數(shù)據(jù)部分,頭部包括協(xié)議版本,操作碼,epoch號(hào),數(shù)據(jù)長(zhǎng)度等.

    between sheep and QEMU

    操作碼

    描述

    SD_OP_CREATE_AND_WRITE_OBJ

    發(fā)送請(qǐng)求以創(chuàng)建新對(duì)象并寫入數(shù)據(jù),如果對(duì)象存在,操作失敗

    SD_OP_READ_OBJ

    讀取對(duì)象中的數(shù)據(jù)

    SD_OP_WRITE_OBJ

    向?qū)ο髮懭霐?shù)據(jù),如果對(duì)象不存在,失敗

    SD_OP_NEW_VDI

    發(fā)送vdi名到對(duì)象存儲(chǔ)并創(chuàng)建新vdi對(duì)象, 返回應(yīng)答vdi的唯一的vdi id

    SD_OP_LOCK_VDI

    SD_OP_GET_VDI_INFO相同

    SD_OP_RELEASE_VDI

    未使用

    SD_OP_GET_VDI_INFO

    獲取vdi信息(:vdi id)

    SD_OP_READ_VDIS

    獲取已經(jīng)使用的vdi id

    between sheep and collie

    操作碼

    描述

    SD_OP_DEL_VDI

    刪除VDI

    SD_OP_GET_NODE_LIST

    獲取sheepdog的節(jié)點(diǎn)列表

    SD_OP_GET_VM_LIST

    未使用

    SD_OP_MAKE_FS

    創(chuàng)建sheepdog集群

    SD_OP_SHUTDOWN

    停止sheepdog集群

    SD_OP_STAT_SHEEP

    獲取本地磁盤使用量

    SD_OP_STAT_CLUSTER

    獲取sheepdog集群信息

    SD_OP_KILL_NODE

    退出sheep守護(hù)進(jìn)程

    SD_OP_GET_VDI_ATTR

    獲取vdi屬性對(duì)象id

    between sheeps

    操作碼

    描述

    SD_OP_REMOVE_OBJ

    刪除對(duì)象

    SD_OP_GET_OBJ_LIST

    獲取對(duì)象id列表,并存儲(chǔ)到目標(biāo)節(jié)點(diǎn)

     

    posted @ 2011-08-28 17:02 俞靈 閱讀(3288) | 評(píng)論 (0)編輯 收藏

    Ant是什么?
    Ant是一種基于Java和XML的build工具.
    1 編寫build.xml

    Ant的buildfile是用XML寫的.每個(gè)buildfile含有一個(gè)project.

    buildfile中每個(gè)task元素可以有一個(gè)id屬性,可以用這個(gè)id值引用指定的任務(wù).這個(gè)值是唯一的.(詳情請(qǐng)參考下面的Task小節(jié))

    1.1 Projects

    project有下面的屬性:
    Attribute Description Required
    name 項(xiàng)目名稱. No
    default 當(dāng)沒(méi)有指定target時(shí)使用的缺省target Yes
    basedir 用于計(jì)算所有其他路徑的基路徑.該屬性可以被basedir property覆蓋.當(dāng)覆蓋時(shí),該屬性被忽略.如果屬性和basedir property都沒(méi)有設(shè)定,就使用buildfile文件的父目錄. No


    項(xiàng)目的描述以一個(gè)頂級(jí)的<description>元素的形式出現(xiàn)(參看description小節(jié)).

    一個(gè)項(xiàng)目可以定義一個(gè)或多個(gè)target.一個(gè)target是一系列你想要執(zhí)行的.執(zhí)行Ant時(shí),你可以選擇執(zhí)行那個(gè)target.當(dāng)沒(méi)有給定target時(shí),使用project的default屬性所確定的target.

    1.2 Targets

    一個(gè)target可以依賴于其他的target.例如,你可能會(huì)有一個(gè)target用于編譯程序,一個(gè)target用于生成可執(zhí)行文件.你在生成可執(zhí)行文件之前先編譯通過(guò),生成可執(zhí)行文件的target依賴于編譯target.Ant會(huì)處理這種依賴關(guān)系.

    然而,應(yīng)當(dāng)注意到,Ant的depends屬性只指定了target應(yīng)該被執(zhí)行的順序-如果被依賴的target無(wú)法運(yùn)行,這種depends對(duì)于指定了依賴關(guān)系的target就沒(méi)有影響.

    Ant會(huì)依照depends屬性中target出現(xiàn)的順序(從左到右)依次執(zhí)行每個(gè)target.然而,要記住的是只要某個(gè)target依賴于一個(gè)target,后者就會(huì)被先執(zhí)行.
    <target name="A"/>
    <target name="B" depends="A"/>
    <target name="C" depends="B"/>
    <target name="D" depends="C,B,A"/>
    假定我們要執(zhí)行target D.從它的依賴屬性來(lái)看,你可能認(rèn)為先執(zhí)行C,然后B,A被執(zhí)行.錯(cuò)了,C依賴于B,B依賴于A,先執(zhí)行A,然后B,然后C,D被執(zhí)行.

    一個(gè)target只能被執(zhí)行一次,即時(shí)有多個(gè)target依賴于它(看上面的例子).

    如 果(或如果不)某些屬性被設(shè)定,才執(zhí)行某個(gè)target.這樣,允許根據(jù)系統(tǒng)的狀態(tài)(java version, OS, 命令行屬性定義等等)來(lái)更好地控制build的過(guò)程.要想讓一個(gè)target這樣做,你就應(yīng)該在target元素中,加入if(或unless)屬性,帶 上target因該有所判斷的屬性.例如:
    <target name="build-module-A" if="module-A-present"/>
    <target name="build-own-fake-module-A" unless="module-A-present"/>
    如果沒(méi)有if或unless屬性,target總會(huì)被執(zhí)行.

    可選的description屬性可用來(lái)提供關(guān)于target的一行描述,這些描述可由-projecthelp命令行選項(xiàng)輸出.

    將你的tstamp task在一個(gè)所謂的初始化target是很好的做法,其他的target依賴這個(gè)初始化target.要確保初始化target是出現(xiàn)在其他target依賴表中的第一個(gè)target.在本手冊(cè)中大多數(shù)的初始化target的名字是"init".

    target有下面的屬性:
    Attribute Description Required
    name target的名字 Yes
    depends 用逗號(hào)分隔的target的名字列表,也就是依賴表. No
    if 執(zhí)行target所需要設(shè)定的屬性名. No
    unless 執(zhí)行target需要清除設(shè)定的屬性名. No
    description 關(guān)于target功能的簡(jiǎn)短描述. No


    1.3 Tasks

    一個(gè)task是一段可執(zhí)行的代碼.

    一個(gè)task可以有多個(gè)屬性(如果你愿意的話,可以將其稱之為變量).屬性只可能包含對(duì)property的引用.這些引用會(huì)在task執(zhí)行前被解析.

    下面是Task的一般構(gòu)造形式:
    <name attribute1="value1" attribute2="value2" ... />
    這里name是task的名字,attributeN是屬性名,valueN是屬性值.

    有一套內(nèi)置的(built-in)task,以及一些可選task,但你也可以編寫自己的task.

    所有的task都有一個(gè)task名字屬性.Ant用屬性值來(lái)產(chǎn)生日志信息.

    可以給task賦一個(gè)id屬性:
    <taskname id="taskID" ... />
    這里taskname是task的名字,而taskID是這個(gè)task的唯一標(biāo)識(shí)符.通過(guò)這個(gè)標(biāo)識(shí)符,你可以在腳本中引用相應(yīng)的task.例如,在腳本中你可以這樣:
    <script ... >
    task1.setFoo("bar");
    </script>
    設(shè)定某個(gè)task實(shí)例的foo屬性.在另一個(gè)task中(用java編寫),你可以利用下面的語(yǔ)句存取相應(yīng)的實(shí)例.
    project.getReference("task1").
    注意1:如果task1還沒(méi)有運(yùn)行,就不會(huì)被生效(例如:不設(shè)定屬性),如果你在隨后配置它,你所作的一切都會(huì)被覆蓋.

    注意2:未來(lái)的Ant版本可能不會(huì)兼容這里所提的屬性,很有可能根本沒(méi)有task實(shí)例,只有proxies.

    1.4 Properties

    一個(gè)project可以有很多的properties.可以在buildfile中用 property task來(lái)設(shè)定,或在Ant之外設(shè)定.一個(gè)property有一個(gè)名字和一個(gè)值.property可用于task的屬性值.這是通過(guò)將屬性名放在"${" 和"}"之間并放在屬性值的位置來(lái)實(shí)現(xiàn)的.例如如果有一個(gè)property builddir的值是"build",這個(gè)property就可用于屬性值:${builddir}/classes.這個(gè)值就可被解析為build /classes.

    內(nèi)置屬性

    如果你使用了<property> task 定義了所有的系統(tǒng)屬性,Ant允許你使用這些屬性.例如,${os.name}對(duì)應(yīng)操作系統(tǒng)的名字.

    要想得到系統(tǒng)屬性的列表可參考the Javadoc of System.getProperties.

    除了Java的系統(tǒng)屬性,Ant還定義了一些自己的內(nèi)置屬性:
    basedir project基目錄的絕對(duì)路徑 (與<project>的basedir屬性一樣).
    ant.file buildfile的絕對(duì)路徑.
    ant.version Ant的版本.
    ant.project.name 當(dāng)前執(zhí)行的project的名字;由<project>的name屬性設(shè)定.
    ant.java.version Ant檢測(cè)到的JVM的版本; 目前的值有"1.1", "1.2", "1.3" and "1.4".

    例子
    <project name="MyProject" default="dist" basedir=".">

    <!-- set global properties for this build -->
    <property name="src" value="."/>
    <property name="build" value="build"/>
    <property name="dist" value="dist"/>

    <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
    </target>

    <target name="compile" depends="init">
    <!-- Compile the java code from ${src} into ${build} -->
    <javac srcdir="${src}" destdir="${build}"/>
    </target>

    <target name="dist" depends="compile">
    <!-- Create the distribution directory -->
    <mkdir dir="${dist}/lib"/>
    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
    <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
    </target>

    <target name="clean">
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
    </target>

    </project>

    1.5 Path-like Structures
    你可以用":"和";"作為分隔符,指定類似PATH和CLASSPATH的引用.Ant會(huì)把分隔符轉(zhuǎn)換為當(dāng)前系統(tǒng)所用的分隔符.

    當(dāng)需要指定類似路徑的值時(shí),可以使用嵌套元素.一般的形式是
    <classpath>
    <pathelement path="${classpath}"/>
    <pathelement location="lib/helper.jar"/>
    </classpath>
    location屬性指定了相對(duì)于project基目錄的一個(gè)文件和目錄,而path屬性接受逗號(hào)或分號(hào)分隔的一個(gè)位置列表.path屬性一般用作預(yù)定義的路徑--其他情況下,應(yīng)該用多個(gè)location屬性.

    為簡(jiǎn)潔起見(jiàn),classpath標(biāo)簽支持自己的path和location屬性.
    <classpath>
    <pathelement path="${classpath}"/>
    </classpath>
    可以被簡(jiǎn)寫作:
    <classpath path="${classpath}"/>
    也可通過(guò)<fileset>元素指定路徑.構(gòu)成一個(gè)fileset的多個(gè)文件加入path-like structure的順序是未定的.
    <classpath>
    <pathelement path="${classpath}"/>
    <fileset dir="lib">
    <include name="**/*.jar"/>
    </fileset>
    <pathelement location="classes"/>
    </classpath>
    上面的例子構(gòu)造了一個(gè)路徑值包括:${classpath}的路徑,跟著lib目錄下的所有jar文件,接著是classes目錄.

    如果你想在多個(gè)task中使用相同的path-like structure,你可以用<path>元素定義他們(與target同級(jí)),然后通過(guò)id屬性引用--參考Referencs例子.

    path-like structure可能包括對(duì)另一個(gè)path-like structurede的引用(通過(guò)嵌套<path>元素):
    <path id="base.path">
    <pathelement path="${classpath}"/>
    <fileset dir="lib">
    <include name="**/*.jar"/>
    </fileset>
    <pathelement location="classes"/>
    </path>
    <path id="tests.path">
    <path refid="base.path"/>
    <pathelement location="testclasses"/>
    </path>
    前面所提的關(guān)于<classpath>的簡(jiǎn)潔寫法對(duì)于<path>也是有效的,如:
    <path id="tests.path">
    <path refid="base.path"/>
    <pathelement location="testclasses"/>
    </path>
    可寫成:
    <path id="base.path" path="${classpath}"/>
    命令行變量

    有些task可接受參數(shù),并將其傳遞給另一個(gè)進(jìn)程.為了能在變量中包含空格字符,可使用嵌套的arg元素.
    Attribute Description Required
    value 一個(gè)命令行變量;可包含空格字符. 只能用一個(gè)
    line 空格分隔的命令行變量列表.
    file 作為命令行變量的文件名;會(huì)被文件的絕對(duì)名替代.
    path 一個(gè)作為單個(gè)命令行變量的path-like的字符串;或作為分隔符,Ant會(huì)將其轉(zhuǎn)變?yōu)樘囟ㄆ脚_(tái)的分隔符.

    例子
    <arg value="-l -a"/>
    是一個(gè)含有空格的單個(gè)的命令行變量.
    <arg line="-l -a"/>
    是兩個(gè)空格分隔的命令行變量.
    <arg path="/dir;/dir2:dir3"/>
    是一個(gè)命令行變量,其值在DOS系統(tǒng)上為dir;dir2;dir3;在Unix系統(tǒng)上為/dir:/dir2:/dir3 .

    References

    buildfile元素的id屬性可用來(lái)引用這些元素.如果你需要一遍遍的復(fù)制相同的XML代碼塊,這一屬性就很有用--如多次使用<classpath>結(jié)構(gòu).

    下面的例子:
    <project ... >
    <target ... >
    <rmic ...>
    <classpath>
    <pathelement location="lib/"/>
    <pathelement path="${java.class.path}/"/>
    <pathelement path="${additional.path}"/>
    </classpath>
    </rmic>
    </target>
    <target ... >
    <javac ...>
    <classpath>
    <pathelement location="lib/"/>
    <pathelement path="${java.class.path}/"/>
    <pathelement path="${additional.path}"/>

    </classpath>
    </javac>
    </target>
    </project>
    可以寫成如下形式:
    <project ... >
    <path id="project.class.path">
    <pathelement location="lib/"/>
    <pathelement path="${java.class.path}/"/>
    <pathelement path="${additional.path}"/>
    </path>
    <target ... >
    <rmic ...>
    <classpath refid="project.class.path"/>
    </rmic>
    </target>
    <target ... >
    <javac ...>
    <classpath refid="project.class.path"/>
    </javac>
    </target>
    </project>
    所有使用PatternSets, FileSets 或 path-like structures嵌套元素的task也接受這種類型的引用.

    轉(zhuǎn)自:
    http://www.linux521.com/2009/java/200904/1760.html

    posted @ 2011-08-07 11:46 俞靈 閱讀(1151) | 評(píng)論 (0)編輯 收藏

    最近看了hadoop進(jìn)度顯示部分代碼,做了個(gè)ppt算是一個(gè)總結(jié)吧.
    /Files/shenh062326/hadoop進(jìn)度計(jì)算.ppt

    posted @ 2011-07-03 09:44 俞靈 閱讀(327) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲二区在线视频| 亚洲av无码乱码在线观看野外| 国产亚洲美女精品久久久2020| 高清一区二区三区免费视频| 国产乱子影视频上线免费观看| 亚洲日韩AV一区二区三区四区 | 亚洲中文字幕无码久久综合网| 一级白嫩美女毛片免费| 99精品视频在线观看免费专区 | 亚洲AV无码资源在线观看| 日本一道高清不卡免费| 亚洲桃色AV无码| 成人影片一区免费观看| 国产香蕉九九久久精品免费| 亚洲国产主播精品极品网红| 久久久久久亚洲AV无码专区| 色欲aⅴ亚洲情无码AV蜜桃| 国产又黄又爽又猛的免费视频播放 | 亚洲国产精品99久久久久久| 91视频免费观看高清观看完整| 亚洲深深色噜噜狠狠爱网站| 免费人成视频在线观看网站| 亚洲成综合人影院在院播放| 人成免费在线视频| 久久亚洲国产精品123区| 亚洲欧美不卡高清在线| 亚洲А∨精品天堂在线| 在线看片免费人成视频福利| 亚洲码在线中文在线观看| 成人免费777777| jizz免费一区二区三区| 久久亚洲免费视频| 成人午夜大片免费7777| free哆拍拍免费永久视频| 亚洲AV成人一区二区三区AV| 成人A级毛片免费观看AV网站| 免费国产va在线观看| 69成人免费视频无码专区| 免费VA在线观看无码| 亚洲天堂一区二区| 国产国产成年年人免费看片|