Redis高級(jí)應(yīng)用總結(jié)

Redis的線程模型


Redis是單進(jìn)程單線程的,但是使用的是單線程非阻塞的多路IO復(fù)用的模型。多線程模型會(huì)導(dǎo)致線程的生成、回收、線程上下文的切換,這些都會(huì)導(dǎo)致性能的降低。多線程牽涉到線程同步,還需要加鎖,但是鎖的使用也會(huì)導(dǎo)致性能降低。那么什么是多路IO復(fù)用呢?

官方的解釋:多路I/O復(fù)用模型是利用select、poll、epoll可以同時(shí)監(jiān)察多個(gè)流的 I/O 事件的能力,在空閑的時(shí)候,會(huì)把當(dāng)前線程阻塞掉,當(dāng)有一個(gè)或多個(gè)流有I/O事件時(shí),就從阻塞態(tài)中喚醒,于是程序就會(huì)輪詢一遍所有的流(epoll是只輪詢那些真正發(fā)出了事件的流),并且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。這里“多路”指的是多個(gè)網(wǎng)絡(luò)連接,“復(fù)用”指的是復(fù)用同一個(gè)線程。采用多路 I/O 復(fù)用技術(shù)可以讓單個(gè)線程高效的處理多個(gè)連接請(qǐng)求(盡量減少網(wǎng)絡(luò)IO的時(shí)間消耗),且Redis在內(nèi)存中操作數(shù)據(jù)的速度非常快(內(nèi)存內(nèi)的操作不會(huì)成為這里的性能瓶頸),主要以上兩點(diǎn)造就了Redis具有很高的吞吐量。

單進(jìn)程單線程的好處:

1.代碼清晰,處理邏輯簡(jiǎn)單。

2.不用考慮鎖,沒有因?yàn)槭褂面i導(dǎo)致的性能下降、死鎖問題。

3.沒有多線程的線程上下文切換、線程生成回收導(dǎo)致的性能消耗。

單進(jìn)程單線程的缺點(diǎn):

在到處是CPU多核的時(shí)代,無法充分發(fā)揮CPU的多核優(yōu)勢(shì),只能在一臺(tái)服務(wù)器上部署多個(gè)實(shí)例的方案來使用多核。

問題:既然Redis是單線程的,那么是不是Redis的服務(wù)上只有一個(gè)線程在運(yùn)行?

單線程指的是Redis處理我們的網(wǎng)絡(luò)請(qǐng)求是單線程的,一個(gè)Redis服務(wù)上運(yùn)行不止這一個(gè)線程,還有其他的比如數(shù)據(jù)持久化的線程。

Memcached使用的是多線程,處理能力非常強(qiáng),Redis正因?yàn)槭褂昧硕嗦稩O復(fù)用的機(jī)制才使單線程的性能不比多線程的差。

Redis的過期策略及內(nèi)存淘汰機(jī)制


Redis中寫入的數(shù)據(jù)超過了內(nèi)存的容量,Redis使用什么機(jī)制來刪除多余的數(shù)據(jù)?

Redis使用的是定期刪除+惰性刪除的策略。為什么不用定時(shí)刪除?定時(shí)刪除需要一個(gè)定時(shí)器來不停的監(jiān)控Redis中的數(shù)據(jù),過期了則刪除,雖然內(nèi)存得到了釋放,但是定時(shí)器不停的輪詢是十分消耗CPU的,在高并發(fā)情況下能明顯降低性能。

定期刪除+惰性刪除是如何工作的?定期刪除,Redis默認(rèn)是100ms檢查一次,是否有過期的數(shù)據(jù),有了則刪除。Redis并不是每個(gè)100ms都檢查所有的數(shù)據(jù),如果數(shù)據(jù)龐大,100ms根本檢查不完,它是隨機(jī)的抽取一部分?jǐn)?shù)據(jù)進(jìn)行檢查。采用定期刪除的策略有一個(gè)問題,就是好多過期的數(shù)據(jù)沒有及時(shí)刪除。于是,惰性刪除就出現(xiàn)了。惰性刪除的意思是,當(dāng)程序讀取某個(gè)數(shù)據(jù)時(shí),Redis會(huì)主動(dòng)的查看下這條數(shù)據(jù)是否設(shè)置了過期時(shí)間并且是否過期,如果過期直接刪除。

定期刪除+惰性刪除還存在一個(gè)問題,如果有些數(shù)據(jù)過期了,但是定時(shí)刪除沒有檢查到它,并且程序也沒有請(qǐng)求這些數(shù)據(jù),那么它會(huì)一直在內(nèi)存中,這該怎么處理呢?這時(shí)候就要內(nèi)存淘汰機(jī)制了。

在redis.conf的配置文件中有一行:# maxmemory-policy volatile-lru

這個(gè)就是設(shè)置內(nèi)存淘汰的。有以下幾個(gè)選項(xiàng):

1. noeviction:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò)。

2. allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的key。推薦使用。

3. allkeys-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,隨機(jī)移除某個(gè)key。

4. volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,移除最近最少使用的key。

5. volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,隨機(jī)移除某個(gè)key。

6. volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,有更早過期時(shí)間的key優(yōu)先移除。

Redis的分布式鎖怎么實(shí)現(xiàn)


首先說明下什么是分布式鎖。分布式系統(tǒng)下有一個(gè)理論CAP理論,這個(gè)理論的意思是任何分布式系統(tǒng)不可能同時(shí)滿足強(qiáng)一致性(Consistency)、可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance),最多只能同時(shí)滿足其中的兩個(gè)?;ヂ?lián)網(wǎng)系統(tǒng)都是犧牲最終一致性來換取高可用性。最終一致性要在合理的時(shí)間范圍內(nèi)。為了保證最終一致性,我們需要分布式鎖。保證一個(gè)方法在同一時(shí)間內(nèi)只能被集群中的一臺(tái)服務(wù)器中的一個(gè)線程執(zhí)行,否則如果被多個(gè)線程執(zhí)行了結(jié)果可能不正確。分布式環(huán)境下的事務(wù)和鎖比單體程序下的復(fù)雜很多。

實(shí)現(xiàn)分布式鎖要滿足的條件:

1. 在分布式系統(tǒng)環(huán)境下,一個(gè)方法在同一時(shí)間只能被一個(gè)機(jī)器的一個(gè)線程執(zhí)行;

2. ?高可用的獲取鎖與釋放鎖;

3. ?高性能的獲取鎖與釋放鎖;

4. ?具備可重入特性;

5. ?具備鎖失效機(jī)制,防止死鎖;

6. ?具備非阻塞鎖特性,即沒有獲取到鎖將直接返回獲取鎖失敗。

實(shí)現(xiàn)分布式鎖有三種方案:數(shù)據(jù)庫、Redis緩存、zookeeper,這里只介紹Redis和zookeeper。

Redis分布式鎖的實(shí)現(xiàn)主要要使用到三個(gè)命令:

1. SETNX key?val:當(dāng)且僅當(dāng)key不存在時(shí),set一個(gè)key為val的字符串,返回1;若key存在,則什么都不做,返回0。

2. expire key?timeout:為key設(shè)置一個(gè)超時(shí)時(shí)間,單位為second,超過這個(gè)時(shí)間鎖會(huì)自動(dòng)釋放,避免死鎖。

3. delete?key:刪除key

實(shí)現(xiàn)思想:

1. 獲取鎖的時(shí)候,使用setnx加鎖,并使用expire命令為鎖添加一個(gè)超時(shí)時(shí)間,超過該時(shí)間則自動(dòng)釋放鎖,鎖的value值為一個(gè)隨機(jī)生成的UUID,通過此在釋放鎖的時(shí)候進(jìn)行判斷。

2. 獲取鎖的時(shí)候還設(shè)置一個(gè)獲取的超時(shí)時(shí)間,若超過這個(gè)時(shí)間則放棄獲取鎖。

3. 釋放鎖的時(shí)候,通過UUID判斷是不是該鎖,若是該鎖,則執(zhí)行delete進(jìn)行鎖釋放。

Redis實(shí)現(xiàn)分布式鎖的問題:

鎖的過期時(shí)間設(shè)置多久為好呢?如果時(shí)間過短,方法還沒執(zhí)行完畢,鎖就釋放了,會(huì)產(chǎn)生并發(fā)問題,如果時(shí)間設(shè)置的過長(zhǎng),其他獲取鎖的線程就要白等很長(zhǎng)時(shí)間。

Zookeeper實(shí)現(xiàn)分布式鎖:

可以使用Zookeeper的臨時(shí)有序節(jié)點(diǎn)來實(shí)現(xiàn)分布式鎖。大致思想即為:每個(gè)客戶端對(duì)某個(gè)方法加鎖時(shí),在zookeeper上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)。判斷是否獲取鎖的方式很簡(jiǎn)單,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)。當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可。同時(shí),其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無法釋放,而產(chǎn)生的死鎖問題。

使用Zookeeper分布式鎖的優(yōu)點(diǎn):

1. 鎖無法釋放?使用Zookeeper可以有效的解決鎖無法釋放的問題,因?yàn)樵趧?chuàng)建鎖的時(shí)候,客戶端會(huì)在ZK中創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn),一旦客戶端獲取到鎖之后突然掛掉(Session連接斷開),那么這個(gè)臨時(shí)節(jié)點(diǎn)就會(huì)自動(dòng)刪除掉。其他客戶端就可以再次獲得鎖。

2. 非阻塞鎖?使用Zookeeper可以實(shí)現(xiàn)阻塞的鎖,客戶端可以通過在ZK中創(chuàng)建順序節(jié)點(diǎn),并且在節(jié)點(diǎn)上綁定監(jiān)聽器,一旦節(jié)點(diǎn)有變化,Zookeeper會(huì)通知客戶端,客戶端可以檢查自己創(chuàng)建的節(jié)點(diǎn)是不是當(dāng)前所有節(jié)點(diǎn)中序號(hào)最小的,如果是,那么自己就獲取到鎖,便可以執(zhí)行業(yè)務(wù)邏輯了。

3. 不可重入?使用Zookeeper也可以有效的解決不可重入的問題,客戶端在創(chuàng)建節(jié)點(diǎn)的時(shí)候,把當(dāng)前客戶端的主機(jī)信息和線程信息直接寫入到節(jié)點(diǎn)中,下次想要獲取鎖的時(shí)候和當(dāng)前最小的節(jié)點(diǎn)中的數(shù)據(jù)比對(duì)一下就可以了。如果和自己的信息一樣,那么自己直接獲取到鎖,如果不一樣就再創(chuàng)建一個(gè)臨時(shí)的順序節(jié)點(diǎn),參與排隊(duì)。

4. 單點(diǎn)問題?使用Zookeeper可以有效的解決單點(diǎn)問題,ZK是集群部署的,只要集中有半數(shù)以上的機(jī)器存活,就可以對(duì)外提供服務(wù)。

Redis分布式鎖和zookeeper分布式鎖的對(duì)比:

可靠性:zookeeper>Redis

性能:Redis>zookeeper

Redis中的虛擬內(nèi)存


和操作系統(tǒng)的虛擬內(nèi)存不是一回事,但思路是一樣的。Redis會(huì)把經(jīng)常不用的數(shù)據(jù)轉(zhuǎn)存到文件中,從而騰出內(nèi)存空間。通過VM操作來實(shí)現(xiàn)。

vm-enabled yes????????????????????????? #開啟vm功能

vm-swap-file /tmp/redis.swap??#交換出來的value保存的文件路徑

vm-max-memory 1000000??????????#redis使用的最大內(nèi)存上限,超過上限后redis開始交換value到磁盤文件中。

vm-page-size 32??????????????????? #每個(gè)頁面的大小32個(gè)字節(jié)

vm-pages 134217728???????????????? #最多使用在文件中使用多少頁面,交換文件的大小 = vm-page-size * vm-pages

vm-max-threads ?4?????????????#用于執(zhí)行value對(duì)象換入換出的工作線程數(shù)量。0表示不使用工作線程

vm-max-threads設(shè)置為0,不使用工作線程時(shí)

換出:當(dāng)檢測(cè)到有換出操作時(shí),主線程會(huì)以阻塞的方式來操作。直到內(nèi)存釋放到設(shè)置的最大上限以下時(shí),才繼續(xù)處理客戶端的請(qǐng)求。

換入:當(dāng)客戶端請(qǐng)求的數(shù)據(jù)被換出到文件時(shí),主線程會(huì)以阻塞的形式從文件中加載對(duì)應(yīng)的數(shù)據(jù),此時(shí)主線程阻塞所有的客戶端請(qǐng)求,直到加載完畢。

vm-max-threads設(shè)置為>0,使用工作線程時(shí)

換出:當(dāng)主線程檢測(cè)到內(nèi)存超出最大上限后,會(huì)將要換出的數(shù)據(jù)放到一個(gè)隊(duì)列中,由工作線程后臺(tái)處理,主線程此時(shí)繼續(xù)能處理客戶端的請(qǐng)求。

換入:當(dāng)客戶端請(qǐng)求的數(shù)據(jù)被換出時(shí),主線程會(huì)阻塞當(dāng)前的請(qǐng)求,把需要換入的數(shù)據(jù)放到隊(duì)列中,由工作線程去加載,加載完畢后工作線程通知主線程,主線程再響應(yīng)此客戶端請(qǐng)求。這種方式下,主線程只阻塞請(qǐng)求的數(shù)據(jù)被換出的客戶端請(qǐng)求,其他請(qǐng)求不阻塞。

重要說明:在Redis的內(nèi)存優(yōu)化中是要關(guān)閉虛擬內(nèi)存的,因?yàn)樘摂M內(nèi)存的換入換出操作的內(nèi)存管理成本是很高的。如果把虛擬內(nèi)存作為數(shù)據(jù)的一種持久化方式的話,這種方式并不成熟,也很雞肋。虛擬內(nèi)存已經(jīng)被作者放棄。

Redis的高可用和集群


什么是高可用?高可用就是指一旦Redis的服務(wù)器宕機(jī)了,緩存服務(wù)可以切換到其他機(jī)器上繼續(xù)對(duì)外提供服務(wù),不影響使用。要解決高可用,肯定得使用集群了。也就是一臺(tái)master服務(wù)器對(duì)外提供服務(wù),然后設(shè)置幾臺(tái)slave服務(wù)器作為備用。一旦master掛了,可以切換到slave中的任意一臺(tái)服務(wù)器繼續(xù)提供服務(wù)。

使用集群了,就得考慮主從服務(wù)器之間的數(shù)據(jù)同步。得保證這幾臺(tái)服務(wù)器上的緩存數(shù)據(jù)必須是一致的。主從同步分為全量同步和增量同步。全量同步一般是在服務(wù)器啟動(dòng)時(shí)進(jìn)行的,然后后續(xù)可以使用增量同步。所有的同步都可以使用Redis的api命令進(jìn)行操作。

Redis有一個(gè)哨兵模式(Redis Sentinel),它主要負(fù)責(zé)主從狀態(tài)的監(jiān)控和切換。

Redis協(xié)議


Redis即?REmote?Dictionary?Server (遠(yuǎn)程字典服務(wù));

而Redis的協(xié)議規(guī)范是 Redis?Serialization Protocol (Redis序列化協(xié)議)

該協(xié)議是用于與Redis服務(wù)器通信的,用的較多的是Redis-cli通過pipe與Redis服務(wù)器聯(lián)系。

Redis的通訊協(xié)議使用消息頭標(biāo)識(shí),消息行,還有行里可能還有個(gè)數(shù)據(jù)塊大小描述。

Redis是以行來劃分,每行以\r\n行結(jié)束。每一行都有一個(gè)消息頭,消息頭共分為5種

分別如下:

(+)表示一個(gè)正確的狀態(tài)信息,具體信息是當(dāng)前行+后面的字符。

(-)表示一個(gè)錯(cuò)誤信息,具體信息是當(dāng)前行-后面的字符。

(*)表示消息體總共有多少行,不包括當(dāng)前行,*后面是具體的行數(shù)。

($)表示下一行數(shù)據(jù)長(zhǎng)度,不包括換行符長(zhǎng)度\r\n,$后面則是對(duì)應(yīng)的長(zhǎng)度的數(shù)據(jù)。

(:)表示返回一個(gè)數(shù)值,:后面是相應(yīng)的數(shù)字節(jié)符。

使用Redis的協(xié)議可以自己編寫Redis的client處理程序。

Redis的內(nèi)存優(yōu)化


1. 禁止開啟虛擬內(nèi)存

2. redis.conf中的 maxmemory 選項(xiàng),意思是當(dāng)內(nèi)存達(dá)到一個(gè)值后,Redis拒絕寫入操作,避免影響性能甚至不停的寫入導(dǎo)致系統(tǒng)崩潰。

Redis針對(duì)不同的數(shù)據(jù)類型提供了不同的參數(shù)來進(jìn)行優(yōu)化。Redis Hash 是 value 內(nèi)部為一個(gè) HashMap,如果該 Map 的成員數(shù)比較少,則會(huì)采用類似一維線性的緊湊格式來存儲(chǔ)該 Map,即省去了大量指針的內(nèi)存開銷,這個(gè)參數(shù)控制對(duì)應(yīng)在 redis.conf 配置文件中下面2項(xiàng):


含義是當(dāng)value這個(gè) Map 內(nèi)部不超過多少個(gè)成員時(shí)會(huì)采用線性緊湊格式存儲(chǔ),默認(rèn)是64,即 value 內(nèi)部有64個(gè)以下的成員就是使用線性緊湊存儲(chǔ),超過該值自動(dòng)轉(zhuǎn)成真正的 HashMap。

hash-max-zipmap-value含義是當(dāng) value 這個(gè) Map 內(nèi)部的每個(gè)成員值長(zhǎng)度不超過多少字節(jié)就會(huì)采用線性緊湊存儲(chǔ)來節(jié)省空間。

以上2個(gè)條件任意一個(gè)條件超過設(shè)置值都會(huì)轉(zhuǎn)換成真正的 HashMap,也就不會(huì)再節(jié)省內(nèi)存了,那么這個(gè)值是不是設(shè)置的越大越好呢,答案當(dāng)然是否定的,HashMap 的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是 O(1) 的,而放棄 Hash 采用一維存儲(chǔ)則是 O(n) 的時(shí)間復(fù)雜度,如果成員數(shù)量很少,則影響不大,否則會(huì)嚴(yán)重影響性能,所以要權(quán)衡好這個(gè)值的設(shè)置,總體上還是最根本的時(shí)間成本和空間成本上的權(quán)衡。

同樣類似的參數(shù)還有:


說明:list數(shù)據(jù)類型多少節(jié)點(diǎn)以下會(huì)采用去指針的緊湊存儲(chǔ)格式。


說明:list數(shù)據(jù)類型節(jié)點(diǎn)值大小小于多少字節(jié)會(huì)采用緊湊存儲(chǔ)格式。


說明:set數(shù)據(jù)類型內(nèi)部數(shù)據(jù)如果全部是數(shù)值型,且包含多少節(jié)點(diǎn)以下會(huì)采用緊湊格式存儲(chǔ)。

如何解決高并發(fā)下Redis客戶端頻繁time out


先明白超時(shí)的原因是什么?首先前提是高并發(fā),那么肯定有許多個(gè)客戶端請(qǐng)求??蛻舳苏?qǐng)求到達(dá)Redis服務(wù)器后,因?yàn)镽edis是單線程的,客戶端的請(qǐng)求命令服務(wù)器端是一條一條執(zhí)行的。只有前面的執(zhí)行完畢了,才能執(zhí)行后面的。如果前面的某條數(shù)據(jù)執(zhí)行時(shí)間比較長(zhǎng),慢查詢,會(huì)導(dǎo)致后面的請(qǐng)求一直沒法到達(dá)Redis服務(wù)器里,導(dǎo)致連接超時(shí),請(qǐng)求阻塞。還有可能是客戶端連接數(shù)太多,超出了服務(wù)器端的承受能力。解決方案如下:

1. 客戶端連接池化,和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫客戶端池化是類似的。

2. 對(duì)于有慢查詢、大數(shù)據(jù)量的查詢盡量安排到去查詢數(shù)據(jù)庫,單獨(dú)隔離出來,不讓它影響其他的客戶端請(qǐng)求。

3. 對(duì)于多核CPU的電腦,可以設(shè)置多個(gè)Redis實(shí)例,數(shù)據(jù)分?jǐn)偟蕉鄠€(gè)Redis實(shí)例下,客戶端請(qǐng)求不同的服務(wù)器實(shí)例,分?jǐn)傔B接數(shù)量。

4. 合理設(shè)置連接的超時(shí)時(shí)間。

5. 使用Redis集群,分擔(dān)客戶端壓力。

Redis的持久化


主要分為兩種方式(快照和AOF),也有說是四種方式的(另外兩種是虛擬內(nèi)存和diskstore),這里只介紹快照和AOF兩種。

快照:Redis內(nèi)部有一個(gè)定時(shí)器,定時(shí)去檢查數(shù)據(jù)發(fā)生的改變次數(shù)和時(shí)間是否滿足持久化的條件,如果滿足,通過操作系統(tǒng)的fork來調(diào)用一個(gè)子進(jìn)程,通過子進(jìn)程來遍歷整個(gè)內(nèi)存進(jìn)行存儲(chǔ)操作。

Redis的緩存穿透和緩存雪崩


緩存穿透:黑客故意去請(qǐng)求緩存中不存在的數(shù)據(jù),導(dǎo)致所有的請(qǐng)求都到數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫連接異常。

解決辦法

1. 互斥鎖。緩存失效的時(shí)候,先獲得鎖,然后去數(shù)據(jù)庫請(qǐng)求數(shù)據(jù),沒得到鎖,就休眠一會(huì)重試,

2. 異步更新??蛻舳苏?qǐng)求Redis時(shí),無論緩存中是否存在請(qǐng)求的數(shù)據(jù)都直接返回。如果緩存過期了,異步開一個(gè)線程,去數(shù)據(jù)庫中讀取,然后更新緩存。這需要做緩存預(yù)熱功能,即程序啟動(dòng)前,先加載緩存。

緩存雪崩:Redis緩存大面積失效,導(dǎo)致所有的請(qǐng)求都到數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫服務(wù)器壓力巨大。

解決辦法

1. 緩存的失效時(shí)間不要設(shè)置為一致,最好是隨機(jī)數(shù),避免同一時(shí)刻緩存大面積過期。

2. 使用互斥鎖。但是鎖的使用降低了性能。一種技術(shù)有優(yōu)點(diǎn),也有缺點(diǎn)。合理使用。

3. 雙緩存。A緩存設(shè)置過期時(shí)間,B緩存不設(shè)置過期時(shí)間。先從A中查詢,查詢不到了再從B中查詢。同時(shí)異步起一個(gè)線程,同時(shí)更新兩個(gè)緩存。在很多微服務(wù)的架構(gòu)中就使用了二級(jí)緩存。

Redis的數(shù)據(jù)類型及使用場(chǎng)景


Redis有5種數(shù)據(jù)類型:

1. String最簡(jiǎn)單最基本的數(shù)據(jù)類型。可以使用計(jì)數(shù)器。

2. Hash哈希的特點(diǎn)是value值是一個(gè)結(jié)構(gòu)化的數(shù)據(jù)。使用的Redis共享session實(shí)現(xiàn)的單點(diǎn)登錄就是使用的hash。程序前端代碼的每個(gè)請(qǐng)求,用戶不用再手動(dòng)寫sessionID的參數(shù),程序自動(dòng)處理。

3. List可以做簡(jiǎn)單的隊(duì)列,還可以實(shí)現(xiàn)Redis的分頁功能。

4. Set特點(diǎn)是不重復(fù)的集合??梢杂脕碜鋈ブ?。

5. Sorted set有序集合,可以做排行榜,Top N的操作。還可以做延時(shí)和范圍查找。

如何解決Redis并發(fā)key


什么是并發(fā)key:就是同時(shí)有多個(gè)子系統(tǒng)或者多個(gè)線程同時(shí)去更新同一個(gè)key的值。特別是在集群,高并發(fā)環(huán)境下。

如果多個(gè)子系統(tǒng)同時(shí)更新key的值沒有先后順序,可以使用分布式鎖(集群環(huán)境下,得使用分布式鎖),誰先獲得鎖,誰先更新數(shù)據(jù)。

如果多個(gè)子系統(tǒng)更新的key值有先后順序,那么必要要求這多個(gè)子系統(tǒng)按照先后順序執(zhí)行??梢詫?shí)現(xiàn)RabbitMQ隊(duì)列來處理(隊(duì)列的兩大特性:異步和先進(jìn)先出)。



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容