這篇文章主要介紹“Clojure的Map-Reduce怎么理解”,在日常操作中,相信很多人在Clojure的Map-Reduce怎么理解問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Clojure的Map-Reduce怎么理解”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
10年積累的成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有高安免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
一種看起來(lái)和用起來(lái)跟 clojure.core 都很像的 map-reduce 語(yǔ)言
可以把 map-reduce 的查詢當(dāng)成程序來(lái)寫(xiě),而不是當(dāng)成腳本來(lái)寫(xiě)
為單元測(cè)試和迭代部署提供強(qiáng)大的支持
注意:如果你對(duì) Clojure 不是很熟悉,我們強(qiáng)烈推薦你試下這里,這里 或者 這里 的教程來(lái)了解一些 基礎(chǔ)。
如果你會(huì) Clojure,你就已經(jīng)會(huì) PigPen 了
PigPen 的主要目標(biāo)是要把語(yǔ)言帶出等式的行列。PigPen 的操作符設(shè)計(jì)的和 Clojure 里盡可能的相似,沒(méi)有特殊的用戶自定義函數(shù)(UDFs)。只需要定義函數(shù)(匿名的或者命名的),然后你就能像在 Clojure 程序里一樣使用它們。
這里有個(gè)常用的 word count 的例子:
(require '[pigpen.core :as pig]) (defn word-count [lines] (->> lines (pig/mapcat #(-> % first (clojure.string/lower-case) (clojure.string/replace #"[^\w\s]" "") (clojure.string/split #"\s+"))) (pig/group-by identity) (pig/map (fn [[word occurrences]] [word (count occurrences)]))))
這段代碼定義了一個(gè)函數(shù),這個(gè)函數(shù)返回一個(gè) PigPen 的查詢表達(dá)式。這個(gè)查詢接受一系列的行作為輸入,返回每個(gè)單詞出現(xiàn)的次數(shù)。你可以看到這只是一個(gè) word count 的邏輯,并沒(méi)有設(shè)計(jì)到一些外部的東西,比如數(shù)據(jù)從哪里來(lái)的,會(huì)產(chǎn)生哪些輸出。
當(dāng)然。PigPen 的查詢是寫(xiě)成函數(shù)的組合——數(shù)據(jù)輸入、輸出。只需要寫(xiě)一次,不需要到處復(fù)制、粘貼。
現(xiàn)在我們利用以上定義的 word-count 函數(shù),加上 load 和 store 命令,組成一個(gè) PigPen 的查詢:
(defn word-count-query [input output] (->> (pig/load-tsv input) (word-count) (pig/store-tsv output)))
這個(gè)函數(shù)返回查詢的 PigPen 表示,他自己不會(huì)做什么,我們需要從本地執(zhí)行它,或者生成一個(gè)腳本(之后會(huì)講)。
利用 PigPen,你可以 mock 輸入數(shù)據(jù)來(lái)為你的查詢寫(xiě)單元測(cè)試。再也不需要交叉著手指想象提交到 cluster 上后會(huì)發(fā)生什么,也不需要截出部分文件來(lái)測(cè)試輸入輸出。
Mock 數(shù)據(jù)真的很容易,通過(guò) pig/return 和 pig/constantly,你可以在你的腳本里注入任意的數(shù)據(jù)作為起始點(diǎn)。
一個(gè)常用的模式是利用 pig/take 來(lái)從實(shí)際數(shù)據(jù)源中抽樣出幾行,用 pig/return 把結(jié)果包一層,就得到了 mock 數(shù)據(jù)。
(use 'clojure.test) (deftest test-word-count (let [data (pig/return [["The fox jumped over the dog."] ["The cow jumped over the moon."]])] (is (= (pig/dump (word-count data)) [["moon" 1] ["jumped" 2] ["dog" 1] ["over" 2] ["cow" 1] ["fox" 1] ["the" 4]]))))
pig/dump 操作符會(huì)在本地執(zhí)行查詢。
向你的查詢傳參數(shù)很麻煩,所有函數(shù)范圍內(nèi)的變量或者 let 的綁定在函數(shù)里都可用。
(defn reusable-fn [lower-bound data] (let [upper-bound (+ lower-bound 10)] (pig/filter (fn [x] (< lower-bound x upper-bound)) data)))
注意 lower-bound 和 upper-bound 在生成腳本的時(shí)候就有了,在 cluster 上執(zhí)行函數(shù)的時(shí)候也能使用。
只要告訴 PigPen 哪里會(huì)把一個(gè)查詢寫(xiě)成一個(gè) Pig 腳本:
(pig/write-script "word-count.pig" (word-count-query "input.tsv" "output.tsv"))
這樣你就能得到一個(gè)可以提交到 cluster 上運(yùn)行的 Pig 腳本。這個(gè)腳本會(huì)用到 pigpen.jar,這是一個(gè)加入所有依賴的 uberjar,所以要保證這個(gè) jar 也一起被提交了。還可以把你的整個(gè) project 打包成一個(gè) uberjar 然后提交,提交之前記得先重命名。怎么打包成 uberjar 請(qǐng)參照教程。
之前看到,我們可以用 pig/dump 來(lái)本地運(yùn)行查詢,返回 Clojure 數(shù)據(jù):
=> (def data (pig/return [["The fox jumped over the dog."] ["The cow jumped over the moon."]])) #'pigpen-demo/data => (pig/dump (word-count data)) [["moon" 1] ["jumped" 2] ["dog" 1] ["over" 2] ["cow" 1] ["fox" 1] ["the" 4]]
如果你現(xiàn)在就像開(kāi)始,請(qǐng)參照 getting started & tutorials。
Map-Reduce 對(duì)于處理單臺(tái)機(jī)器搞不定的數(shù)據(jù)是很有用,有了 PigPen,你可以像在本地處理數(shù)據(jù)一樣處理海量數(shù)據(jù)。Map-Reduce 通過(guò)把數(shù)據(jù)分散到可能成千上萬(wàn)的集群節(jié)點(diǎn)來(lái)達(dá)到這一目的,這些節(jié)點(diǎn)每個(gè)都會(huì)處理少量的數(shù)據(jù),所有的處理都是并行的,這樣完成一個(gè)任務(wù)就比單臺(tái)機(jī)器快得多。像 join 和 group 這樣的操作,需要多個(gè)節(jié)點(diǎn)數(shù)據(jù)集的協(xié)調(diào),這種情況會(huì)通過(guò)公共的 join key 把數(shù)據(jù)分到同一個(gè)分區(qū)計(jì)算,join key 的同一個(gè)值會(huì)送到同一個(gè)指定的機(jī)器。一旦機(jī)器上得到了所有可能的值,就能做 join 的操作或者做其他有意思的事。
想看看 PigPen 怎么做 join 的話,就來(lái)看看 pig/cogroup 吧。cogroup 接受任意數(shù)量的數(shù)據(jù)集然后根據(jù)一個(gè)共同的 key 來(lái)分組。假設(shè)我們有這樣的數(shù)據(jù):
foo: {:id 1, :a "abc"} {:id 1, :a "def"} {:id 2, :a "abc"} bar: [1 42] [2 37] [2 3.14] baz: {:my_id "1", :c [1 2 3]]}
如果想要根據(jù) id 分組,可以這樣:
(pig/cogroup (foo by :id) (bar by first) (baz by #(-> % :my_id Long/valueOf)) (fn [id foos bars bazs] ...))
前三個(gè)參數(shù)是要 join 的數(shù)據(jù)集,每一個(gè)都會(huì)指定一個(gè)函數(shù)來(lái)從數(shù)據(jù)源中選出 key。最后的一個(gè)參數(shù)是一個(gè)函數(shù),用來(lái)把分組結(jié)果結(jié)合起來(lái)。在我們的例子中,這個(gè)函數(shù)會(huì)被調(diào)用兩次:
[1 ({:id 1, :a "abc"}, {:id 1, :a "def"}) ([1 42]) ({:my_id "1", :c [1 2 3]]})] [2 ({:id 2, :a "abc"}) ([2 37] [2 3.14]) ()]
這把所有 id 為 1 的值和 id 為 2 的值結(jié)合在了一起。不同的鍵值被獨(dú)立的分配到不同的機(jī)器。默認(rèn)情況下,key 可以不在數(shù)據(jù)源中出現(xiàn),但是有選項(xiàng)可以指定必須出現(xiàn)。
Hadoop 提供了底層的接口做 map-reduce job,但即便如此還是有限制的,即一次只會(huì)運(yùn)行一輪 map-reduce,沒(méi)有數(shù)據(jù)流和復(fù)雜查詢的概念。Pig 在 Hadoop 上抽象出一層,但到目前為止,它仍舊只是一門腳本語(yǔ)言,你還是需要用 UDF 來(lái)對(duì)數(shù)據(jù)做一些有意思的事情。PigPen 更進(jìn)一步的做了抽象,把 map-reduce 做成了一門語(yǔ)言。
如果你剛接觸 map-reduce,我們推薦你看下這里。
**代碼重用。**我們希望能定義一段邏輯,然后通過(guò)穿參數(shù)把它用到不同的 job 里。
**代碼一體化。**我們不想在腳本和不同語(yǔ)言寫(xiě)的 UDF。 之間換來(lái)?yè)Q去,不想考慮不同數(shù)據(jù)類型在不同語(yǔ)言中的對(duì)應(yīng)關(guān)系。
**組織好代碼。**我們想把代碼寫(xiě)在多個(gè)文件里,想怎么組織怎么組織,不要被約束在文件所屬的 job 里。
**單元測(cè)試。**我們想讓我們的抽樣數(shù)據(jù)關(guān)聯(lián)上我們的單元測(cè)試,我們想讓我們的單元測(cè)試在不存取數(shù)據(jù)的情況下測(cè)試業(yè)務(wù)邏輯。
**快速迭代。**我們想能夠在任何時(shí)候注入 mock data,我們想在不用等 JVM 啟動(dòng)的情況下測(cè)試一個(gè)查詢。
**只給想要命名的東西命名。**大部分 map-reduce 語(yǔ)言對(duì)中間結(jié)果要求命名和指定數(shù)據(jù)結(jié)構(gòu),這使得用 mock data 來(lái)測(cè)試單獨(dú)的 job 變得困難。我們想要在我們覺(jué)得合適的地方組織業(yè)務(wù)邏輯并命名,而不是受語(yǔ)言的指使。
我們受夠了寫(xiě)腳本,我們想要寫(xiě)程序。
注意:PigPen 不是一個(gè) Clojure 對(duì) Pig 腳本的封裝,很有可能產(chǎn)生的腳本是人看不懂的。
PigPen 設(shè)計(jì)的和 Clojure 盡可能保持一致。Map-Reduce 是函數(shù)式編程,那為什么不利用一門已存在的強(qiáng)大的函數(shù)式編程語(yǔ)言呢?這樣不光學(xué)習(xí)曲線低,而且大多數(shù)概念也能更容易的應(yīng)用到大數(shù)據(jù)上。
在 PigPen 中,查詢被當(dāng)做 expression tree 處理,每個(gè)操作符都被表示需要的行為信息的 map,這些 map 可以嵌套在一起組成一個(gè)復(fù)雜查詢的樹(shù)形表式。每個(gè)命令包含了指向祖命令的引用。在執(zhí)行的時(shí)候,查詢樹(shù)會(huì)被轉(zhuǎn)化成一個(gè)有向無(wú)環(huán)的查詢圖。這可以很容易的合并重復(fù)的命令,優(yōu)化相關(guān)命令的順序,并且可以利用 debug 信息調(diào)試查詢。
去重當(dāng)我們把查詢表示成操作圖的時(shí)候,去重是一件很麻煩的事。Clojure 提供了值相等的操作,即如果連個(gè)對(duì)象的內(nèi)容相同,它們就相等。如果兩個(gè)操作有相同的表示,那它們完全相同,所以在寫(xiě)查詢的時(shí)候不用擔(dān)心重復(fù)的命令,它們?cè)趫?zhí)行之前都會(huì)被優(yōu)化。
舉個(gè)例子,假設(shè)我們有這樣兩個(gè)查詢:
(let [even-squares (->> (pig/load-clj "input.clj") (pig/map (fn [x] (* x x))) (pig/filter even?) (pig/store-clj "even-squares.clj")) odd-squares (->> (pig/load-clj "input.clj") (pig/map (fn [x] (* x x))) (pig/filter odd?) (pig/store-clj "odd-squares.clj"))] (pig/script even-squares odd-squares))
在這個(gè)查詢中,我們從一個(gè)文件加載數(shù)據(jù),計(jì)算每個(gè)數(shù)的平方,然后分成偶數(shù)和奇數(shù),操作圖看起來(lái)是這樣: 在此輸入圖片描述
這符合我們的查詢,但是做了很多額外的工作。我們加載了 input.clj
兩次,所有數(shù)的平方也都計(jì)算了兩次。這看上去可能沒(méi)有很多工作,但是當(dāng)你對(duì)很多數(shù)據(jù)做這樣的事情,簡(jiǎn)單的操作累加起來(lái)就很多。為了優(yōu)化這個(gè)查詢,我們可以找出相同的操作??吹谝谎郯l(fā)現(xiàn)我們計(jì)算平方的操作可能是一個(gè)候選,但是他們有不同的父節(jié)點(diǎn),因此不能把他們合并在一起。但是我們可以把加載函數(shù)合并,因?yàn)樗麄儧](méi)有父節(jié)點(diǎn),而且他們加載相同的文件。
現(xiàn)在我們的圖看起來(lái)是這樣:
現(xiàn)在我們值加載一次數(shù)據(jù),這會(huì)省一些時(shí)間,但還是要計(jì)算兩次平方。因?yàn)槲覀儸F(xiàn)在只有一個(gè)加載的命令,我們的 map 操作現(xiàn)在相同,可以合并:
這樣我們就得到了一個(gè)優(yōu)化過(guò)的查詢,每個(gè)操作都是唯一的。因?yàn)槲覀兠看沃粫?huì)合并一個(gè)命令,我們不會(huì)修改查詢的邏輯。你可以很容易的生成查詢,而不用擔(dān)心重復(fù)的執(zhí)行,PigPen 對(duì)重復(fù)的部分只會(huì)執(zhí)行一次。
序列化當(dāng)我們用 Clojure 處理完數(shù)據(jù)以后,數(shù)據(jù)必須序列化成二進(jìn)制字節(jié),Pig 才能在集群的機(jī)器間傳數(shù)據(jù)。這對(duì) PigPen 是一個(gè)很昂貴但是必須的過(guò)程。幸運(yùn)的是一個(gè)腳本中經(jīng)常有很多連續(xù)的操作可以合成一個(gè)操作,這對(duì)于不必要的序列化和反序列化節(jié)省了很多時(shí)間。例如,任意連續(xù)的 map,filter 和 mapcat 操作都可以被重寫(xiě)成一個(gè)單獨(dú)的 mapcat 操作。
我們通過(guò)一些例子來(lái)說(shuō)明:
在這個(gè)例子中,我們從一個(gè)序列化的值(藍(lán)色)4開(kāi)始,對(duì)它反序列化(橙色),執(zhí)行我們的 map 函數(shù),然后再把它序列化。
現(xiàn)在我們來(lái)試一個(gè)稍微復(fù)雜一點(diǎn)的(更現(xiàn)實(shí)的)例子。在這個(gè)例子中,我們執(zhí)行一個(gè) map,一個(gè) mapcat 和一個(gè) filter 函數(shù)。
如果你以前沒(méi)用過(guò) mapcat,我可以告訴你這是對(duì)一個(gè)值運(yùn)行一個(gè)函數(shù)然后返回一串值的操作。那個(gè)序列會(huì)被 flatten,每個(gè)值都會(huì)傳給下一步使用。在 Clojure 里,那是 map 和 concat 聯(lián)合之后的結(jié)果,在 Scala 里,這叫做 flatMap,而在 C# 里叫 selectMany。
在下圖中,左邊的流程是我們優(yōu)化之前的查詢,右邊的是優(yōu)化之后的。和第一個(gè)例子一樣,我們同樣從 4 開(kāi)始,計(jì)算平方,然后對(duì)這個(gè)值做減一的操作,返回本身和加一的操作。Pig 會(huì)得到這個(gè)值的集合然后做 flatten,使每個(gè)值都成為下一步的輸入。注意在和 Pig 交互的時(shí)候我們要序列化和反序列化。第三步,也就是最后一步對(duì)數(shù)據(jù)進(jìn)行過(guò)濾,在這個(gè)例子中我們只保留奇數(shù)值。如圖所示,我們?cè)谌我鈨刹街g都序列化和反序列化數(shù)據(jù)。
右邊的圖顯示了優(yōu)化后的結(jié)果。每個(gè)操作都返回了一個(gè)元素序列。map 操作返回一個(gè)只有單元素 16 的序列,mapcat 也一樣,過(guò)濾操作返回 0 元素或單元素的序列。通過(guò)是這些命令保持一致,我們可以很容易的把他們合并到一起。我們?cè)谝惶酌钪衒lattrn 了更多的值序列,但是在步驟之間沒(méi)有序列化的消耗。雖然卡起來(lái)更復(fù)雜,但是這個(gè)優(yōu)化是每個(gè)步驟都執(zhí)行的更快了。
交互式開(kāi)發(fā),測(cè)試,以及可調(diào)試性是 PigPen 的關(guān)鍵功能。如果你有一個(gè)一次運(yùn)行好幾天的 job,那你最不想看到的是跑了十一個(gè)小時(shí)后冒出來(lái)一個(gè) bug。PigPen 有個(gè)基于 rx 的本地運(yùn)行模式。這可以讓我們對(duì)查詢寫(xiě)單元測(cè)試。這樣我們可以更有把握的知道運(yùn)行的時(shí)候不會(huì)掛掉,并且能返回期待的值。更牛逼的是這個(gè)功能可以讓我們進(jìn)行交互式的開(kāi)發(fā)。
通常情況下,我們剛開(kāi)始會(huì)從數(shù)據(jù)源中選一些記錄來(lái)做單元測(cè)試。因?yàn)?PigPen 在 REPL 中返回?cái)?shù)據(jù),我們不需要額外構(gòu)造測(cè)試數(shù)據(jù)。這樣,通過(guò) REPL,我們可以根據(jù)需要對(duì) mock 數(shù)據(jù)做 map,filter,join 和 reduce 的操作。每個(gè)步驟都可以驗(yàn)證結(jié)果是不是我們想要的。這種方法相對(duì)于寫(xiě)一長(zhǎng)串腳本然后憑空想象能產(chǎn)生更可靠的數(shù)據(jù)。還有一個(gè)有用的地方是可以把復(fù)雜的查詢寫(xiě)成幾個(gè)較小的函數(shù)單元。Map-reduce 查詢隨著數(shù)據(jù)源的量級(jí)可能產(chǎn)生劇烈的增加或減少。當(dāng)你把腳本作為一個(gè)整體測(cè)試的時(shí)候,你可能要讀一大堆數(shù)據(jù),最后產(chǎn)生一小撮數(shù)據(jù)。通過(guò)把查詢細(xì)化成較小的單元,你可以對(duì)讀 100 行,產(chǎn)生 2 行這樣子來(lái)測(cè)試一個(gè)單元,然后測(cè)試第二個(gè)單元的時(shí)候可以用這兩行作為模板來(lái)產(chǎn)生 100 多個(gè)數(shù)據(jù)。
調(diào)試模式對(duì)于解決異常很有用,啟用后會(huì)在正常輸出的同時(shí),把腳本中每個(gè)操作的結(jié)果寫(xiě)到磁盤上。這對(duì)于像 Hadoop 這樣的環(huán)境很有用,在這種情況下,你沒(méi)法單步跟蹤代碼,而且每個(gè)步驟都可能花好幾個(gè)小時(shí)。調(diào)試模式還可以可視化流程圖。這樣可以可視化的把執(zhí)行計(jì)劃的和實(shí)際操作的輸出關(guān)聯(lián)起來(lái)。
要啟用調(diào)試模式,請(qǐng)參考 pig/write-script 和 pig/generate-script 的選項(xiàng),這會(huì)在指定的目錄下寫(xiě)額外的調(diào)試輸出。
啟用調(diào)試模式的例子:
(pig/write-script {:debug "/debug-output/"} "my-script.pig" my-pigpen-query)
要啟用可視化模式,可以看看 pig/show 和 pig/dump&show。
可視化的例子:
(pig/show my-pigpen-query) ;; Shows a graph of the query (pig/dump&show my-pigpen-query) ;; Shows a graph and runs it locally
PigPen 有個(gè)好用的功能是可以很容易的創(chuàng)建自己的操作符。例如,我們可以定義像求差集和交集這樣的集合和多集合的操作符,這些只是像 co-group
這樣的操作符的變體,但是如果能定義,測(cè)試它們,然后再也不去想這些邏輯怎么實(shí)現(xiàn)的,那就更好了。
這對(duì)更復(fù)雜的操作也是很有用的。對(duì)于集合數(shù)據(jù)我們有 sum
,avg
,min
,max
,sd
和 quantiles
這些可重用的統(tǒng)計(jì)操作符,還有 pivot
這樣的操作符可以把多維數(shù)據(jù)分組然后對(duì)每組計(jì)數(shù)。
這些操作本身都是簡(jiǎn)單的操作,但是當(dāng)你把它們從你的查詢中抽象出來(lái)之后,你的查詢也會(huì)變的簡(jiǎn)單很多。這時(shí)候你可以花更多的時(shí)間去想怎么解決問(wèn)題,而不是每次都重復(fù)寫(xiě)基本的統(tǒng)計(jì)方法。
我們選擇 Pig 是因?yàn)槲覀儾幌氚?Pig 已有的優(yōu)化的邏輯重寫(xiě)一遍,不考慮語(yǔ)言層面的東西的話,Pig 在移動(dòng)大數(shù)據(jù)方面做得很好。我們的策略是利用 Pig 的 DataByteArray 二進(jìn)制格式來(lái)移動(dòng)序列化的 Clojure 數(shù)據(jù)。在大多數(shù)情況下,Pig 不需要知道數(shù)據(jù)的底層展現(xiàn)形式。Byte array 可以很快的做比較,這樣對(duì)于 join 和 group 操作,Pig 只需要簡(jiǎn)單的比較序列化的二進(jìn)制,如果序列化的輸出一致,在 Clojure 中值就相等。不過(guò)這對(duì)于數(shù)據(jù)排序不適用。二進(jìn)制的排序其實(shí)沒(méi)什么用,而且和原始數(shù)據(jù)的排序結(jié)果也不一樣。要想排序,還得把數(shù)據(jù)轉(zhuǎn)化回去,而且只能對(duì)簡(jiǎn)單類型排序。這也是 Pig 強(qiáng)加給 PigPen 的為數(shù)不多的一個(gè)缺陷。
我們?cè)跊Q定做 PigPen 之前也評(píng)估過(guò)其他語(yǔ)言。第一個(gè)要求就是那必須是一門編程語(yǔ)言,并不是一種腳本語(yǔ)言加上一堆 UDF。我們簡(jiǎn)單看過(guò) Scalding,它看上去很有前途,但是我們的團(tuán)隊(duì)主要是用的 Clojure。 可以這么說(shuō),PigPen 對(duì)于 Clojure 就像是 Scalding 對(duì)于 Scala。Cascalog 是用 Clojure 寫(xiě) map-reduce 通常會(huì)用的語(yǔ)言,但是從過(guò)去的經(jīng)驗(yàn)來(lái)看,Cascalog 對(duì)于日常工作其實(shí)沒(méi)什么用,你需要學(xué)一套復(fù)雜的新語(yǔ)法和很多概念,通過(guò)變量名對(duì)齊來(lái)做隱式 join 也不是理想的方案,如果把操作符順序弄錯(cuò)了會(huì)造成很大的性能問(wèn)題,Cascalog 會(huì) flatten 數(shù)據(jù)結(jié)果(這可能很浪費(fèi)),而且組合查詢讓人感覺(jué)很別扭。
我們也考慮過(guò)對(duì) PigPen 用一門宿主語(yǔ)言。這樣也能在 Hive 之上構(gòu)建類似的抽象,但是對(duì)每個(gè)中間產(chǎn)物都定義 schema 跟 Clojure 的理念不符。而且 Hive 類似與 SQL,使得從功能性語(yǔ)言翻譯更難。像 SQL 和 Hive 這樣的關(guān)系模型語(yǔ)言與像 Clojure 和 Pig 這樣的功能性語(yǔ)言之間有著巨大的差。最后,最直接的解決辦法就是在 Pig 之上做一層抽象。
到此,關(guān)于“Clojure的Map-Reduce怎么理解”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
名稱欄目:Clojure的Map-Reduce怎么理解
文章出自:http://www.rwnh.cn/article36/ipcgpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站策劃、面包屑導(dǎo)航、ChatGPT、手機(jī)網(wǎng)站建設(shè)、軟件開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)