目前想採用的方案是使用HBse + geohash
HBase要想能很快的搜尋,就必須把row key設計好,但從之前的例子,我們直接使用經度+緯度 或是 緯度+經度當成row key,都無法達成我們想要下列的目標
1.查詢空間內彼此接近的點,在硬碟上的儲存位置也是彼此接近
2.回應查詢時,回傳盡可能少的點
也許我們可以實作一個coprocessor,把多餘的經度或緯度的資料濾掉,但這個不是理想的方式,因為還是需要先讀出資料,先避開無關的資料不去讀取,才是最好的方式。
所以現在的問題是,如何把經度和緯度整合起來變成一個好的row key,這時我們可使用geohash
geohash的介紹可參考
http://www.cnblogs.com/LBSer/p/3310455.html
http://charlee.li/geohash-intro.html
geohash可把經緯度編碼成一組字串,編碼時可指定字元長度,最長12字元。因為geohash的編碼把經緯度當成一組在地圖上的矩形區域,所以有可能多個相近經緯度,其geohash的值在同一區域,當然編碼的長度越長則越精準。

用geohash來編碼經緯度後當作row key後,我們可以用scan的方式查找geo hash首碼類似的點,這樣就可以找到該近緯度附近的點了,也就實現了我們之前的目標一,但是目標二還沒有完全達到
因為如果geo hash的精度過低,則可能會掃描出過多的點。如下圖,首碼掃描前6碼及前7碼,正常來說,掃描前6碼回傳的資料會比較多。

另一種情況是,雖然只是在附近幾個區域,但是首碼相同的情況卻不多,如下圖,中間區塊的7碼geohase,和上方區塊相比,只有前2碼相同。

由此來看,只是單純scan 固定首碼不能達到查詢空間內彼此接近的點這個目標,比較好的方式是先把目標轉成geohash,再去scan 目標周遭九宮格的資訊(geohash 有 function:getAdjacent來取得周遭鄰居的geohash)
下一篇提供一些簡單的虛擬程式邏輯看如何解決
。
(本資訊由HBase-搞定big data-no sql實戰 整理而出)
