干掉幾百行的大SQL,我用Hadoop
一、前奏
?Hadoop是目前大數(shù)據(jù)領(lǐng)域最主流的一套技術(shù)體系,包含了多種技術(shù)。
包括HDFS(分布式文件系統(tǒng)),YARN(分布式資源調(diào)度系統(tǒng)),MapReduce(分布式計(jì)算系統(tǒng)),等等。
有些朋友可能聽(tīng)說(shuō)過(guò)Hadoop,但是卻不太清楚他到底是個(gè)什么東西,這篇文章就用大白話給各位闡述一下。
假如你現(xiàn)在公司里的數(shù)據(jù)都是放在MySQL里的,那么就全部放在一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器上,我們就假設(shè)這臺(tái)服務(wù)器的磁盤空間有2T吧,大家先看下面這張圖。?
?現(xiàn)在問(wèn)題來(lái)了,你不停的往這臺(tái)服務(wù)器的MySQL里放數(shù)據(jù),結(jié)果數(shù)據(jù)量越來(lái)越大了,超過(guò)了2T的大小了,現(xiàn)在咋辦?
你說(shuō),我可以搞多臺(tái)MySQL數(shù)據(jù)庫(kù)服務(wù)器,分庫(kù)分表??!每臺(tái)服務(wù)器放一部分?jǐn)?shù)據(jù)不就得了。如上圖所示!
好,沒(méi)問(wèn)題,那咱們搞3臺(tái)數(shù)據(jù)庫(kù)服務(wù)器,3個(gè)MySQL實(shí)例,然后每臺(tái)服務(wù)器都可以2T的數(shù)據(jù)。
現(xiàn)在我問(wèn)你一個(gè)問(wèn)題,所謂的大數(shù)據(jù)是在干什么?
我們來(lái)說(shuō)一下大數(shù)據(jù)最初級(jí)的一個(gè)使用場(chǎng)景。假設(shè)你有一個(gè)電商網(wǎng)站,現(xiàn)在要把這個(gè)電商網(wǎng)站里所有的用戶在頁(yè)面和APP上的點(diǎn)擊、購(gòu)買、瀏覽的行為日志都存放起來(lái)分析。
你現(xiàn)在把這些數(shù)據(jù)全都放在了3臺(tái)MySQL服務(wù)器,數(shù)據(jù)量很大,但還是勉強(qiáng)可以放的下。?
某天早上,你的boss來(lái)了。要看一張報(bào)表,比如要看每天網(wǎng)站的X指標(biāo)、Y指標(biāo)、Z指標(biāo),等等,二三十個(gè)數(shù)據(jù)指標(biāo)。
好了,兄弟,現(xiàn)在你嘗試去從那些點(diǎn)擊、購(gòu)買、瀏覽的日志里,通過(guò)寫(xiě)一個(gè)SQL來(lái)分析出那二三十個(gè)指標(biāo)試試看?
我跟你打賭,你絕對(duì)會(huì)寫(xiě)出來(lái)一個(gè)幾百行起步,甚至上千行的超級(jí)復(fù)雜大SQL。這個(gè)SQL,你覺(jué)得他能運(yùn)行在分庫(kù)分表后的3臺(tái)MySQL服務(wù)器上么?
如果你覺(jué)得可以的話,那你一定是不太了解MySQL分庫(kù)分表后有多坑,幾百行的大SQL跨庫(kù)join,各種復(fù)雜的計(jì)算,根本不現(xiàn)實(shí)。
所以說(shuō),大數(shù)據(jù)的存儲(chǔ)和計(jì)算壓根兒不是靠MySQL來(lái)搞的,因此,Hadoop、Spark等大數(shù)據(jù)技術(shù)體系才應(yīng)運(yùn)而生。
本質(zhì)上,Hadoop、Spark等大數(shù)據(jù)技術(shù),其實(shí)就是一系列的分布式系統(tǒng)。
比如hadoop中的HDFS,就是大數(shù)據(jù)技術(shù)體系中的核心基石,負(fù)責(zé)分布式存儲(chǔ)數(shù)據(jù),這是啥意思?別急,繼續(xù)往下看。
HDFS全稱是Hadoop Distributed File System,是Hadoop的分布式文件系統(tǒng)。
它由很多機(jī)器組成,每臺(tái)機(jī)器上運(yùn)行一個(gè)DataNode進(jìn)程,負(fù)責(zé)管理一部分?jǐn)?shù)據(jù)。
然后有一臺(tái)機(jī)器上運(yùn)行了NameNode進(jìn)程,NameNode大致可以認(rèn)為是負(fù)責(zé)管理整個(gè)HDFS集群的這么一個(gè)進(jìn)程,他里面存儲(chǔ)了HDFS集群的所有元數(shù)據(jù)。
然后有很多臺(tái)機(jī)器,每臺(tái)機(jī)器存儲(chǔ)一部分?jǐn)?shù)據(jù)!好,HDFS現(xiàn)在可以很好的存儲(chǔ)和管理大量的數(shù)據(jù)了。
這時(shí)候你肯定會(huì)有疑問(wèn):MySQL服務(wù)器也不是這樣的嗎?你要是這樣想,那就大錯(cuò)特錯(cuò)了。
這個(gè)事情不是你想的那么簡(jiǎn)單的,HDFS天然就是分布式的技術(shù),所以你上傳大量數(shù)據(jù),存儲(chǔ)數(shù)據(jù),管理數(shù)據(jù),天然就可以用HDFS來(lái)做。
如果你硬要基于MySQL分庫(kù)分表這個(gè)事兒,會(huì)痛苦很多倍,因?yàn)镸ySQL并不是設(shè)計(jì)為分布式系統(tǒng)架構(gòu)的,他在分布式數(shù)據(jù)存儲(chǔ)這塊缺乏很多數(shù)據(jù)保障的機(jī)制。
好,你現(xiàn)在用HDFS分布式存儲(chǔ)了數(shù)據(jù),接著不就是要分布式來(lái)計(jì)算這些數(shù)據(jù)了嗎?
對(duì)于分布式計(jì)算:
- 很多公司用Hive寫(xiě)幾百行的大SQL(底層基于MapReduce)。
- 也有很多公司開(kāi)始慢慢的用Spark寫(xiě)幾百行的大SQL(底層是Spark Core引擎)。
總之就是寫(xiě)一個(gè)大SQL,人家會(huì)拆分為很多的計(jì)算任務(wù),放到各個(gè)機(jī)器上去,每個(gè)計(jì)算任務(wù)就負(fù)責(zé)計(jì)算一小部分?jǐn)?shù)據(jù),這就是所謂的分布式計(jì)算。
這個(gè),絕對(duì)比你針對(duì)分庫(kù)分表的MySQL來(lái)跑幾百行大SQL要靠譜的多。
對(duì)于上述所說(shuō)的分布式存儲(chǔ)與分布式計(jì)算,老規(guī)矩,同樣給大家來(lái)一張圖,大伙兒跟著圖來(lái)仔細(xì)捋一下整個(gè)過(guò)程。
二、HDFS的NameNode架構(gòu)原理
好了,前奏鋪墊完之后,進(jìn)入正題。本文其實(shí)主要就是討論一下HDFS集群中的NameNode的核心架構(gòu)原理。
NameNode有一個(gè)很核心的功能:管理整個(gè)HDFS集群的元數(shù)據(jù),比如說(shuō)文件目錄樹(shù)、權(quán)限的設(shè)置、副本數(shù)的設(shè)置,等等。
下面就用最典型的文件目錄樹(shù)的維護(hù),來(lái)?給大家舉例說(shuō)明,我們看看下面的圖?,F(xiàn)在?有一個(gè)客戶端系統(tǒng)要上傳一個(gè)1TB的大文件到HDFS集群里。
此時(shí)他會(huì)先跟NameNode通信,說(shuō):大哥,我想創(chuàng)建一個(gè)新的文件,他的名字叫“
/usr/hive/warehouse/access_20180101.log”,大小是1TB,你看行不?
然后NameNode就會(huì)在自己內(nèi)存的文件目錄樹(shù)里,在指定的目錄下搞一個(gè)新的文件對(duì)象,名字就是“access_20180101.log”。
這個(gè)文件目錄樹(shù)不就是HDFS非常核心的一塊元數(shù)據(jù),維護(hù)了HDFS這個(gè)分布式文件系統(tǒng)中,有哪些目錄,有哪些文件,對(duì)不對(duì)?
但是有個(gè)問(wèn)題,這個(gè)文件目錄樹(shù)是在NameNode的內(nèi)存里的啊!
?這可坑爹了,你把重要的元數(shù)據(jù)都放在內(nèi)存里,萬(wàn)一NameNode不小心宕機(jī)了可咋整?元數(shù)據(jù)不就全部丟失了?
可你要是每次都頻繁的修改磁盤文件里的元數(shù)據(jù),性能肯定是極低的??!畢竟這是大量的磁盤隨機(jī)讀寫(xiě)!
沒(méi)關(guān)系,我們來(lái)看看HDFS優(yōu)雅的解決方案。
每次內(nèi)存里改完了,寫(xiě)一條edits log,元數(shù)據(jù)修改的操作日志到磁盤文件里,不修改磁盤文件內(nèi)容,就是順序追加,這個(gè)性能就高多了。
每次NameNode重啟的時(shí)候,把edits log里的操作日志讀到內(nèi)存里回放一下,不就可以恢復(fù)元數(shù)據(jù)了?
大家順著上面的文字,把整個(gè)過(guò)程,用下面這張圖跟著走一遍。?
?但是問(wèn)題又來(lái)了,那edits log如果越來(lái)越大的話,豈不是每次重啟都會(huì)很慢?因?yàn)橐x取大量的edits log回放恢復(fù)元數(shù)據(jù)!
所以HDFS說(shuō),我可以這樣子啊,我引入一個(gè)新的磁盤文件叫做fsimage,然后呢,再引入一個(gè)JournalNodes集群,以及一個(gè)Standby NameNode(備節(jié)點(diǎn))。
每次Active NameNode(主節(jié)點(diǎn))修改一次元數(shù)據(jù)都會(huì)生成一條edits log,除了寫(xiě)入本地磁盤文件,還會(huì)寫(xiě)入JournalNodes集群。
然后Standby NameNode就可以從JournalNodes集群拉取edits log,應(yīng)用到自己內(nèi)存的文件目錄樹(shù)里,跟Active NameNode保持一致。
然后每隔一段時(shí)間,Standby NameNode都把自己內(nèi)存里的文件目錄樹(shù)寫(xiě)一份到磁盤上的fsimage,這可不是日志,這是完整的一份元數(shù)據(jù)。這個(gè)操作就是所謂的checkpoint檢查點(diǎn)操作。?
然后把這個(gè)fsimage上傳到到Active NameNode,接著清空掉Active NameNode的舊的edits log文件,這里可能都有100萬(wàn)行修改日志了!
然后Active NameNode繼續(xù)接收修改元數(shù)據(jù)的請(qǐng)求,再寫(xiě)入edits log,寫(xiě)了一小會(huì)兒,這里可能就幾十行修改日志而已!
如果說(shuō)此時(shí),Active NameNode重啟了,bingo!沒(méi)關(guān)系,只要把Standby NameNode傳過(guò)來(lái)的fsimage直接讀到內(nèi)存里,這個(gè)fsimage直接就是元數(shù)據(jù),不需要做任何額外操作,純讀取,效率很高!
然后把新的edits log里少量的幾十行的修改日志回放到內(nèi)存里就ok了!
這個(gè)過(guò)程的啟動(dòng)速度就快的多了!因?yàn)椴恍枰胤糯罅可习偃f(wàn)行的edits log來(lái)恢復(fù)元數(shù)據(jù)了!如下圖所示。
此外,大家看看上面這張圖,現(xiàn)在咱們有倆NameNode。
- 一個(gè)是主節(jié)點(diǎn)對(duì)外提供服務(wù)接收請(qǐng)求
- 另外一個(gè)純就是接收和同步主節(jié)點(diǎn)的edits log以及執(zhí)行定期checkpoint的備節(jié)點(diǎn)。
大家有沒(méi)有發(fā)現(xiàn)!他們倆內(nèi)存里的元數(shù)據(jù)幾乎是一模一樣的??!
所以呢,如果Active NameNode掛了,是不是可以立馬切換成Standby NameNode對(duì)外提供服務(wù)?
這不就是所謂的NameNode主備高可用故障轉(zhuǎn)移機(jī)制么!
?接下來(lái)大家再想想,HDFS客戶端在NameNode內(nèi)存里的文件目錄樹(shù),新加了一個(gè)文件。
但是這個(gè)時(shí)候,人家要把數(shù)據(jù)上傳到多臺(tái)DataNode機(jī)器上去啊,這可是一個(gè)1TB的大文件!咋傳呢??
?很簡(jiǎn)單,把1TB的大文件拆成N個(gè)block,每個(gè)block是128MB。1TB = 1024GB = 1048576MB,一個(gè)block是128MB,那么就是對(duì)應(yīng)著8192個(gè)block。
這些block會(huì)分布在不同的機(jī)器上管理著,比如說(shuō)一共有100臺(tái)機(jī)器組成的集群,那么每臺(tái)機(jī)器上放80個(gè)左右的block就ok了。
但是問(wèn)題又來(lái)了,那如果這個(gè)時(shí)候1臺(tái)機(jī)器宕機(jī)了,不就導(dǎo)致80個(gè)block丟失了?
也就是說(shuō)上傳上去的1TB的大文件,會(huì)丟失一小部分?jǐn)?shù)據(jù)啊。沒(méi)關(guān)系!HDFS都考慮好了!
它會(huì)默認(rèn)給每個(gè)block搞3個(gè)副本,一模一樣的副本,分放在不同的機(jī)器上,如果一臺(tái)機(jī)器宕機(jī)了,同一個(gè)block還有另外兩個(gè)副本在其他機(jī)器上呢!
大伙兒看看下面這張圖。每個(gè)block都在不同的機(jī)器上有3個(gè)副本,任何一臺(tái)機(jī)器宕機(jī)都沒(méi)事!還可以從其他的機(jī)器上拿到那個(gè)block。
這下子,你往HDFS上傳一個(gè)1TB的大文件,可以高枕無(wú)憂了吧!?
OK,上面就是大白話加上一系列手繪圖,給大家先聊聊小白都能聽(tīng)懂的Hadoop的基本架構(gòu)原理
接下來(lái)會(huì)給大家聊聊HDFS,這個(gè)作為世界上最優(yōu)秀的分布式存儲(chǔ)系統(tǒng),承載高并發(fā)請(qǐng)求、高性能文件上傳的一些核心機(jī)制以及原理。