HBase系列之-分頁查詢研究

1.前言

如果是利用關係型數據庫做分頁查詢想必很簡單,例如:Mysql Oracle這種常用的關係型數據庫,利用MongoDB做分頁查詢也比較簡單,有現成的API可以調用,但是HBase這種分頁之前沒有接觸過,看了一些資料也沒有想象中的方便,這裏寫這篇博客純粹相當於一次HBase分頁查詢的探索。並實際運用到項目。

衆所周知,hbase通過scan來掃描表,通過startKey,stopKey來確定範圍,hbase官方提供了一個PageFilter來支持一次scan可以返回多少條數據即每頁的行數。假如一頁是10條,這樣是第一頁還好,但是第二頁呢,如果不改變PageFilter的pageSize,那返回的還是第一頁的數據,如果改變pageSize爲20,則返回了第一頁10條多餘的數據,在客戶端要過濾掉,性能不好。那怎麼辦呢,方法就是在查詢下一頁時,指定下一頁的startKey,這樣PageFilter每次就不會返回多餘的記錄,所以我們只需要關心startKey的獲取,那現在問題是,怎麼得到下一頁的startKey(即下一頁第一行的rowkey)呢?

2.startKey獲取

  1. 上一頁的最後一行記錄的rowkey作爲下一頁的startKey。
  2. 在每次scan時多取一條記錄,即把下一頁第一條行頁取出來,把該行的rowkey做爲下一頁的startKey。

不管用一還是二,都要注意,hbase scan時是包含startKey的,如果是採用第一種,則要在記錄多取一條,排除第一條。第二種頁是多取一條,但是排除最後一條,用來做下一頁的startKey。還有需要注意的是在計算是否有下一頁時,可以根據返回的條數來判斷。
startKey怎麼取沒有問題了。但是怎麼存儲呢,有同學可能會想到存到session,但是如果你的服務是rest api型的,就沒有session的概念了。那還有兩種選擇:

  1. 是存到客戶端,讓客戶端每次請求時把startKey再傳回來,這樣需要依賴客戶端,如果客戶端是遠程,或者是開放平臺的情況下,可能不合適。

  2. 存在服務端,存在服務端需要注意併發訪問的情況。比如scan同一個表,一個訪問第2頁,一個訪問第3頁,服務端就需要對每一個table的scan 存每一頁的startKey,需要爲同一個查詢條件包含pageSize,因爲pageSize不一樣,startKey也會不一樣,在服務crash情況下,從起後都從第一頁開始。

但是上面的方式都存在問題,如果是按照順序訪問可以正常使用,但是頁數跨度比較大,還是會有性能的問題。上面只能算是兩種解決方案。特殊操作性能也不能保證。除非只提供上一頁下一頁的按鈕操作頁面查詢,這樣的話和前端配合可以快速拿到數據。而且,最好是前端存儲startKey,避免後端做很多性能浪費操作。

3.僞分頁

我考慮的場景是,通常hbase表都是上億甚至是百億的,客戶也不可能說點擊所有的頁面來查看數據,這樣下來客戶的手都要廢了,我想到的是利用定時任務來緩存最新的數據至於數據量自己可以控制,通過緩存做分頁不比HBase香,但是這種數據庫如果按照時間維度來查詢的話還是設置具體的算法,來給客戶展示數據,客戶如果要按照指定的頁數來訪問數據,這種辦法可以給用戶指出性能的瓶頸,如果用戶可以接受訪問速度很慢的情況,我們就按照實際的分頁給出數據。

代碼操作各位自己研究,我自己先嚐試看看能不能總結到更好的辦法,這上面總結的辦法僅供參考,博主也是剛剛項目實際運用HBase做分頁,不足之處,還請批評指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章