鎖屏面試題百日百刷,每個工作日堅持更新面試題。請看到最後就能獲取你想要的,接下來的是今日的面試題: 1.解釋一下布隆過濾器原理 在日常生活中,包括在設計電腦軟體時,我們經常要判斷一個元素是否在一個集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 ...
鎖屏面試題百日百刷,每個工作日堅持更新面試題。請看到最後就能獲取你想要的,接下來的是今日的面試題:
1.解釋一下布隆過濾器原理
在日常生活中,包括在設計電腦軟體時,我們經常要判斷一個元素是否在一個集合中。比如在字處理軟體中,需要檢查一個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲里,一個網址是否被訪問過等等。最直接的方法就是將集合中全部的元素存在電腦中,遇到一個新元素時,將它和集合中的元素直接比較即可。一般來講,電腦中的集合是用哈希表(hash table)來存儲的。它的好處是快速準確,缺點是費存儲空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,哈希表存儲效率低的問題就顯現出來了。比如說,一個象 Yahoo,Hotmail 和 Gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自發送垃圾郵件的人(spamer)的垃圾郵件。一個辦法就是記錄下那些發垃圾郵件的 email地址。由於那些發送者不停地在註冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網路伺服器。如果用哈希表,每存儲一億個 email 地址, 就需要 1.6GB 的記憶體(用哈希表實現的具體辦法是將每一個 email 地址對應成一個八位元組的信息指紋googlechinablog.com/2006/08/blog-post.html,然後將這些信息指紋存入哈希表,由於哈希表的存儲效率一般只有 50%,因此一個 email 地址需要占用十六個位元組。
一億個地址大約要 1.6GB, 即十六億位元組的記憶體)。因此存貯幾十億個郵件地址可能需要上百 GB 的記憶體。除非是超級電腦,一般伺服器是無法存儲的。
布隆過濾器只需要哈希表 1/8 到 1/4 的大小就能解決同樣的問題。
Bloom Filter是一種空間效率很高的隨機數據結構,它利用位數組很簡潔地表示一個集合,並能判斷一個元素是否屬於這個集合。Bloom Filter的這種高效是有一定代價的:在判斷一個元素是否屬於某個集合時,有可能會把不屬於這個集合的元素誤認為屬於這個集合(false positive)。因此,Bloom Filter不適合那些“零錯誤”的應用場合。
而在能容忍低錯誤率的應用場合下,Bloom Filter通過極少的錯誤換取了存儲空間的極大節省。
下麵我們具體來看Bloom Filter是如何用位數組表示集合的。初始狀態時,Bloom Filter是一個包含m位的位數組,每一位都置為0。
為了表達S={x1, x2,…,xn}這樣一個n個元素的集合,Bloom Filter使用k個相互獨立的哈希函數(Hash Function), 它們分別將集合中的每個元素映射到{1,…,m}的範圍中。對任意一個元素x,第i個哈希函數映射的位置hi(x)就會被置 為1(1≤i≤k)。註意,如果一個位置多次被置為1,那麼只有第一次會起作用,後面幾次將沒有任何效果。在下圖中, k=3,且有兩個哈希函數選中同一個位置(從左邊數第五位)。
在判斷y是否屬於這個集合時,我們對y應用k次哈希函數,如果所有hi(y)的位置都是1(1≤i≤k),那麼我們就認為y是集合中的元素,否則就認為y不是集合中的元素。下圖中y1就不是集合中的元素。y2或者屬於這個集合,或者剛好是一個false positive。
· 為了add一個元素,用k個hash function將它hash得到bloom filter中k個bit位,將這k個bit位置1。
· 為了query一個元素,即判斷它是否在集合中,用k個hash function將它hash得到k個bit位。若這k bits全為1,則此元素在集合中;若其中任一位不為1,則此元素比不在集合中(因為如果在,則在add時已經把對應的k個bits位置為1)。
· 不允許remove元素,因為那樣的話會把相應的k個bits位置為0,而其中很有可能有其他元素對應的位。因此remove會引入false negative,這是絕對不被允許的。
布隆過濾器決不會漏掉任何一個在黑名單中的可疑地址。但是,它有一條不足之處,也就是它有極小的可能將一個不在黑名單中的電子郵件地址判定為在黑名單中,因為有可能某個好的郵件地址正巧對應個八個都被設置成一的二進位位。好在這種可能性很小,我們把它稱為誤識概率。
布隆過濾器的好處在於快速,省空間,但是有一定的誤識別率,常見的補救辦法是在建立一個小的白名單,存儲那些可能別誤判的郵件地址。
2.如何實現HBase的二級索引?
方案一: 通常情況下,較原生方式,我們可以採用ES或者Solr來實現hbase的二級索引的操作, 當用戶要寫入數據時候, 基於hbase的observer協處理器攔截下來, 使用es或者Solr來構建hbase的索引數據, 這樣當查詢hbase中數據時候, 可以先去ES中查詢到對應的數據, 然後根據結果, 在從hbase中獲取最終的完整的結果
方案二: 基於Phoenix實現, Phoenix是一款基於hbase的SQL客戶端, 可以使用SQL的方式來操作hbase, 同時為了提升整體的查詢性能, Phoenix中提供了各種索引(全局索引, 本地索引, 覆蓋索引以及函數索引), 這些索引都是基於Hbase的協處理器(主要是ObServer協處理器)而實現的, 二基於索引的查詢方案, 也是Phoenix實現hbase二級索引的方式
3.Hbase的storeFile(compact)合併機制是什麼?
compact合併機制:
指的memStore中不斷進行flush刷新操作, 就會產生多個storeFile的文件, 當storeFile的文
件達到一定閾值後, 就會觸發compact的合併機制, 將多個storeFile合併為一個大的HFile文件
閾值: 達到3個及以上
整個合併過程分為兩大階段:
minor :
作用: 將多個小的storeFile合併為一個較大的Hfile操作
閾值: 達到3個及以上
註意: 此合併過程, 僅僅將多個合併為一個, 對數據進行排序操作, 如果此時數據有過期, 或者有標記為刪除數據, 此時不做任何的處理 (類似於 記憶體合併中基礎型)
所以說, 此合併操作, 效率比較高
major:
作用: 將較大的HFile 和 之前的大的Hfile進行合併形成一個更大的Hfile文件 (全局合併)
閾值: 預設 7天
註意: 此合併過程, 會將那些過期的數據, 或者已經標記刪除的數據, 在這次合併中, 全部
都清除掉,由於這是一種全局合併操作, 對性能影響比較大, 在實際生產中, 建議 關閉掉自動合併, 採用手動觸發的方案
4.Hbase的flush刷新機制?
flush刷新機制(溢寫合併機制):
流程: 客戶端不斷將數據寫入到memStore記憶體中, 當記憶體中數據達到一定閾值後, 需要
將數據溢寫刷新的HDFS中 形成一個storeFile文件
閾值: 128M 或者 1小時 滿足了那個都會觸發flush機制
內部詳細流程: hbase 2.0架構 以上流程
-
客戶端不斷向memStore中寫入數據, 當memStore只數據達到閾值後, 就會啟動flush操作
-
首先hbase會先關閉掉當前這個已經達到閾值的記憶體空間, 然後開啟一個新的memStore的空間,用於繼續寫入工作
-
將這個達到閾值的記憶體空間數據放入到 記憶體隊列中, 此隊列的特性是只讀, 在hbase 2.0架構中, 可以設置此隊列的數據儘可能晚的刷新到HDFS中, 當這個隊列中數據達到某個閾值後(記憶體不足), 這個時候觸發flush刷新操作 (隊列中可能存儲了多個memStore的數據)
-
flush線程會將隊列中所有的數據全部讀取出來, 然後對數據進行排序合併操作, 將合併後數據存儲到HDFS中, 形成一個storeFile的文件
註意: 在 hbase2.0以下的架構中, 不存在推遲刷新功能, 同樣也不存在 合併數據的
操作當memStore數據達到閾值後, 放入到隊列中, 專門有一個flush刷新監控隊列, 一旦有數據直接刷新到HDFS上
註意說明:
hbase 2.0 只是提供了基於記憶體的合併功能, 但是預設情況下 不開啟的, 所以 在預設情況
下 整個flush機制基本和2.0以下的版本是一致的, 但是一旦開啟了, 就是剛剛描述流程
合併方案: 三種基礎型(basic): 直接將多個memStore數據合併在一起直接刷新到HDFS上,如果數據存在過期的數據, 或者是已經標記為刪除的數據, 基礎型不做任何處理
饑渴型(eager): 在將多個memStore合併的過程中, 積極判斷數據是否存在過期, 或者是否已經標記刪除, 如果有, 直接過濾掉這些標記刪除和過期的數據即可
適應性(adaptive): 檢查數據是否有過期數據, 如果過期數據量達到一定閾值後, 就會自動使
用饑渴型, 否則就使用基礎型
5.如何解決hbase中數據熱點問題?
所謂數據熱點, 指的是大量的數據寫到hbase的某一個或者某幾個region中, 導致其餘的region沒有數據, 其他region對應regionServer的節點承受了大量的併發請求, 此時就出現了熱點問題
解決方案: 通過預分區和設計良好的rowkey來解決
1)加鹽處理(加隨機數) : 可以在rowkey前面動態添加一些隨機數, 從而保證數據可以均勻落在不同region中
n 基本保證數據落在不同region
n 將相關性比較強的數據分散在不同的額region中, 導致查詢的效率有一定降低
2)hash處理: 根據rowkey計算其hash值, 在rowkey前面hash計算值即可 (MD5 HASH)
n 讓相關性比較強的數據可以被放置到同一個region中
n 如果相關數據比較多, 依然會導致熱點問題
3)反轉策略: 比如說手機號反轉 或者 時間戳的反轉
n 好處: 基本保證數據落在不同region
n 弊端: 將相關性比較強的數據分散在不同的region中, 導致查詢的效率有一定降低
全部內容在git上,瞭解更多請點我頭像或到我的主頁去獲得,謝謝