?五、HBase
1、HBase特點(diǎn)
????Hbase是構(gòu)建在HDFS上的分布式數(shù)據(jù)庫(kù),提供?高可靠性?、?高性能?、?列存儲(chǔ)?、?可伸縮?、?實(shí)時(shí)讀寫?的分布式數(shù)據(jù)庫(kù)系統(tǒng)。HBase主要用于大數(shù)據(jù)領(lǐng)域,MySQL 是行式存儲(chǔ),HBase 是列式存儲(chǔ)。
????HBase 是一種構(gòu)建在 HBase 之上的分布式、面向列的存儲(chǔ)系統(tǒng),需要實(shí)時(shí)讀寫、隨機(jī)訪問超大規(guī)模數(shù)據(jù)集時(shí),可以使用HBase。
????HDFS不支持小文件,不支持并發(fā)寫,不支持文件隨機(jī)修改,查詢效率也低 。HBase 卻是一個(gè)支持百萬級(jí)別高并發(fā)寫入,支持實(shí)時(shí)查詢,適合存儲(chǔ)稀疏數(shù)據(jù)的分布式數(shù)據(jù)庫(kù)系統(tǒng)。
·(1)海量存儲(chǔ):
????HBase 單表可以有百億行、百萬列,可以在橫向和縱向兩個(gè)維度插入數(shù)據(jù),具有很大的彈性。
當(dāng)關(guān)系型數(shù)據(jù)庫(kù)的單個(gè)表的記錄在億級(jí)時(shí),查詢和寫入的性能都會(huì)呈現(xiàn)指數(shù)級(jí)下降,這種龐大的數(shù)據(jù)量對(duì)傳統(tǒng)數(shù)據(jù)庫(kù)來說是一種災(zāi)難,而HBase 在限定某個(gè)列的情況下對(duì)于單表存儲(chǔ)百億甚至更多的數(shù)據(jù)都沒有性能問題;?HBase 采用 LSM 樹作為內(nèi)部數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),這種結(jié)構(gòu)會(huì)周期性地將較小文件合并成大文件,以減少對(duì)磁盤的訪問。
·(2)列式存儲(chǔ):
????HBase表的數(shù)據(jù)是基于列族進(jìn)行存儲(chǔ)的,列族是在列的方向上的劃分,每個(gè)列族是單獨(dú)存儲(chǔ)的,且支持基于列的獨(dú)立檢索。
· (3)稀疏性:主要是針對(duì)HBase列的靈活性,在列族中,你可以指定任意多的列,在列數(shù)據(jù)為空的情況下,是不會(huì)占用存儲(chǔ)空間的,在很大程度上節(jié)省了存儲(chǔ)開銷。
·(4)擴(kuò)展性強(qiáng):依賴HDFS,當(dāng)磁盤空間不足的時(shí)候,只需要?jiǎng)討B(tài)增加datanode節(jié)點(diǎn)就可以了,可以通過增加服務(wù)器來對(duì)集群的存儲(chǔ)進(jìn)行擴(kuò)容;
HBase工作在 HDFS 之上,理所當(dāng)然地支持分布式表,也繼承了 HDFS 的可擴(kuò)展性。HBase 的擴(kuò)展是橫向的,橫向擴(kuò)展是指在擴(kuò)展時(shí)不需要提升服務(wù)器本身的性能,只需添加服務(wù)器到現(xiàn)有集群即可。????HBase表根據(jù) Region 大小進(jìn)行分區(qū),分別存在集群中不同的節(jié)點(diǎn)上,當(dāng)添加新的節(jié)點(diǎn)時(shí),集群就重新調(diào)整,在新的節(jié)點(diǎn)啟動(dòng) HBase 服務(wù)器,動(dòng)態(tài)地實(shí)現(xiàn)擴(kuò)展。這里需要指出,HBase 的擴(kuò)展是熱擴(kuò)展,即在不停止現(xiàn)有服務(wù)的前提下,可以隨時(shí)添加或者減少節(jié)點(diǎn)。
·(5)高可靠性
????HBase運(yùn)行在 HDFS 上,HDFS 的多副本存儲(chǔ)可以讓它在岀現(xiàn)故障時(shí)自動(dòng)恢復(fù),同時(shí) HBase 內(nèi)部也提供 WAL 和 Replication 機(jī)制。
????WAL(Write-Ahead-Log)預(yù)寫日志是在 HBase 服務(wù)器處理數(shù)據(jù)插入和刪除的過程中用來記錄操作內(nèi)容的日志,保證了數(shù)據(jù)寫入時(shí)不會(huì)因集群異常而導(dǎo)致寫入數(shù)據(jù)的丟失;而 Replication 機(jī)制是基于日志操作來做數(shù)據(jù)同步的。
????當(dāng)集群中單個(gè)節(jié)點(diǎn)出現(xiàn)故障時(shí),協(xié)調(diào)服務(wù)組件ZooKeeper通知集群的主節(jié)點(diǎn),將故障節(jié)點(diǎn)的 HLog 中的日志信息分發(fā)到各從節(jié)點(diǎn)進(jìn)行數(shù)據(jù)恢復(fù)。
·(6)高并發(fā):支持高并發(fā)的讀寫請(qǐng)求
·(7)數(shù)據(jù)多版本:表中數(shù)據(jù)可以有多個(gè)版本值,默認(rèn)情況下是根據(jù)版本號(hào)去區(qū)分,版本號(hào)就是插入數(shù)據(jù)的時(shí)間戳
·(8)數(shù)據(jù)類型單一:所有的數(shù)據(jù)在HBase中是以字節(jié)數(shù)組進(jìn)行存儲(chǔ)
·啟動(dòng)時(shí),需要提前啟動(dòng)HDFS及 ZooKeeper集群
rowkey行鍵 -> Column Family列族? -> Column列 -> cell單元格? -> Timestamp時(shí)間戳
2、架構(gòu)原理
HMaster??->??HRegionServer??-> ?Region
·(1)Client客戶端 :Client是操作HBase集群的入口
?????? ·對(duì)于管理類的操作,如表的增刪改操縱,Client通過RPC與HMaster通信完成;
?????? ·對(duì)于表數(shù)據(jù)的讀寫操作,Client通過RPC與RegionServer交互,讀寫數(shù)據(jù);
????? ·Client類型:HBase shell、Java編程接口、Thrift、Avro、Rest等等;
·(2)ZooKeeper集群:
????·實(shí)現(xiàn)了HMaster的高可用,多HMaster間進(jìn)行主備選舉;
????·保存HBase元數(shù)據(jù)信息meta表,提供HBase表中region的尋址入口的線索數(shù)據(jù);
????·對(duì)HMaster和HRegionServer實(shí)現(xiàn)了監(jiān)控
·(3)HMaster:負(fù)責(zé)Table表和Region的相關(guān)管理工作:
????????·關(guān)于Table:管理Client對(duì)Table的增刪改的操作
?????? ·關(guān)于Region:在Region分裂后,負(fù)責(zé)新Region分配到指定的HRegionServer 上;管理HRegionServer間的負(fù)載均衡,遷移region分布;當(dāng) HRegionServer宕機(jī)后,負(fù)責(zé)其上的region的遷移
·(4)HRegionServer
????????·響應(yīng)客戶端的讀寫數(shù)據(jù)請(qǐng)求
????????? ·負(fù)責(zé)管理一系列的Region
?????????? ·切分在運(yùn)行過程中變大的region
·(5)Region:HBase集群中分布式存儲(chǔ)的最小單元
????·一個(gè)Region對(duì)應(yīng)一個(gè)Table表的部分?jǐn)?shù)據(jù)
????·Region是HBase集群中分布式存儲(chǔ)的最小單元,一個(gè)Region對(duì)應(yīng)一個(gè)Table表的部分?jǐn)?shù)據(jù)。
????·memstore是一塊?內(nèi)存區(qū)域,寫入的數(shù)據(jù)會(huì)先寫入memstore進(jìn)行緩沖,然后再把數(shù)據(jù)刷到磁盤;?
????·StoreFile是HFile的抽象對(duì)象,如果說到StoreFile就等于HFile,每次memstore刷寫數(shù)據(jù)到磁盤,就生成對(duì)應(yīng)的一個(gè)新的HFile文件出來
????·一個(gè)HRegionServer會(huì)負(fù)責(zé)管理很多個(gè)region?,一個(gè)region包含很多個(gè)store,一個(gè)列族就劃分成一個(gè)store,一個(gè)store里面只有一個(gè)memstore,有很多個(gè)?StoreFile?,最后數(shù)據(jù)是以很多個(gè)?HFile?這種數(shù)據(jù)結(jié)構(gòu)的文件保存在HDFS上。
3、讀寫過程
Hbase讀數(shù)據(jù)
·1、客戶端首先與zk進(jìn)行連接,從zk找到包含meta表的HRegionServer,連接此包含HRegionServer,讀取meta表中的數(shù)據(jù);
· 2、根據(jù)要查詢信息,先找到數(shù)據(jù)對(duì)應(yīng)的region信息,在找到這個(gè)region對(duì)應(yīng)的regionServer,然后發(fā)送請(qǐng)求
·3、查找并定位到對(duì)應(yīng)的region,
·4、先從memstore查找數(shù)據(jù)---如果沒有從BlockCache上讀取----如果也沒有再到StoreFile上進(jìn)行讀取。
·5、從storeFile中讀取到數(shù)據(jù)之后,不是直接把結(jié)果數(shù)據(jù)返回給客戶端,而是把數(shù)據(jù)先寫入到BlockCache中,目的是為了加快后續(xù)的查詢;然后在返回結(jié)果給客戶端。
Hbase寫數(shù)據(jù)
·1、客戶端首先與zk進(jìn)行連接,從zk找到zk找到meta表的region位置,即包含meta表的HRegionServer,連接此包含HRegionServer,讀取meta表中的數(shù)據(jù);
·2、根據(jù)要查詢信息,先找到數(shù)據(jù)對(duì)應(yīng)的region信息,在找到這個(gè)region對(duì)應(yīng)的regionServer,然后發(fā)送請(qǐng)求
·3、查找并定位到對(duì)應(yīng)的region,
·4、寫數(shù)據(jù)時(shí),把數(shù)據(jù)分別寫到HLog 和memstore各一份進(jìn)行緩沖,
·5、flush:memstore達(dá)到閾值后,把數(shù)據(jù)**刷到磁盤**生成多個(gè)storeFile文件。
? ? ? ? ? ? ? ?Region中任意一個(gè)memstore達(dá)到128MB
?????????????? Region中所有Memstore的大小總和達(dá)到block.multiplier * flush.size
? ? ? ? ? ? ? ?Region Server中HLog數(shù)量達(dá)到上限
·6、compact:
? ????????????小合并:小的store file合并成相對(duì)較大的store file,
????????????大合并:合并Store中所有的HFile為一個(gè)HFile
4、flush刷寫
為了減少flush過程對(duì)讀寫的影響,將整個(gè)flush過程分為三個(gè)階段:
????????①prepare階段: 將Memstore中當(dāng)前數(shù)據(jù)集做一個(gè)快照snapshot;再新建一個(gè)數(shù)據(jù)集CellSkipListSet。后期寫入的數(shù)據(jù)都會(huì)寫入新的CellSkipListSet中。
????????②flush階段:將prepare階段生成的snapshot持久化為臨時(shí)文件,統(tǒng)一放到目錄.tmp下。涉及到磁盤IO操作,相對(duì)比較耗時(shí)。
????????③commit階段:將flush階段生成的臨時(shí)文件移到指定的ColumnFamily目錄下,針對(duì)HFile生成對(duì)應(yīng)的storefile和Reader,最后再清空prepare階段生成的snapshot。
觸發(fā)條件:
????????①一個(gè)MemStore的大小達(dá)到了上限128m
????????②一個(gè)Region中所有Memstore總和達(dá)到了上限,128*個(gè)數(shù)
????????③一個(gè)Region Server中所有Memstore總和超過低水位閾值
????????④一個(gè)Region Server中HLog數(shù)量達(dá)到上限
????????⑤定期1小時(shí)刷新Memstore
????????⑥通過shell命令flush ‘tablename’或者flush ‘region name’,手動(dòng)刷寫
5、campact合并
????為防止小文件過多,以保證查詢效率,需將這些小的store file合并成相對(duì)較大的store file,這個(gè)過程就稱之為compaction。
????小合并:將一些小的、相鄰的StoreFile,合并成一個(gè)更大的StoreFile,對(duì)于超過了TTL的數(shù)據(jù)、更新的數(shù)據(jù)、刪除的數(shù)據(jù)僅僅只是做了標(biāo)記,并沒有進(jìn)行物理刪。一次結(jié)果是更少并且更大的StoreFile,觸發(fā)頻率很高。
????大合并:將所有的StoreFile合并成一個(gè)StoreFile,?清理三類無意義數(shù)據(jù):被刪除的數(shù)據(jù)、TTL過期數(shù)據(jù)、版本號(hào)超過設(shè)定版本號(hào)的數(shù)據(jù)。合并頻率比較低,默認(rèn)7天執(zhí)行一次,并且性能消耗非常大,建議生產(chǎn)關(guān)閉(設(shè)置為0),在應(yīng)用空閑時(shí)間手動(dòng)觸發(fā)。一般可以是手動(dòng)控制進(jìn)行合并,防止出現(xiàn)在業(yè)務(wù)高峰期。
6、region拆分
????????①0.94版本前默認(rèn),region大小大于某個(gè)閾值10G;
????????②0.94~2.0版本默認(rèn),大小遞增,regioncount^3 * 128M * 2,256M 2048M 6912M 10G;
????????③2.0版本默認(rèn),如果region個(gè)數(shù)等于1, 切分閾值為flush size * 2,否則為MaxRegionFileSize;
????????④根據(jù)rowKey前綴對(duì)數(shù)據(jù)進(jìn)行分組
7、預(yù)分區(qū)
????????當(dāng)一個(gè)table剛被創(chuàng)建的時(shí)候,Hbase默認(rèn)的分配一個(gè)region給table。?說這個(gè)時(shí)候,所有的讀寫請(qǐng)求都會(huì)訪問到同一個(gè)regionServer的同一個(gè)region中,這個(gè)時(shí)候就達(dá)不到負(fù)載均衡的效果了,集群中的其他regionServer就可能會(huì)處于比較空閑的狀態(tài)。
?????????在創(chuàng)建table的時(shí)候就配置好預(yù)分區(qū),生成多個(gè)region。增加數(shù)據(jù)讀寫效率;負(fù)載均衡,防止數(shù)據(jù)傾斜;方便集群容災(zāi)調(diào)度region;優(yōu)化Map數(shù)量
????????每一個(gè)region維護(hù)著startRow與endRowKey,如果加入的數(shù)據(jù)符合某個(gè)region維護(hù)的rowKey范圍,則該數(shù)據(jù)交給這個(gè)region維護(hù)。
8、rowkey設(shè)計(jì)三原則
長(zhǎng)度原則、散列原則、唯一原則
?rowkey長(zhǎng)度原則
?????????rowkey是一個(gè)二進(jìn)制碼流,可以是任意字符串,最大長(zhǎng)度64kb,實(shí)際應(yīng)用中一般為10-100bytes,以byte[]形式保存,一般設(shè)計(jì)成定長(zhǎng)。建議盡可能短;但是也不能太短,否則rowkey前綴重復(fù)的概率增大; 設(shè)計(jì)過長(zhǎng):會(huì)降低memstore內(nèi)存的利用率和HFile存儲(chǔ)數(shù)據(jù)的效率。
?rowkey散列原則:
?????建議將rowkey的高位:作為散列字段,這樣將提高數(shù)據(jù)均衡分布在每個(gè)RegionServer,以實(shí)現(xiàn)負(fù)載均衡的幾率。如果沒有散列字段,首字段直接是時(shí)間信息。所有的數(shù)據(jù)都會(huì)集中在一個(gè)RegionServer上,這樣在數(shù)據(jù)檢索的時(shí)候負(fù)載會(huì)集中在個(gè)別的RegionServer上,造成熱點(diǎn)問題,會(huì)降低查詢效率。
?rowkey唯一原則:
必須在設(shè)計(jì)上保證其唯一性,rowkey是按照字典順序排序存儲(chǔ)的;因此,設(shè)計(jì)rowkey的時(shí)候,要充分利用這個(gè)排序的特點(diǎn),可以將經(jīng)常讀取的數(shù)據(jù)存儲(chǔ)到一塊,將最近可能會(huì)被訪問的數(shù)據(jù)放到一塊
9、什么是熱點(diǎn)
????檢索habse的記錄首先要通過row key來定位數(shù)據(jù)行。當(dāng)大量的client訪問hbase集群的一個(gè)或少數(shù)幾個(gè)節(jié)點(diǎn),造成少數(shù)region server的讀/寫請(qǐng)求過多、負(fù)載過大,而其他region server負(fù)載卻很小,就造成了“熱點(diǎn)”現(xiàn)象。
熱點(diǎn)的解決方案(預(yù)分區(qū)、加鹽、哈希、反轉(zhuǎn))
????????預(yù)分區(qū):目的讓表的數(shù)據(jù)可以均衡的分散在集群中,而不是默認(rèn)只有一個(gè)region分?? 布在集群的一個(gè)節(jié)點(diǎn)上。
? ? ????加鹽:在rowkey的前面增加隨機(jī)數(shù),具體就是給rowkey分配一個(gè)隨機(jī)前綴以使得 它和之前的rowkey的開頭不同
????????哈希:使同一行永遠(yuǎn)用一個(gè)前綴加鹽。哈希也可以使負(fù)載分散到整個(gè)集群,但是讀 卻是可以預(yù)測(cè)的。使用確定的哈??梢宰尶蛻舳酥貥?gòu)完整的rowkey,可以使 用get操作準(zhǔn)確獲取某一個(gè)行數(shù)據(jù)。
????????反轉(zhuǎn):反轉(zhuǎn)固定長(zhǎng)度或者數(shù)字格式的rowkey。這樣可以使得rowkey中經(jīng)常改變的 部分(最沒有意義的部分)放在前面。
10、協(xié)處理器
????????Hbase作為列族數(shù)據(jù)庫(kù)最經(jīng)常被人詬病的特性包括:無法輕易建立“二級(jí)索引”,難以執(zhí)行求和、計(jì)數(shù)、排序等操作。比如,在舊版本的(<0.92)Hbase 中,統(tǒng)計(jì)數(shù)據(jù)表的總行數(shù),需 要使用 Counter 方法,執(zhí)行一次 MapReduce Job 才能得到。
????????雖然HBase在數(shù)據(jù)存儲(chǔ)層中集成了 MapReduce,能夠有效用于數(shù)據(jù)表的分布式計(jì)算。然而在很多情況下,做一些簡(jiǎn)單的相加或者聚合計(jì)算的時(shí)候, 如果直接將計(jì)算過程放置在server端,能夠減少通訊開銷,從而獲得很好的性能提升。
????????于是,HBase在 0.92 之后引入了協(xié)處理器(coprocessors),實(shí)現(xiàn)一些激動(dòng)人心的新特性:能夠輕易建立二次索引、復(fù)雜過濾器(謂詞下推)以及訪問控制等。
協(xié)處理器有兩種:Observer協(xié)處理器?? ?endpoint協(xié)處理器
????????Observer協(xié)處理器: 類似于傳統(tǒng)數(shù)據(jù)庫(kù)中的觸發(fā)器,主要在服務(wù)端工作;允許集群在正常的客戶端操作過程中,可以有不同的行為表現(xiàn);可以實(shí)現(xiàn)權(quán)限管理、優(yōu)先級(jí)設(shè)置、監(jiān)控、ddl控制、 二級(jí)索引等功能。
????????endpoint協(xié)處理器;類似于傳統(tǒng)數(shù)據(jù)庫(kù)中的存儲(chǔ)過程,主要在client端工作;允許擴(kuò)展集群的能力,對(duì)客戶端應(yīng)用開放新的運(yùn)算命令;可以實(shí)現(xiàn)min、 max、 avg、 sum、 distinct、 group by 等功能
????????協(xié)處理器的加載方式有兩種:靜態(tài)加載修改hbase-site.xml?;動(dòng)態(tài)加載啟用表aggregation,只對(duì)特定的表生效。
六、Hive
? ????????Hive是基于Hadoop的一個(gè)數(shù)據(jù)倉(cāng)庫(kù)工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫(kù)表,并提供類SQL查詢功能。本質(zhì)是將SQL轉(zhuǎn)換為MapReduce任務(wù)進(jìn)行運(yùn)算,底層由HDFS來提供數(shù)據(jù)的存儲(chǔ),可以理解就是一個(gè)MapReduce的客戶端,通過解析hql語句,實(shí)現(xiàn)hdfs上面的數(shù)據(jù)的查詢操作,真實(shí)的數(shù)據(jù)保存在hdfs上面的,數(shù)據(jù)的計(jì)算,使用的mr的程序。每執(zhí)行一次查詢,不一定會(huì)有對(duì)應(yīng)的mr任務(wù)執(zhí)行,有些查詢,不需要mr的參與;
????????hive當(dāng)中建庫(kù)建表的元數(shù)據(jù)信息保存在mysql里面;Hive只適合用來做海量離線數(shù)據(jù)統(tǒng)計(jì)分析,也就是數(shù)據(jù)倉(cāng)庫(kù)。
1、數(shù)據(jù)倉(cāng)庫(kù)的基本概念
????????數(shù)據(jù)倉(cāng)庫(kù)Data Warehouse,簡(jiǎn)寫為DW或DWH。數(shù)據(jù)倉(cāng)庫(kù)的目的是構(gòu)建面向分析的集成化數(shù)據(jù)環(huán)境,為企業(yè)提供決策支持。它出于分析性報(bào)告和決策支持目的而創(chuàng)建。
????????本身并不“生產(chǎn)”任何數(shù)據(jù),也不需要“消費(fèi)”任何的數(shù)據(jù),數(shù)據(jù)來源于外部,并且開放給外部應(yīng)用,這也是為什么叫“倉(cāng)庫(kù)”,而不叫“工廠”的原因。
????????倉(cāng)庫(kù),就是把數(shù)據(jù)拿過來,分類存好,讓別人來??;數(shù)據(jù)倉(cāng)庫(kù)是面向主題的、集成的、非易失的和時(shí)變數(shù)據(jù)集合,用以支持管理決策。有、主要用于報(bào)表展示、用戶畫像、數(shù)據(jù)挖掘、實(shí)時(shí)的風(fēng)控、推薦系統(tǒng)。
2、數(shù)據(jù)倉(cāng)庫(kù)與數(shù)據(jù)庫(kù)區(qū)別,
(1)是OLTP與 OLAP 的區(qū)別。
????????????OLTP(On-Line Transaction Processing,)操作型處理,叫聯(lián)機(jī)事務(wù)處理,是針對(duì)具體業(yè)務(wù)在數(shù)據(jù)庫(kù)聯(lián)機(jī)查詢、修改等日常操作。關(guān)心操作響應(yīng)時(shí)間、數(shù)據(jù)安全性、完整性和并發(fā)支持的用戶數(shù)等問題,數(shù)據(jù)庫(kù)系統(tǒng)。
????????????OLAP(On-Line Analytical Processing)分析型處理,叫聯(lián)機(jī)分析處理 ,一般針對(duì)某些主題的歷史數(shù)據(jù)進(jìn)行分析,支持管理決策。
(2)數(shù)據(jù)庫(kù)設(shè)計(jì)是盡量避免冗余。數(shù)據(jù)倉(cāng)庫(kù)在設(shè)計(jì)是有意引入冗余,依照分析需求,分析維度、分析指標(biāo)進(jìn)行設(shè)計(jì)。
(3)數(shù)據(jù)庫(kù)是為捕獲數(shù)據(jù)而設(shè)計(jì),數(shù)據(jù)倉(cāng)庫(kù)是為分析數(shù)據(jù)而設(shè)計(jì)。
3、數(shù)據(jù)倉(cāng)庫(kù)分層架構(gòu)
????????按照數(shù)據(jù)流入流出的過程,數(shù)據(jù)倉(cāng)庫(kù)架構(gòu)可分為三層——源數(shù)據(jù)、數(shù)據(jù)倉(cāng)庫(kù)、數(shù)據(jù)應(yīng)用。? ? ? ? ? ?數(shù)據(jù)倉(cāng)庫(kù)的數(shù)據(jù)來源于不同的源數(shù)據(jù),并提供多樣的數(shù)據(jù)應(yīng)用,數(shù)據(jù)自下而上流入數(shù)據(jù)倉(cāng)庫(kù)后向上層開放應(yīng)用,而數(shù)據(jù)倉(cāng)庫(kù)只是中間集成化數(shù)據(jù)管理的一個(gè)平臺(tái)
·(1)源數(shù)據(jù)層(ODS):此層數(shù)據(jù)無任何更改,直接沿用外圍系統(tǒng)數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù),不對(duì)外開放;為臨時(shí)存儲(chǔ)層,是接口數(shù)據(jù)的臨時(shí)存儲(chǔ)區(qū)域,為后一步的數(shù)據(jù)處理做準(zhǔn)備。
·(2)數(shù)據(jù)倉(cāng)庫(kù)層(DW):也稱為細(xì)節(jié)層,DW層的數(shù)據(jù)應(yīng)該是一致的、準(zhǔn)確的、干凈的數(shù)據(jù),即對(duì)源系統(tǒng)數(shù)據(jù)進(jìn)行了清洗(去除了雜質(zhì))后的數(shù)據(jù)。
·(3)數(shù)據(jù)應(yīng)用層(DA或APP):前端應(yīng)用直接讀取的數(shù)據(jù)源;根據(jù)報(bào)表、專題分析需求而計(jì)算生成的數(shù)據(jù)。
????????數(shù)據(jù)倉(cāng)庫(kù)從各數(shù)據(jù)源獲取數(shù)據(jù)及在數(shù)據(jù)倉(cāng)庫(kù)內(nèi)的,數(shù)據(jù)轉(zhuǎn)換和流動(dòng)都可以認(rèn)為是ETL(抽取Extra, 轉(zhuǎn)化Transfer, 裝載Load)的過程,ETL是數(shù)據(jù)倉(cāng)庫(kù)的流水線,也可以認(rèn)為是數(shù)據(jù)倉(cāng)庫(kù)的血液,它維系著數(shù)據(jù)倉(cāng)庫(kù)中數(shù)據(jù)的新陳代謝,而數(shù)據(jù)倉(cāng)庫(kù)日常的管理和維護(hù)工作的大部分精力就是保持ETL的正常和穩(wěn)定。
為什么要對(duì)數(shù)據(jù)倉(cāng)庫(kù)分層?
①?gòu)?fù)雜問題簡(jiǎn)單化、②清晰數(shù)據(jù)結(jié)構(gòu)(方便管理)、③增加數(shù)據(jù)的復(fù)用性、④隔離原始數(shù)據(jù)(解耦)
????·用空間換時(shí)間,通過大量的預(yù)處理來提升應(yīng)用系統(tǒng)的用戶體驗(yàn)(效率),因此數(shù)據(jù)倉(cāng)庫(kù)會(huì)存在大量冗余的數(shù)據(jù);不分層的話,如果源業(yè)務(wù)系統(tǒng)的業(yè)務(wù)規(guī)則發(fā)生變化將會(huì)影響整個(gè)數(shù)據(jù)清洗過程,工作量巨大。
????·通過數(shù)據(jù)分層管理可以簡(jiǎn)化數(shù)據(jù)清洗的過程,因?yàn)榘言瓉硪徊降墓ぷ鞣值搅硕鄠€(gè)步驟去完成,相當(dāng)于把一個(gè)復(fù)雜的工作拆成了多個(gè)簡(jiǎn)單的工作,把一個(gè)大的黑盒變成了一個(gè)白盒,每一層的處理邏輯都相對(duì)簡(jiǎn)單和容易理解,這樣我們比較容易保證每一個(gè)步驟的正確性,當(dāng)數(shù)據(jù)發(fā)生錯(cuò)誤的時(shí)候,往往我們只需要局部調(diào)整某個(gè)步驟即可。
4、怎么把hive翻譯成的mr的
主要就是通過解析器的,就是將sql語法解析成為mr的任務(wù)
????????解析器:主要就是用于解析sql語法
????????編譯器:將解析之后的sql語法進(jìn)行編譯成為MR的任務(wù)
????????優(yōu)化器:一定的優(yōu)化功能,自動(dòng)的會(huì)對(duì)我們寫的sql語句進(jìn)行調(diào)優(yōu),調(diào)優(yōu)的功能有限
????????執(zhí)行器:提交mr的任務(wù)到y(tǒng)arn上面去執(zhí)行的
5、hive優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
(1)操作接口采用類SQL語法,提供快速開發(fā)的能力(簡(jiǎn)單、容易上手)。
(2)避免了去寫MapReduce,減少開發(fā)人員的學(xué)習(xí)成本。
(3)Hive支持用戶自定義函數(shù),用戶可以根據(jù)自己的需求來實(shí)現(xiàn)自己的函數(shù)。
缺點(diǎn):
(1)Hive 不支持記錄級(jí)別的增刪改操作;
(2)Hive 的查詢延遲很嚴(yán)重;
(3)Hive 不支持事務(wù);
6、hive幾種表
????①內(nèi)部表:創(chuàng)建內(nèi)部表的時(shí)候,沒有external關(guān)鍵字;刪除內(nèi)部表的時(shí)候,會(huì)同步的刪除hdfs的數(shù)據(jù)。DW層
????②外部表:創(chuàng)建外部表的時(shí)候有external關(guān)鍵字;刪除外部表的時(shí)候,不會(huì)刪除hdfs的數(shù)據(jù)外部表刪的只是表結(jié)構(gòu),數(shù)據(jù)存在hdfs,元數(shù)據(jù)在mysql。ODS層
????③分區(qū)表:就是分文件夾,實(shí)際工作當(dāng)中,數(shù)據(jù)一般都是按照每天進(jìn)行采集的,每天的數(shù)據(jù)都會(huì)放到某一個(gè)日期文件夾。
????④分桶表:就是分文件,將一個(gè)大的文件分成多個(gè)小的文件,每個(gè)文件里面保存部分?jǐn)?shù)據(jù),到時(shí)候如果需要獲取數(shù)據(jù)的時(shí)候,可以直接從對(duì)應(yīng)的文件里面獲取即可。
????分桶將整個(gè)數(shù)據(jù)內(nèi)容,按照某列屬性值取hash值進(jìn)行區(qū)分,具有相同hash值的數(shù)據(jù)進(jìn)入到同一個(gè)文件中??梢赃^濾掉大量不相關(guān)的文件,提高查詢效率。
7、4個(gè)By區(qū)別
????1)Sort By:分區(qū)內(nèi)有序;
????2)Order By:全局排序,只有一個(gè)Reducer;
????3)Distrbute By:類似MR中Partition,進(jìn)行分區(qū),結(jié)合sort by使用。
????4) Cluster By:當(dāng)Distribute by和Sorts by字段相同時(shí),可以使用Cluster by方式。Cluster by除了具有Distribute by的功能外還兼具Sort by的功能。但是排序只能是升序排序,不能指定排序規(guī)則為ASC或者DESC。
8、SparkSQL整合hive
????????由于hive原生是基于MapReduce的,導(dǎo)致其查詢耗時(shí)較長(zhǎng)。為了保留Hive的架構(gòu)解決方案,并優(yōu)化查詢速度,采用SparkSql與hive整合(spark on hive),通過SparkSql讀取hive中表的元數(shù)據(jù),把HiveHQL底層采用MapReduce處理任務(wù)導(dǎo)致性能慢的特點(diǎn),改為更加強(qiáng)大的Spark引擎來進(jìn)行相應(yīng)的計(jì)算處理。
????????Spark SQL的其中一個(gè)分支就是Spark on Hive,就是使用Hive中HQL的解析邏輯、執(zhí)行計(jì)劃翻譯、執(zhí)行計(jì)劃優(yōu)化等邏輯,近似認(rèn)為僅將物理執(zhí)行計(jì)劃從MR作業(yè)替換成了Spark作業(yè)。????
????Spark SQL整合hive:就是獲取hive表中的元數(shù)據(jù)信息(在mysql中),然后通過Spark SQL來操作數(shù)據(jù)。
整合步驟:
????1)、拷貝hive配置文件到spark
????????????hive目錄中conf目錄下的hive-site.xml,hive的元數(shù)據(jù)信息在node03的mysql數(shù)據(jù)庫(kù)中,而整合需要spark能夠讀取找到Hive的元數(shù)據(jù)以及數(shù)據(jù)存放位置
????2)、拷貝mysql驅(qū)動(dòng)到spark
????3)啟動(dòng):?jiǎn)?dòng)HDFS,YARN集群;啟動(dòng)spark集群;啟動(dòng)hive;啟動(dòng)spark sql
可以像在spark-sql中操作hive中的數(shù)據(jù)庫(kù)和表,表明整合成功。
9、hive調(diào)優(yōu)
①Fetch抓取:對(duì)某些情況的查詢可以不必使用MapReduce計(jì)算,在全局查找、字段查找、limit查找等都不走mapreduce。
????????把hive-default.xml.template文件中hive.fetch.task.conversion設(shè)置成more,然后執(zhí)行查詢語句,查詢方式都不會(huì)執(zhí)行mr程序。默認(rèn)是more,(老版本minimal);設(shè)置成none,然后執(zhí)行查詢語句,都會(huì)執(zhí)行mapreduce程序
②本地模式:如果數(shù)據(jù)量小,只啟動(dòng)一個(gè)Maptask
????????默認(rèn)情況下是啟用hadoop的job模式,把任務(wù)提交到集群中運(yùn)行,這樣會(huì)導(dǎo)致計(jì)算非常緩慢;開啟本地模式,并執(zhí)行查詢語句? ?set hive.exec.mode.local.auto=true; //開啟本地mr
③表的優(yōu)化?join
? ? ? ? ?老版本hive,大小表 join 時(shí),小表放在join的左邊;大表join大表 時(shí),空 key 過濾,空 key 賦一個(gè)隨機(jī)的值;map join,在Map端先進(jìn)行部分聚合,最后在Reduce端得出最終結(jié)果;count distinct,使用先group by 再count的方式替換;多個(gè)表關(guān)聯(lián)時(shí),最好分拆成小段,避免大sql(無法控制中間Job);
④使用分區(qū)剪裁、列剪裁,盡可能早地過濾掉盡可能多的數(shù)據(jù)量,避免大量數(shù)據(jù)流入外層SQL。盡量使用分區(qū)過濾,少用select *
⑤并行執(zhí)行,把一個(gè)sql語句中沒有相互依賴的階段,并行去運(yùn)行,提高集群資源利用率配置:set hive.exec.parallel=true; set hive.exec.parallel.thread.number=16;
⑥開啟嚴(yán)格模式,防止用戶執(zhí)行,那些可能意想不到的不好的影響的查詢。
????配置:set hive.mapred.mode=strict;默認(rèn)是非嚴(yán)格模式nonstrict
????開啟嚴(yán)格模式,可以禁止3種類型的查詢。對(duì)于分區(qū)表,除非where語句中含有分區(qū)字段過濾條件來限制范圍,否則不允許執(zhí)行對(duì)于使用了order by語句的查詢,要求必須使用limit語句
⑦限制笛卡爾積的查詢
⑧開啟數(shù)據(jù)的壓縮,Hive表中間數(shù)據(jù)壓縮Hive表最終輸出結(jié)果壓縮
⑩避免數(shù)據(jù)傾斜:合理設(shè)置Map數(shù)?;合理設(shè)置Reduce數(shù);小文件合并;復(fù)雜文件增加Map數(shù) ;
11、運(yùn)維如何對(duì)hive進(jìn)行調(diào)度
????將hive的sql定義在腳本當(dāng)中;使用azkaban或者oozie進(jìn)行任務(wù)的調(diào)度;監(jiān)控任務(wù)調(diào)度頁面。
12、Hive中split、coalesce及collect_list函數(shù)的用法(可舉例)?
????·split將字符串轉(zhuǎn)化為數(shù)組,即:split('a,b,c,d' , ',') ==> ["a","b","c","d"]。
????·coalesce(T v1, T v2, …)返回參數(shù)中的第一個(gè)非空值;如果所有值都為 NULL,那么返回NULL。
????·collect_list列出該字段所有的值,不去重 => select collect_list(id) from table。
13、Count(Distinct) 去重統(tǒng)計(jì)
????數(shù)據(jù)量小的時(shí)候無所謂,數(shù)據(jù)量大的情況下,由于COUNT DISTINCT操作需要用一個(gè)Reduce Task來完成,這一個(gè)Reduce需要處理的數(shù)據(jù)量太大,就會(huì)導(dǎo)致整個(gè)Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換
????盡量避免笛卡爾積,join的時(shí)候不加on條件,或者無效的on條件,Hive只能使用1個(gè)reducer來完成笛卡爾積
14、Group By
????????默認(rèn)情況下,Map階段同一Key數(shù)據(jù)分發(fā)給一個(gè)reduce,當(dāng)一個(gè)key數(shù)據(jù)過大時(shí)就傾斜了。并不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端進(jìn)行部分聚合,最后在Reduce端得出最終結(jié)果。
?開啟Map端聚合參數(shù)設(shè)置
?(1) 是否在Map端進(jìn)行聚合,默認(rèn)為True hive.map.aggr = true
(2) 在Map端進(jìn)行聚合操作的條目數(shù)目 hive.groupby.mapaggr.checkinterval = 100000?
(3)有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡(默認(rèn)是false) hive.groupby.skewindata = true
????????當(dāng)選項(xiàng)設(shè)定為true,生成的查詢計(jì)劃會(huì)有兩個(gè)MR Job。第一個(gè)MR Job中,Map的輸出結(jié)果會(huì)隨機(jī)分布到Reduce中,每個(gè)Reduce做部分聚合操作,并輸出結(jié)果,這樣處理的結(jié)果是相同的Group By Key有可能被分發(fā)到不同的Reduce中,從而達(dá)到負(fù)載均衡的目的;
????????第二個(gè)MR Job再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照Group By Key分布到Reduce中(這個(gè)過程可以保證相同的Group By Key被分布到同一個(gè)Reduce中),最后完成最終的聚合操作。
14、Hive有哪些方式保存元數(shù)據(jù),各有哪些特點(diǎn)?
????????元數(shù)據(jù):Metastore?包括:表名、表所屬的數(shù)據(jù)庫(kù)(默認(rèn)是default)、表的擁有者、列/分區(qū)字段、表的類型(是否是外部表)、表的數(shù)據(jù)所在目錄等;默認(rèn)存儲(chǔ)在自帶的derby數(shù)據(jù)庫(kù)中,推薦使用MySQL存儲(chǔ)Metastore?
????1)、內(nèi)置derby存儲(chǔ)
????????不同路徑啟動(dòng)hive,每一個(gè) hive 擁有一套自己的元數(shù)據(jù),無法共享hive服務(wù)和metastore服務(wù)運(yùn)行在同一個(gè)進(jìn)程中,derby服務(wù)也運(yùn)行在該進(jìn)程中.內(nèi)嵌模式使用的是內(nèi)嵌的Derby數(shù)據(jù)庫(kù)來存儲(chǔ)元數(shù)據(jù),也不需要額外起Metastore服務(wù)。
????????在哪個(gè)目錄下啟動(dòng),就會(huì)在對(duì)應(yīng)的目錄下生成 derby.log 和 metastore.db,只有在此目錄下再次啟動(dòng)才可以繼續(xù)使用上次的元數(shù)據(jù)庫(kù)。
????????這個(gè)是默認(rèn)的,配置簡(jiǎn)單,但是一次只能一個(gè)客戶端連接,適用于用來實(shí)驗(yàn),不適用于生產(chǎn)環(huán)境。
????2)、本地模式(Local):本地安裝mysql 替代derby存儲(chǔ)元數(shù)據(jù);
????????不再使用內(nèi)嵌的Derby作為元數(shù)據(jù)的存儲(chǔ)介質(zhì),而是使用其他數(shù)據(jù)庫(kù)比如MySQL來存儲(chǔ)元數(shù)據(jù)。hive服務(wù)和metastore服務(wù)運(yùn)行在同一個(gè)進(jìn)程中,mysql是單獨(dú)的進(jìn)程,可以同一臺(tái)機(jī)器,也可以在遠(yuǎn)程機(jī)器上。
????????這種方式是一個(gè)多用戶的模式,運(yùn)行多個(gè)用戶client連接到一個(gè)數(shù)據(jù)庫(kù)中。這種方式一般作為公司內(nèi)部同時(shí)使用Hive。每一個(gè)用戶必須要有對(duì)MySQL的訪問權(quán)利,即每一個(gè)客戶端使用者需要知道MySQL的用戶名和密碼才行。
????????3)、遠(yuǎn)程模式(Remote): 遠(yuǎn)程安裝mysql 替代derby存儲(chǔ)元數(shù)據(jù);
????????Hive服務(wù)和metastore在不同的進(jìn)程內(nèi),可能是不同的機(jī)器,該模式需要將hive.metastore.local設(shè)置為false,將hive.metastore.uris設(shè)置為metastore服務(wù)器URL遠(yuǎn)程元存儲(chǔ)需要單獨(dú)起metastore服務(wù),然后每個(gè)客戶端都在配置文件里配置連接到該metastore服務(wù)。將metadata作為一個(gè)單獨(dú)的服務(wù)進(jìn)行啟動(dòng)。各種客戶端通過beeline來連接,連接之前無需知道數(shù)據(jù)庫(kù)的密碼。
????????僅連接遠(yuǎn)程的mysql并不能稱之為“遠(yuǎn)程模式”,是否遠(yuǎn)程指的是metastore和hive服務(wù)是否在同一進(jìn)程內(nèi)。