
set類型是string類型的集合,其特點是集合元素無序且不重復,每個集合最多可以存儲 232 - 1 個元素(40多億),set類型主要有以下應用場景。
1. 好友/關注/粉絲/感興趣的人集合
set類型唯一的特點使得其適合用於存儲好友/關注/粉絲/感興趣的人集合,集合中的元素數量可能很多,每次全部取出來成本不小,set類型提供了一些很實用的命令用於直接操作這些集合,如
a. sinter命令可以獲得A和B兩個用戶的共同好友
b. sismember命令可以判斷A是否是B的好友
c. scard命令可以獲取好友數量
c. 關注時,smove命令可以將B從A的粉絲集合轉移到A的好友集合
需要注意的是,如果你用的是Redis Cluster集群,對於sinter、smove這種操作多個key的命令,要求這兩個key必須存儲在同一個slot(槽位)中,否則會報出 (error) CROSSSLOT Keys in request don't hash to the same slot 錯誤。Redis Cluster一共有16384個slot,每個key都是通過哈希算法CRC16(key)獲取數值哈希,再模16384來定位slot的。要使得兩個key處於同一slot,除了兩個key一模一樣,還有沒有別的方法呢?答案是肯定的,Redis提供了一種Hash Tag的功能,在key中使用{}括起key中的一部分,在進行 CRC16(key) mod 16384 的過程中,只會對{}內的字符串計算,例如friend_set:{123456}和fans_set:{123456},分別表示用戶123456的好友集合和粉絲集合,在定位slot時,只對{}內的123456進行計算,所以這兩個集合肯定是在同一個slot內的,當用戶123456關注某個粉絲時,就可以通過smove命令將這個粉絲從用戶123456的粉絲集合移動到好友集合。相比於通過srem命令先將這個粉絲從粉絲集合中刪除,再通過sadd命令將這個粉絲加到好友集合,smove命令的優勢是它是原子性的,不會出現這個粉絲從粉絲集合中被刪除,卻沒有加到好友集合的情況。然而,對於通過sinter獲取共同好友而言,Hash Tag則無能為力,例如,要用sinter去獲取用戶123456和456789兩個用戶的共同好友,除非我們將key定義為{friend_set}:123456和{friend_set}:456789,否則不能保證兩個key會處於同一個slot,但是如果真這樣做的話,所有用戶的好友集合都會堆積在同一個slot中,數據分布會嚴重不均勻,不可取,所以,在實戰中使用Redis Cluster時,sinter這個命令其實是不適合作用於兩個不同用戶對應的集合的(同理其它操作多個key的命令)。
2. 隨機展示
通常,app首頁的展示區域有限,但是又不能總是展示固定的內容,一種做法是先確定一批需要展示的內容,再從中隨機獲取。如下圖所示,酷狗音樂K歌擂台賽當日的打擂歌曲共29首,首頁隨機展示5首;昨日打擂金曲共200首,首頁隨機展示30首。

set類型適合存放所有需要展示的內容,而srandmember命令則可以從中隨機獲取幾個。
3. 黑名單/白名單
經常有業務出於安全性方面的考慮,需要設置用戶黑名單、ip黑名單、設備黑名單等,set類型適合存儲這些黑名單數據,sismember命令可用於判斷用戶、ip、設備是否處於黑名單之中。
set類型的常用命令可參考http://www.runoob.com/redis/redis-sets.html
加入set類型的應用場景后的思維導圖如下。

