Redis還可以做哪些事?
在上一篇文章中,講到了redis五大基本數(shù)據(jù)類型的使用場(chǎng)景,除了string,hash,list,set,zset之外,redis還提供了一些其他的數(shù)據(jù)結(jié)構(gòu)(當(dāng)然,嚴(yán)格意義上也不算數(shù)據(jù)結(jié)構(gòu)),一起來(lái)看看redis還可以做哪些事?
一 Bitmaps
在計(jì)算機(jī)中,使用二進(jìn)制做為信息的基礎(chǔ)單元,也就是輸入的任何信息,最終在計(jì)算機(jī)底層都會(huì)轉(zhuǎn)會(huì)為一串二進(jìn)制的數(shù)字。在redis中,提供了Bitmaps來(lái)進(jìn)行位操作。我們可以把Bitmaps想象成一個(gè)以位為單位的數(shù)組,數(shù)組的下標(biāo)叫做偏移量。使用Bitmaps的優(yōu)勢(shì)就是占用空間更少。
假如我們想記錄員工今天是否登錄過(guò)公司官網(wǎng),我們可以日期做為key,員工id做為偏移量(這里員工id在數(shù)據(jù)庫(kù)中是自增的),如果id是從1000開(kāi)始,為了節(jié)省空間,一般會(huì)將員工id減去這個(gè)初始值來(lái)做為偏移量,偏移量一般從0開(kāi)始。是否訪問(wèn)官網(wǎng)用0和1來(lái)表示。
這樣的話,id為3的員工訪問(wèn)了官網(wǎng),就將他的值寫成1
- # id為3的員工訪問(wèn)了官網(wǎng)
- setbit user:2020-11-04 3 1
- # id為18的員工訪問(wèn)了官網(wǎng)
- setbit user:2020-11-04 18 1
查看某個(gè)員工是否訪問(wèn)過(guò)官網(wǎng)
- getbit user:2020-11-04 1
查詢指定范圍(字節(jié))內(nèi)值為1的個(gè)數(shù),比如我想查看id從1-24之間有多少員工訪問(wèn)了官網(wǎng)
- bitcount user:2020-11-04 1 3
二 HyperLogLog
HyperLogLog可以利用極小的內(nèi)存空間完成數(shù)據(jù)統(tǒng)計(jì),無(wú)法獲取單條數(shù)據(jù),只能做為統(tǒng)計(jì)使用,會(huì)有一定的誤差率。
假如我想統(tǒng)計(jì)訪問(wèn)官網(wǎng)的IP地址
添加官網(wǎng)今天訪問(wèn)的ip列表
- # 2020-11-04訪問(wèn)的ip
- pfadd 2020-11-04:ip "ip1" "ip2" "ip3"
- # 2020-11-05訪問(wèn)的ip
- pfadd 2020-11-05:ip "ip3" "ip4" "ip5"
計(jì)算今天官網(wǎng)訪問(wèn)的ip數(shù)
- pfcount 2020-11-04:ip
返回結(jié)果為3
查看2020-11-04和2020-11-05這兩天總共有多少個(gè)獨(dú)立ip訪問(wèn)過(guò)網(wǎng)站
先將兩天的數(shù)據(jù)做并集,并復(fù)制給某個(gè)值
- pfmerge 2020-11:ip 2020-11-04:ip 2020-11-05:ip
然后使用pfcount命令查詢,獲得的值為5
- pfcount 2020-11:ip
三 GEO
在Redis3.2版本中增加了GEO(地理位置定位)功能,可以使用此功能來(lái)獲取附近的人。
添加命令如下,可批量添加
- geoadd city longitud latitude member
我們添加幾個(gè)城市的位置信息,來(lái)獲取某個(gè)城市附近的城市
- geoadd city 116.28 39.55 beijing 117.12 39.08 tianjin
獲取北京的經(jīng)緯度命令如下
- geopos city beijing
查看beijing和tianjin兩座城市的距離
- geodist city beijing tianjin km
最后面的km表示距離單位是公里,支持的單位有以下幾個(gè):
- m,米
- km,千米
- mi,英里
- ft,尺
獲取附近的位置有兩個(gè)命令,georadius根據(jù)經(jīng)緯度獲取,georadiusbymember根據(jù)成員獲取
- georadius key longitude laitude [單位]
- georadiusbymember key member [單位]
后面還可以跟非必須參數(shù),參數(shù)分別如下
- withcoord:返回結(jié)果中包含經(jīng)緯度
- withdist:返回結(jié)果中包含距離中心位置的距離
- withhash:返回結(jié)果中包含geohash(就是將經(jīng)緯度轉(zhuǎn)換為hash值)
- COUNT count:指定返回結(jié)果的數(shù)量
- asc|desc:返回結(jié)果按距離中心位置的距離排序
- store key:將返回結(jié)果的地理位置信息保存到指定key中
- storedist key:將返回結(jié)果距離中心位置的距離保存到指定key中
四 發(fā)布訂閱模式消息
在上一篇文章中講到了可以使用list和zset來(lái)實(shí)現(xiàn)消息隊(duì)列,但是上面實(shí)現(xiàn)的消息隊(duì)列是點(diǎn)對(duì)點(diǎn)模式,也就是一條消息只能由一個(gè)消費(fèi)者來(lái)消費(fèi)。除此之外,redis還支持發(fā)布訂閱模式,即一個(gè)消息由所有訂閱者消費(fèi),比如廣播、公告等等,發(fā)布一條公告后,所有關(guān)注了我的用戶都可以收到這條公告。
1.發(fā)布消息
發(fā)布到信道channel:message一條消息,消息內(nèi)容為hi
- pulish channel:message hi
2.訂閱信道
訂閱者可以訂閱一個(gè)或多個(gè)信道,比如訂閱channel:message
- subscribe channel:message
3.取消訂閱
- unsubscribe channel:message
4.查看活躍信道
- pubsub channels
5.查看訂閱數(shù)
查看信道channel:message訂閱個(gè)數(shù)
- pubsub numsub channel:message
redis的發(fā)布訂閱模式和專業(yè)的消息中間件相比,略顯粗糙,但是實(shí)現(xiàn)起來(lái)非常簡(jiǎn)單,學(xué)習(xí)成本較低。
五 Bloom Filter
布隆過(guò)濾器是redis4版本中新增的一個(gè)功能。其實(shí)現(xiàn)原理和Bitmaps差不多,也是利用一個(gè)位數(shù)組,將你的值經(jīng)過(guò)多個(gè)hash函數(shù),得到對(duì)應(yīng)的位數(shù)組的位置,將這些值設(shè)置為1。布隆過(guò)濾器經(jīng)常別用來(lái)防止緩存穿透。
存在的問(wèn)題,如果說(shuō)某個(gè)元素不存在,則一定不存在,如果說(shuō)某個(gè)元素存在,則可能不存在。這是因?yàn)槿绻腥齻€(gè)元素a,b,c要放入同一個(gè)數(shù)組中去,假設(shè)a經(jīng)過(guò)三次hash,得到1,5,7三個(gè)位置,那么就會(huì)將這三個(gè)位置修改成1,b經(jīng)過(guò)三次hash,得到2,4,6三個(gè)位置,將這三個(gè)位置修改成1。c經(jīng)過(guò)三次hash得到2,5,7三個(gè)位置,但是經(jīng)過(guò)前兩個(gè)元素hash后,這三個(gè)位置已經(jīng)修改成1了,那么我們能說(shuō)c一定存在嗎?顯然不能!
本文轉(zhuǎn)載自微信公眾號(hào)「Java旅途」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java旅途公眾號(hào)。