作者 | 梁唐
出品 | 公眾號:Coder梁(ID:Coder_LT)
大家好,我是梁唐。
最近我發(fā)現,很多萌新說(shuō)著(zhù)想要做算法工程師,但是卻對這個(gè)崗位的要求以及工作內容一無(wú)所知。以為學(xué)一個(gè)Python,再學(xué)一些機器學(xué)習、深度學(xué)習的模型就可以勝任了。工作就是用Python不停地寫(xiě)模型。
顯然,這樣的想法是有問(wèn)題的,如果真這么干,即使通過(guò)了面試成功入職,也會(huì )干得非常痛苦。因為你會(huì )發(fā)現這也不知道那也不知道,做啥都很吃力,需要一段很長(cháng)的時(shí)間學(xué)習。而這種為了應付工作臨時(shí)抱佛腳的學(xué)習往往很難深入,有種不停打補丁的感覺(jué)。
今天就和大家聊聊算法工程師的幾項基本功,看看除了算法和模型之外,還需要學(xué)些什么。
首先當然是hadoop,不過(guò)hadoop不是一門(mén)技術(shù),而是一個(gè)大數據框架。它的logo是一只黃色的小象,據說(shuō)是這個(gè)項目的創(chuàng )建者用女兒的玩具命名的。
經(jīng)過(guò)了很多年的發(fā)展,現在hadoop框架已經(jīng)非常成熟,衍生出了一個(gè)龐大的家族。有多龐大呢,我在google里給大家找了一張圖,大家可以看看感受一下,這里面有多少是自己知道的,有多少沒(méi)聽(tīng)說(shuō)過(guò)。
當然對于算法工程師來(lái)說(shuō),hadoop家族并不需要全部了解,只需要著(zhù)重關(guān)注幾個(gè)就可以了。
首先是hdfs,hdfs是hadoop框架中的分布式文件系統。因為在工業(yè)場(chǎng)景當中,數據量是非常龐大的,動(dòng)輒TB甚至是PB量級。如此龐大的數據,顯然不可能存在一塊磁盤(pán)里,必須要分布式存儲,分成不同的部分,不同的部分分開(kāi)存儲。通過(guò)hdfs我們可以很方便地實(shí)現這一點(diǎn),可以使用一些簡(jiǎn)單的shell命令管理大規模的數據。
hdfs的內部是分片(block)存儲的,并且設計了嚴謹的容錯機制,盡可能地保證了數據的準確性。一般我們用hdfs存儲一些離線(xiàn)數據,也就是對延遲要求不高的數據,比如模型的訓練數據。它的特點(diǎn)是存儲能力很強,但是讀取速度很慢,中間的延遲很長(cháng)。
因為訓練數據的規模往往也非常龐大,并且從用戶(hù)線(xiàn)上的實(shí)時(shí)行為轉化成模型需要的輸入,中間需要大量的計算步驟。這會(huì )帶來(lái)巨大的計算壓力,因此對于這樣的數據,我們往往都是借助于hdfs做離線(xiàn)處理。設計一套數據處理流程,進(jìn)行若干步驟的處理,每一步處理的中間數據都存儲在hdfs上。
模型訓練的時(shí)候,也通過(guò)掛載hdfs的方式直接讀取tensor進(jìn)行訓練。
hdfs是hadoop的存儲系統,hadoop同樣也推出過(guò)一套計算系統,就是MapReduce。
我在之前的文章曾經(jīng)介紹過(guò)MapReduce的原理,其實(shí)非常簡(jiǎn)單,它將數據的計算過(guò)程抽象成了兩個(gè)步驟。一個(gè)步驟叫map,一個(gè)步驟叫reduce。
map步驟做的數據的映射,比如我們從一個(gè)很大的json文件當中讀取出我們想要的字段,在這個(gè)步驟當中,我們從json獲得了幾個(gè)字段。
reduce步驟做的是匯總,我們把剛剛map階段得到的結果,按照我們的想法匯聚在一起,比如計算平均數、中位數等等。
這個(gè)想法巧妙的地方在于map和reduce都是可以分布式進(jìn)行的,比如map階段,我們可以對hdfs里的每一個(gè)文件都設置一個(gè)map讀取文件進(jìn)行處理。map階段結束之后,我們也可以起多個(gè)reducer對map的結果進(jìn)行加工,盡可能導致了整個(gè)過(guò)程都是并發(fā)進(jìn)行的,也就保證了數據的處理速度。
雖然MapReduce的提出到現在已經(jīng)十多年了,但仍然沒(méi)有淘汰,還在很多場(chǎng)景當中廣泛使用。
hive也是hadoop家族核心的一員,它的思想也很巧妙,做了一件非常有利于程序員的事情。
使用hdfs以及MapReduce其實(shí)就足夠應付幾乎所有大數據計算的場(chǎng)景了,但是足夠應付并不代表應付起來(lái)很舒服。有些場(chǎng)景使用起來(lái)就不是很順手,比如說(shuō)我們要把兩份數據關(guān)聯(lián)在一起,一份是用戶(hù)點(diǎn)擊數據,一份是商品數據,我們想要得到用戶(hù)點(diǎn)過(guò)的商品信息。
你會(huì )發(fā)現使用MapReduce去做這樣一件事情會(huì )非常蛋疼,要寫(xiě)很多代碼。所以有人突發(fā)奇想,我們能不能利用hdfs以及MapReduce做一套好用一點(diǎn)的數據處理系統,比如說(shuō)將數據全部格式化,然后像是數據庫一樣使用SQL來(lái)進(jìn)行數據的查詢(xún)和處理?于是就有了hive。
hive底層的運算框架就是MapReduce,只不過(guò)有了表結構之后,很多之前很復雜的操作被大大簡(jiǎn)化了。尤其是數據表之間的join、group by等操作,之前需要寫(xiě)大量MapReduce的代碼,現在幾行SQL就搞定了。
不過(guò)hive畢竟不是數據庫,它的使用還是有一些它自己專(zhuān)屬的奇淫技巧。比如說(shuō)避免數據傾斜的情況,比如說(shuō)設置合理的內存分片,比如說(shuō)udf的使用等等。
只是懂SQL的語(yǔ)法是寫(xiě)不好hive的,多少還需要做一些深入的了解。
說(shuō)到spark相信很多同學(xué)也是久仰大名,它是一個(gè)非常著(zhù)名的開(kāi)源集群計算框架,也可以理解成一個(gè)分布式計算框架。
spark在MapReduce的基礎上對MapReduce當中的一些問(wèn)題進(jìn)行了優(yōu)化,比如MapReduce每次運算結束之后都會(huì )把數據存儲在磁盤(pán)上,這會(huì )帶來(lái)巨大的IO開(kāi)銷(xiāo)。
而spark使用了存儲器內運算技術(shù),可以盡量減少磁盤(pán)的寫(xiě)入。這其中的技術(shù)細節看不懂沒(méi)有關(guān)系,我們只需要知道它的運算性能比MapReduce快很多就可以了,一般來(lái)說(shuō)運算速度是MapReduce的十倍以上。并且spark原生支持hdfs,所以大部分公司都是使用hdfs做數據存儲,spark來(lái)進(jìn)行數據運算。
在hadoop推出了hive之后,spark也推出了自己的spark SQL。不過(guò)后來(lái)hive也支持使用spark作為計算引擎代替MapReduce了,這兩者的性能上差異也就很小了,我個(gè)人還是更喜歡hive一點(diǎn),畢竟寫(xiě)起來(lái)方便。
另外spark除了計算框架之外,當中也兼容了一些機器學(xué)習的庫,比如MLlib,不過(guò)我沒(méi)有用過(guò),畢竟現在機器學(xué)習的時(shí)代都快結束了。很少再有使用場(chǎng)景了,大家感興趣也可以了解一下。
最后做一個(gè)簡(jiǎn)單的總結,總體上來(lái)說(shuō)想要成為一名合格的算法工程師,hadoop、MapReduce、hive這些或多或少都需要有所了解。不說(shuō)能夠精通到原理級,但至少需要會(huì )用,大概知道里面怎么回事。
這也是工業(yè)界和實(shí)驗室里的最大區別,畢竟學(xué)校里的實(shí)驗數據量也不會(huì )很大,直接放在內存里就完事了。所以數據處理一般都是numpy + pandas什么的,但是在公司里,幾乎沒(méi)有pandas的用武之地,畢竟數據量太大了,不可能都放內存里,必須要借助大數據計算平臺來(lái)解決。
好了,就說(shuō)這么多吧,感謝大家的閱讀。
聯(lián)系客服