visual studio網(wǎng)站開發(fā)教程需要優(yōu)化的網(wǎng)站有哪些?
目錄
引言
Zset 集合命令
ZINTERSTORE
ZUNIONSTORE
Zset 編碼方式
Zset 應(yīng)用場景
排行榜系統(tǒng)
引言
- 在 Redis 中集合間操作無非就是?交集、并集、差集?
- Set 類型與之相對應(yīng)的操作命令為 sinter、sunion、sdiff
注意:
- 從 Redis 6.2 版本開始,Zset 命令才開始支持?zinter、zunion、zdiff 這幾個命令
- 但是此處我們使用的是 Redis 5 版本,所以下文不涉及介紹這三個命令
Zset 集合命令
ZINTERSTORE
- 用于求出給定有序集合中元素的交集,并將其保存進目標有序集合中
- 合并過程中以元素為單位進行合并,元素對應(yīng)的分數(shù)按照不同的聚合方式和權(quán)重得到新的分數(shù)
語法:
zinterstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <sum | min | max>]
- destination:表示要把結(jié)果存儲到哪個 key 對應(yīng)的 zset 中
- numkeys:描述了后續(xù)有幾個 key 參與交集運算,因此該變量需為整型
- weight:可理解為 權(quán)重,此處指定的權(quán)重,相當于一個系數(shù),會乘以當前的分數(shù)
- aggregate:指定 當前給定的有序集合 應(yīng)采用哪種聚合方式來得出新的分數(shù)
注意:
- 前面介紹的命令也是支持多個 key 的,如mget、mset 等
- 但這些命令卻不涉及到類似于此處的設(shè)定,即需手動指出?key 的個數(shù)
官方文檔解釋:
- 主要是為了避免 zinterstore 命令的 選項 和 keys 弄混淆
- 即通過 numkeys 描述出 key 的個數(shù)后,便可明確知道后面的 "選項" 是從哪里開始的
總結(jié):
- 正因為 mget、mset 等命令,在指定 keys 后無復(fù)雜的選項
- 所以無需采用?numkeys 來手動指出 key 的個數(shù),以便知道?key 和 選項 之間的分界處
時間復(fù)雜度:
- O(N) + O(M * logM)
- N 為 所有輸入命令中總的 有序集合 元素個數(shù)
- M 為 結(jié)果集?的元素個數(shù)
實例理解
- 此處我們可以指定 權(quán)重
- 我們還可以指定 聚合方式
ZUNIONSTORE
- 用于求出給定有序集合的并集,并將其保存到目標有序集合中
- 合并過程中以元素為單位進行合并,元素對應(yīng)的分數(shù)按照不同的聚合方式和權(quán)重得到新的分數(shù)
語法:
zunionstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <sum | min | max>]
- zunionstore 和 zinterstore 命令的用法大致相同
時間復(fù)雜度:
- O(N) + O(M * logM)
- N 為 所有輸入命令中總的 有序集合 元素個數(shù)
- M 為 結(jié)果集?的元素個數(shù)
實例理解
- 此處我們可以指定 權(quán)重
- 我們還可以指定 聚合方式
Zset 編碼方式
- 有序集合的內(nèi)部編碼有 兩種
- ziplist(壓縮列表)
- skiplist(跳表)
注意點一:
- 如果有序集合中的元素個數(shù)較少,或者單個元素體積較小時
- 使用 ziplist 來存儲,以達到 節(jié)省空間 的效果
注意點二:
- 如果有序集合中的元素個數(shù)較多,或者單個元素體積非常大時
- 使用 skiplist 來存儲
兩個配置項
- ??????zset-max-ziplist-entries:(單位為元素個數(shù))
- zset-max-ziplist-value:(單位為字節(jié))
- 當有序集合的元素個數(shù)小于 1號配置項,當每個元素的值都小于 2號配置項時
- Redis 會使用 ziplist 來作為有序集合的內(nèi)部編碼
關(guān)于跳表
- 簡單來說,跳表是一個 復(fù)雜鏈表,其查詢元素的時間復(fù)雜度為 O(logN)
- 相比于樹形結(jié)構(gòu),更適合按照范圍獲取元素(B+ 樹)
Zset 應(yīng)用場景
排行榜系統(tǒng)
- 微博熱搜、游戲天梯排行、成績排行等
關(guān)鍵要點:
- 用來排行的分數(shù)為實時變化的
- 雖然是實時變化的,卻也能夠高效的更新排行
重點理解:
- 有序集合(zset) 能很好的滿足上述需求和關(guān)鍵要點
實例理解
- 比如游戲天梯排行
- 只需要將 玩家信息和該玩家所對應(yīng)的分數(shù)給放到有序集合中即可
- 從而便能 自動就形成一個排行榜
- 我們也能 隨時按照排行(下標)、按照分數(shù) 來進行范圍查詢
- 隨著分數(shù)發(fā)生改變,也可以比較方便的使用 zincrby 命令來修改分數(shù),且排行榜順序也能自動進行調(diào)整,該操作的時間復(fù)雜度為 O(logN)
問題:
- 游戲玩家這么多,此時都用這個 zset 來存,內(nèi)存能否存下?
舉例:
- 假設(shè)此時我們有?1億 個玩家
- 約定?userId 4個字節(jié),score 8個字節(jié),即一個玩家需要 12 個字節(jié)來表示
- 12億 字節(jié) ——> 1.2 GB,對于當今計算機來說,綽綽有余!
實例理解二
- 相較于游戲排行榜,其排序依據(jù)很容易確定,僅需根據(jù)玩家積分即可
- 微博的排行榜,其排序依據(jù)評估起來更為復(fù)雜,因為 微博熱度是一個綜合數(shù)值!
- 其參考方面包含 瀏覽量、點贊量、轉(zhuǎn)發(fā)量、評論量等
- 上述各方面具有不同?權(quán)重 weight,進而計算得到綜合數(shù)值(熱度)
重點理解
- 此時可以借助 zinterstore / zunionstore 命令,按照加權(quán)方式進行處理
- 可以把上述每個維度的數(shù)值均放到一個有序集合中
- member 為?微博的id,score 為各自維度的數(shù)值
- 通過? zinterstore / zunionstore 命令將上述有序集合按照約定好的權(quán)重,進行集合間運算即可
- 最終得到結(jié)果集合,其分數(shù)便為熱度,且 排行榜也順帶著出來了!
總結(jié):
- 上述應(yīng)用場景,Redis 中的 zset 是一個選擇,但不是說非得用 Reids 中的 zset 不可
- 有些場景下確實可以使用到有序集合,但又不方便使用 Redis 時,可以考慮使用其他方式的有序集合