以下大部分題目是從網(wǎng)上搜索得來,答案是筆者給的碟绑,若有錯誤俺猿,煩請指出茎匠,謝謝。
1 每天百億數(shù)據(jù)存入HBase押袍,如何保證數(shù)據(jù)的存儲正確和在規(guī)定的時間里全部錄入完畢诵冒,不殘留數(shù)據(jù)
答:看到這個題目的時候我們要思考的是它在考查什么知識點?
我們來看看要求:
1)百億數(shù)據(jù):證明數(shù)據(jù)量非常大
2)存入HBase:證明是跟HBase的寫入數(shù)據(jù)有關(guān)
3)保證數(shù)據(jù)的正確:要設(shè)計正確的數(shù)據(jù)結(jié)構(gòu)保證正確性
4)在規(guī)定時間內(nèi)完成:對存入速度是有要求的
那么針對以上的四個問題我們來一一分析
1)數(shù)據(jù)量百億條汽馋,什么概念呢圈盔?假設(shè)一整天60x60x24 = 86400秒都在寫入數(shù)據(jù)驱敲,那么每秒的寫入條數(shù)高達100萬條,HBase當(dāng)然是支持不了每秒百萬條數(shù)據(jù)的众眨,所以這百億條數(shù)據(jù)可能不是通過實時地寫入娩梨,而是批量地導(dǎo)入。批量導(dǎo)入推薦使用BulkLoad方式(推薦閱讀:Spark之讀寫HBase)颂龙,性能是普通寫入方式幾倍以上
2)存入HBase:普通寫入是用JavaAPI put來實現(xiàn)纽什,批量導(dǎo)入推薦使用BulkLoad
3)保證數(shù)據(jù)的正確:這里需要考慮RowKey的設(shè)計稿湿、預(yù)建分區(qū)和列族設(shè)計等問題
4)在規(guī)定時間內(nèi)完成也就是存入速度不能過慢押赊,并且當(dāng)然是越快越好,使用BulkLoad
2 HBase 如何給WEB前端提供接口來訪問涕俗?
答:使用JavaAPI來編寫WEB應(yīng)用神帅;使用HBase提供的RESTful接口
3 HBase優(yōu)化方法
答:優(yōu)化手段主要有以下四個方面
1)減少調(diào)整
減少調(diào)整這個如何理解呢找御?HBase中有幾個內(nèi)容會動態(tài)調(diào)整绍填,如region(分區(qū))栖疑、HFile,所以通過一些方法來減少這些會帶來I/O開銷的調(diào)整
- Region
如果沒有預(yù)建分區(qū)的話卿闹,那么隨著region中條數(shù)的增加萝快,region會進行分裂揪漩,這將增加I/O開銷,所以解決方法就是根據(jù)你的RowKey設(shè)計來進行預(yù)建分區(qū)蚌铜,減少region的動態(tài)分裂 - HFile
HFile是數(shù)據(jù)底層存儲文件嫩海,在每個memstore進行刷新時會生成一個HFile,當(dāng)HFile增加到一定程度時审葬,會將屬于一個region的HFile進行合并奕谭,這個步驟會帶來開銷但不可避免血柳,但是合并后HFile大小如果大于設(shè)定的值,那么HFile會重新分裂膝宁。為了減少這樣的無謂的I/O開銷根吁,建議估計項目數(shù)據(jù)量大小击敌,給HFile設(shè)定一個合適的值
2)減少啟停
數(shù)據(jù)庫事務(wù)機制就是為了更好地實現(xiàn)批量寫入,較少數(shù)據(jù)庫的開啟關(guān)閉帶來的開銷圣蝎,那么HBase中也存在頻繁開啟關(guān)閉帶來的問題。
- 關(guān)閉Compaction组去,在閑時進行手動Compaction
因為HBase中存在Minor Compaction和Major Compaction步淹,也就是對HFile進行合并缭裆,所謂合并就是I/O讀寫,大量的HFile進行肯定會帶來I/O開銷辛燥,甚至是I/O風(fēng)暴缝其,所以為了避免這種不受控制的意外發(fā)生内边,建議關(guān)閉自動Compaction,在閑時進行compaction - 批量數(shù)據(jù)寫入時采用BulkLoad
如果通過HBase-Shell或者JavaAPI的put來實現(xiàn)大量數(shù)據(jù)的寫入嘴高,那么性能差是肯定并且還可能帶來一些意想不到的問題和屎,所以當(dāng)需要寫入大量離線數(shù)據(jù)時建議使用BulkLoad
3)減少數(shù)據(jù)量
雖然我們是在進行大數(shù)據(jù)開發(fā)柴信,但是如果可以通過某些方式在保證數(shù)據(jù)準(zhǔn)確性同時減少數(shù)據(jù)量,何樂而不為呢潜沦?
- 開啟過濾线罕,提高查詢速度
開啟BloomFilter钞楼,BloomFilter是列族級別的過濾袄琳,在生成一個StoreFile同時會生成一個MetaBlock,用于查詢時過濾數(shù)據(jù) - 使用壓縮:一般推薦使用Snappy和LZO壓縮
4)合理設(shè)計
在一張HBase表格中RowKey和ColumnFamily的設(shè)計是非常重要刻蟹,好的設(shè)計能夠提高性能和保證數(shù)據(jù)的準(zhǔn)確性
-
RowKey設(shè)計:應(yīng)該具備以下幾個屬性
- 散列性:散列性能夠保證相同相似的rowkey聚合嘿辟,相異的rowkey分散红伦,有利于查詢
簡短性:rowkey作為key的一部分存儲在HFile中昙读,如果為了可讀性將rowKey設(shè)計得過長,那么將會增加存儲壓力
唯一性:rowKey必須具備明顯的區(qū)別性
-
業(yè)務(wù)性:舉些例子
- 假如我的查詢條件比較多唠叛,而且不是針對列的條件沮稚,那么rowKey的設(shè)計就應(yīng)該支持多條件查詢
- 如果我的查詢要求是最近插入的數(shù)據(jù)優(yōu)先蕴掏,那么rowKey則可以采用叫上Long.Max-時間戳的方式囚似,這樣rowKey就是遞減排列
-
列族的設(shè)計
列族的設(shè)計需要看應(yīng)用場景- 多列族設(shè)計的優(yōu)劣
- 優(yōu)勢:HBase中數(shù)據(jù)時按列進行存儲的,那么查詢某一列族的某一列時就不需要全盤掃描徐伐,只需要掃描某一列族办素,減少了讀I/O性穿;其實多列族設(shè)計對減少的作用不是很明顯雷滚,適用于讀多寫少的場景
- 劣勢:降低了寫的I/O性能。原因如下:數(shù)據(jù)寫到store以后是先緩存在memstore中呆万,同一個region中存在多個列族則存在多個store商源,每個store都一個memstore牡彻,當(dāng)其實memstore進行flush時庄吼,屬于同一個region
的store中的memstore都會進行flush严就,增加I/O開銷
- 多列族設(shè)計的優(yōu)劣
4 HBase中RowFilter和BloomFilter原理
答:
1)RowFilter原理簡析
RowFilter顧名思義就是對rowkey進行過濾盈蛮,那么rowkey的過濾無非就是相等(EQUAL)抖誉、大于(GREATER)袒炉、小于(LESS)我磁,大于等于(GREATER_OR_EQUAL),小于等于(LESS_OR_EQUAL)和不等于(NOT_EQUAL)幾種過濾方式芋哭。Hbase中的RowFilter采用比較符結(jié)合比較器的方式來進行過濾减牺。
比較器的類型如下:
- BinaryComparator
- BinaryPrefixComparator
- NullComparator
- BitComparator
- RegexStringComparator
- SubStringComparator
例子:
Filter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,
new BinaryComparator(Bytes.toBytes(rowKeyValue)));
Scan scan = new Scan();
scan.setFilter(rowFilter)
...
在上面例子中存谎,比較符為EQUAL既荚,比較器為BinaryComparator
2)BloomFilter原理簡析
- 主要功能:提供隨機讀的性能
- 存儲開銷:BloomFilter是列族級別的配置稚失,一旦表格中開啟BloomFilter,那么在生成StoreFile時同時會生成一份包含BloomFilter結(jié)構(gòu)的文件MetaBlock恰聘,所以會增加一定的存儲開銷和內(nèi)存開銷
- 粒度控制:ROW和ROWCOL
- BloomFilter的原理
簡單說一下BloomFilter原理- 內(nèi)部是一個bit數(shù)組诫钓,初始值均為0
- 插入元素時對元素進行hash并且映射到數(shù)組中的某一個index菌湃,將其置為1惧所,再進行多次不同的hash算法下愈,將映射到的index置為1势似,同一個index只需要置1次履因。
- 查詢時使用跟插入時相同的hash算法栅迄,如果在對應(yīng)的index的值都為1毅舆,那么就可以認(rèn)為該元素可能存在憋活,注意,只是可能存在
- 所以BlomFilter只能保證過濾掉不包含的元素盐欺,而不能保證誤判包含
- 設(shè)置:在建表時對某一列設(shè)置BloomFilter即可
5 HBase的導(dǎo)入導(dǎo)出方式
答:
1)導(dǎo)入:bin/hbase org.apache.hadoop.hbase.mapreduce.Driver import 表名 路徑
路徑:來源
- 本地路徑 file:///path
- HDFS hdfs://cluster1/path
2)導(dǎo)出:bin/hbase org.apache.hadoop.hbase.mapreduce.Driver export 表名 路徑
路徑:目的地
- 本地路徑 file:///path
- HDFS hdfs://cluster1/path
6 Region如何預(yù)建分區(qū)
預(yù)建分區(qū)的方法很簡單,有以下兩種
- hbase shell
- create 't1', 'f1',SPLITS=>['10','20','30']
- create 't1','f1',SPLITS_FILE =>'splits.txt'
- Java API
- 創(chuàng)建一個byte[][] splitKeys = {{1,2,3},{4,5,6}}
- admin.createTable(tableDesc,splitKeys)
預(yù)建分區(qū)的難點在于key如何設(shè)計粉洼,分多少個和如何分的問題安拟,那么下面我們就對這三個問題一一分析:
1)如何設(shè)計Key糠赦,我們設(shè)計Key的原則就是要讓Key足夠散列拙泽,但同時又要保持Key的長度適中顾瞻,這里給出一個方法,樣本取自Spark讀寫HBase中的數(shù)據(jù)
01055HAXMTXG10100001@KEY_VOLTAGE_TEC_PWR@1.60@1.62@1.75@1.55
我想要的rowKey是:01055HAXMTXG10100001KEY_VOLTAGE_TEC_PWR
但是很明顯這樣肯定是不會足夠散列的蕴纳,那么我們可以對上面那個Key進行MD5,然后取前面三個字符(為了更加散列喇潘,可以取1,3,5或者其他組合)再加上原來的Key
DigestUtils.md5Hex(x(0)+x(1)).substring(0,3)+x(0)+x(1)
這樣的話我們就可以得到足夠散列的數(shù)據(jù)颖低,并且MD5取得的是十六進制字符串,那么Key的范圍就是(0,0,0)至(f莺戒,f从铲,f)
2)分多少個:這個需要我們就要根據(jù)我們集群規(guī)模來進行安排阱扬,假設(shè)我們有5regionServer麻惶,每個regionServer有20個region窃蹋,那么總共就是100個region碎乃,最后的工作就是將000-fff分成100份恰梢。
3)如何分:就是生成一個byte[][]嵌言,用于創(chuàng)建表格,這個我將會些一篇另外的博文來介紹苛白,敬請期待
7 HRegionServer宕機如何處理购裙?
1)ZooKeeper會監(jiān)控HRegionServer的上下線情況,當(dāng)ZK發(fā)現(xiàn)某個HRegionServer宕機之后會通知HMaster進行失效備援薇芝;
2)該HRegionServer會停止對外提供服務(wù),就是它所負(fù)責(zé)的region暫時停止對外提供服務(wù)
3)HMaster會將該HRegionServer所負(fù)責(zé)的region轉(zhuǎn)移到其他HRegionServer上峭状,并且會對HRegionServer上存在memstore中還未持久化到磁盤中的數(shù)據(jù)進行恢復(fù)
4)這個恢復(fù)的工作是由WAL重播來完成优床,這個過程如下:
- wal實際上就是一個文件,存在/hbase/WAL/對應(yīng)RegionServer路徑下
- 宕機發(fā)生時移层,讀取該RegionServer所對應(yīng)的路徑下的wal文件,然后根據(jù)不同的region切分成不同的臨時文件recover.edits
- 當(dāng)region被分配到新的RegionServer中,RegionServer讀取region時會進行是否存在recover.edits晦溪,如果有則進行恢復(fù)
8 HBase簡單讀寫流程
讀:
找到要讀取數(shù)據(jù)的region所在的RegionServer,然后按照以下順序進行讀戎廴狻:先去BlockCache讀取,若BlockCache沒有磷籍,則到Memstore讀取,若MemStore中沒有,則到HFile中讀取强法。
寫:
找到要寫入數(shù)據(jù)的region所在的RegionServer闰歪,然后將數(shù)據(jù)先寫到WAL中,然后再將數(shù)據(jù)寫到MemStore等待刷新,回復(fù)客戶端寫入完成。
9 HBase和Hive的對比
HBase | Hive | |
---|---|---|
類型 | 列式數(shù)據(jù)庫 | 數(shù)據(jù)倉庫 |
內(nèi)部機制 | 數(shù)據(jù)庫引擎 | MapReduce |
增刪改查 | 都支持 | 只支持導(dǎo)入和查詢 |
Schema | 只需要預(yù)先定義列族,不需要具體到列列可以動態(tài)修改 | 需要預(yù)先定義表格 |
應(yīng)用場景 | 實時 | 離線處理 |
特點 | 以K-V形式存儲 | 類SQL |
10 HBase首次讀寫流程
- Client從ZooKeeper中讀取hbase:meta表
- Client從hbase:meta中獲取想要操作的region的位置信息膘掰,并且將hbase:meta緩存在Client端,用于后續(xù)的操作
- 當(dāng)一個RegionServer宕機而執(zhí)行重定位之后,Client需要重新獲取新的hase:meta信息進行緩存
11 HBase搭建過程中需要注意什么惠豺?
hbase-env.sh的配置
- 是否使用外部ZooKeeper戒财,這個一般使用Hadoop集群的ZooKeeper集群即可孝扛。
- HBASE_MANAGES_ZK=false
hbase-site.sh的配置
- hbase.zookeeper.quorum="host1:2181,host2:2181"