我们常常意识不到问题的存在,直到有人解决了这些问题
Hadoop MapReduce雖然已經可以滿足大數據的應用場景,但是其執行速度和編程復雜度并不讓人們滿意。于是UC Berkeley的AMP Lab推出的Spark應運而生,Spark擁有更快的執行速度和更友好的編程接口,在推出后短短兩年就迅速搶占MapReduce的市場份額,成為主流的大數據計算框架。
讀到這里請你先停一下,請給這段看似“沒毛病”的引子找找問題。
不知道你意識到沒有,我在這段開頭說的,“Hadoop MapReduce雖然已經可以滿足大數據的應用場景,但是其執行速度和編程復雜度并不讓人們滿意”,這句話其實是錯誤的。這樣說好像可以讓你更加清晰地看到事物發展的因果關系,同時也可以暗示別人自己有洞察事物發展規律的能力。然而,這種靠事后分析的因果規律常常是錯誤的,往往把結果當作了原因。
事實上,在Spark出現之前,我們并沒有對MapReduce的執行速度不滿,我們覺得大數據嘛、分布式計算嘛,這樣的速度也還可以啦。至于編程復雜度也是一樣,一方面Hive、Mahout這些工具將常用的MapReduce編程封裝起來了;另一方面,MapReduce已經將分布式編程極大地簡化了,當時人們并沒有太多不滿。
真實的情況是,人們在Spark出現之后,才開始對MapReduce不滿。原來大數據計算速度可以快這么多,編程也可以更簡單。而且Spark支持Yarn和HDFS,公司遷移到Spark上的成本很小,于是很快,越來越多的公司用Spark代替MapReduce。也就是說,因為有了Spark,才對MapReduce不滿;而不是對MapReduce不滿,所以誕生了Spark。真實的因果關系是相反的。
這里有一條關于問題的定律分享給你:我們常常意識不到問題的存在,直到有人解決了這些問題。
當你去詢問人們有什么問題需要解決,有什么需求需要被滿足的時候,他們往往自己也不知道自己想要什么,常常言不由衷。但是如果你真正解決了他們的問題,他們就會恍然大悟:啊,這才是我真正想要的,以前那些統統都是“垃圾”,我早就想要這樣的東西(功能)了。
所以頂尖的產品大師(問題解決專家),并不會拿著個小本本四處去做需求調研,問人們想要什么。而是在旁邊默默觀察人們是如何使用產品(解決問題)的,然后思考更好的產品體驗(解決問題的辦法)是什么。最后當他拿出新的產品設計(解決方案)的時候,人們就會視他為知己:你最懂我的需求(我最懂你的設計)。
喬布斯是這樣的大師,Spark的作者馬鐵也是這樣的專家。
說了那么多,我們回到Spark。Spark和MapReduce相比,有更快的執行速度。下圖是Spark和MapReduce進行邏輯回歸機器學習的性能比較,Spark比MapReduce快100多倍。
除了速度更快,Spark和MapReduce相比,還有更簡單易用的編程模型。使用Scala語言在Spark上編寫WordCount程序,主要代碼只需要三行。
val textFile = sc.textFile(\u0026quot;hdfs://...\u0026quot;)val counts = textFile.flatMap(line =\u0026gt; line.split(\u0026quot; \u0026quot;)) .map(word =\u0026gt; (word, 1)) .reduceByKey(_ + _)counts.saveAsTextFile(\u0026quot;hdfs://...\u0026quot;)不熟悉Scala語言沒關系,我來解釋一下上面的代碼。
第1行代碼:根據HDFS路徑生成一個輸入數據RDD。
第2行代碼:在輸入數據RDD上執行3個操作,得到一個新的RDD。
- 將輸入數據的每一行文本用空格拆分成單詞。
- 將每個單詞進行轉換,word =\u0026gt; (word, 1),生成\u0026lt;Key, Value\u0026gt;的結構。
- 相同的Key進行統計,統計方式是對Value求和,(_ + _)。
第3行代碼:將這個RDD保存到HDFS。
RDD是Spark的核心概念,是彈性數據集(Resilient Distributed Datasets)的縮寫。RDD既是Spark面向開發者的編程模型,又是Spark自身架構的核心元素。
我們先來看看作為Spark編程模型的RDD。我們知道,大數據計算就是在大規模的數據集上進行一系列的數據計算處理。MapReduce針對輸入數據,將計算過程分為兩個階段,一個Map階段,一個Reduce階段,可以理解成是面向過程的大數據計算。我們在用MapReduce編程的時候,思考的是,如何將計算邏輯用Map和Reduce兩個階段實現,map和reduce函數的輸入和輸出是什么,這也是我們在學習MapReduce編程的時候一再強調的。
而Spark則直接針對數據進行編程,將大規模數據集合抽象成一個RDD對象,然后在這個RDD上進行各種計算處理,得到一個新的RDD,繼續計算處理,直到得到最后的結果數據。所以Spark可以理解成是面向對象的大數據計算。我們在進行Spark編程的時候,思考的是一個RDD對象需要經過什么樣的操作,轉換成另一個RDD對象,思考的重心和落腳點都在RDD上。
所以在上面WordCount的代碼示例里,第2行代碼實際上進行了3次RDD轉換,每次轉換都得到一個新的RDD,因為新的RDD可以繼續調用RDD的轉換函數,所以連續寫成一行代碼。事實上,可以分成3行。
val rdd1 = textFile.flatMap(line =\u0026gt; line.split(\u0026quot; \u0026quot;))val rdd2 = rdd1.map(word =\u0026gt; (word, 1))val rdd3 = rdd2.reduceByKey(_ + _)RDD上定義的函數分兩種,一種是轉換(transformation)函數,這種函數的返回值還是RDD;另一種是執行(action)函數,這種函數不再返回RDD。
RDD定義了很多轉換操作函數,比如有計算map(func)、過濾filter(func)、合并數據集union(otherDataset)、根據Key聚合reduceByKey(func, [numPartitions])、連接數據集join(otherDataset, [numPartitions])、分組groupByKey([numPartitions])等十幾個函數。
我們再來看看作為Spark架構核心元素的RDD。跟MapReduce一樣,Spark也是對大數據進行分片計算,Spark分布式計算的數據分片、任務調度都是以RDD為單位展開的,每個RDD分片都會分配到一個執行進程去處理。
RDD上的轉換操作又分成兩種,一種轉換操作產生的RDD不會出現新的分片,比如map、filter等,也就是說一個RDD數據分片,經過map或者filter轉換操作后,結果還在當前分片。就像你用map函數對每個數據加1,得到的還是這樣一組數據,只是值不同。實際上,Spark并不是按照代碼寫的操作順序去生成RDD,比如“rdd2 = rdd1.map(func)”這樣的代碼并不會在物理上生成一個新的RDD。物理上,Spark只有在產生新的RDD分片時候,才會真的生成一個RDD,Spark的這種特性也被稱作惰性計算。
另一種轉換操作產生的RDD則會產生新的分片,比如reduceByKey,來自不同分片的相同Key必須聚合在一起進行操作,這樣就會產生新的RDD分片。實際執行過程中,是否會產生新的RDD分片,并不是根據轉換函數名就能判斷出來的,具體我們下一期再討論。
總之,你需要記住,Spark應用程序代碼中的RDD和Spark執行過程中生成的物理RDD不是一一對應的,RDD在Spark里面是一個非常靈活的概念,同時又非常重要,需要認真理解。
當然Spark也有自己的生態體系,以Spark為基礎,有支持SQL語句的Spark SQL,有支持流計算的Spark Streaming,有支持機器學習的MLlib,還有支持圖計算的GraphX。利用這些產品,Spark技術棧支撐起大數據分析、大數據機器學習等各種大數據應用場景。
我前面提到,頂尖的產品設計大師和問題解決專家,不會去詢問人們想要什么,而是分析和觀察人們的做事方式,從而思考到更好的產品設計和問題解決方案。
但是這種技巧需要深邃的觀察力和洞察力,如果沒有深度的思考,做出的東西就會淪為異想天開和自以為是。要知道大眾提出的需求雖然也無法觸及問題的核心,但是好歹是有共識的,大家都能接受,按這種需求做出的東西雖然平庸,但是不至于令人厭惡。
而缺乏洞見的自以為是則會違反常識,讓其他人本能產生排斥感,進而產生對立情緒。這種情緒之下,設計沒有了進一步改進的基礎,最后往往成為悲劇。這兩年在所謂互聯網思維的鼓吹下,一些缺乏專業技能的人,天馬行空創造需求,受到質疑后公開批評用戶,也是讓人倍感驚詫。
我們在自己的工作中,作為一個不是頂尖大師的產品經理或工程師,如何做到既不自以為是,又能逐漸擺脫平庸,進而慢慢向大師的方向靠近呢?
有個技巧可以在工作中慢慢練習:不要直接提出你的問題和方案,不要直接說“你的需求是什么?”“我這里有個方案你看一下”。
直向曲中求,對于復雜的問題,越是直截了當越是得不到答案。迂回曲折地提出問題,一起思考問題背后的規律,才能逐漸發現問題的本質。通過這種方式,既能達成共識,不會有違常識,又可能產生洞見,使產品和方案呈現閃光點。
- 你覺得前一個版本最有意思(最有價值)的功能是什么?
- 你覺得我們這個版本應該優先關注哪個方面?
- 你覺得為什么有些用戶在下單以后沒有支付?
作者介紹
李智慧,極客時間《從0開始學大數據》專欄講師,同程藝龍交通首席架構師、Apache Spark源代碼貢獻者,長期從事大數據、大型網站架構的研發工作,曾擔任阿里巴巴技術專家、Intel亞太研發中心架構師、宅米和WiFi萬能鑰匙CTO,有超過6年的線下咨詢、培訓經驗,著有暢銷書《大型網站技術架構:核心原理與案例分析》。
總結
以上是生活随笔為你收集整理的我们常常意识不到问题的存在,直到有人解决了这些问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别人家的程序员是如何使用 Java 进行
- 下一篇: idea编辑springboot,如何打