Redis高階使用消息隊(duì)列分布式鎖排行榜等(高階用法)
一、前言
在大多數(shù)傳統(tǒng)的web系統(tǒng)中,使用Redis一般都是作為緩存使用,在大數(shù)據(jù)查詢時(shí)作為緩解性能的一種解決方案。博主的的系統(tǒng)中使用Redis也主要使用到緩存的作用,還有做了注冊(cè)中心,分布式事務(wù)。其他的強(qiáng)大的功能,沒(méi)有運(yùn)用上。下面看一張圖,看看Redis高階還能用到哪些常見(jiàn)的場(chǎng)景。
二、Redis高階用法
1.消息隊(duì)列:Redis的列表數(shù)據(jù)結(jié)構(gòu)非常適合作為簡(jiǎn)單的消息隊(duì)列。消息發(fā)布者可以使用LPUSH命令向隊(duì)列中添加消息,而多個(gè)消息訂閱者則可以通過(guò)阻塞線程使用BRPOP命令從隊(duì)列中取出消息。需要注意的是,Redis官方并不提供可靠消費(fèi)/發(fā)布的機(jī)制,因此需要自行實(shí)現(xiàn)故障轉(zhuǎn)移、隊(duì)列持久化、隊(duì)列監(jiān)控和流量控制等功能。
2.Lua腳本:Redis支持使用Lua腳本在服務(wù)器端執(zhí)行一系列命令。這有助于減少客戶端與服務(wù)器之間的網(wǎng)絡(luò)開(kāi)銷,并且可以實(shí)現(xiàn)復(fù)雜的原子操作。
3.事務(wù):Redis支持事務(wù),可以將一系列命令作為一個(gè)原子操作來(lái)執(zhí)行。這通過(guò)MULTI、EXEC、DISCARD和WATCH等命令來(lái)實(shí)現(xiàn),確保在事務(wù)執(zhí)行期間,中間步驟不會(huì)被其他客戶端打斷。
4.分布式鎖:Redis可以利用SET命令的NX(不覆蓋)參數(shù)來(lái)實(shí)現(xiàn)分布式鎖。獲取鎖的客戶端可以執(zhí)行臨界區(qū)的代碼,而其他客戶端則需要等待鎖的釋放。
public String lock(String key, int timeOutSecond) { for (; ; ) { String stamp = String.valueOf(System.nanoTime()); boolean exist = redisTemplate.opsForValue().setIfAbsent(key, stamp, timeOutSecond, TimeUnit.SECONDS); if (exist) { return stamp; } } } public void unlock(String key, String stamp) { redisTemplate.execute(script, Arrays.asList(key), stamp); }
- 排行榜:Redis的有序集合數(shù)據(jù)結(jié)構(gòu)(zset)非常適合用來(lái)實(shí)現(xiàn)排行榜功能。例如,可以通過(guò)zadd命令添加分?jǐn)?shù)和成員,然后使用zrevrange命令獲取排名最高的成員。
- HyperLogLog:這是Redis用于基數(shù)統(tǒng)計(jì)的算法。當(dāng)輸入元素的數(shù)量或體積非常大時(shí),HyperLogLog所需的計(jì)算空間總是固定的且很小。通過(guò)pfadd命令添加元素,然后使用pfcount命令獲取基數(shù)統(tǒng)計(jì)結(jié)果。
- 過(guò)期鍵管理:Redis可以為鍵設(shè)置過(guò)期時(shí)間,過(guò)期后鍵會(huì)自動(dòng)被刪除。這對(duì)于緩存系統(tǒng)特別有用,可以避免長(zhǎng)時(shí)間占用內(nèi)存。
redis的數(shù)據(jù)結(jié)構(gòu)豐富,一般不會(huì)在功能性上造成困擾。但隨著請(qǐng)求量的增加,SLA要求的提高,我們勢(shì)必會(huì)對(duì)Redis進(jìn)行一些改造和定制性開(kāi)發(fā)。
高可用挑戰(zhàn)
redis提供了主從、哨兵、cluster等三種集群模式,其中cluster模式為目前大多數(shù)公司所采用的方式。
但是,redis的cluster模式,有不少的硬傷。redis cluster采用虛擬槽的概念,把所有的key映射到 0~16383個(gè)整數(shù)槽內(nèi),屬于無(wú)中心化的架構(gòu)。但它的維護(hù)成本較高,slave也不能夠參與讀取操作。
它的主要問(wèn)題,在于一些批量操作的限制。由于key被hash到多臺(tái)機(jī)器上,所以mget、hmset、sunion等操作就非常的不友好,經(jīng)常發(fā)生性能問(wèn)題。
redis的主從模式是最簡(jiǎn)單的模式,但無(wú)法做到自動(dòng)failover,通常在主從切換后,還需要修改業(yè)務(wù)代碼,這是不能忍受的。即使加上haproxy這樣的負(fù)載均衡組件,復(fù)雜性也是非常高的。
哨兵模式在主從數(shù)量比較多的時(shí)候,能夠顯著的體現(xiàn)它的價(jià)值。一個(gè)哨兵集群,能夠監(jiān)控成百上千個(gè)集群,但是哨兵集群本身的維護(hù)是比較困難的。幸運(yùn)的是,redis的文本協(xié)議非常簡(jiǎn)單,在netty中,甚至直接提供了redis的codec。自研一套哨兵系統(tǒng),加強(qiáng)它的功能,是可行的。
冷熱數(shù)據(jù)分離
redis的特點(diǎn)是,不管什么數(shù)據(jù),都一股腦地搞到內(nèi)存里做計(jì)算,這對(duì)于有時(shí)間序列概念,有冷熱數(shù)據(jù)之分的業(yè)務(wù),造成了非常大的成本考驗(yàn)。為什么大多數(shù)開(kāi)發(fā)者喜歡把數(shù)據(jù)存放在MySQL中,而不是Redis中?除了事務(wù)性要求以外,很大原因是歷史數(shù)據(jù)的問(wèn)題。
通常,這種冷熱數(shù)據(jù)的切換,是由中間件完成的。我們上面也談到了,Redis是一個(gè)文本協(xié)議,非常簡(jiǎn)單。做一個(gè)中間件,或者做一個(gè)協(xié)議兼容的Redis模擬存儲(chǔ),是比較容易的。
比如我們Redis中,只保留最近一年的活躍用戶。一個(gè)好幾年不活躍的用戶,突然間訪問(wèn)了系統(tǒng),這時(shí)候我們獲取數(shù)據(jù)的時(shí)候,就需要中間件進(jìn)行轉(zhuǎn)換,從容量更大,速度更慢的存儲(chǔ)中查找。
這個(gè)時(shí)候,Redis的作用,更像是一個(gè)熱庫(kù),更像是一個(gè)傳統(tǒng)cache層做的事情,發(fā)生在業(yè)務(wù)已經(jīng)上規(guī)模的時(shí)候。但是注意,直到此時(shí),我們的業(yè)務(wù)層代碼,一直都是操作的redis的api。它們使用這眾多的函數(shù)指令,并不關(guān)心數(shù)據(jù)到底是真正存儲(chǔ)在redis中,還是在ssdb中。
功能性需求
redis還能玩很多花樣。舉個(gè)例子,全文搜索。很多人都會(huì)首選es,但redis生態(tài)就提供了一個(gè)模塊:RediSearch,可以做查詢,可以做filter。
但我們通常還會(huì)有更多的需求,比如統(tǒng)計(jì)類、搜索類、運(yùn)營(yíng)效果分析等。這類需求與大數(shù)據(jù)相關(guān),即使是傳統(tǒng)的DB也不能勝任。這時(shí)候,我們當(dāng)然要把redis中的數(shù)據(jù),導(dǎo)入到其他平臺(tái)進(jìn)行計(jì)算啦。
如果你選擇的是redis數(shù)據(jù)庫(kù),那么dba打交道的,就是rdb,而不是binlog。有很多的rdb解析工具(比如redis-rdb-tools),能夠定期把rdb解析成記錄,導(dǎo)入到hadoop等其他平臺(tái)。
此時(shí),rdb成為所有團(tuán)隊(duì)的中樞,成為基本的數(shù)據(jù)交換格式。導(dǎo)入到其他db后的業(yè)務(wù),該怎么玩怎么玩,完全不會(huì)因?yàn)闃I(yè)務(wù)系統(tǒng)選用了redis就無(wú)法運(yùn)轉(zhuǎn)。
到此這篇關(guān)于Redis高階使用消息隊(duì)列分布式鎖排行榜等的文章就介紹到這了,更多相關(guān)Redis消息隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot3+Redis實(shí)現(xiàn)消息隊(duì)列的多種方法小結(jié)
- 一文詳解消息隊(duì)列中為什么不用redis作為隊(duì)列
- SpringBoot集成Redisson實(shí)現(xiàn)消息隊(duì)列的示例代碼
- redis?消息隊(duì)列完成秒殺過(guò)期訂單處理方法(一)
- 如何使用?redis?消息隊(duì)列完成秒殺過(guò)期訂單處理操作(二)
- Redis消息隊(duì)列的三種實(shí)現(xiàn)方式
- Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列的項(xiàng)目實(shí)踐
- Redis使用ZSET實(shí)現(xiàn)消息隊(duì)列使用小結(jié)
- python使用redis實(shí)現(xiàn)消息隊(duì)列(異步)的實(shí)現(xiàn)完整例程
- 詳解Redis Stream做消息隊(duì)列
- 基于Redis實(shí)現(xiàn)消息隊(duì)列的示例代碼
相關(guān)文章
如何高效地向Redis插入大量的數(shù)據(jù)(推薦)
本篇文章主要介紹了如何高效地向Redis插入大量的數(shù)據(jù),現(xiàn)在分享給大家,感興趣的小伙伴們可以參考一下。2016-11-11Ubuntu下Redis密碼設(shè)置問(wèn)題及其解決過(guò)程
這篇文章主要介紹了Ubuntu下Redis密碼設(shè)置問(wèn)題及其解決過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06Redis 數(shù)據(jù)遷移的項(xiàng)目實(shí)踐
本文主要介紹了Redis 數(shù)據(jù)遷移的項(xiàng)目實(shí)踐,通過(guò)Redis-shake的sync(同步)模式,可以將Redis的數(shù)據(jù)實(shí)時(shí)遷移至另一套R(shí)edis環(huán)境,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09如何利用Redis?List實(shí)現(xiàn)Java數(shù)據(jù)庫(kù)分頁(yè)快速查詢
這篇文章主要給大家介紹了關(guān)于如何利用Redis?List實(shí)現(xiàn)Java數(shù)據(jù)庫(kù)分頁(yè)快速查詢的相關(guān)資料,Redis是一個(gè)高效的內(nèi)存數(shù)據(jù)庫(kù),它支持包括String、List、Set、SortedSet和Hash等數(shù)據(jù)類型的存儲(chǔ),需要的朋友可以參考下2024-02-02Redis中ServiceStack.Redis和StackExchange.Redis區(qū)別詳解
本文主要介紹了Redis中ServiceStack.Redis和StackExchange.Redis區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05redis中使用redis-dump導(dǎo)出、導(dǎo)入、還原數(shù)據(jù)實(shí)例
這篇文章主要介紹了redis中使用redis-dump導(dǎo)出、導(dǎo)入、還原數(shù)據(jù)實(shí)例,本文直接給出操作命令,并給出注釋加以說(shuō)明,需要的朋友可以參考下2014-11-11