跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)
前言
對(duì)于Redis而言,很多小伙伴只關(guān)注其關(guān)鍵的五大基礎(chǔ)類型:string、hash、list、set、sorted set(有序集合),其實(shí)還有三種特殊類型在很多應(yīng)用場(chǎng)景也比較適合使用,分別是:bitmap、geospatial、hyperloglog;上一篇(跟我一起學(xué)Redis之五種基本類型及其應(yīng)用場(chǎng)景舉例(干了6個(gè)小時(shí)))對(duì)五種類型進(jìn)行分享,接下來結(jié)合應(yīng)用場(chǎng)景來說說三種特殊類型的使用方式;
正文
geospatial(地理空間)
該類型在Redis3.2.0版本中加入,其本質(zhì)是將經(jīng)緯度通過geohash技術(shù)轉(zhuǎn)換成一個(gè)值,使用sorted set將其存儲(chǔ);具體內(nèi)部實(shí)現(xiàn)在這里不進(jìn)行研究,這次主要說應(yīng)用。
經(jīng)度(longitude)、維度(latitude)小伙伴肯定不陌生(流淚,當(dāng)初地理差的一批):
有效的經(jīng)度是-180度到180度;
有效的緯度是-85.05112878度到85.05112878度;
該類型只有六個(gè)命令,先簡(jiǎn)單介紹一下各命令的功能和關(guān)鍵參數(shù):
GEOADD:添加地理空間位置信息,即經(jīng)緯度信息;
GEOADD key 經(jīng)度1 維度1 member1 [經(jīng)度2 維度2 member2 ...]
GEODIST:獲取指定位置之間的距離,默認(rèn)單位為米;
GEODIST key member1 member2 [單位]
單位可以指定,如下幾種:
m:指定單位為米;
km:指定單位為千米;
mi:指定單位為英里;
ft:指定單位為英尺;
GEOHASH:返回11個(gè)字符的Geohash字符串,字符串越相似,位置越接近;一般底層調(diào)試使用的比較多。
GEOHASH key member1 [member2 ...]
GEOPOS:返回指定一個(gè)或多個(gè)位置元素的位置信息,即經(jīng)緯度信息;
GEOPOS key member1 [member2 ...]
GEORADIUS:以指定的經(jīng)緯度為圓心,查找指定半徑范圍的位置元素;
GEORADIUS key 經(jīng)度 維度 半徑 m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
半徑后面指定一個(gè)單位,m|km|ft|mi指定其中一個(gè);
WITHDIST:在返回查找到位置元素, 同時(shí)對(duì)應(yīng)位置元素與中心之間的距離也一并返回。
WITHCOORD:將位置元素的經(jīng)度和維度也一并返回。
WITHHASH:以 52 位有符號(hào)整數(shù)的形式返回, 返回位置元素經(jīng)過原始 geohash 編碼的有序集合分值,即一串字符串;
COUNT:代表返回位置信息的條數(shù),類似于分頁條數(shù);
GEORADIUSBYMEMBER:指定的對(duì)應(yīng)位置元素為圓心,查找指定半徑范圍的位置元素;GEORADIUS命令是通過指定經(jīng)緯度為圓心,其他使用方式一致;
GEORADIUSBYMEMBER key member 半徑 m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
命令功能及參數(shù)說明就簡(jiǎn)單說這么多(我怕說理論),欲知詳情,請(qǐng)小伙伴去官網(wǎng)瞅瞅;
接下來結(jié)合應(yīng)用場(chǎng)景進(jìn)行命令實(shí)戰(zhàn),不然小伙伴要忍不住啦↓↓↓
應(yīng)用場(chǎng)景實(shí)戰(zhàn)1
綠色出行,小黃、小藍(lán)、青桔、哈羅各種共享自行車應(yīng)該已經(jīng)是很多小伙伴們出行必用了吧,來,先截個(gè)哈羅的圖看看:
圖中顯示定位附近的小車,小伙伴可以先想想,如果這個(gè)需求給自己,怎么實(shí)現(xiàn)?
如果用Redis,這樣搞試試:
每一輛共享單車肯定有定位功能,將其定位信息(經(jīng)緯度)存儲(chǔ)到后臺(tái)管理系統(tǒng)中,這里我們模擬定位信息存儲(chǔ),我們用百度地圖坐標(biāo)拾取器可以取得地圖上任意一點(diǎn)的經(jīng)緯度信息,如下圖:
網(wǎng)頁地址為:http://api.map.baidu.com/lbsapi/getpoint/index.html
模擬共享單車定位信息存儲(chǔ)到后臺(tái)Redis:
當(dāng)我們打開手機(jī)時(shí),App同樣會(huì)通過手機(jī)進(jìn)行定位,比如得到對(duì)應(yīng)位置的經(jīng)緯度信息為:113.768365(經(jīng)度),34.724814(緯度),這樣就可以指定用戶的定位信息為中心,去查找附近指定半徑的單車,然后將其標(biāo)注在地圖上:
應(yīng)用場(chǎng)景實(shí)戰(zhàn)2
再來一個(gè)需求,比如說微信附近的人,直播APP附近直播的播友,還有某陌附近的美女,如下圖:
如果用Redis實(shí)現(xiàn),同樣是通過APP(比如微信)將用戶的定位信息保存到后臺(tái)Redis中,這里還是使用百度地圖拾取器的方式取得位置信息模擬將定位信息保存在Redis:
附近餐館、附近加油站、附近酒店同樣的原理,最后關(guān)于具體的信息可以通過得到信息(比如說用戶ID、共享單車標(biāo)識(shí)等)去存儲(chǔ)詳細(xì)信息的數(shù)據(jù)庫中查詢。
bitmap
bitmap在Redis2.2.0版本加入,其并不是一種實(shí)際的數(shù)據(jù)類型,而是在字符串類型基礎(chǔ)上定義的一組面向位的操作。因?yàn)樽址嵌M(jìn)制安全的blob,對(duì)應(yīng)value能存儲(chǔ)的最大長(zhǎng)度是512 MB,即可以設(shè)置2^32個(gè)不同的位;大概的結(jié)構(gòu)如下:
實(shí)踐出真理,看看其類型到底是不是string類型:
常用命令如下:
SETBIT:設(shè)置指定key中指定位置(offset)的值(0 或 1);
SETBIT key offset value
GETBIT:獲取指定key中指定位置(offset)的值,未設(shè)置過默認(rèn)返回0;
GETBIT key offset
BITCOUNT:統(tǒng)計(jì)指定key位置為1的數(shù)量,可以指定區(qū)間(這里的區(qū)間以字節(jié)(byte)為單位);
BITCOUNT key [start end]
BITOP:進(jìn)行位運(yùn)算,支持四種表達(dá)式運(yùn)算: AND(交集), OR(并集), XOR(異或)和NOT(取非);
BITOP operation destkey key [key ...]
operation 可以指定對(duì)應(yīng)的運(yùn)算方式,運(yùn)算的結(jié)果存入destkey中;
BITPOS:返回指定key中指定值的第一個(gè)位置;
BITPOS key bit [start] [end]
模擬應(yīng)用場(chǎng)景實(shí)戰(zhàn):
bitmap由于存儲(chǔ)的值只能是0或1,所以很適合兩種狀態(tài)的數(shù)據(jù)記錄和分析,比如說是否簽到,是否登錄,然后通過簽到記錄的數(shù)據(jù)可以統(tǒng)計(jì)周、月、年簽到數(shù),通過登錄的數(shù)據(jù)可以分析用戶是否活躍;
應(yīng)用場(chǎng)景用戶簽到
比如某多多連續(xù)簽到送現(xiàn)金、運(yùn)動(dòng)打卡App(比如Keep)、學(xué)習(xí)打卡App或者小程序,都會(huì)有對(duì)打卡數(shù)據(jù)的統(tǒng)計(jì),如下圖某音極速版連續(xù)簽到送積分:
如果用Redis實(shí)現(xiàn),如下:
應(yīng)用場(chǎng)景用戶登錄即用戶活躍分析:
如下統(tǒng)計(jì)邏輯:
bitmap適合數(shù)據(jù)量比較大的場(chǎng)景,如果數(shù)據(jù)幾十上千,用bitmap反而相對(duì)比較占空間,直接使用用戶ID作為Key使用set存儲(chǔ),但是如果數(shù)據(jù)量大時(shí),Key值所占空間比較大,比較浪費(fèi),而bitmap用512M內(nèi)存就能標(biāo)識(shí)40億數(shù)據(jù)狀態(tài);當(dāng)然,不介意bitmap的位數(shù)很大,設(shè)置或分析數(shù)據(jù)的時(shí)候可能會(huì)導(dǎo)致堵塞,所以當(dāng)位數(shù)很大時(shí),建議將其拆分為多個(gè)Key,保證分析的高效。
先休息一下,晃晃頭,眨巴眨巴眼睛,然后繼續(xù)往下↓↓↓
hyperloglog
先說說什么是基數(shù)?
基數(shù)(cardinal number)在數(shù)學(xué)上,是集合論中刻畫任意集合大小的一個(gè)概念。兩個(gè)能夠建立元素間一一對(duì)應(yīng)的集合稱為互相對(duì)等集合。例如3個(gè)人的集合和3匹馬的集合可以建立一一對(duì)應(yīng),是兩個(gè)對(duì)等的集合。
百度百科
比如數(shù)據(jù)集?{1, 3, 5, 7, 5, 7, 8},?那么這個(gè)數(shù)據(jù)集的基數(shù)集為?{1, 3, 5 ,7, 8}, 基數(shù)(不重復(fù)元素)為5。?基數(shù)估計(jì)就是在誤差可接受的范圍內(nèi),快速計(jì)算基數(shù)。
菜鳥教程
通俗一點(diǎn)就是不重復(fù)元素的個(gè)數(shù)(這是個(gè)人通俗的理解),先到這,實(shí)戰(zhàn)再來回顧這句話;
hyperloglog是一種概率數(shù)據(jù)統(tǒng)計(jì)結(jié)構(gòu),適合超大數(shù)據(jù)量的基數(shù)統(tǒng)計(jì),速度快,而且空間占用小,;但是統(tǒng)計(jì)的結(jié)果存在低于1%的誤差,如果需要的是精確統(tǒng)計(jì)的話,使用基礎(chǔ)類型set進(jìn)行統(tǒng)計(jì)也不錯(cuò),但當(dāng)統(tǒng)計(jì)元素比較多時(shí),內(nèi)存占用空間會(huì)增大,畢竟用空間換精確度嘛。
和bitmap感覺很像,都適合大數(shù)據(jù)量的統(tǒng)計(jì),但是bitmap還關(guān)注統(tǒng)計(jì)對(duì)象,比如說誰簽到多少次,而hyperloglog只進(jìn)行基數(shù)統(tǒng)計(jì),不關(guān)注是誰進(jìn)行簽到;比如常聽到UV統(tǒng)計(jì)場(chǎng)景,即一個(gè)頁面,一個(gè)用戶訪問多次,也只算一次,最后只關(guān)注這個(gè)頁面被多少用戶訪問,而不在乎是誰訪問;微信公眾號(hào)文章的統(tǒng)計(jì)也是針對(duì)用戶統(tǒng)計(jì)的,同一個(gè)用戶不管訪問幾次,只算一次閱讀;
常用命令:
PFADD:添加元素到指定HyperLogLog;
PFADD key element [element ...]PFCOUNT:返回指定HyperLogLog的基數(shù)估算值;
PFCOUNT key [key ...]如果指定多個(gè)HyperLogLog ,返回它們并集近似基數(shù),存在低于1%的誤差;
PFMERGE:將多個(gè) HyperLogLog 合并為一個(gè) HyperLogLog ;
PFMERGE destkey sourcekey [sourcekey ...]
模擬應(yīng)用場(chǎng)景
模擬頁面UV統(tǒng)計(jì),即用戶訪問數(shù),不注重是誰訪問:
模擬App應(yīng)用市場(chǎng)下載數(shù),比如某音下載量都好幾億了,這個(gè)肯定不關(guān)心是誰下載吧,只關(guān)心下載數(shù)量來衡量應(yīng)用參數(shù);
總結(jié)
先到這吧,這篇總耗時(shí)又搞了幾個(gè)小時(shí),上文中應(yīng)用場(chǎng)景模擬只是給小伙伴提供思路,小伙伴可以根據(jù)需求進(jìn)行設(shè)計(jì);下一遍說說配置文件;
一個(gè)被程序搞丑的帥小伙,關(guān)注"Code綜藝圈",識(shí)別關(guān)注跟我一起學(xué)~~~
擼文不易,莫要白瞟,三連走起~~~~
總結(jié)
以上是生活随笔為你收集整理的跟我一起学Redis之看完这篇比常人多会三种类型实战(又搞了几个小时)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 七国要求科技巨头预留后门 应对马甲芯片高
- 下一篇: T-SQL | 逻辑查询处理内幕学习