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

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

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

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

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      210 隨筆 :: 1 文章 :: 320 評論 :: 0 Trackbacks
     

    基于MapReduce的配置型日志分析組件

    Author:放翁(文初)

    Email:fangweng@taobao.com

    Blog: http://blog.csdn.net/cenwenchu79/

    目錄

    需求場景

    組件功能設計關鍵點

    設計點分析

    分析模型抽象

    分析實體抽象:

    分析流程抽象:

    關鍵路徑任務分割

    分析過程生命周期定義:

    基于命令行方式執行階段性任務

    單任務并行處理化

    低耦合多機協作


    需求場景

    從海量的訪問日志中分析得到系統健康情況,業務增長趨勢。

    組件功能設計關鍵點


    1 組件功能設計點描述圖

             這個組件與傳統的MapReduce框架(例如Hadoop)的不同之處在于:

    1. 解決問題域側重于日志分析統計及趨勢對比。通過抽象分析對象,分析流程,分析結果定制了配置模型和規則解析處理引擎,實現配置替代編碼實現自定義分析。

    2. 對于多機協作采用松散方式,簡化多機協作控制流程。

    設計點分析

    分析模型抽象

             分析模型抽象主要分為兩部分:分析模型抽象和分析流程抽象。分析模型抽象就是將MapReduceKey-Value統計,轉化成為傳統意義上的報表結構。

             分析的輸入:

             c1,c2,c3,c4,c5,c6…(通常情況下就是用一定的分割符與內容組合起來的字符串)

             MapReduce可以處理的:

        

             如下圖,傳統報表的一行可以看作是多個相同key但不同統計字段組合的結果。
         
        

             例如:輸入的數據結構如下:

             服務名稱,服務類型,服務上行數據流量,服務處理結果(錯誤碼),服務耗時

             那么定制如下MapReduce組合:

             Key:服務名稱,Value:服務上行數據流量總和。

             Key:服務名稱,Value:服務耗時總和。

             Key:服務名稱,Value:服務平均耗時。

        Key:服務名稱,Value:服務最大耗時。

             Key:服務名稱,Value:服務最小耗時。

             那么將這些MapReduce處理后的Key-value在組合一次就可以得到:

             Key:服務名稱,Value:服務上行數據流量總和,服務耗時總和,服務平均耗時,服務最大耗時,服務最小耗時。

             可以看出,現在就已經成為了我們傳統意義上的報表結構。

          分析實體抽象:


    2 實體抽象類圖

    Alias對象

    KeyValue生成時需要指定是對那一列或者幾列作分析,因此需要直接指定列號,但是當日志數據結構改變以后,那么就會影響所有的配置,為了便于使用和維護,設定了Alias來規避直接使用列號,具體的使用可以參看最后的配置說明。

    ReportEntry對象

    MapReduceKey-Value處理列和規則的定義。

    keys表示生成key的列(可以直接使用行號或者使用Alias)Map就是通過對keys的定義將key的列用特定的分割符串聯起來形成新的key串,然后根據后面valueExpression的表達式獲得value(表達式支持通過對列的簡單(+-*/)的計算,也支持對于其他Reportentry的計算獲得value)。

    valueExpressionRecude的簡單定義。當前抽象ReportEntryValueType定義的那些類型:min(取最小)max(取最大)sum(總和),average(平均),count(總次數)plain(無需處理,這主要用于顯示key那些列)。具體使用參看后面的配置說明。

    conditions可以過濾不符合規則的輸入。(支持簡單的條件表達式組合)

    valueFilter可以過濾計算后不符合定義的結果。(支持簡單的條件表達式組合)

    MapClass,MapParams,ReduceClass,ReduceParams是用于如果滿足不了現有規則的情況下自定義Map,Reduce,需要實現對應的接口IReportMap或者IReportReduce

    Format可以對最后的結果在輸出的時候格式化一下,當前只支持小數點round

    Report對象

                      包含了一個和多個ReportEntry對象,同時也支持在Report中定義ReportEntry對象(區別在于是否需要將這個ReportEntry共享給其他Report)。file指定了將會輸出的文件名稱。

    Report Alert對象

                      報表的結果是一天的數據,只能做一些縱向比較,如果需要對多天的數據作橫向比較以及趨勢分析,就需要將多天的報表結合起來分析。具體配置也參見后面的數據定義。

    分析流程抽象:

    分析流程如下:


    3 分析流程抽象

    流程中可以擴展的在第三步和第四步,第三步影響了Key的生成(當簡單的列組合成字符串無法滿足生成key的情況下可擴展),第四步影響value的生成。(當mapvalue生成以及Reduce無法滿足需求的情況下可擴展),要使用minmax…以外的reduce,可以直接在ReduceClass中作處理,然后使用plain輸出實現。

    這種流程比傳統的MapReduce的寫法好處在于可以對輸入只讀取一次(海量的日志文件為了多種條件分析,反復讀取本身就是最大的損耗)。可以看到在文件IO操作上,不會隨著分析模型配置的增多而增長,中間數據也不會隨著報表組合的不同而過快膨脹(只要報表復用Entry足夠多)。

    關鍵路徑任務分割

    分析過程生命周期定義:


    4 分析過程生命周期定義

    各階段設計描述:(這些階段都是接口的方法定義)

    配置解析:運行期載入,支持在線配置更新,提高系統靈活性。(本地或者URL資源)

    獲取分析列表:獲取要分析的文件列表,并根據本地已有數據現狀,選擇性的生成需要獲取的文件數據。

    獲取任務數據:從外部文件系統或者數據庫獲得數據。

    切割任務數據文件:根據配置的文件塊大小,將任務文件切割到合適的塊。當前實現了實際切割和虛擬切割。TIPS:切割工作可以是并行多線程實現,實際切割是消耗CPU和內存的,特別是使用管道的方式,因此需要評估資源情況來開線程。虛擬切割,只是建立虛擬文件,定義好對應到實體文件的塊起始。前者切割時候消耗較大,執行分析時分析線程干擾較小效率高,后者切割時無太大消耗,執行分析時會有干擾效率不是很高。(這個原因還沒有細查,測試效果是這樣)

    分派任務并執行:單機多線程或者多機并行執行分析流程。由于單機會受到CPUIO的限制,當到達一定數量線程以后,分析效率反而降低,因此才會有分布式的需求。

    增量合并處理結果:分派好任務以后,多線程或者多機并性分析時,可以根據執行的情況部分增量式合并處理結果,當所有任務完成以后,結果合并結束。

    輸出分析結果:可以根據需求來創建報表格式。當前采用了csv的文件格式來創建報表,易于閱讀和使用。同時也作了入庫處理,也可以直接用Google Chart API創建圖形化的Html

    輸出對比告警:支持當日閥值預警,當日與昨日,當日與上周同期,當日與上月同期數據橫向對比,到達閥值生成預警頁面。

    基于命令行方式執行階段性任務

             由于整個分析流程已經是任務化了,因此應用只需要具備命令接收功能就可以從任何一步開始執行分析流程,也可以選擇執行到任何步驟直接返回或者輸出中間結果。

             當前應用啟動通過監聽端口數據包,接收命令并執行。

    單任務并行處理化

             希望通過并行化處理來提高效率,就必須要分析場景。

             以下情況不適于用并行化執行來提高效率:

    1. 串行化任務。(上一個任務的輸出成為下一個任務的輸入,或者是有任務順序的限制)

    2. 執行任務時有共享資源競爭。例如CPU,IO,網絡等等,不是并行數越大越好,關鍵還是要看資源分配狀況以及競爭狀況。

    3. 并行化開銷大于帶來的收益。應用復雜度(并發控制),并行本身需要的資源消耗(計算能力,空間存儲,帶寬消耗等)較大。(在MapReduce中涉及到一點就是計算代價總是小于數據傳輸,因此讓數據靠近計算,也就能極大提高效率,反過來看,如果為了分布式而將數據遠離于計算,就得不償失了)

    4. 流程瓶頸不在于當前并行處理的任務。也就是關鍵路徑的問題。

    在分析流程上,對于文件獲取,文件切割,任務分析都是可以做并行化處理,但是還是要根據以上不適合的情況來考慮并行的規模和單機多線程或者多機多線程的方式來做,提升效率。

    低耦合多機協作


    5 兩種Master-Slave模式

             上圖畫了兩種Master-Slave模式,看起來沒什么區別,但是箭頭的方向不同帶來的協作模式也有很大的區別。Hadoop Master負責維護任務的分派,任務執行監控,任務合并指派和監控的工作,而松散的M-S模式,Master處于被動狀態,Master的設計更加簡單化同時也增加了處理的靈活度。

             用一種形象的描述來說明松散方式下的Master-Slave的協作模式。(就拿年底買火車票來說事)

    1. Master要買去成都,武漢,長沙,北京,西安,廣州的火車票各10張。(get Jobs

    2. SlaveA聯系上Master要求領取任務,Master將買成都的火車票任務交給SlaveA,將任務標示為正在執行。(require job)

    3. SlaveA自己托關系去開始買票。(do job)

    4. SlaveB聯系上Master要求領取任務,Master將買武漢的火車票任務交給SlaveB,將任務標示為正在執行。

    5. SlaveB自己托關系開始買票。

    6. ……

    7. Master發現SlaveA在預期時間內還沒有返回,將任務重置為未分配,允許其他Slave來獲取任務。

    8. SlaveB將買到的票給MasterMaster將任務標示為完成,并且與其它已經完成的任務統計合并。

    9. SlaveA返回,但是發現任務已經被別人完成,則無功而回。(計算資源被浪費)

    10.              Master發現所有任務已經完成,則向上級匯報,本次任務已經全部完成,輸出結果。

    其實從上面的描述可以看到Master設計十分簡單,Slave功能也十分單一,帶來的優勢就是處理簡單,易與管理,同時任何時候都允許新的Slave加入,充分利用資源。缺點就是可能在某些Slave不正常的時候不知情(浪費了部分時間),不過由于Master會有預期結果返回時間,因此這個時間設置小一些會減少浪費時間的場景,但也可能帶來重復勞動的代價,這里可以通過算法來最大程度降低異常節點時間消耗,增加Slave有效工作。

    Master職責:獲取任務列表,分派任務,維護任務列表,合并分析結果,出最終結果報表。

    Slave職責:請求任務,執行任務,返回分析結果。

    下面兩個圖描述了具體的多機協作流程和任務狀態轉換情況。


    6 多機協作基本流程圖


    7 任務狀態轉換圖

    附錄

    項目結構說明:


    8 項目包圖

    com.taobao.top.analysis:單機版和多機版的運行實例類在此包內。

    com.taobao.top.analysis.data:抽象配置對象定義。

    com.taobao.top.analysis.jobmanager:流程抽象接口和實現。

    com.taobao.top.analysis.transportNIO的底層通信實現。

    com.taobao.top.analysis.mapMap接口定義和范例實現。

    com.taobao.top.analysis.reduceReduce接口定義和范例實現。

    com.taobao.top.analysis.util:工具類包。

    com.taobao.top.analysis.worker:并行處理的工作者線程實現。

    具體配置及說明:
    top-report.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <top_reports>
     <!-- 全局條件自動會應用到所有的entity中,
      具體condition的定義和使用方式參看后面entity中condition的定義 -->
     <global-condition value="$logflag$!=session"/>
        <global-condition value="$RECORD_LENGTH$&gt;16&amp;$RECORD_LENGTH$&lt;26"/>
       
        <!-- 全局條件自動會應用到所有的entity中,
      具體valuefilter的定義和使用方式參看后面entity中valuefilter的定義
        <global-valuefilter value=""/>
       
        -->

     <!-- 別名,用于定義分析文件中的列,
      防止因為列的移位導致整個報表都需要修改,多個別名可以對應一個列,key代表列數值 -->
        <aliases>
         <alias name="logflag" key="1"/>
       
         <alias name="remoteIp" key="1"/>
         <alias name="partnerId" key="2"/>
         <alias name="format" key="3"/>
         <alias name="appKey" key="4"/>
         <alias name="apiName" key="5"/>
         <alias name="readBytes" key="6"/>
         <alias name="errorCode" key="7"/>
         <alias name="subErrorCode" key="8"/>
         <alias name="localIp" key="9"/>
         <alias name="nick" key="10"/>
         <alias name="version" key="11"/>
         <alias name="signMethod" key="12"/>
         
         <alias name="timestamp1" key="13"/>
         <alias name="timestamp2" key="14"/>
         <alias name="timestamp3" key="15"/>
         <alias name="timestamp4" key="16"/>
         <alias name="timestamp5" key="17"/>
         <alias name="timestamp6" key="18"/>
         
         <alias name="timestamp7" key="19"/>
         <alias name="timestamp8" key="20"/>
         <alias name="timestamp9" key="21"/>
         <alias name="timestamp10" key="22"/>
         <alias name="timestamp11" key="23"/>
         <alias name="timestamp12" key="24"/>
         <alias name="timestamp13" key="25"/>
        </aliases>
       
        <!-- 統計列的定義:
         id是唯一索引,
         name表示在報表中顯示的名稱,
         key可以是alias也可以直接定義列號(不推薦)主要表示對那一列或者幾列作為主鍵進行統計例如key=apiname表示對apiName作分類統計,
          相同的apiname的紀錄作為一組作后面value的運算,key有保留字GLOBAL_KEY代表對所有記錄作總計統計
         value表示計算方式當前支持:min,max,average,count,sum,plain。分別代表統計最小值,最大值,平均值,計數,總和。plain表示直接顯示,一般用于主鍵列的顯示
          同時min,max,average,sum,plain支持表達式,用$$圍起來的代表列,entry()表示對統計后的entry作再次計算得到新的entry的結果。
         condition表示key的過濾條件,支持對列的過濾條件,支持大于,小于,不等于,大于等于,小于等于的表達式(大于小于需要轉義),
          同時可以多個條件串聯用&amp;串聯。注意,表達式中不支持有空格。
         valuefilter表示value的過濾條件,支持計算出來的結果過濾,有大于,小于,不等于,大于等于,小于等于,是否是數字(isnumber),大于小于需要轉義,
          同時可以多個條件串聯用&amp;串聯。注意,表達式中不支持有空格。
         支持自定義map和reduce函數:范例如下:
          mapClass="com.taobao.top.analysis.map.TimeMap" mapParams="xxx=xxx"
       reduceClass="com.taobao.top.analysis.reduce.TimeReduce" reduceParams="xxx=xxx"
          -->
     <entrys>
      <ReportEntry id="1" name="服務請求總次數" key="apiName" value="count()"/>
      <ReportEntry id="2" name="訪問成功次數" key="apiName" value="count()" condition="$errorCode$=0" />
      <ReportEntry id="3" name="訪問失敗次數" key="apiName" value="count()" condition="$errorCode$!=0" />
      <ReportEntry id="4" name="業務平均處理時間" key="apiName" value="average($timestamp4$ - $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="5" name="TOP平均處理時間" key="apiName" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="6" name="業務處理最小時間" key="apiName" value="min($timestamp4$ - $timestamp3$)" valuefilter="&gt;=0&amp;isnumber"/>
      <ReportEntry id="7" name="業務處理最大時間" key="apiName" value="max($timestamp4$ - $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber"/>
      <ReportEntry id="8" name="TIP服務調用前處理時間" key="apiName" value="average($timestamp3$ - $timestamp1$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="9" name="TIP服務調用后處理時間" key="apiName" value="average($timestamp5$ - $timestamp4$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>  
      <ReportEntry id="10" name="日志及輸出消耗時間" key="apiName" value="average($timestamp6$ - $timestamp5$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="api_AverageSuccessTIPTimeConsume" name="成功請求TOP處理平均時間" key="apiName" condition="$errorCode$=0"
        value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
      <ReportEntry id="api_AverageFailTIPTimeConsume" name="失敗請求TOP處理平均時間" key="apiName" condition="$errorCode$!=0"
       value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/> 
      
      
      <ReportEntry id="11" name="訪問總數" key="GLOBAL_KEY" value="count()" />
      <ReportEntry id="12" name="成功總數" key="GLOBAL_KEY" value="count()" condition="$errorCode$=0" />
      <ReportEntry id="13" name="失敗總數" key="GLOBAL_KEY" value="count()" condition="$errorCode$!=0" />
      <ReportEntry id="14" name="業務平均消耗時間(ms)" key="GLOBAL_KEY" value="average($timestamp4$ - $timestamp3$)"  valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="15" name="TOP平均消耗時間(ms)" key="GLOBAL_KEY" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)"  valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
        
      
      <ReportEntry id="16" name="錯誤次數" key="errorCode" value="count()" condition="$errorCode$!=0" />
      
      
      <ReportEntry id="17" name="單機訪問總量" key="localIp" value="count()" />
      <ReportEntry id="18" name="單機訪問成功量" key="localIp" value="count()" condition="$errorCode$=0" />
      <ReportEntry id="19" name="單機訪問失敗量" key="localIp" value="count()" condition="$errorCode$!=0" />
      <ReportEntry id="20" name="單機業務平均消耗時間(ms)" key="localIp" value="average($timestamp4$ - $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="21" name="單機TOP平均消耗時間(ms)" key="localIp" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      
      
      <ReportEntry id="22" name="應用訪問總量" key="appKey" value="count()" />
      <ReportEntry id="23" name="應用成功訪問總量" key="appKey" value="count()" condition="$errorCode$=0" />
      <ReportEntry id="24" name="應用失敗訪問總量" key="appKey" value="count()" condition="$errorCode$!=0"/>
      <ReportEntry id="25" name="應用訪問業務平均耗時(ms)" key="appKey" value="average($timestamp4$ - $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      <ReportEntry id="26" name="應用訪問TOP平均耗時(ms)" key="appKey" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" valuefilter="&gt;=0&amp;&lt;10000&amp;isnumber&amp;round:3"/>
      
      <ReportEntry id="27" name="時間段內訪問總量" key="timestamp1" value="count()"
       mapClass="com.taobao.top.analysis.map.TimeMap"/>
      <ReportEntry id="28" name="時間段內訪問成功總量" key="timestamp1" value="count()" condition="$errorCode$=0"
       mapClass="com.taobao.top.analysis.map.TimeMap"/>
      <ReportEntry id="29" name="時間段內訪問失敗總量" key="timestamp1" value="count()" condition="$errorCode$!=0"
       mapClass="com.taobao.top.analysis.map.TimeMap" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
      <ReportEntry id="30" name="時間段內訪問業務平均耗時(ms)" key="timestamp1" value="average($timestamp4$ - $timestamp3$)"
       mapClass="com.taobao.top.analysis.map.TimeMap" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
      <ReportEntry id="31" name="時間段內訪問TOP平均耗時(ms)" key="timestamp1" value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)"
       mapClass="com.taobao.top.analysis.map.TimeMap" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
       
      
      <ReportEntry id="api_sysFailCount" name="TOP平臺級錯誤量" key="apiName" value="count()"
         condition="$errorCode$&lt;100&amp;$errorCode$&gt;0" />
      <ReportEntry id="api_serviceSysFailCount" name="服務系統級錯誤量(900到901)" key="apiName" value="count()"
         condition="$errorCode$&lt;902&amp;$errorCode$&gt;899" />
      <ReportEntry id="api_serviceSysFailCount1" name="服務系統級錯誤量(大于901)" key="apiName" value="count()"
         condition="$errorCode$&gt;901"/>
      <ReportEntry id="api_serviceAPIFailCount" name="服務業務級錯誤量" key="apiName" value="count()"
         condition="$errorCode$&gt;100&amp;$errorCode$&lt;900"/>
      <ReportEntry id="api_serviceSysFailTotalCount" name="服務系統級總錯誤量" key="apiName" value="count()"
         condition="$errorCode$&gt;899" />
        
      
     </entrys>
     
     
     <!--
      報表定義:
      id為報表主鍵,除了數字也可以用英文字符串
      file為報表保存的名稱,不建議使用中文
      entryList描述了報表包含的所有的entry,可以引用上面定義的全局性的entry,也可以內部定義私有的entry。
      
      -->
     <reports>
         <report id="0" file="totalTIPConsumeReport">
          <entryList>
        <entry name="TOP獲取參數耗時" key="GLOBAL_KEY" value="average($timestamp7$)" condition="$errorCode$=0"/>
        <entry name="TOP獲取參數最小耗時" key="GLOBAL_KEY" value="min($timestamp7$)" condition="$errorCode$=0"/>
        <entry name="TOP獲取參數最大耗時" key="GLOBAL_KEY" value="max($timestamp7$)" condition="$errorCode$=0"/>
          
        <entry name="獲取API信息耗時" key="GLOBAL_KEY" value="average($timestamp8$)" condition="$errorCode$=0"/>
        <entry name="獲取API信息最小耗時" key="GLOBAL_KEY" value="min($timestamp8$)" condition="$errorCode$=0"/>
        <entry name="獲取API信息最大耗時" key="GLOBAL_KEY" value="max($timestamp8$)" condition="$errorCode$=0"/>
          
        <entry name="處理協議必選參數耗時" key="GLOBAL_KEY" value="average($timestamp9$)" condition="$errorCode$=0"/>
        <entry name="處理協議必選參數最小耗時" key="GLOBAL_KEY" value="min($timestamp9$)" condition="$errorCode$=0"/>
        <entry name="處理協議必選參數最大耗時" key="GLOBAL_KEY" value="max($timestamp9$)" condition="$errorCode$=0"/>
          
          
        <entry name="頻率黑名單校驗耗時" key="GLOBAL_KEY" value="average($timestamp10$)" condition="$errorCode$=0"/>
        <entry name="頻率黑名單校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp10$)" condition="$errorCode$=0"/>
        <entry name="頻率黑名單校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp10$)" condition="$errorCode$=0"/>
          
        <entry name="協議可選參數校驗耗時" key="GLOBAL_KEY" value="average($timestamp11$)" condition="$errorCode$=0"/>
        <entry name="協議可選參數校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp11$)" condition="$errorCode$=0"/>
        <entry name="協議可選參數校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp11$)" condition="$errorCode$=0"/>
          
        <entry name="業務必選參數校驗耗時" key="GLOBAL_KEY" value="average($timestamp12$)" condition="$errorCode$=0"/>
        <entry name="業務必選參數校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp12$)" condition="$errorCode$=0"/>
        <entry name="業務必選參數校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp12$)" condition="$errorCode$=0"/>
          
        <entry name="業務可選參數校驗耗時" key="GLOBAL_KEY" value="average($timestamp13$)" condition="$errorCode$=0"/>
        <entry name="業務可選參數校驗最小耗時" key="GLOBAL_KEY" value="min($timestamp13$)" condition="$errorCode$=0"/>
        <entry name="業務可選參數校驗最大耗時" key="GLOBAL_KEY" value="max($timestamp13$)" condition="$errorCode$=0"/>

        </entryList>
         </report>
     
      <report id="1" file="totalReport">
       <entryList>
        <entry id="11"/>
        <entry name="訪問總流量(M)" key="GLOBAL_KEY" value="sum($readBytes$/#1000000#)"  valuefilter="&gt;=0&amp;isnumber&amp;round:4"/>
        <entry id="12"/>
        <entry name="訪問成功率" key="GLOBAL_KEY" value="plain(entry(12)/entry(11))" valuefilter="&gt;=0&amp;isnumber&amp;round:4"/>
        <entry id="13"/>
        <entry name="平臺系統錯誤率(占總錯誤百分比)" key="GLOBAL_KEY" value="plain(entry(sysFailCount)/entry(13))" valuefilter="&gt;=0&amp;isnumber&amp;round:4"/>
        <entry name="服務系統錯誤率(占總錯誤百分比)" key="GLOBAL_KEY" value="plain(entry(serviceSysFailCount)/entry(13))" valuefilter="&gt;=0&amp;isnumber&amp;round:4"/>
        <entry name="服務業務錯誤率(占總錯誤百分比)" key="GLOBAL_KEY" value="plain(entry(serviceAPIFailCount)/entry(13))" valuefilter="&gt;=0&amp;isnumber&amp;round:4"/>
        <entry id="14"/>
        <entry id="15"/>
        <entry name="TOP成功處理平均耗時" key="GLOBAL_KEY"
         value="average($timestamp6$ - $timestamp1$ - $timestamp4$ + $timestamp3$)" condition="$errorCode$=0" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="sysFailCount" name="平臺系統錯誤數" key="GLOBAL_KEY" value="count()" condition="$errorCode$&lt;100&amp;$errorCode$&gt;0"/>
        <entry id="serviceSysFailCount" name="服務系統錯誤數" key="GLOBAL_KEY" value="count()" condition="$errorCode$&gt;899"/>
        <entry id="serviceAPIFailCount" name="服務業務錯誤數" key="GLOBAL_KEY" value="count()" condition="$errorCode$&gt;100&amp;$errorCode$&lt;900"/>
       </entryList>
      </report>
     
      <report id="2" file="apiReport">
       <entryList>
           <entry name="服務名稱" key="apiName" value="plain($apiName$)" />
        <entry id="1"/>
        <entry name="占總量比例" key="apiName" value="plain(entry(1)/entry(sum:1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="2"/>
        <entry name="服務請求成功率" key="apiName" value="plain(entry(2)/entry(1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="3"/>
        <entry id="4"/>
        <entry id="5"/>
        <entry name="TOP占總處理時間百分比" key="apiName" value="plain(entry(5)/entry(5+4))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="api_AverageSuccessTIPTimeConsume"/>
        <entry id="api_AverageFailTIPTimeConsume"/>
        <entry id="6"/>
        <entry id="7"/>
        <entry id="8"/>
        <entry id="9"/>
        <entry id="10"/>
        <entry id="api_sysFailCount"/>
        <entry id="api_serviceSysFailTotalCount"/>
        <entry id="api_serviceAPIFailCount"/>
       </entryList>
      </report>
      
      <report id="3" file="errorCodeReport">
       <entryList>
           <entry id="33" name="錯誤碼" key="errorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
        <entry id="16"/>
        <entry name="錯誤比例" key="errorCode" value="plain(entry(16)/entry(sum:16))" condition="$errorCode$!=0" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
       </entryList>
      </report>
      
      <report id="4" file="machineReport">
       <entryList>
           <entry name="服務器IP" key="localIp" value="plain($localIp$)" />
        <entry id="17"/>
        <entry name="占總量比例" key="localIp" value="plain(entry(17)/entry(sum:17))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="18"/>
        <entry name="成功率" key="localIp" value="plain(entry(18)/entry(17))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="19"/>
        <entry id="20"/>
        <entry id="21"/>
        <entry name="TOP占總處理時間比值" key="localIp" value="plain(entry(21)/entry(20+21))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
       </entryList>
      </report>
      
      <report id="5" file="appReport">
       <entryList>
           <entry name="應用ID" key="appKey" value="plain($appKey$)" />
        <entry id="22"/>
        <entry name="占總訪問比例" key="appKey" value="plain(entry(22)/entry(sum:22))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="23"/>
        <entry name="應用訪問成功率" key="appKey" value="plain(entry(23)/entry(22))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="24"/>
        <entry id="25"/>
        <entry id="26"/>
       </entryList>
      </report>
      
      <report id="6" file="periodReport">
       <entryList>
           <entry name="時間段" key="timestamp1" value="plain($timestamp1$)"
            mapClass="com.taobao.top.analysis.map.TimeMap"
            reduceClass="com.taobao.top.analysis.reduce.TimeReduce"/>
        <entry id="27"/>
        <entry name="占請求總量比例" key="timestamp1" value="plain(entry(27)/entry(sum:27))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="28"/>
        <entry name="請求成功率" key="timestamp1" value="plain(entry(28)/entry(27))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="29"/>
        <entry id="30"/>
        <entry id="31"/>
       </entryList>
      </report>
      
      <report id="7" file="appAPIReport">
       <entryList>
           <entry name="應用ID" key="appKey,apiName" value="plain($appKey$)" condition="$errorCode$=0"/>
           <entry name="服務名稱" key="appKey,apiName" value="plain($apiName$)" condition="$errorCode$=0"/>
        <entry id="app_api_successCount" name="訪問成功總量" key="appKey,apiName" value="count()" condition="$errorCode$=0"/>
       </entryList>
      </report>
      
      <report id="8" file="errorCodeAndSubErrorCodeReport">
       <entryList>
           <entry name="錯誤碼" key="errorCode,subErrorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/> 
           <entry name="子錯誤碼" key="errorCode,subErrorCode" value="plain($subErrorCode$)"  condition="$errorCode$!=0"/>
        <entry name="錯誤總數" key="errorCode,subErrorCode" value="count()" condition="$errorCode$!=0"/>
       </entryList>
      </report>
      
        
      <report id="9" file="apiFailDetailReport">
       <entryList>
           <entry name="服務名稱" key="apiName" value="plain($apiName$)" />
        <entry id="1"/>
        <entry id="3"/>
        <entry name="失敗數占服務請求量比例" key="apiName" value="plain(entry(3)/entry(1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry name="失敗數占失敗總量比例" key="apiName" value="plain(entry(3)/entry(sum:3))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="api_sysFailCount"/>
        <entry name="平臺級錯誤占總服務請求比例" key="apiName" value="plain(entry(api_sysFailCount)/entry(1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="api_serviceSysFailCount"/>
        <entry name="服務系統級錯誤量(900到901)占總服務請求比例" key="apiName" value="plain(entry(api_serviceSysFailCount)/entry(1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="api_serviceSysFailCount1"/>
        <entry name="服務系統級錯誤量(大于901)占總服務請求比例" key="apiName" value="plain(entry(api_serviceSysFailCount1)/entry(1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
        <entry id="api_serviceAPIFailCount"/>
        <entry name="服務業務級錯誤占總服務請求比例" key="apiName" value="plain(entry(api_serviceAPIFailCount)/entry(1))" valuefilter="&gt;=0&amp;isnumber&amp;round:3"/>
       </entryList>
      </report>
      
      <report id="10" file="appApiErrorReport">
       <entryList>
           <entry name="應用ID" key="appKey,apiName,errorCode" value="plain($appKey$)" condition="$errorCode$!=0"/>
           <entry name="服務名稱" key="appKey,apiName,errorCode" value="plain($apiName$)" condition="$errorCode$!=0"/>
           <entry name="錯誤碼" key="appKey,apiName,errorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
        <entry name="錯誤次數" key="appKey,apiName,errorCode" value="count()" condition="$errorCode$!=0"/>
       </entryList>
      </report>
      
      <report id="11" file="verionAndSignTypeReport">
       <entryList>
           <entry name="版本號" key="version,signMethod" value="plain($version$)" condition="$errorCode$=0"/>
           <entry name="簽名類型" key="version,signMethod" value="plain($signMethod$)" condition="$errorCode$=0"/>
           <entry name="訪問成功總數" key="version,signMethod" value="count()" condition="$errorCode$=0"/>
       </entryList>
      </report>
      
      <report id="12" file="appErrorCodeReport">
       <entryList>
           <entry name="應用ID" key="appKey,errorCode" value="plain($appKey$)" condition="$errorCode$!=0"/>
           <entry name="錯誤碼" key="appKey,errorCode" value="plain($errorCode$)" condition="$errorCode$!=0"/>
           <entry name="錯誤總數" key="appKey,errorCode" value="count()" condition="$errorCode$!=0"/>
       </entryList>
      </report>
     
     </reports>
     
     <alerts>
      <!-- 對比告警 alerttype:now,day,week,month。
       valve代表閥值:&lt;(now類型代表小于告警,如果是同期比較代表下降超過),
       &gt;(now類型代表大于告警,如果是同期比較代表上升),沒有符號代表絕對值超過告警-->
      <alert reportId="1" entryname="訪問成功率" alerttype="now" valve="&lt;0.9" />
      <alert reportId="1" entryname="訪問總數" alerttype="day" valve="5000000" />
      <alert reportId="1" entryname="訪問成功率" alerttype="day" valve="&lt;0.01" />
      <alert reportId="1" entryname="平臺系統錯誤率" alerttype="day" valve="&gt;0.05" />
      <alert reportId="1" entryname="服務系統錯誤率" alerttype="day" valve="&gt;0.05" />
      <alert reportId="1" entryname="服務業務錯誤率" alerttype="day" valve="&gt;0.05" />
      <alert reportId="1" entryname="TOP平均消耗時間(ms)" alerttype="day" valve="&gt;10" />
      <alert reportId="1" entryname="業務平均消耗時間(ms)" alerttype="day" valve="&gt;10" />
      
      <alert reportId="2" keyentry="服務名稱" entryname="占總量比例" alerttype="day" valve="&gt;0.01" />
      <alert reportId="2" keyentry="服務名稱" entryname="服務請求成功率" alerttype="day" valve="&lt;0.01" />
      <alert reportId="2" keyentry="服務名稱" entryname="業務平均處理時間" alerttype="day" valve="&gt;20" />
      <alert reportId="2" keyentry="服務名稱" entryname="TOP平均處理時間" alerttype="day" valve="&gt;20" />
      
      <alert reportId="3" keyentry="錯誤碼" entryname="錯誤比例" alerttype="day" valve="&gt;0.01" />
      
      <alert reportId="4" keyentry="服務器IP" entryname="成功率" alerttype="day" valve="&lt;0.01" />
      
      <alert reportId="5" keyentry="應用ID" entryname="占總訪問比例" alerttype="day" valve="0.01" />
      <alert reportId="5" keyentry="應用ID" entryname="應用訪問成功率" alerttype="day" valve="&lt;0.05" />
      
      <alert reportId="7" keyentry="應用ID,服務名稱" entryname="訪問成功總量" alerttype="day" valve="&gt;10000000" />
      
      <alert reportId="9" keyentry="服務名稱" entryname="失敗數占總量比例" alerttype="day" valve="&gt;0.01" />
      
      <alert reportId="10" keyentry="應用ID,服務名稱,錯誤碼" entryname="錯誤次數" alerttype="day" valve="&gt;10000" />
      
      <alert reportId="11" keyentry="版本號,簽名類型" entryname="訪問成功總數" alerttype="day" valve="&lt;1000000" />
      
      <alert reportId="12" keyentry="應用ID,錯誤碼" entryname="錯誤總數" alerttype="day" valve="&gt;100000" />
      
     </alerts>
     
    </top_reports>


    posted on 2010-01-12 21:58 岑文初 閱讀(3859) 評論(5)  編輯  收藏

    評論

    # re: 基于MapReduce的配置型日志分析組件 2010-01-17 01:31 ethan
    目前的功能范圍還比較窄(也許是我沒看到):
    1.沒有看到數據清洗(轉換)處理流程,日志處理有時候需要對數據進行轉換和容錯;
    2.對于TOP排名之類的應用還是有一定的問題;[如時間窗口隨意的情況]
    3.不太適合Distinct之類的應用;[這個目前你的需求里確實也沒有]
    4.沒有看到權重設置(也就是資源占用)之類的內容,如max肯定比count計數之類的跑的慢;
    5.沒有看到com.taobao.top.analysis.worker中關于master節點對于并行隊列的處理和涉及。很多時候容易碰到slave并行提交給master的場景(當你的任務設置過小的話);
    6.沒有看到slave監控的涉及[尤其是多服務器的情況]。


    TIPS1:日志拆分和slave的拆分是一個需要多次調優的過程

    TIPS2:拆分工作我們做過測試,分別用shell(結合awk)、perl(crc32 hash)、java做過長時間的測試和代碼優化(因為測試環境差別,不說詳細的數據,拆分一個12GB的話單文件[60列,每行200個字節,拆分成50個小文件],t(java)=3*t(shell),t(shell)=4*t(perl),t(*)代表時間消耗,但是perl拆分文件的占用cpu最高,一直在85%以上,perl的時間在4分鐘左右)。  回復  更多評論
      

    # re: 基于MapReduce的配置型日志分析組件 2010-01-17 12:14 岑文初
    @ethan
    1.condition和valuefilter就是數據清洗的環節,當然也支持,map和reduce的自定義。
    2.對于top排名只需要定義order即可,當前流出了字段,不了解什么叫做時間窗隨意。
    3.沒有這個需求,我不是做DB。
    4.對于與處理來說由于對于記錄輸入只是一次遍歷,因此沒有必要再去細分什么類型的reduce,一條記錄閱讀完成以后這些分析必須全部做,這是一個串行的過程,因此無所謂前后之分。
    5.松散的設計就是讓master足夠輕,同時任務slave就是資源廉價,通過用算法來分配任務,在失效時間和分配之間找到平衡點,master和slave的關系。
    6.還是那個設計,如果master要監控slave,那么就不是我說的松散設計,而是傳統的分布式mapreduce的思想。選擇松散就是在控制度和復雜度之間找到平衡點。

    對于處理來說就是需要找到關鍵路徑,然后在關鍵路徑上找各個環節可以優化并行處理的工作,至于如何優化,的卻需要去驗證,就好比文件切割和任務塊執行,最簡單的設計就是根據多核來設定單機的工作線程,因為這是消耗cpu的工作。

    對于文件切割會根據采用的方式不同而不同,我只是關心java方式,呵呵,其他我不關心了,對于java我就用map file的方式來切割,管道輸入輸出效率還是很高的,我不了解你的測試用的是什么方式。

    不過很感謝你的留言,起碼看到有人還是看了,呵呵。  回復  更多評論
      

    # re: 基于MapReduce的配置型日志分析組件 2010-01-17 15:18 ethan
    @岑文初
    1.時間窗口隨意指的是如1/1日的top 10,1/2的top 10,1/1-1/3的top 10.可以隨意做時間窗口設計。
    2.Distinct 之類的應用并不只是數據庫專屬應用。如使用用戶數就是一個distinct的典型應用,一個用戶本月使用三次,在本月使用用戶數指標中只能有算一個。延展開來就是網站中常用的獨立訪問用戶數的概念。
    3.關于master端隊列的設計是可以保證slave在并行提交數據給master的時候能保證正常處理。[因為你的設計中是slave主動將合并結果給master,不是master去取,hadoop沒有這樣的問題]
    ------------

    我很想了解一下你所說的map file方式文件拆分的性能測試數據和實現方式。
    在大數據量話單和日志分析系統中,拆分是保證時效性和性能中最重要的一環。  回復  更多評論
      

    # re: 基于MapReduce的配置型日志分析組件 2010-01-18 13:39 岑文初
    @ethan
    1.對于趨勢統計我們現在是將每日數據入庫來做更加個性化的統計,因為分析后的數據已經是比較粗粒度,但是同時有能夠滿足個性化需求的,因此就不再這個系統中設計了。當然趨勢告警這邊有做
    2.先不說月,我在系統中有max,min,average,其實就有一定的這個意思,當著些邏輯滿足不了,可以自動擴展reduce的方法來實現。
    3.對于結果的merge是master單線程做的,多線程提交只是放在合并隊列,因此不存在并發問題。而且合并結果本來就有資源競爭,對于此類過程,多線程和單線程效率沒什么區別,多線程反而增加復雜度。

    mapping file其實就是用java的管道和內存文件來做的,效率應該說在java中比較好了,實際的測試我到沒有準確的做過,也不好給出結果。

    當前正在做即時分析,數據源也可以切換到DB上去了,時間可以縮短,省掉了對大文件切割和拖拉的時間。(這塊時間的卻是在分析中最耗時的),這樣我除了每天的日報表,也有了段時間的報表(每15分鐘,自己可以定義時間段),增量合并后就是一天的報表。  回復  更多評論
      

    # re: 基于MapReduce的配置型日志分析組件 2010-01-19 18:19 Ethan
    @岑文初
    我們目前的系統分為兩個部分
    1.下載文件 -->切割-->邏輯處理(比較復雜的邏輯)-->合并(很簡單的合并,電信行業有歷史記錄查詢需求)-->加載入庫
    2.數據庫-->切割(hash)-->統計報表預處理-->報表

    有兩次切割。  回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲中文久久精品无码1| 美女视频黄.免费网址 | 久久性生大片免费观看性| 亚洲AV无码1区2区久久| 无码人妻一区二区三区免费| 免费在线观看亚洲| 亚洲酒色1314狠狠做| 国产乱子伦片免费观看中字| 免费人成毛片动漫在线播放 | 亚洲最大成人网色香蕉| 国产成人亚洲精品影院| 曰批视频免费40分钟试看天天| 国产精品亚洲lv粉色| 99久久亚洲综合精品成人网| 国产精品免费电影| 成人免费的性色视频| 国产免费一区二区三区免费视频| 亚洲videos| 亚洲人成无码网站| 国产免费资源高清小视频在线观看| 久久久精品午夜免费不卡| 久久久亚洲精华液精华液精华液 | 亚洲国产人成在线观看| 亚洲一级特黄无码片| 成人午夜18免费看| 99爱在线观看免费完整版| 暖暖免费中文在线日本 | 特级无码毛片免费视频尤物| 国产成人亚洲精品91专区高清 | 久久精品国产亚洲Aⅴ蜜臀色欲| 国产免费毛不卡片| 久久精品免费一区二区三区| 午夜在线免费视频 | 亚洲综合视频在线| 亚洲乱亚洲乱少妇无码| 免费a级毛片高清视频不卡| 99久久精品国产免费| a级毛片高清免费视频就| 手机永久免费的AV在线电影网| 亚洲综合一区无码精品| 亚洲午夜电影一区二区三区|