本人如今在一家非科技公司工做,到如今入職已經5個多月了。mysql
我以前有過大數據工做的經驗,算接觸了一點皮毛,到這家公司也是抱着繼續往大數據方向發展的心態而來的。程序員
面試個人是一位海歸博士,剛開始以爲他應該是一位大數據專家,但在面試的過程當中就發現不太對頭,不過以爲公司應該有CTO的人物存在,因而稀裏糊塗就進了這家公司。面試
事實證實並無。sql
到如今作的事情基本和hadoop、spark這些都沒什麼關係了,我親手搭建的cloudera平臺也被領導要求撤了,由於沒有用武之地,領導以爲還不如裝oracle,裝mysql。緩存
可是我不會輕易改變個人職業規劃,因而暗地裏本身還在惡補大數據工程開發的相關知識,這些東西不能丟,補習一段時間,準備找個時間就跑路吧。oracle
在這裏也奉勸各位和我同樣入世不深的程序員們,選公司儘可能避開這些傳統行業的公司,這些公司領導每每不懂技術,更有甚者還不尊重技術,這時候有個技術總監類型的人物還好,不然日子很很差過。年輕的程序員小夥伴們,大家仍是多找找互聯網公司吧,別把青春耽誤了。app
本人也是初學者,處於大數據學習的起步階段,平時愛好把學到的東西寫下來,進行總結,我計劃作一個Spark學習的系列博客,志同道合的朋友,咱們能夠互相交流。博客中描述不許確或者有誤的地方也請各位不吝賜教,謝謝。分佈式
我以前粗略的看過幾本spark的相關書籍,大部分一上來就跟你講工做的原理,各個組件的機制,對於初學者來講,可能看兩頁就看不下去了,從而放棄了對spark的學習。工具
我本人也是這麼認爲的,因此今天咱們先從RDD這一spark的核心對象提及,讓你們能快速的上手操做,在之後的博客中,咱們再回過頭來分析原理。明白原理咱們才能踏踏實實的寫代碼。oop
本人寫系列博客的出發點是爲了記錄本身的學習過程,然本身學的更深刻,因此不能做爲你們學習spark的參考,若是你是一名初學者,建議購買一些spark的書籍進行學習,如《Spark快速大數據分析》,不過在此以前,你能夠看一下《快學Scala》先打一下Scala的基礎,畢竟spark是用scala語言編寫的,用母語寫程序,味道才正宗。
RDD,即彈性分佈式數據集(Resilient Distributed Dataset),說白了就是分佈式的元素集合。咱們能夠把它想象成一個分佈在集羣中的一個隊列,對RDD進行簡單的操做,咱們就能夠輕鬆的實現對整個集羣的上數據進行並行的操做。
RDD有這樣幾個特性:不可變的、分區的、能夠包含任意類型的對象。
咱們有兩種方法建立RDD:一、讀取外部的數據文件。二、將程序中的集合類型的數據(list、set)轉化而成。
分別舉兩個例子來講明:
//第一種方式
val lines = sc.textFile("test.txt")
//第二種方式
val lines = sc.parallelize(["a", "b", "c"])
RDD的操做分爲兩種:一、轉化操做(transformation)。二、行動操做(action)
轉化操做會生成新的RDD,可是spark只會惰性的進行計算,直到第一次執行一個行動操做,以前的轉化操做纔會開始執行。
這有點相似於咱們裝系統的時候,利用磁盤工具對硬盤進行分區、更改卷標號、格式化硬盤等操做,你在點擊確認操做以前,全部的分區操做都不會真正的執行,直到你點擊了確認按鈕,軟件才真正開始執行你剛剛指定的操做。
因此你們若是用debug調試spark程序,會發現很奇怪的現象,明明程序運行到第10行了,可是再單步往下調試的時候,又跳到第6行去了,由於轉化操做纔剛剛開始執行。
若是你們以前有在hadoop上寫過mapreduce(如下簡稱MR),就會以爲這種方式是很是高效的。MR程序會全量的讀入你指定的文件,哪怕你在mapper中寫了一條if,丟棄了其中80%的數據,可是spark不一樣,在運行載入文件命令時,它不會真的把全部數據讀進內存,而是看你以後對數據進行了哪些操做,換句話說,它想看看你究竟要作些什麼操做,我好省省體力,不要作無用功。
說到這裏又想起個段子:女朋友學會了一個新菜,要你打下手,她拿着菜譜說,首先把杯子洗乾淨,並擦乾裏面的水,因而你擦了半天,終於把被子擦的一滴水都沒有了,而後她接着說,第二步,在杯中倒入100ml的水。
默認狀況下,spark的RDD會在你每次對它們進行行動操做的時候從新計算,這時,若是你要反覆操做同一個RDD,你應該把這個RDD緩存起來,避免重複的運算,使用persist方法將RDD進行緩存。
//從外部讀取文件,生成RDD val lines = sc.textFile("test.txt") //將RDD緩存起來,方法若是沒有參數能夠省略括號 lines.persist //調用轉化操做,讀取包含'error'的行 val errorLines = lines.filter(x => x.contains("error")) //調用第一個行動操做,使得以前的轉化操做開始執行 errorLines.first()
緩存後的數據默認是以序列化的形式緩存在內存中,咱們也能經過傳入參數來改變緩存的位置,如存放到磁盤中。咱們甚至能在末尾加上_2指定緩存的份數
總而言之,轉化操做返回新的RDD,而且具備「血統」,能保存從父RDD轉化的過程,在數據丟失時,根據血統信息進行重算便可;而行動操做則返回操做的結果(數值、字符串等格式)或者是將數據存入磁盤中。
時候不早了,今天的分享就到這裏。