redis zset實現排行榜

2021-12-25 偉忠分享


轉載自 https://duyanghao.github.io/redis-rank/


排行榜介紹

在業務開發過程中會遇到很多排行榜類似的需求,比如粉絲排行榜,播放排行榜等,排行榜本身含義非常清晰,就是維護一個列表,其中每個條目有一個score,依據score進行排序,形成排行榜。

redis zset

redis zset由於如下特性天生支持排行榜需求:

利用 redis zset 實現排行榜功能

現在假定有如下排行榜需求:實現一個粉絲Top10排行榜。

簡單分析該需求,我們可以將用戶id作為member,用戶粉絲量作為score,

並設置 redis key 為 fans_rank 形成 redis zset

按照如下步驟你可以很容易地實現該功能:

1.zset添加member

如果用戶粉絲數目發生變動,則需要將該用戶重新添加到zset中進行排序,假定用戶id為user_id,粉絲量為score,則命令如下:

ZADD fans_rank user_id score

注意算法複雜度:

Time complexity: O(log(N)) for each item added, where N is the number of elements in the sorted set.

2.zset維持TopN操作

由於要維持TopN排行榜,所以最好的處理方法是每次ZADD後執行ZREMRANGEBYRANK,假定要維護TopN榜單,則命令如下:

ZREMRANGEBYRANK fans_rank 0 -(TopN+1)

注意:

這裡範圍是0——-(TopN+1),因為redis zset是按照從小到大方式排序的,所以需要維持的榜單是倒數TopN,也即從最後一個元素開始,倒數推TopN個

時間複雜度:

Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements removed by the operation.


3. zset刪除member

如果某個用戶進行註銷操作,或者被封號了,這個時候該用戶應該從redis zset中被踢掉,如下:

ZREM fans_rank user_id

注意算法複雜度:

Time complexity: O(M*log(N)) with N being the number of elements in the sorted set and M the number of elements to be removed.


4、zset範圍讀取

最後是獲取排行榜TopN數據,命令如下:

ZREVRANGE fans_rank 0 (TopN-1) withscores

注意:

這裡範圍是0——TopN-1,原因是:redis zset下標從0開始,而ZREVRANGE是倒序取數據

redis zset ZRANGE與ZREVRANGE當元素score相同時會默認根據member字典序排序

withscores會將member與對應score一起返回

算法複雜度:

Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements returned.

通過如上四個步驟就可以順利完成排行榜核心邏輯開發


其他

這裡給出redis zset與排行榜功能相關的其它幾個常用命令:

順序取數據——ZRANGE

計算長度——ZCARD

相關焦點

  • 用Redis的zset有序集合實現一個本周熱議功能
    小Hub領讀:項目eblog的第四篇講解文章,今天我們先來實現一個比較牛逼的功能,博客裡面有個本周熱議排行功能,就是根據評論的數量
  • redis的zset有多牛?請把耳朵遞過來
    本篇文章很短,但信息量很大,是關於redis的zset。我來分享一點遇到過的線上數據,或許對你的決策有幫助。redis支持一個數據結構,叫做 zset,也就是有序的列表。當然redis也不能濫用,可以看我以前的規範文章:《這可能是最中肯的Redis規範了》忘了zset是個啥的同學可以看這張gif圖。通過它,可以實現遊戲排行榜一類的功能,或者實現Topx這樣的需求,也能精準的讓用戶在海量數據中找到自己的位置。
  • 一文讀懂redis的zset
    zset的數據結構在redis中有一個有序列表,它的底層是由壓縮列表或跳表組成。
  • 【快速了解redis】五種數據類型-zset篇
    >現在我們看看我們記錄的最喜歡的水果有多少種# ZCARD zset127.0.0.1:6379> zcard "favorite fruit"(integer) 4ZRANGE 獲取指定範圍內的元素我們想把前三名的水果都查出來,則可以通過zrange來查出來
  • Redis的set和zset
    字符串沒啥說的,最基礎和常見的String;哈希就是key-value結構;對於鍊表,有c語言基礎的應該也了解,可以簡單理解為在數組基礎上多了一個指向下一個元素的指針;集合就類似於Java裡的Set,無序無重複元素集合;有序集合則在集合的基礎上增加了順序,可以先簡單理解為通過為每個元素增加「分數」概念實現。
  • Golang中間件——go-redis操作Redis
    集合是通過哈希表實現的,所以添加,刪除,查找的複雜度都是 O(1)。redis正是通過分數來為集合中的成員進行從小到大的排序。zset的成員是唯一的,但分數(score)卻可以重複。= nil { fmt.Println("connect redis failed:", err) return } rdb.ZAdd(ctx, "test_zset", &redis.Z{ Score: 1, Member: "python", }) rdb.ZAdd(ctx, "test_zset", &redis.Z{ Score
  • 如何實現redis主從複製?
    主從複製,主要優勢在於實現了數據備份(主機和從機數據同步一致)、讀寫分離(主機主要負責寫入數據,從機讀數據,在讀大於寫的項目中提高了性能)。最後也為後續集成哨兵機制和集群的實現提供了依據。,本質上是同時啟動幾個redis實例來實現。
  • Redis的簡單入門
    Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。Redis支持數據的備份,即master-slave模式的數據備份。Redis 優勢性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 架構秘笈:移花接木,使用MySQL模擬Redis
    大家都知道redis速度快,但它的容量和內存容量有關,很容易達到瓶頸。有些網際網路公司,直接使用redis作為後端資料庫(在下佩服)。當業務量暴增,就面臨一個redis容量和價格的權衡問題。改業務代碼是來不及了,只好用一些持久化存儲 ,來模擬redis的一些數據結構。redis支持近十種數據類型,最常用的有5種。string、hash、zset、set、list等。本文將針對幾種常見的數據結構,探討一下常用操作的模擬實現。
  • 還不懂Redis是什麼?一文帶你深入Redis基本結構,準備向開發進軍
    #運行redis容器〉docker run - name myredis -d -p6379:6379 redis .〉yum install redis#運行客戶端> redis-cliRedis基礎數據結構Redis有5種基礎數據結構,分別為: string (字符串)、list (列表)、set (集合)、hash (哈希)和zset
  • Redis,常見的 9 種使用場景
    3、計數器相關問題redis 由於 incrby 命令可以實現原子性的遞增,所以可以運用於高並發的秒殺活動、分布式序列號的生成、具體業務還體現在比如限制一個手機號發多少條簡訊、一個接口一分鐘限制多少請求、一個接口一天限制調用多少次等等。
  • redis基礎筆記
    ——陶淵明《飲酒》前言reference: https://www.tutorialspoint.com/redis/redis_quick_guide.htmscrapy過濾重複連結使用到了redis,所以就先熟悉了下redis的基礎。
  • laravel框架中使用redis
    一、簡介Redis是一個nosql資料庫,現在用的比較多,PHP中直接操作redis大家都很熟悉了,在laravel中如何操作redis呢?本專題內容來講解。二、特性redis是一個key-value存儲系統。
  • Redis常用命令手冊:鍵值相關命令
    鍵值相關命令  1、keys  返回滿足給定pattern的所有key:  redis 127.0.0.1:6379> keys *  1) "myzset2"  2) "myzset3"  3) "mylist"  4) "myset2
  • 圖解redis五種數據結構底層實現(動圖哦)
    redis有五種基本數據結構:字符串、hash、set、zset、list。但是你知道構成這五種結構的底層數據結構是怎樣的嗎? 今天我們來花費五分鐘的時間了解一下。 (目前redis版本為3.0.6)動態字符串SDSSDS是"simple dynamic string"的縮寫。
  • Redis怎麼實現查找附近的人,請看特殊數據類型Geospatial
    前面我們已經把五大數據類型講完了,今天我開始講redis特殊數據類型Geospatial,地理位置的存儲,這個是數據類型可以實現朋友定位,兩個地方之間的距離,搜索附近的人等。獲取某個元素附近的元素以給定元素為原點,找出半徑內的所有元素,這個功能是不是可以實現我們搜索附近的人,假如我當前位置經度緯度為 110 30 現在要找出記錄這個點周圍1000km內的城市GEORADIUS [key] [當前位置經度] [當前位置緯度]
  • Python操作Redis大全
    'b'LIAOgaoxiang'b'goo'19b'10'b'10111'二、列表 listsPython操作Redis主要利用了redis模塊來實現,list表操作函數主要模擬了Redis操作命令LPUSH,LRANGE,LINDEX,BLPOP,BRPOP。
  • Redis中ZSet的底層數據結構跳躍表skiplist,你真的了解嗎?
    我們來想一下,為啥 Redis 中這兩個場景要選擇 skiplist?既然跳躍表是一種有序數據結構,那我們就來考慮在有序序列中查找某個特定元素的情境:如果該序列用支持隨機訪問的線性結構(數組)存儲,那麼我們很容易地用二分查找來做。但是考慮到增刪效率和內存擴展性,很多時候要用不支持隨機訪問的線性結構(鍊表)存儲,就只能從頭遍歷、逐個比對。
  • 用 Python 操作 Redis,看這一篇就夠了
    **',port=6379,password='123456',decode_responses=True,charset='UTF-8', encoding='UTF-8')接下來我們以操作字符串、列表、set 集合、zset 集合、哈希表、事務為例,講講 Python 操作這些數據的方法1、字符串操作操作字符串有兩種方式,操作方法分別是:set
  • 超強、超詳細Redis入門教程
    官網地址: https://redis.io/命令地址:http://doc.redisfans.com/最新版本 : 3.2.9應用版本: 3.0.4Redis的五大數據類型以及應用場景 Listk-v格式中 v的數據類型是List