hbase分頁的功能實現

hbase分頁功能的幾種實現方案。

分頁功能是線上系統的常用功能,對hbase,有以下幾個方案可以選擇(拋磚引玉)。

假設要查第N頁,1頁大小爲M

1 client分頁,scan查到N*M條,過濾掉N*(M--1)條,返回M條。對於M,N較小時比較適合。

2 自定義Filter,該filter可以傳遞offset(server端需要過濾的記錄條數),在server端分頁,注意,跨不同的region時需要重新計算該offset。

例子:第1個HRegion的請求傳遞該值爲N*M-1,表示需要在server端過濾掉N*M--1條記錄。當第1個HRegion返回時,需要知道該次請求在server端實際過濾了多少條記錄(假設爲Size條),

第2個HRegion的請求傳遞該值爲(N*(M-1))-Size。

3 緩存上次分頁查詢的最後一條,下次分頁查詢從這條(不包含)開始查。

4 查詢條件固定的話,定時任務彙總表。

5 結合其他框架想辦法。

少量數據的推薦使用的,使用了方案1。

————————————————————————————————————————————————

1、PG數據庫(包括其他一些關係型數據庫)據說在單表記錄數超過100w時就會變得很慢。解決方法是分表,或者遷移到專注於處理海量數據的NoSQL。——我們選擇了後者。

2、拿到HBase我做的第一件工作是性能測試,主要驗證了兩件事:

a)HBase對數據操作的響應速度與當前表中的數據量無關,但是與數據的split以及本地緩存等配置項有很大關係。 比如rowKey的合理設計,使相關數據相鄰存放;比如使用scan時setCatch(num)方法中num的取值。

b)HBase對數據操作的響應在毫秒級,滿足我們前端顯示的需要。

3、分頁查詢時,前端需要請求記錄總數,用於計算總頁數。然後再請求每頁的內容,請求每頁內容時兩個主要參數(start,limit)。比如0,20;肯定是第一頁數據,從第0條開始,請求20條數據。比如20,20;這就是第二頁,從第20條開始請求20條數據,以此類推。

4、HBase獲得記錄總數很困難,瀏覽所有數據倒好說,我可以在數據庫中存一下當前數據庫中記錄的總數。但如果是搜索功能怎麼辦?如果滿足條件的記錄有1億條,我總不能先遍歷一邊記個數啊……聽說在MapReduce層可以有辦法完成總數的統計,以後有機會接觸到我會研究一下寫出來的。

5、既然HBase無法獲得記錄總數,那就採用那種不需要總頁數的分頁方式唄。比如微博、某些論壇那樣,前端根本不去獲取總記錄數,只要知道後面還有沒有數據就可以了,提供給用戶“下一頁”,或“下n頁”的功能。我糾結與記錄總數主要是因爲之前UI控件的限制……

6、上述的分頁展現形式類似於:用戶瀏覽數據首頁時,選頁欄顯示 1 2 3 4 5 6.....,當用戶點到第5頁時,選頁欄顯示 ... 3 4 5 6 7 8 ....。不提供用戶隨意輸頁號,也不提供最後一頁的按鈕。

7、HBase端處理時,肯定要用到scan,然後調用setFilter方法,使用pageFilter限制一下返回的記錄條數。

8、我還設計了一種緩存機制,綁定每個登陸的用戶,在用戶瀏覽記錄時,每個一定記錄數(比如100條),記錄一下這條記錄的rowKey。這樣在用戶請求第100條到120條記錄這一頁時我的scan可以設置startRowKey爲我剛纔緩存的那個。這樣可以避免把前面所有的數據scan出來後再逐條遍歷去數數。

9、我使用了Spring最新提供的Spring Hadoop框架,這個框架爲我管理了幾乎所有的HBase Client資源,非常好用!我不用在scan完後手動調用close方法,我不用自己維護一個TablePool每次去選表,我不用自己創建Configuration實例,我不用自己去寫將一條記錄映射回實例的接口(實現當然還要自己寫……,只要實現了RowMapper接口就可以了)。


這只是我目前在項目中自己摸索並使用的一種可行方案。

接下來打算補充一些關於搜素功能的實現思路,比如同時按時間範圍、文件名、分類名、權限幾個條件的搜索~

以及二級索引的實現方式,數據記錄id自增的實現,數據定期定量刪除等。

發佈了120 篇原創文章 · 獲贊 6 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章