前言
對於Redis而言,很多小夥伴只關注其關鍵的五大基礎型別:string、hash、list、set、sorted set(有序集合),其實還有三種特殊型別在很多應用場景也比較適合使用,分別是:bitmap、geospatial、hyperloglog;上一篇(跟我一起學Redis之五種基本型別及其應用場景舉例(幹了6個小時))對五種型別進行分享,接下來結合應用場景來說說三種特殊型別的使用方式;
正文
geospatial(地理空間)
該型別在Redis3.2.0版本中加入,其本質是將經緯度通過geohash技術轉換成一個值,使用sorted set將其儲存;具體內部實現在這裡不進行研究,這次主要說應用。
經度(longitude)、維度(latitude)小夥伴肯定不陌生(流淚,當初地理差的一批):
- 有效的經度是-180度到180度;
- 有效的緯度是-85.05112878度到85.05112878度;
該型別只有六個命令,先簡單介紹一下各命令的功能和關鍵引數:
-
GEOADD:新增地理空間位置資訊,即經緯度資訊;
GEOADD key 經度1 維度1 member1 [經度2 維度2 member2 ...]
-
GEODIST:獲取指定位置之間的距離,預設單位為米;
GEODIST key member1 member2 [單位]
單位可以指定,如下幾種:
m:指定單位為米;
km:指定單位為千米;
mi:指定單位為英里;
ft:指定單位為英尺;
-
GEOHASH:返回11個字元的Geohash字串,字串越相似,位置越接近;一般底層除錯使用的比較多。
GEOHASH key member1 [member2 ...]
-
GEOPOS:返回指定一個或多個位置元素的位置資訊,即經緯度資訊;
GEOPOS key member1 [member2 ...]
-
GEORADIUS:以指定的經緯度為圓心,查詢指定半徑範圍的位置元素;
GEORADIUS key 經度 維度 半徑 m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
半徑後面指定一個單位,m|km|ft|mi指定其中一個;
WITHDIST:在返回查詢到位置元素, 同時對應位置元素與中心之間的距離也一併返回。
WITHCOORD:將位置元素的經度和維度也一併返回。
WITHHASH:以 52 位有符號整數的形式返回, 返回位置元素經過原始 geohash 編碼的有序集合分值,即一串字串;
COUNT:代表返回位置資訊的條數,類似於分頁條數;
-
GEORADIUSBYMEMBER:指定的對應位置元素為圓心,查詢指定半徑範圍的位置元素;GEORADIUS命令是通過指定經緯度為圓心,其他使用方式一致;
GEORADIUSBYMEMBER key member 半徑 m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
命令功能及引數說明就簡單說這麼多(我怕說理論),欲知詳情,請小夥伴去官網瞅瞅;
接下來結合應用場景進行命令實戰,不然小夥伴要忍不住啦↓↓↓
應用場景實戰1
綠色出行,小黃、小藍、青桔、哈羅各種共享自行車應該已經是很多小夥伴們出行必用了吧,來,先截個哈羅的圖看看:
圖中顯示定位附近的小車,小夥伴可以先想想,如果這個需求給自己,怎麼實現?
如果用Redis,這樣搞試試:
每一輛共享單車肯定有定位功能,將其定位資訊(經緯度)儲存到後臺管理系統中,這裡我們模擬定位資訊儲存,我們用百度地圖座標拾取器可以取得地圖上任意一點的經緯度資訊,如下圖:
網頁地址為:http://api.map.baidu.com/lbsapi/getpoint/index.html
模擬共享單車定位資訊儲存到後臺Redis:
當我們開啟手機時,App同樣會通過手機進行定位,比如得到對應位置的經緯度資訊為:113.768365(經度),34.724814(緯度),這樣就可以指定使用者的定位資訊為中心,去查詢附近指定半徑的單車,然後將其標註在地圖上:
應用場景實戰2
再來一個需求,比如說微信附近的人,直播APP附近直播的播友,還有某陌附近的美女,如下圖:
如果用Redis實現,同樣是通過APP(比如微信)將使用者的定位資訊儲存到後臺Redis中,這裡還是使用百度地圖拾取器的方式取得位置資訊模擬將定位資訊儲存在Redis:
附近餐館、附近加油站、附近酒店同樣的原理,最後關於具體的資訊可以通過得到資訊(比如說使用者ID、共享單車標識等)去儲存詳細資訊的資料庫中查詢。
bitmap
bitmap在Redis2.2.0版本加入,其並不是一種實際的資料型別,而是在字串型別基礎上定義的一組面向位的操作。因為字串是二進位制安全的blob,對應value能儲存的最大長度是512 MB,即可以設定2^32個不同的位;大概的結構如下:**
**
實踐出真理,看看其型別到底是不是string型別:
常用命令如下:
-
SETBIT:設定指定key中指定位置(offset)的值(0 或 1);
SETBIT key offset value
-
GETBIT:獲取指定key中指定位置(offset)的值,未設定過預設返回0;
GETBIT key offset
-
BITCOUNT:統計指定key位置為1的數量,可以指定區間(這裡的區間以位元組(byte)為單位);
BITCOUNT key [start end]
-
BITOP:進行位運算,支援四種表示式運算: AND(交集), OR(並集), XOR(異或)和NOT(取非);
BITOP operation destkey key [key ...]
operation 可以指定對應的運算方式,運算的結果存入destkey中;
-
BITPOS:返回指定key中指定值的第一個位置;
BITPOS key bit [start] [end]
模擬應用場景實戰:
bitmap由於儲存的值只能是0或1,所以很適合兩種狀態的資料記錄和分析,比如說是否簽到,是否登入,然後通過簽到記錄的資料可以統計周、月、年簽到數,通過登入的資料可以分析使用者是否活躍;
應用場景使用者簽到
比如某多多連續簽到送現金、運動打卡App(比如Keep)、學習打卡App或者小程式,都會有對打卡資料的統計,如下圖某音極速版連續簽到送積分:
如果用Redis實現,如下:
應用場景使用者登入即使用者活躍分析:
如下統計邏輯:
bitmap適合資料量比較大的場景,如果資料幾十上千,用bitmap反而相對比較佔空間,直接使用使用者ID作為Key使用set儲存,但是如果資料量大時,Key值所佔空間比較大,比較浪費,而bitmap用512M記憶體就能標識40億資料狀態;當然,不介意bitmap的位數很大,設定或分析資料的時候可能會導致堵塞,所以當位數很大時,建議將其拆分為多個Key,保證分析的高效。
先休息一下,晃晃頭,眨巴眨巴眼睛,然後繼續往下↓↓↓
hyperloglog
先說說什麼是基數?
基數(cardinal number)在數學上,是集合論中刻畫任意集合大小的一個概念。兩個能夠建立元素間一一對應的集合稱為互相對等集合。例如3個人的集合和3匹馬的集合可以建立一一對應,是兩個對等的集合。
百度百科
比如資料集 {1, 3, 5, 7, 5, 7, 8}, 那麼這個資料集的基數集為 {1, 3, 5 ,7, 8}, 基數(不重複元素)為5。 基數估計就是在誤差可接受的範圍內,快速計算基數。
菜鳥教程
通俗一點就是不重複元素的個數(這是個人通俗的理解),先到這,實戰再來回顧這句話;
hyperloglog是一種概率資料統計結構,適合超大資料量的基數統計,速度快,而且空間佔用小,;但是統計的結果存在低於1%的誤差,如果需要的是精確統計的話,使用基礎型別set進行統計也不錯,但當統計元素比較多時,記憶體佔用空間會增大,畢竟用空間換精確度嘛。
和bitmap感覺很像,都適合大資料量的統計,但是bitmap還關注統計物件,比如說誰簽到多少次,而hyperloglog只進行基數統計,不關注是誰進行簽到;比如常聽到UV統計場景,即一個頁面,一個使用者訪問多次,也只算一次,最後只關注這個頁面被多少使用者訪問,而不在乎是誰訪問;微信公眾號文章的統計也是針對使用者統計的,同一個使用者不管訪問幾次,只算一次閱讀;
常用命令:
-
PFADD:新增元素到指定HyperLogLog;
PFADD key element [element ...]
-
PFCOUNT:返回指定HyperLogLog的基數估算值;
PFCOUNT key [key ...]
如果指定多個HyperLogLog ,返回它們並集近似基數,存在低於1%的誤差;
-
PFMERGE:將多個 HyperLogLog 合併為一個 HyperLogLog ;
PFMERGE destkey sourcekey [sourcekey ...]
模擬應用場景
模擬頁面UV統計,即使用者訪問數,不注重是誰訪問:
模擬App應用市場下載數,比如某音下載量都好幾億了,這個肯定不關心是誰下載吧,只關心下載數量來衡量應用引數;
總結
先到這吧,這篇總耗時又搞了幾個小時,上文中應用場景模擬只是給小夥伴提供思路,小夥伴可以根據需求進行設計;下一遍說說配置檔案;
一個被程式搞醜的帥小夥,關注"Code綜藝圈",識別關注跟我一起學~~~
擼文不易,莫要白瞟,三連走起~~~~