最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis Sorted Set類型使用及應(yīng)用場景

 更新時間:2024年06月12日 11:44:30   作者:Applosl  
Sorted Set是Redis常用的一種是數(shù)據(jù)類型,本文主要介紹了Redis Sorted Set類型使用及應(yīng)用場景,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

sorted set在沒有重復(fù)元素的集合基礎(chǔ)上,每個元素多了一個分?jǐn)?shù)score屬性作為權(quán)重,查詢時可以用score排序。

Sorted Set類型的常用操作

ZADD 添加元素

127.0.0.1:6379> ZADD rank 98 u1
(integer) 1
127.0.0.1:6379> ZADD rank 95 u2
(integer) 1
127.0.0.1:6379> ZADD rank 60 u3
(integer) 1
127.0.0.1:6379> ZADD rank 76 u4
(integer) 1
127.0.0.1:6379> ZADD rank 77 u5
(integer) 1

ZCARD 獲取集合成員數(shù)量

127.0.0.1:6379> ZCARD rank
(integer) 5

ZCOUNT 獲取指定分?jǐn)?shù)段內(nèi)的成員數(shù)量

127.0.0.1:6379> ZCOUNT rank 80 100
(integer) 2

ZINCRBY 給集合中指定成員增加指定分?jǐn)?shù)

127.0.0.1:6379> ZINCRBY rank 2 u3
"62"

ZRANGE/ZREVRANGE 返回按索引排序的成員

127.0.0.1:6379> ZRANGE rank 0 1 # 分?jǐn)?shù)從小到大
1) "u3"
2) "u4"

127.0.0.1:6379> ZREVRANGE rank 0 2 # 分?jǐn)?shù)從大到下
1) "u1"
2) "u2"
3) "u5"

ZRANGEBYSCORE/ZREVRANGEBYSCORE 返回按指定分?jǐn)?shù)段內(nèi)的元素列表

127.0.0.1:6379> ZRANGEBYSCORE rank 80 100 # 分?jǐn)?shù)段從小到大
1) "u2"
2) "u1"

127.0.0.1:6379> ZREVRANGEBYSCORE rank 100 80 # 分?jǐn)?shù)段從大到小
1) "u1"
2) "u2"

ZREM 刪除指定元素

127.0.0.1:6379> ZREM rank u2
(integer) 1

實際應(yīng)用場景

1.排行榜

實現(xiàn)一個實時變化的積分排行榜,可以利用 ZREVRANGE 輕松展現(xiàn)最高排名,并實現(xiàn)分頁查詢
首先將成員名單錄入

127.0.0.1:6379> ZADD rank 0 player1 0 player2 0 player3 0 player4 0 player5 0 player6
(integer) 6

當(dāng)然也可以在合適的時機(jī)將新增的成員單個寫入

然后開始實時計算增加的分?jǐn)?shù) 使用ZINCRBY, 增加完后會直接返回當(dāng)前成員的最終分?jǐn)?shù)

127.0.0.1:6379> ZINCRBY rank 50 player1 
"50"
127.0.0.1:6379> ZINCRBY rank 53 player3 
"53"
127.0.0.1:6379> ZINCRBY rank 20 player5 
"20"
127.0.0.1:6379> ZINCRBY rank 40 player6
"40"
127.0.0.1:6379> ZINCRBY rank 40 player5
"60"
127.0.0.1:6379> ZINCRBY rank -2 player6 # 負(fù)數(shù)也是可以的 相當(dāng)于減分
"38"

也可以不用初始化成員分?jǐn)?shù) 直接給一個不存在的的成員增加分?jǐn)?shù),默認(rèn)會創(chuàng)建并增加分?jǐn)?shù),默認(rèn)從0開始

127.0.0.1:6379> ZINCRBY rank 55 player7
"55"

最后獲取排行榜上前3的成員,使用ZREVRANGE

127.0.0.1:6379> ZREVRANGE rank 0 2
1) "player5"
2) "player7"
3) "player3"

如果要帶上分?jǐn)?shù),需要增加一個參數(shù) WITHSCORES

127.0.0.1:6379> ZREVRANGE rank 0 2 WITHSCORES
1) "player5"
2) "60"
3) "player7"
4) "55"
5) "player3"
6) "53"

2.定時/延遲任務(wù)

定時/延遲任務(wù),或是延遲隊列類功能,最重要的是在指定時間后才開始處理相關(guān)任務(wù)。

以下是大致實現(xiàn)方式

任務(wù)生產(chǎn)端:

每個任務(wù)生成一個任務(wù)ID(要有唯一性),將具體的任務(wù)信息可以放在其他數(shù)據(jù)庫里,當(dāng)然也可以放在Redis里。然后將任務(wù)ID作為sorted set的成員, 需要執(zhí)行任務(wù)時間點的時間戳作為score寫入(如果是延遲任務(wù)就計算出具體的時間戳)

127.0.0.1:6379> ZADD tasks 1000 t1 # 假設(shè)當(dāng)前時間戳從1000開始
(integer) 1
127.0.0.1:6379> ZADD tasks 1003 t2  # 3s后才能觸發(fā)的任務(wù)
(integer) 1
127.0.0.1:6379> ZADD tasks 1004 t3
(integer) 1
127.0.0.1:6379> ZADD tasks 1004 t4
(integer) 1

這時sorted set里的任務(wù)順序大概是這樣(按分?jǐn)?shù)從小達(dá)到)

t1t2t3t4
1000100310041004

任務(wù)消費(fèi)端

啟動一個進(jìn)程循環(huán)獲取任務(wù), 獲取分?jǐn)?shù)的范圍在當(dāng)前時間戳之前(表示已經(jīng)到期的任務(wù))

127.0.0.1:6379> ZRANGEBYSCORE tasks -inf 1000
1) "t1"

程序代碼大概可以這樣寫

# 偽代碼
while true {
	nowTimestamp = time.now() # 獲取當(dāng)前時間戳
	taskIds = redis.ZRANGEBYSCORE("tasks", "-inf", nowTimestamp)
	for taskId in TaskIds {
		# TODO 執(zhí)行任務(wù)處理邏輯
	}
}

不過有個很明顯的問題, 當(dāng)時間戳到1003的時候,任務(wù)t1還是能夠獲取到

127.0.0.1:6379> ZRANGEBYSCORE tasks -inf 1003
1) "t1"
2) "t2"

這是因為ZRANGEBYSCORE只是查詢出來,并沒有刪除元素,刪除元素需要使用ZREM
完善一下代碼

# 偽代碼
while true {
	nowTimestamp = time.now() # 獲取當(dāng)前時間戳
	taskIds = redis.ZRANGEBYSCORE("tasks", "-inf", nowTimestamp)
	for taskId in taskIds {
	    # TODO 執(zhí)行任務(wù)處理邏輯
	    # 正常處理了調(diào)用ZREM
	    redis.ZREM("tasks", taskId)
	}
}

接下來隨著任務(wù)越來越多,上面的處理邏輯可能短時間內(nèi)也處理不完,或者單個任務(wù)處理時間較長,就會導(dǎo)致已經(jīng)到期的任務(wù)無法及時處理。
一般情況下,任務(wù)之間是沒有依賴關(guān)系,這時可以考慮橫向庫容消費(fèi)進(jìn)程,并行處理任務(wù)。

不過直接將上面的邏輯復(fù)制在多個進(jìn)程里,會有任務(wù)重復(fù)的問題。

t1t2t3t4
1000100310041004
進(jìn)程1查詢點
進(jìn)程2查詢點

就像上面一樣,可能出現(xiàn),兩個進(jìn)程同時獲取到t1任務(wù)

有兩種處理方式:

第一種 增加分布式鎖,可以基于Redis的set類型數(shù)據(jù)

代碼如下

# 偽代碼
while true {
	nowTimestamp = time.now() # 獲取當(dāng)前時間戳
	taskIds = redis.ZRANGEBYSCORE("tasks", "-inf", nowTimestamp)
	for taskId in taskIds {
		addSuccess = redis.SADD("tasks:lock", taskId)
		if addSuccess == 0 {
			# 寫入不成功 說明有其他進(jìn)程在處理該任務(wù)
			continue
		}
	    # TODO 執(zhí)行任務(wù)處理邏輯
	    
	    redis.ZREM("tasks", taskId) # 正常處理了調(diào)用ZREM 刪除任務(wù)
	    redis.SREM("tasks:lock", taskId)  # 釋放鎖, 當(dāng)然如果是任務(wù)處理失敗 也可以釋放鎖 以便可以重試任務(wù)
	}
}

如果某一段時間沒有任務(wù),會存在 ZRANGEBYSCORE 空轉(zhuǎn)的情況,增加了不必要的網(wǎng)絡(luò)調(diào)用
可以在獲取不到任務(wù)的時候,等待一個任務(wù)時間最小間隔 通常是1s

# 偽代碼
while true {
	nowTimestamp = time.now() # 獲取當(dāng)前時間戳
	taskIds = redis.ZRANGEBYSCORE("tasks", "-inf", nowTimestamp)
	if len(taskIds) == 0 {
		sleep(1)
		continue
	}
	for taskId in taskIds {
		addSuccess = redis.SADD("tasks:lock", taskId)
		if addSuccess == 0 {
			# 寫入不成功 說明有其他進(jìn)程在處理該任務(wù)
			continue
		}
	    # TODO 執(zhí)行任務(wù)處理邏輯
	    
	    redis.ZREM("tasks", taskId) # 正常處理了調(diào)用ZREM 刪除任務(wù)
	    redis.SREM("tasks:lock", taskId)  # 釋放鎖, 當(dāng)然如果是任務(wù)處理失敗 也可以釋放鎖 以便可以重試任務(wù)
	}
}

第二種 任務(wù)實際處理邏輯繼續(xù)下沉

當(dāng)前程序不進(jìn)行任務(wù)處理 只取到期的任務(wù),任務(wù)處理交給其他任務(wù)處理進(jìn)程專門處理,只向List里推送任務(wù)

# 偽代碼
# 定時獲取任務(wù)程序 保留一個
while true {
	nowTimestamp = time.now() # 獲取當(dāng)前時間戳
	taskIds = redis.ZRANGEBYSCORE("tasks", "-inf", nowTimestamp)
	
	if len(taskIds) == 0 {
		sleep(1)
		continue
	}
	for taskId in taskIds {
		redis.LPUSH("tasks:list", taskId) # 下推到隊列任務(wù)
	    redis.ZREM("tasks", taskId) # 刪除指定元素
	}
}

# 下層的任務(wù)處理程序 可以橫向擴(kuò)展運(yùn)行多個進(jìn)程
while true {
	taskId = redis.BRPOP("tasks:list", 10) # 還考慮服務(wù)器 閑置連接超時 斷開的異常
	if taskId is null {
 		continue
	}
	# TODO 執(zhí)行任務(wù)處理邏輯
	# 任務(wù)如果處理失敗需要重試 可以考慮重新ZADD到 tasks 里
}

如果生產(chǎn)消息的速度非???,也是可以考慮把 “定時獲取任務(wù)程序” 也橫向擴(kuò)展,不過需要增加分布式鎖,避免重復(fù)消費(fèi),可參考 第一種 的處理方式;也可以將任務(wù)按業(yè)務(wù)類型分類,放在不同的sorted set 中分別處理,互不影響。

到此這篇關(guān)于Redis Sorted Set類型使用及應(yīng)用場景的文章就介紹到這了,更多相關(guān)Redis Sorted Set使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis分片集群存儲的搭建到使用

    Redis分片集群存儲的搭建到使用

    這篇文章主要介紹了Redis分片集群存儲的搭建到使用,分片集群顧名思義,將數(shù)據(jù)分開存儲到Redis集群中,這樣能夠存儲更多的數(shù)據(jù),避免浪費(fèi)資源,需要的朋友可以參考下
    2022-06-06
  • redis8.0新特性之布谷鳥過濾器(Cuckoo Filter)的使用

    redis8.0新特性之布谷鳥過濾器(Cuckoo Filter)的使用

    布谷鳥過濾器是一種概率數(shù)據(jù)結(jié)構(gòu),就像布隆過濾器一樣,可以以非常快速且節(jié)省空間的方式檢查元素是否存在于集合中,同時還支持刪除操作,并在某些場景下表現(xiàn)優(yōu)于布隆過濾器,感興趣的可以了解一下
    2025-08-08
  • redis輕松處理經(jīng)緯度坐標(biāo)點數(shù)據(jù)的實現(xiàn)方法

    redis輕松處理經(jīng)緯度坐標(biāo)點數(shù)據(jù)的實現(xiàn)方法

    這篇文章主要介紹了redis輕松處理經(jīng)緯度坐標(biāo)點數(shù)據(jù)的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Windows系統(tǒng)一鍵啟動Redis腳本

    Windows系統(tǒng)一鍵啟動Redis腳本

    本文介紹了在Windows系統(tǒng)中創(chuàng)建一鍵啟動Redis的腳本,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • Redis通過scan查找不過期的 key(方法詳解)

    Redis通過scan查找不過期的 key(方法詳解)

    SCAN 命令是一個基于游標(biāo)的迭代器,每次被調(diào)用之后, 都會向用戶返回一個新的游標(biāo), 用戶在下次迭代時需要使用這個新游標(biāo)作為 SCAN 命令的游標(biāo)參數(shù), 以此來延續(xù)之前的迭代過程,對Redis scan 查找 key相關(guān)知識感興趣的朋友一起看看吧
    2021-08-08
  • springboot +redis 實現(xiàn)點贊、瀏覽、收藏、評論等數(shù)量的增減操作

    springboot +redis 實現(xiàn)點贊、瀏覽、收藏、評論等數(shù)量的增減操作

    這篇文章主要介紹了springboot +redis 實現(xiàn)點贊、瀏覽、收藏、評論等數(shù)量的增減操作,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • 解鎖redis鎖的正確姿勢

    解鎖redis鎖的正確姿勢

    這篇文章主要為大家詳細(xì)介紹了解鎖redis鎖的正確姿勢,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Redis的哈希Hash類型常用命令的使用小結(jié)

    Redis的哈希Hash類型常用命令的使用小結(jié)

    Redis哈希類型類似于一個鍵值對集合,通常用于存儲對象,每個哈希包含多個字段,每個字段都有一個值,哈希類型支持一系列常用命令,下面就來詳細(xì)的介紹一下這些命令的使用,感興趣的可以了解一下
    2025-08-08
  • window手動操作清理redis緩存的技巧總結(jié)

    window手動操作清理redis緩存的技巧總結(jié)

    在本篇文章中小編給大家分享了關(guān)于window環(huán)境手動操作清理redis緩存的方法和技巧,有興趣的朋友們可以跟著學(xué)習(xí)下。
    2019-07-07
  • 基于redis.properties文件的配置及說明介紹

    基于redis.properties文件的配置及說明介紹

    今天小編就為大家分享一篇基于redis.properties文件的配置及說明介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05

最新評論

建始县| 句容市| 台州市| 绥江县| 永安市| 甘洛县| 巴林左旗| 固镇县| 寿阳县| 承德市| 界首市| 鄂托克前旗| 玉屏| 邢台县| 北海市| 名山县| 通州市| 文山县| 景谷| 锡林郭勒盟| 五原县| 富平县| 呼伦贝尔市| 财经| 会昌县| 楚雄市| 福鼎市| 甘南县| 资中县| 东乡族自治县| 扎鲁特旗| 张家界市| 应城市| 文水县| 长治市| 奈曼旗| 镇平县| 阳西县| 海阳市| 通江县| 安丘市|