這是cascading官方userguide的中文翻譯,其中有些概念看過一段時間又忘了,在此做個記錄,一是友善自己複習,二是友善新手。
關于cascading我不想多說了,你如果寫過原生mapreduce程式,然後再接觸cascading,你會發現cascading great job。它對map和reduce進行了高度抽象,用tap、pipe、function、operation這些概念替代了原有的map和reduce,可以很舒服的開發hadoop程式,但是這些概念過了一個來月我又忘的差不多了,是以有了這篇翻譯。
對于一些不好翻譯的單詞我這裡直接給出了原單詞,是以說看資料還是英文原版的好,看翻譯的書籍有很大風險,萬一别人翻譯錯了,那你這個newbie怎麼能懂!
下面的翻譯來自cascading-userguide/ch03s03.html,下載下傳位址:http://docs.cascading.org/cascading/2.5/userguide/html/userguide.zip
首先是一段關于pipe assembly的代碼例子

通用流模式common stream pattern
split
一分多
merge
多合一stream擁有相同fields常見的有:merge、groupby
join 和sqljoin一樣,把擁有不同列的stream按照相同列join起來。hashjoin、cogroup
除了split、merge、join以外,管道組裝還有examine、filter、organize、transform這些操作,為了友善處理,在元組中的每個值都被賦予一個fieldname,就像資料庫中的列名一樣,這樣他們就能很友善的被引用與選擇。
術語介紹:
operation(cascading.operation.operation)接受一個參數元組tuple,輸出零或多個結果元組。cascading提供了幾個常用的operation,開發者也可以自己實作。
tuple,在cascading中,資料被看作元組(cascading.tuple.tuple)的流,元組由fields構成,元組和資料庫中的記錄或行類似。一個元組是一組值的數組,每個值可以為任何java.lang.object。
fields(cascading.tuple,fields)被用于聲明或引用元組中的某一列,fields可以表示為像“firstname”、“birthdate”的字元串,也可以是整數值(0表示第一個,-1表示最後一個),或者還可以是預定義的值(fields.all、fields.result、fields.replace等)
pipe類是用于執行個體化與命名一個pipe,pipe的名字可以被planner用于綁定到tap上,作為source或者sink使用。(第三種選擇是綁定pipebranch到一個tap,作為一個trap,這在進階主題在詳細讨論)
subassembly子類是一個特殊的pipe類型,他用于嵌套一組可重用的pipeassemblies,這樣可以友善用于更大範圍内的pipeassembly。
其餘六種pipe類型:
each這種pipe基于tuple的内容做處理,包括analyze、transform、filter。還可以用each類splitor
branch一個流,達到這種效果你僅僅需要把each的輸出定向到一個不同的pipe或sink即可。
merge這個pipe和each一樣都可以把一個流split成兩個,merge還可以把多個流合并成一個,前途是這些流具有相同的fields。當不需要grouping(noaggregator
or buffer操作會被使用時)時使用merge,merge比groupby快。
groupby基于特定field,把一個流中的tuples分組。如果傳入多個stream,它在分組之前先進行merge操作,在進行merge時,groupby要求多個stream必須用相同的fieldstructure。分組的目的通常是為every管道準備一個處理流,every管道可以針對groups進行aggregator和buffer操作,比如counting,totalling,averaging。我們應該明确,grouping這裡意味着基于某一特地field的值進行分組(bygroupby或cogroup),比如按照timestamp或zipcode進行分組,在每一分組中,元組的順序是随機的,不過你也可以指定一個次sortkey,但是通常情況下,是不必要的,這隻會增加運作時間。
every用于處理分組後的流。隻能用于groupby或cogroup的輸出流,不能處理each、merge、hashjoin的輸出流。
cogroup對多個流進行join,和sqljoin類似。它隻基于某特定field進行group,産出一個結果流。如果在多流中包含有相同的field名,它們必須被重命名來避免結果tuple中field的沖突
hashjoin和cogroup一樣,用于對多個流的join。但是它更适用于不需要grouping的場合下,這時它的性能更優。
pipe類型對比表
pipe type
purpose
input
output
<code>pipe</code>
instantiate a pipe; create or name a branch
name
a (named) pipe
<code>subassembly</code>
create nested subassemblies
<code>each</code>
apply a filter or function, or branch a stream
tuple stream (grouped or not)
a tuple stream, optionally filtered or transformed
<code>merge</code>
merge two or more streams with identical fields
two or more tuple streams
a tuple stream, unsorted
<code>groupby</code>
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
<code>every</code>
apply aggregator or buffer operation
grouped tuple stream
a tuple stream plus new fields with operation results
<code>cogroup</code>
join 1 or more streams on matching field values
one or more tuple streams
a single tuple stream, joined on key field(s)
<code>hashjoin</code>
a tuple stream in arbitrary order
each、every的文法如下:
這兩個pipe都有四個參數:
一個pipe執行個體
一個參數選擇器
一個operation執行個體
一個輸出選擇器
each與every的主要不同在于each用于處理單個元組,every用于處理由groupby或cogroup輸出的分組tuple,這限制了它們分别可以實施的操作、結果的輸出。
each的操作可以是functions和filters的子類。比如你可以從日志檔案中解析出特定field;過濾掉除了httpget以外的請求,把timestring替換成datefield。
every的操作可以是aggregators和buffer的子類。比如你可以用every去統計每天get請求數,它會為每天輸出一個統計值。
大多數operation子類都聲明了resultfield(就是上圖中的declaredfields),outputselector指定輸出tuple中的field,而輸出tuple中的field來源于input的field和operation的結果這兩個方面。如果outputselector=fields.all那麼輸出的tuple就是input+result的資料merge後的結果。
對于each來說argumentselector預設為fields.all,outputselector預設為fields.result
對于every來說aggregator的result預設被追加到inputtuple上。比如,你在department域上做grouping,然後統計這個較高價的電梯大廈的names,那麼結果fields會是["department","num_employees"]
當every與bufferoperation一起使用時,行為和aggregator很不一樣,operationresult這次是和目前valuestuple關聯在一起,而不是目前groupingtuple。這就像each與function一起使用時一樣。這也許看起來不是很直覺,但這提供了很大的靈活性。換一個說法,bufferoperation的result沒有被追加到thecurrent
keys being grouped on,是由buffer來決定是emit它們ifthey
are relevant,而且對于buffer來說,針對每個唯一的grouping有可能emit多個resulttuple。也就是說,一個buffer可能或者可能不和aggregator行為一緻,但是aggregator隻是一個特殊的buffer。