cascading基本概念-博客-云棲社區(qū)-阿里云
https://yq.aliyun.com/articles/37671
摘要: 這是cascading官方userguide的中文翻譯号醉,其中有些概念看過一段時間又忘了蜓竹,在此做個記錄计雌,一是方便自己復(fù)習(xí)申屹,二是方便新手旬痹。 關(guān)于cascading我不想多說了乐设,你如果寫過原生mapreduce程序稚晚,然后再接觸cascading,你會發(fā)現(xiàn)cascading Great job雅采。它對Map和Reduce進(jìn)行了高度抽象爵憎,用Tap、Pipe婚瓜、Function宝鼓、Op
這是cascading官方userguide的中文翻譯,其中有些概念看過一段時間又忘了巴刻,在此做個記錄愚铡,一是方便自己復(fù)習(xí),二是方便新手胡陪。
關(guān)于cascading我不想多說了沥寥,你如果寫過原生mapreduce程序,然后再接觸cascading柠座,你會發(fā)現(xiàn)cascading Great job邑雅。它對Map和Reduce進(jìn)行了高度抽象,用Tap愚隧、Pipe蒂阱、Function锻全、Operation這些概念替代了原有的Map和Reduce,可以很舒服的開發(fā)hadoop程序录煤,但是這些概念過了一個來月我又忘的差不多了鳄厌,所以有了這篇翻譯。
對于一些不好翻譯的單詞我這里直接給出了原單詞妈踊,所以說看資料還是英文原版的好了嚎,看翻譯的書籍有很大風(fēng)險,萬一別人翻譯錯了廊营,那你這個newbie怎么能懂歪泳!
下面的翻譯來自cascading-userguide/ch03s03.html,下載地址:http://docs.cascading.org/cascading/2.5/userguide/html/userguide.zip
首先是一段關(guān)于pipe assembly的代碼例子
// the "left hand side" assembly headPipe lhs = new Pipe( "lhs" );lhs = new Each( lhs, new SomeFunction() );lhs = new Each( lhs, new SomeFilter() );// the "right hand side" assembly headPipe rhs = new Pipe( "rhs" );rhs = new Each( rhs, new SomeFunction() );// joins the lhs and rhsPipe join = new CoGroup( lhs, rhs );join = new Every( join, new SomeAggregator() );join = new GroupBy( join );join = new Every( join, new SomeAggregator() );// the tail of the assemblyjoin = new Each( join, new SomeFunction() );
通用流模式Common Stream Pattern
Split 一分多
Merge 多合一stream擁有相同fields常見的有:Merge露筒、GroupBy
Join 和sqljoin一樣呐伞,把擁有不同列的stream按照相同列join起來。HashJoin慎式、CoGroup
除了split伶氢、merge、join以外瘪吏,管道組裝還有examine癣防、filter、organize掌眠、transform這些操作蕾盯,為了方便處理,在元組中的每個值都被賦予一個fieldname蓝丙,就像數(shù)據(jù)庫中的列名一樣级遭,這樣他們就能很方便的被引用與選擇。
術(shù)語介紹:
Operation(cascading.operation.Operation)接受一個參數(shù)元組Tuple渺尘,輸出零或多個結(jié)果元組装畅。Cascading提供了幾個常用的Operation,開發(fā)者也可以自己實現(xiàn)沧烈。
Tuple,在Cascading中像云,數(shù)據(jù)被看作元組(cascading.tuple.Tuple)的流锌雀,元組由fields構(gòu)成,元組和數(shù)據(jù)庫中的記錄或行類似迅诬。一個元組是一組值的數(shù)組腋逆,每個值可以為任何java.lang.Object。
Fields(cascading.tuple,Fields)被用于聲明或引用元組中的某一列侈贷,fields可以表示為像“firstname”惩歉、“birthdate”的字符串,也可以是整數(shù)值(0表示第一個,-1表示最后一個)撑蚌,或者還可以是預(yù)定義的值(Fields.All上遥、Fields.RESULT、Fields.REPLACE等)
Pipe類是用于實例化與命名一個pipe争涌,Pipe的名字可以被planner用于綁定到tap上粉楚,作為source或者sink使用。(第三種選擇是綁定pipebranch到一個tap亮垫,作為一個trap模软,這在高級主題在詳細(xì)討論)
SubAssembly子類是一個特殊的pipe類型,他用于嵌套一組可重用的pipeassemblies饮潦,這樣可以方便用于更大范圍內(nèi)的pipeassembly燃异。
其余六種pipe類型:
Each這種pipe基于tuple的內(nèi)容做處理,包括analyze继蜡、transform回俐、filter。還可以用Each類splitor branch一個流壹瘟,達(dá)到這種效果你僅僅需要把Each的輸出定向到一個不同的pipe或sink即可鲫剿。
Merge這個pipe和Each一樣都可以把一個流split成兩個,Merge還可以把多個流合并成一個稻轨,前途是這些流具有相同的fields灵莲。當(dāng)不需要grouping(noaggregator or buffer操作會被使用時)時使用Merge,Merge比GroupBy快殴俱。
GroupBy基于特定field政冻,把一個流中的tuples分組。如果傳入多個stream线欲,它在分組之前先進(jìn)行merge操作明场,在進(jìn)行merge時,GroupBy要求多個stream必須用相同的fieldstructure李丰。分組的目的通常是為Every管道準(zhǔn)備一個處理流苦锨,Every管道可以針對groups進(jìn)行aggregator和buffer操作,比如counting趴泌,totalling舟舒,averaging。我們應(yīng)該明確嗜憔,grouping這里意味著基于某一特地field的值進(jìn)行分組(byGroupBy或CoGroup),比如按照timestamp或zipcode進(jìn)行分組秃励,在每一分組中,元組的順序是隨機的吉捶,不過你也可以指定一個次sortkey夺鲜,但是通常情況下皆尔,是不必要的,這只會增加運行時間币励。
Every用于處理分組后的流慷蠕。只能用于GroupBy或Cogroup的輸出流,不能處理Each榄审、Merge砌们、HashJoin的輸出流。
CoGroup對多個流進(jìn)行join搁进,和SQLjoin類似浪感。它只基于某特定field進(jìn)行g(shù)roup,產(chǎn)出一個結(jié)果流饼问。如果在多流中包含有相同的field名影兽,它們必須被重命名來避免結(jié)果tuple中field的沖突
HashJoin和Cogroup一樣,用于對多個流的join莱革。但是它更適用于不需要grouping的場合下峻堰,這時它的性能更優(yōu)。
Pipe類型對比表
Pipe type
Purpose
Input
Output
Pipe
instantiate a pipe; create or name a branch
name
a (named) pipe
SubAssembly
create nested subassemblies
Each
apply a filter or function, or branch a stream
tuple stream (grouped or not)
a tuple stream, optionally filtered or transformed
Merge
merge two or more streams with identical fields
two or more tuple streams
a tuple stream, unsorted
GroupBy
sort/group on field values; optionally merge two or morestreams with identical fields
one or more tuple streams with identical fields
a single tuple stream, grouped on key field(s) with optionalsecondary sort
Every
apply aggregator or buffer operation
grouped tuple stream
a tuple stream plus new fields with operation results
CoGroup
join 1 or more streams on matching field values
one or more tuple streams
a single tuple stream, joined on key field(s)
HashJoin
join 1 or more streams on matching field values
one or more tuple streams
a tuple stream in arbitrary order
Each盅视、Every的語法如下:
new Each( previousPipe, argumentSelector, operation, outputSelector )new Every( previousPipe, argumentSelector, operation, outputSelector )
這兩個pipe都有四個參數(shù):
一個pipe實例
一個參數(shù)選擇器
一個Operation實例
一個輸出選擇器
Each與Every的主要不同在于Each用于處理單個元組捐名,Every用于處理由GroupBy或CoGroup輸出的分組tuple,這限制了它們分別可以實施的操作闹击、結(jié)果的輸出镶蹋。
Each的操作可以是Functions和Filters的子類。比如你可以從日志文件中解析出特定field赏半;過濾掉除了HTTPGET以外的請求贺归,把timestring替換成datefield。
Every的操作可以是Aggregators和Buffer的子類断箫。比如你可以用Every去統(tǒng)計每天GET請求數(shù)拂酣,它會為每天輸出一個統(tǒng)計值。
大多數(shù)Operation子類都聲明了resultfield(就是上圖中的declaredfields)仲义,outputSelector指定輸出Tuple中的field婶熬,而輸出Tuple中的field來源于input的field和operation的結(jié)果這兩個方面。如果outputSelector=Fields.ALL那么輸出的Tuple就是input+result的數(shù)據(jù)merge后的結(jié)果埃撵。
對于Each來說argumentSelector默認(rèn)為Fields.All尸诽,outputSelector默認(rèn)為Fields.RESULT
對于Every來說Aggregator的result默認(rèn)被追加到inputTuple上。比如盯另,你在department域上做grouping,然后統(tǒng)計這個公寓的names洲赵,那么結(jié)果fields會是["department","num_employees"]
當(dāng)Every與Bufferoperation一起使用時鸳惯,行為和Aggregator很不一樣商蕴,operationresult這次是和當(dāng)前valuestuple關(guān)聯(lián)在一起,而不是當(dāng)前groupingtuple芝发。這就像Each與Function一起使用時一樣绪商。這也許看起來不是很直觀,但這提供了很大的靈活性辅鲸。換一個說法格郁,bufferoperation的result沒有被追加到thecurrent keys being grouped on,是由buffer來決定是emit它們ifthey are relevant独悴,而且對于Buffer來說例书,針對每個唯一的grouping有可能emit多個resultTuple。也就是說刻炒,一個Buffer可能或者可能不和Aggregator行為一致决采,但是Aggregator只是一個特殊的Buffer。