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

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

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

    放翁(文初)的一畝三分地

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      210 隨筆 :: 1 文章 :: 320 評(píng)論 :: 0 Trackbacks

    Author:放翁(文初)

    Emailfangweng@taobao.com

    Bloghttp://blog.csdn.net/cenwenchu79

     

    閑話:(果圖片看不清楚可以看另一個(gè)blog,因?yàn)閳D片在家,這里上傳就只能轉(zhuǎn)貼了)

             為什么又叫做什么的點(diǎn)滴,首先現(xiàn)在寫程序就是練手,不論自己經(jīng)歷了多少,如果想成為一個(gè)好的P,那么就要持續(xù)的去學(xué)習(xí),去寫,當(dāng)寫出來的東西總是一個(gè)樣子,那就要去學(xué)習(xí)一下,當(dāng)覺得整天飄飄然的和同行在胡侃,那么就要靜下心來寫點(diǎn)東西。因此我的分享總是這個(gè)點(diǎn)滴那個(gè)點(diǎn)滴的,其實(shí)大家寫程序都大同小異,最寶貴的不是一個(gè)系統(tǒng)如何成功,而是在設(shè)計(jì)和實(shí)現(xiàn)這個(gè)系統(tǒng)的過程中,有哪些閃光點(diǎn),這些閃光點(diǎn)日積月累就會(huì)讓你寫出來的東西給人一種“踏實(shí)”的感覺,同時(shí)不斷的多想一步,會(huì)讓你總是比別人做得更加精彩。

     

    起因:

             現(xiàn)在手頭工作太忙,所以分享的東西很多,但是沒有時(shí)間寫,因此這個(gè)MapReduce “單機(jī)版說說是練手,但其實(shí)和當(dāng)前TOP的業(yè)務(wù)也很有關(guān)系。過去在開放平臺(tái)中有重要的一部分內(nèi)容就是日志分析和報(bào)表的功能,由于開放平臺(tái)的API請求里量很大,因此過去首先采用異步日志結(jié)合MySql分表模式來做日志分析,后來演化成為了異步日志結(jié)合Hadoop的分析模式。

    TOP當(dāng)前對于日志系統(tǒng)的需求是:

    1.       滿足不穩(wěn)定的需求統(tǒng)計(jì)分析(性能監(jiān)控調(diào)優(yōu),業(yè)務(wù)趨勢分析,ISV行為統(tǒng)計(jì)等),快速出結(jié)果。(框架靈活度要高)

    2.       分析系統(tǒng)配置使用簡單。(部署簡單,維護(hù)簡單,使用簡單)

    3.       硬件資源節(jié)省。(資源投入少,長期有規(guī)劃上有規(guī)模化的集群分析計(jì)算)

    4.       短期內(nèi)上線。(開發(fā)成本低)

    5.處理速度可接受。

             根據(jù)以上幾點(diǎn)當(dāng)前的需求,起碼現(xiàn)階段的TOP需要的分析器不需要用Hadoop,同時(shí)采用Hadoop在業(yè)務(wù)上不能滿足靈活的需求(發(fā)布要走流程),使用也過于復(fù)雜,硬件資源投入起碼兩到三臺(tái)PC,開發(fā)流程上由于業(yè)務(wù)的需求變動(dòng)比較大,這樣如果采用比較硬的編碼方式,則很難短期上線。對于當(dāng)前TOP的日志量用Hadoop的速度優(yōu)勢暫時(shí)還不明顯。

             就上面這些因素,考慮化幾天時(shí)間做一個(gè)單機(jī)版的MapReduce的日志分析器,滿足現(xiàn)有需求。

     

    設(shè)計(jì):

    1  Simple MapReduce Log Analysis UseCase

            

                  

    2 基本流程定義

     

    3 角色工作圖

             系統(tǒng)簡化來看就分成三個(gè)角色:

    1. JobManager:負(fù)責(zé)讀取系統(tǒng)配置,和初始化分析規(guī)則引擎,切割文件,創(chuàng)建Worker,協(xié)同Worker并行分析,合并分析結(jié)果,輸出報(bào)表。

    2. RuleEngine:根據(jù)配置載入和構(gòu)建日志解析規(guī)則(可定制化MapReduce實(shí)現(xiàn)),中間結(jié)果合并規(guī)則,報(bào)表創(chuàng)建規(guī)則,附帶發(fā)送郵件等功能配置。

    3. JobWorker:根據(jù)規(guī)則引擎配置,逐行分析日志,每行分析出所有配置需要的結(jié)果,作一次簡單的MapReduce操作,輸出中間結(jié)果給Manager。

     

     

    實(shí)現(xiàn):

     

    一.報(bào)表配置及規(guī)則引擎

    a.       兩個(gè)層次。在HadoopMapReduce的計(jì)算結(jié)果是Key&Value,這通常并不是我們很多分析系統(tǒng)希望要的最終結(jié)果,分析系統(tǒng)希望是得到類似于SQL查詢到的一組結(jié)果,反過來看,對于一組結(jié)果其實(shí)就是一堆Key&Value的組合:

    例如:

    Select name,address,count(*) form t 得到的結(jié)果就是以name&address組合成為key,然后累加次數(shù)產(chǎn)生的value

             Select name,address,average(age) form t得到的結(jié)果就是以name&address組合成為key,然后平均年齡得到的value。

             而這兩個(gè)結(jié)果由于都是以相同的兩個(gè)字段作為索引,因此歸類在一起就會(huì)形成我們通常希望看到的一個(gè)報(bào)表。因此產(chǎn)生了定義的報(bào)表配置的兩個(gè)層次:

    1. ReportEntry就是一個(gè)key&value產(chǎn)生的規(guī)則定義。

    2. Report就是單個(gè)報(bào)表創(chuàng)建的定義。

     

    b.       五種基本統(tǒng)計(jì)函數(shù),對于統(tǒng)計(jì)來說大多都是對數(shù)字的處理,抽象起來公用的主要有五種:min,max,sum,count,average。同時(shí)為了能夠提供顯示主鍵的功能,提供一個(gè)直接顯示內(nèi)容的plain函數(shù),這樣基本涵蓋了70%的統(tǒng)計(jì)需求。

    c.       兩種表達(dá)式創(chuàng)建Value。對于value的創(chuàng)建可以設(shè)置表達(dá)式,比如說每一條記錄的第三列減去第四列的最大值可以配置為value=”$3$ - $4$”,用$符號(hào)分割表示對列的引用。也可以定義某一統(tǒng)計(jì)結(jié)果是其他列統(tǒng)計(jì)結(jié)果的計(jì)算結(jié)果,例如成功率可以使成功數(shù)量/總量,配置為value=”entry(成功數(shù)列號(hào))/entry(總量列號(hào))”,此類結(jié)果將在報(bào)表創(chuàng)建時(shí)候才被計(jì)算生成,屬于lazy分析。

     

    下圖是具體的類定義圖

     

    具體配置參見附錄說明。

     

    二.切割日志文件

    單臺(tái)服務(wù)器單日最大的日志有1G多的日志,對于這么大的日志需要考慮切分一下交由多個(gè)Jobworker來并行處理提高效率。因此就涉及到了切割文件的工作。切割文件就需要做到高效,數(shù)據(jù)完整性。

    高效:一般切割是對一個(gè)目錄下所有文件切割,因此起一個(gè)線程池并行切割,提高效率。同時(shí)對于單個(gè)文件的切割,采用FileChannel的方式(MapFile),簡單按照配置大小切割成子文件。

    數(shù)據(jù)完整性:由于TOP的日志文件是以回車換行作為記錄分割符,因此從第二個(gè)文件開始,每一個(gè)文件讀取第一句有回車換行的內(nèi)容到上一個(gè)文件,這樣就可以保證數(shù)據(jù)的完整性(簡單補(bǔ)償方案),需要注意的就是邊界情況,當(dāng)最后一個(gè)文件就一句話內(nèi)容,那么這句內(nèi)容一旦被提前,需要?jiǎng)h除這個(gè)子文件。

            

             遇到的問題:

    1.       直接根據(jù)設(shè)置的文件塊來拷貝,導(dǎo)致多線程并行處理時(shí),native方法消耗內(nèi)存溢出(這個(gè)其實(shí)在很多第三方的開源包中處理不好都會(huì)有這樣的問題),由于Jdk提供了內(nèi)存映像文件,提高速度的同時(shí),也為這類內(nèi)存申請使用帶來了內(nèi)存溢出的隱患(這類內(nèi)存的回收和普通的GC回收不同,回收的時(shí)機(jī)也不一樣),因此當(dāng)機(jī)器速度越快的時(shí)候,可能溢出的情況越容易發(fā)生。于是將inChannel.transferTo(beg,blocksize, outChannel)改成了一段一段的復(fù)制。

    2.       單機(jī)磁盤IO瓶頸在某種程度上決定了多線程并行未必會(huì)提高多少處理效率。

    3.       有同學(xué)和我說你其實(shí)不用切割,直接用RandomAccessFile來讀取分析就可以了,節(jié)省時(shí)間。感覺很有道理,前期陷入了思維定勢,但是對于單機(jī)來說磁盤IO及文件鎖使得虛擬切割的效率還不如單線程處理。(作了一下測試)

     

    三.JobWorker實(shí)現(xiàn)

    對于通過數(shù)據(jù)庫來做統(tǒng)計(jì)的情況,通常會(huì)需要Select幾次才會(huì)得到一個(gè)報(bào)表的幾項(xiàng)結(jié)果,但對于逐行掃描處理的情況來說,不論配置多少Entry,在一次日志讀取以后就能根據(jù)規(guī)則來計(jì)算出這個(gè)Entry的結(jié)果,因此對于海量數(shù)據(jù)的分析,在一次數(shù)據(jù)遍歷以后就可以得到所有的結(jié)果。這點(diǎn)也是去年我和開放平臺(tái)同學(xué)review他的hadoop MapReduce的時(shí)候提出的建議,如果就做一次MapReduce就需要分析一次數(shù)據(jù),那么肯定會(huì)效率很低,通常就是需要定義一個(gè)Map就能夠作很多規(guī)則的分析,這就需要對于在傳統(tǒng)MapReduce中作較好的層次級(jí)別規(guī)劃,一次數(shù)據(jù)分析能夠被多個(gè)分析共享。而在這里設(shè)計(jì)JobWorker來說,本身逐行解析就可以實(shí)現(xiàn)這點(diǎn),這也使得報(bào)表不論定義多少,分析的時(shí)間復(fù)雜度幾乎沒有增加。

    IReportManager作用就是管理整個(gè)分析流程,初始化資源(載入配置,初始化規(guī)則引擎,切割文件),創(chuàng)建協(xié)調(diào)工作者,合并結(jié)果集,出報(bào)表。

             定義了Worker兩個(gè)實(shí)現(xiàn),一個(gè)是真實(shí)文件處理的Worker,一個(gè)是虛擬文件處理的Worker。(所謂的虛擬文件,就是上面提到的虛擬切割后生成的虛擬文件)在JobWorker處理中,可以根據(jù)規(guī)則引擎中定義的單個(gè)Entry處理模式和定制化Map或者Reduce實(shí)現(xiàn)來替換框架已有的MapReduce滿足不同的業(yè)務(wù)需求。具體的MapReduce參看下面的類圖。

             IReportMap就一個(gè)接口generateKeyReportEntryReportEntry entry,Sting[] contents),也就是每一個(gè)Map都可以得到當(dāng)前處理的數(shù)據(jù)內(nèi)容以及當(dāng)前Entry的數(shù)據(jù)定義。IReportMap和下面的IReportReduce都是可以通過運(yùn)行期配置的方式替換現(xiàn)有框架中的業(yè)務(wù)邏輯。

    Worker具體流程圖如下:

            在流程中允許用自定義的MapReduce實(shí)現(xiàn)類替換默認(rèn)的處理類,滿足用戶個(gè)性化需求,同時(shí)降低對于基礎(chǔ)框架的依賴。

     

    問題:

            1.多線程池(Executor等)必須控制好線程數(shù)量,防止內(nèi)存溢出。

            2.瓶頸在IO,因此效率提高有限。

            3.自定義協(xié)議解析替換了J2se 6js engine。JS引擎很強(qiáng)大,但是效率不高,在大規(guī)模數(shù)據(jù)處理的時(shí)候耗時(shí)嚴(yán)重,成為最大的瓶頸,因此采用簡單的算法來替換。

     

    四.報(bào)表生成

    最終報(bào)表的輸出類型,選擇了csv,首先由于csv結(jié)果排版簡單,其次,可以借助excel的強(qiáng)大圖形功能將數(shù)字結(jié)果轉(zhuǎn)換成為更加直觀的圖形結(jié)果。

     

    比較和改進(jìn)

    傳統(tǒng)的MapReduce步驟如下:導(dǎo)入數(shù)據(jù)到分布式文件系統(tǒng)(切割文件,文件傳輸?shù)?/span>dataNode,同時(shí)做好容災(zāi)準(zhǔn)備),JobNodeJobTracker的協(xié)調(diào)下開始分析,并在本地作一次reduce(減少數(shù)據(jù)傳輸),再匯總作Reduce,最后生成結(jié)果。

    單機(jī)版MapReduce,只是將多機(jī)協(xié)作變成了多線程協(xié)作。

    1. 省略數(shù)據(jù)傳輸不用讓數(shù)據(jù)靠近計(jì)算。

    2. 通過配置文件的方式定制報(bào)表,可以靈活的將報(bào)表系統(tǒng)變成隨時(shí)可以根據(jù)需求變動(dòng)的動(dòng)態(tài)分析系統(tǒng)。(每次配置文件可以從遠(yuǎn)端讀取,這樣就可以不發(fā)布而立刻獲得不同的報(bào)表)。

    3. 使用便利,通過一個(gè)系統(tǒng)配置文件設(shè)定系統(tǒng)運(yùn)行參數(shù),然后直接執(zhí)行jar,即可運(yùn)行,不需要配置多機(jī)環(huán)境。

    4. 對于幾十個(gè)G的數(shù)據(jù)處理正合適(效率)

    5. 開發(fā)調(diào)試周期短,基本上5個(gè)人日開發(fā)+測試就搞定了。

     

    但其實(shí)缺陷還是很一目了然的,就是我們?yōu)槭裁匆?/span>MapReduce的多機(jī)配置的初衷,單機(jī)最終在CPU,IO上都成為瓶頸,垂直擴(kuò)容和水平擴(kuò)容已經(jīng)沒有什么好爭議的了,因此采用多機(jī)合作在規(guī)模化的處理上是必然趨勢。對于這個(gè)單機(jī)版作適當(dāng)?shù)恼{(diào)整,成為簡化型日志分析專用型多機(jī)版MapReduce還是蠻有必要的。那么切入點(diǎn)其實(shí)就是以下幾點(diǎn):

    1. 分析數(shù)據(jù)將會(huì)散布到多機(jī),分別切割處理。(可以不考慮容災(zāi))

    2. 多機(jī)多線程分析并在本機(jī)Reduce一次,然后通過配置找到內(nèi)部的Master,交由Master來最終作Reduce。(workernode之間無需知道對方的存在)

    3. Master由原來內(nèi)存結(jié)果合并,轉(zhuǎn)變?yōu)閭鬏斶^來的結(jié)果反序列化或者遵照私有消息格式來合并結(jié)果,最終創(chuàng)建出報(bào)表。

    因此簡單來說就是數(shù)據(jù)分布及中間結(jié)果的傳遞和合并的工作處理一下,單機(jī)版就變成了多機(jī)版。最后就在附錄中詳細(xì)說明一下配置及運(yùn)行后的效果。

     

     

     

     

    附錄:

     

    配置實(shí)例說明:

    下面寫一個(gè)具體的實(shí)際配置來展示如何配置一個(gè)簡單的報(bào)表:(其中衍生出一些需求增強(qiáng)的內(nèi)容)

    配置文件是xml格式的,配置如下:

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

    <top_reports>

         <entrys>//定義需要給多個(gè)報(bào)表復(fù)用的Entry

             <ReportEntry id="1" name="api_totalCount" key="6" value="count()"/>//id是這個(gè)entry唯一的標(biāo)識(shí)(后面被引用到報(bào)表的依據(jù)),name將會(huì)作為報(bào)表的列名,key表示會(huì)以日志記錄的第幾項(xiàng)內(nèi)容作為索引,可以通過逗號(hào)分割(組合索引),value表示創(chuàng)建的值是按照什么規(guī)則來創(chuàng)建,count函數(shù)不需要有內(nèi)部表達(dá)式,average,min,max,plain都需要有表達(dá)式,表達(dá)式內(nèi)部$16$代表日志記錄第幾位作為參數(shù)傳入運(yùn)算,entry(16)代表對第16entry結(jié)果作引用計(jì)算(具體參見下面配置)。這句話表示用第六位這個(gè)api名稱字段作為索引,計(jì)算各個(gè)api的總調(diào)用量。

             <ReportEntry id="2" name="api_successCount" key="6" value="count()"

                       mapClass="com.taobao.top.analysis.map.APIErrorCodeMap" mapParams="key=6&amp;errorCode=0"/>//這個(gè)配置和上面不同的就在于mapClass可以自定義實(shí)現(xiàn),其實(shí)也就是實(shí)現(xiàn)了對于Key產(chǎn)生的規(guī)則實(shí)現(xiàn),也就是MapReduce模型中的Map函數(shù)實(shí)現(xiàn),這里可以用默認(rèn)的(即簡單的列組合),也可以采用復(fù)雜的方式過濾和合并key,只需要實(shí)現(xiàn)Map接口即可,這后面詳細(xì)描述。這個(gè)配置表示產(chǎn)生key的過程中過濾掉不成功的請求,只統(tǒng)計(jì)成功請求

             <ReportEntry id="3" name="api_failCount" key="6" value="count()"

                       mapClass="com.taobao.top.analysis.map.APIErrorCodeMap" mapParams="key=6&amp;errorCode=1"/>//統(tǒng)計(jì)錯(cuò)誤請求

             <ReportEntry id="4" name="api_AverageServiceTimeConsume" key="6" value="average($14$ - $13$)" />//統(tǒng)計(jì)服務(wù)平均相應(yīng)時(shí)間,由于在服務(wù)處理前后有時(shí)間打點(diǎn),因此簡單的相減即可

             <ReportEntry id="5" name="api_AverageTIPTimeConsume" key="6" value="average($16$ - $11$ - $14$ + $13$)" />

             <ReportEntry id="6" name="api_MinServiceTimeConsume" key="6" value="min($14$ - $13$)" />//最小時(shí)間消耗

             <ReportEntry id="7" name="api_MaxServiceTimeConsume" key="6" value="max($14$ - $13$)" />//最大時(shí)間消耗

             ……

         </entrys>

         <reports>

             //具體的報(bào)表定義

             <report id="2" file="apiReport" mailto="wenchu.cenwc@alibaba-inc.com">

                  <entryList>

                      <entry name="APIName" key="6" value="plain($6$)" />//不需要復(fù)用的entry可以直接定義在報(bào)表內(nèi)部,這個(gè)定義表示直接顯示第六列即API的名稱

                       <entry id="1"/>

                       <entry id="2"/>

                       <entry name="APISuccessRatio" key="6" value="plain(entry(2)/entry(1))" /> //可以計(jì)算比例,通過對entry1entry2的結(jié)果相除,不過這個(gè)就不是在逐行分析過程中實(shí)現(xiàn),而是在結(jié)果合并時(shí)處理,屬于lazy后處理

                       <entry id="3"/>

                       <entry id="4"/>

                       <entry id="5"/>

                       <entry name="TIPTimeConsumeRatio" key="6" value="plain(entry(5)/entry(5)+entry(4))" />

                       <entry id="6"/>

                       <entry id="7"/>

                  </entryList>

             </report>

         </reports>

    </top_reports>

     

     

     

    posted on 2009-10-30 12:27 岑文初 閱讀(3677) 評(píng)論(6)  編輯  收藏

    評(píng)論

    # re: MapReduce“單機(jī)版”日志分析實(shí)踐點(diǎn)滴 2009-10-30 14:21 little
    代碼嗎?
    抬頭、深呼吸、靜學(xué)習(xí)  回復(fù)  更多評(píng)論
      

    # re: MapReduce“單機(jī)版”日志分析實(shí)踐點(diǎn)滴 2009-10-30 14:43 Agraviton
    悍文,有幸能看到代碼就好了。  回復(fù)  更多評(píng)論
      

    # re: MapReduce“單機(jī)版”日志分析實(shí)踐點(diǎn)滴 2009-10-30 15:57 Agraviton
    能否發(fā)一份原始日志的內(nèi)容?哪怕是幾行,相信會(huì)有助于理解你的程序設(shè)計(jì)。  回復(fù)  更多評(píng)論
      

    # re: MapReduce“單機(jī)版”日志分析實(shí)踐點(diǎn)滴 2009-11-03 19:00 楊欣
    拜讀啊  回復(fù)  更多評(píng)論
      

    # re: MapReduce“單機(jī)版”日志分析實(shí)踐點(diǎn)滴 2009-11-04 01:15 永源
    頂樓上,拜讀~~~~  回復(fù)  更多評(píng)論
      

    # re: MapReduce“單機(jī)版”日志分析實(shí)踐點(diǎn)滴 2009-11-04 01:31 永源
    兩個(gè)地方我覺得很好的:

    1.日志按格式記錄:之前大家做的分析,日志都是亂記的,所以后來分析都需要手寫代碼分析。

    2.按配置文件自行分析:由于日志是按格式記錄的,使得可以使用根據(jù)配置文件分析。

    方翁的習(xí)慣真好,類圖,流程圖,要好好向你學(xué)習(xí)。  回復(fù)  更多評(píng)論
      


    只有注冊用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲毛片av日韩av无码| 久久福利青草精品资源站免费| 麻豆国产精品免费视频| 亚洲人成图片小说网站| 一级看片免费视频囗交| 亚洲国产精品人人做人人爽| 国产成人亚洲精品播放器下载| 国产成人综合久久精品免费| 亚洲av午夜电影在线观看 | 亚洲高清视频在线| 亚洲一区二区三区免费在线观看| 亚洲狠狠综合久久| 最近免费中文字幕mv电影| 久久久久亚洲精品日久生情| 69式互添免费视频| 亚洲人成77777在线播放网站不卡| 2020久久精品国产免费| 亚洲中文精品久久久久久不卡| 成年女人免费视频播放体验区| 一区二区亚洲精品精华液| 日日AV拍夜夜添久久免费| 国产精品亚洲专一区二区三区 | 成人免费一区二区三区在线观看| 亚洲国产综合精品中文第一| 日韩在线视频免费看| 成人一级免费视频| 亚洲AV乱码久久精品蜜桃| 中文字幕免费观看| 亚洲五月综合缴情婷婷| 免费看男女下面日出水视频| 一级做性色a爰片久久毛片免费| 亚洲区小说区激情区图片区| 免费A级毛片av无码| 亚洲中文字幕一二三四区| 亚洲第一区精品观看| 四虎影视无码永久免费| 亚洲AV无码精品蜜桃| 亚洲精品tv久久久久| 亚洲免费福利视频| 色婷婷精品免费视频| 亚洲视频免费一区|