Redis數(shù)據(jù)結(jié)構(gòu)及應(yīng)用場(chǎng)景總結(jié)

redis與memcached區(qū)別?

長(zhǎng)弓張(memcached):

1、我的系統(tǒng)業(yè)務(wù)以純kv的緩存為主,數(shù)據(jù)量、并發(fā)業(yè)務(wù)量大,memcache較為合適。

2、memcache將所有數(shù)據(jù)存儲(chǔ)在物理內(nèi)存中。redis則有自己的VM機(jī)制,當(dāng)數(shù)據(jù)超量時(shí),會(huì)引發(fā)swap(交換分區(qū)),影響我的性能。

3、memcache使用多線程的模式(主線程監(jiān)聽(tīng),work子線程工作),而redis使用單線程,難以充分利用目前的多核cpu。

子木李(redis):

1、redis在數(shù)據(jù)持久化提供了兩種方式RDB、AOF,雖然不是那么完美,但是系統(tǒng)發(fā)生崩潰時(shí)有這一層聊勝于無(wú),對(duì)不對(duì)。

2、redis天然高可用,官方提供了sentinel集群管理工具,釋放了大量的工作內(nèi)容。

3、redis能存儲(chǔ)的內(nèi)容較memcached的1M要大多了。

4、redis青出于藍(lán)而勝于藍(lán),代碼質(zhì)量比memcached好多了。

5、我的系統(tǒng)不僅僅只用了KV,我需要用到redis豐富的數(shù)據(jù)結(jié)構(gòu)及相關(guān)功能函數(shù),memcached不適合我的系統(tǒng)。

redis常用的數(shù)據(jù)結(jié)構(gòu)

字符串鍵

1、結(jié)構(gòu)類型如下圖:

? ? ?Bits:二進(jìn)制資源,可以存放文件、圖片類型等

2、常見(jiàn)操作SET、SETNX區(qū)別:SET設(shè)置鍵值,SETNX設(shè)置一個(gè)不存在的鍵值才會(huì)生效

3、使用場(chǎng)景

? ? ? 3.1 字符串鍵-分布式鎖

? ? ? ? ? ?//設(shè)置鎖字符串鍵,若存在則設(shè)置失敗

? ? ? ? ? ?SETNX("order",'lock')==1 //成功獲取鎖

? ? ? ? ? ?SETNX(orderKey,'lock')==0 //有人占用資源獲取鎖失敗

? ? ? ? ? ? //業(yè)務(wù)處理完畢釋放分布式鎖

? ? ? ? ? ?DEL(orderKey);

? ? ? ? ? ?//設(shè)置鎖字符串鍵的失效時(shí)間,防止宕機(jī),系統(tǒng)運(yùn)行意外,導(dǎo)致無(wú)法釋放鎖

? ? ? ? ? ?PEXPIRE(orderKey,lockMilliSeconds)

? ? ?3.2 字符串鍵-計(jì)數(shù)器(帖子閱讀量)

? ? ? ? ? ?// INCR? readcount::{帖子ID}? 每閱讀一次 + 1

? ? ? ? ? ?INCR key? ? ?

? ? ? ? ? ?// GET readcount::{帖子ID}?獲取閱讀量

? ? ? ? ? ?GET key

? ? ? ? ? ?說(shuō)明:該操作是原子性操作,且redis是單線程操作不存在多線程時(shí)安全性問(wèn)題,該設(shè)計(jì)適用于分布式系統(tǒng)

? ? ?3.3 字符串鍵-分布式全局系列

Hash鍵

?1、結(jié)構(gòu)類型如下圖


?2、Hash鍵意義

? ? ? ? ? ? ?1、Hash鍵可以將信息凝聚在一起,而不是直接分散的儲(chǔ)存在整個(gè)Redis中,這不僅方便了數(shù)據(jù)管理,還可以盡量避免一定的誤操作;

?????????????2、避免鍵名沖突;

? ? ? ? ? ? ?3、最主要的意義:減少內(nèi)存占用;

3、不適合Hash鍵的情況

? ? ? ? ? ? ?1、過(guò)期功能的使用,過(guò)期功能只能用在key上;

? ? ? ? ? ? ?2、二進(jìn)制操作命令如:SETBIT、GETBIT、BITOP;

? ? ? ? ? ? ?3、需要考慮數(shù)據(jù)量分布的問(wèn)題(redis的分布用預(yù)Hash巢/虛擬節(jié)點(diǎn) 方式實(shí)現(xiàn)如下圖);


列表(List)鍵

?1、結(jié)構(gòu)類型如下圖


2、常見(jiàn)操作

? ? ? lpush key string 在 key 對(duì)應(yīng) list 頭部添加字符串元素

? ? ? rpush key string 在 key 對(duì)應(yīng) list 尾部添加字符串元素

? ? ? rpop key 從 list 尾部刪除元素 并返回刪除的元素

? ? ? lpop key 從 list 頭部刪除元素 并返回刪除的元素

? ? ? llen key 返回 key 對(duì)應(yīng) list 的長(zhǎng)度 key 不存在 返回 0 如果key對(duì)應(yīng)的類型不是 list 返回錯(cuò)誤

? ? ? lrange key start end 返回指定區(qū)間內(nèi)的元素 從下標(biāo) 0 開(kāi)始

? ? ? ltrin key start end 截取list 保留指定區(qū)間的元素

3、應(yīng)用場(chǎng)景

????3.1 基于列表(list)鍵,實(shí)現(xiàn)阻塞消息隊(duì)列


3.2 基于列表(list)鍵,實(shí)現(xiàn)新浪\推特用戶消息列表

集合(SET)鍵

1、結(jié)構(gòu)類型如下圖

? ? ?結(jié)合鍵結(jié)構(gòu)具有如下特點(diǎn):1、無(wú)序,2、不可重復(fù)

2、常見(jiàn)操作

sadd:將指定的元素添加到集合。如果集合中存在該元素,則忽略。 如果集合不存在,會(huì)先創(chuàng)建一個(gè)集合然后在添加元素。

srem:移除一個(gè)或者多個(gè)元素,并返回移除的數(shù)量。

sismember:檢查某個(gè)元素是否存在某個(gè)集合里面。

scard:返回集合里面元素的數(shù)量。

smembers:返回集合里面所有的元素。

srandmember:從集合里面隨機(jī)返回一個(gè)或者多個(gè)元素。

spop:隨機(jī)移除一個(gè)元素,返回隨機(jī)移除的元素。

smove:smove source-key dest-key item 如果集合source-key包含元素item,那么從集合source-key里面移除元素item,并添加到集合dest-key里面,如果移除成功移除,那么命令返回1,否則返回0。

sdiff:sdiff key-name [key-name …] 返回那些存在于第一個(gè)集合,但不存在其他集合當(dāng)中的元素(相當(dāng)于差集運(yùn)算)。

sdiffstore:sdiffstore store-key key1 [key… ] 將存在于第一個(gè)集合,但不存在其他集合當(dāng)中的元素(相當(dāng)于差集運(yùn)算)找出來(lái),并且存到dest-key里面,區(qū)別于上一步就是多了一個(gè)保存。

sinter:交集運(yùn)算。

sinterstore:交集運(yùn)算并存儲(chǔ)。

sunion:并集運(yùn)算。

sunionstore:并集運(yùn)算并存儲(chǔ)。

3、應(yīng)用場(chǎng)景

? ? ?3.1 集合鍵-直播刷禮物、轉(zhuǎn)發(fā)微博等抽獎(jiǎng)活動(dòng)

? ? ? //刷禮物、轉(zhuǎn)發(fā)微博加入到集合中

? ? ? SADD key{userID}

? ? ? //獲取所有用戶,大輪盤轉(zhuǎn)起來(lái)

? ? ? SMEMBERS key

? ? ? //抽取count名中獎(jiǎng)?wù)?/p>

? ? ? SPOP key[count] / SRANDMEMBER key[count]

? ? ? 3.2?集合鍵-點(diǎn)贊、簽到、like等功能

點(diǎn)贊--> SADD like::8001 1001

取消點(diǎn)贊--> SREM? like::8001 1001

檢查用戶是否點(diǎn)過(guò)贊-->? SISMEMBER like::8001?1001

獲取點(diǎn)贊的用戶列表-->??SISMEMBER like::8001

獲取點(diǎn)贊用戶數(shù)--> SCARD like::8001

3.3 集合鍵-集合運(yùn)算

? ?SDIFF:計(jì)算差集時(shí)以第一個(gè)為主

查看共同關(guān)注的人模型

seven關(guān)注的人: sevenSubKey -->{'qing','mic','james'}

qing關(guān)注的人:qingSubKey-->{'seven','jack','mic','james'}

mic關(guān)注的人:micSubKey-->{'seven','james','qing','jack','tom'}

我和qing共同關(guān)注的人:SINTER?sevenSubKey??qingSubKey -->{'mic','james'}

我關(guān)注的人也關(guān)注他:SISMEMBER?micSubKey?qing 、SISMEMBER?micSubKey qing

我可能認(rèn)識(shí)的人:SDIFFSTORE sevenMayKnow qingSubKey?sevenSubKey -->{'seven','jack'}

3.4?集合鍵-集合運(yùn)算-電商商品刪選

每個(gè)商品入庫(kù)時(shí)建立他的靜態(tài)標(biāo)簽列表如:品牌、尺寸、處理器、內(nèi)存...

錄入:

SADD brand::lenovo 拯救者y7000P-001 ThinkPad-T480

SADD screenSize::15.6 ?拯救者y7000P-001 機(jī)械革命Z2AIR

SADD processor::i7??拯救者y7000P-001?機(jī)械革命X8TIPlus

SADD memory::8G?拯救者y7000P-001?ThinkPad-T480?機(jī)械革命Z2AIR?機(jī)械革命X8TIPlus

查找:

SINTER?brand::lenovo?screenSize::15.6??processor::i7??memory::8G -->?拯救者y7000P-001

3.5??集合鍵-集合運(yùn)算-支付系統(tǒng)對(duì)賬

通過(guò)兩個(gè)交集計(jì)算出有問(wèn)題的訂單

有序集合(Zset)鍵

1、結(jié)構(gòu)類型如下圖

2、常見(jiàn)操作

2.1 設(shè)定/修改命令

zadd key score member [[score member] [score member] ...]

? ? 將一個(gè)或多個(gè)member元素及其score值加入到key當(dāng)中

? ? score值可以是整數(shù)值或雙精度浮點(diǎn)數(shù)

? ? 如果某個(gè)member已經(jīng)是有序集合的成員,那么更新這個(gè)member的score值

? ? 如果key不存在,創(chuàng)建一個(gè)空的有序集并執(zhí)行zadd操作

? ? 返回被成功添加的新成員的數(shù)量,不包括那些被更新的、已經(jīng)存在的成員

zincrby key increment member

? ? 為key的成員member的score值加上增量increment(可以為負(fù)數(shù))

? ? key不存在時(shí)創(chuàng)建一個(gè)空的有序集并執(zhí)行zincrby操作

? ? member成員不存在時(shí),創(chuàng)建該成員并設(shè)置其score值為0并執(zhí)行zincrby操作

? ? 返回member成員的新score值(字符串形式)

2.2 移除命令

zrem key member [member ...]:移除key中一個(gè)或多個(gè)成員,不存在的成員將被忽略。返回被成功移除的成員數(shù)量(不包括被忽略的成員)

zremrangebyrank key start stop:移除key中指定下標(biāo)區(qū)間內(nèi)(包含start和stop)的所有成員。返回移除成員的數(shù)量

zremrangebyscore key min max:

? ? 移除key中score值在min和max之間(包括mi和max)的成員

? ? 可以給參數(shù)min和max前增加"("括號(hào)來(lái)使結(jié)果不包含

? ? 返回移除成員的數(shù)量

2.3 獲取命令

zrange key start stop [withscores]

? ? 返回key中指定下標(biāo)(可以為負(fù)數(shù))區(qū)間內(nèi)的成員并按score值遞增(從小到大)來(lái)排序的列表

? ? 具有相同score值的成員按字典序(lexicographical order)來(lái)排列

? ? start大于最大下標(biāo)或者start>stop,返回空列表

? ? stop大于最大下標(biāo)將stop當(dāng)作最大下標(biāo)來(lái)處理

? ? withscores選項(xiàng)讓成員和它的score值一并返回,返回列表以value1,score1, ..., valueN,scoreN的格式表示

zrevrange key start stop [withscores]:返回key中逆序排序(按score值從大到小)后指定下標(biāo)(可以為負(fù)數(shù))區(qū)間內(nèi)的成員列表

zrangebyscore key min max [withscores] [limit offset count]

? ? 返回key中score值介于min和max之間(包括min和max)的成員

? ? min和max可以是-inf(無(wú)限大)和+inf(無(wú)限小),這樣可以在不知道最低和最高score的情況下使用zrangebyscore這類命令

? ? 可選的limit參數(shù)指定返回結(jié)果的數(shù)量及區(qū)間

? ? withscores選項(xiàng)讓成員和它的score值一并返回

? ? 默認(rèn)情況下,包括score值等于min和max的成員,可以給參數(shù)min和max前增加"("括號(hào)來(lái)使結(jié)果不包含,如:

? ? zrangebyscore zset (1 5:返回所有1<score<=5的成員

? ? zrangebyscore zset (5 (10:返回所有5<score<10的成員

? ? 返回指定區(qū)間內(nèi)的有序集成員的列表

zrevrangebyscore key min max [withscores] [limit offset count]:返回key中score值介于min和max之間(包括min和max)的成員并把這些成員逆序排序(按score值從大到小)

zscore key member:返回key成員member的score值(字符串形式),如果member元素不是key的成員或key不存在返回null

2.4 交集并集

zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

? ? 計(jì)算給定的一個(gè)或多個(gè)有序集的和集(并集)并將該并集(結(jié)果集)儲(chǔ)存到destination

? ? numkeys為給定key的數(shù)量

? ? weights選項(xiàng)為每個(gè)對(duì)應(yīng)的key分別指定一個(gè)乘法因子,對(duì)應(yīng)的key所有成員的score值在傳遞給聚合函數(shù)(aggregate)之前都要先乘以該因子,默認(rèn)為1

? ? aggregat選項(xiàng)指定和集(并集)的結(jié)果集中score值的聚合方式

? ? ? ? 默認(rèn)為sum,將所有集合中某個(gè)相同成員的score值之和作為結(jié)果集中該成員的score值;

? ? ? ? min將所有集合中某個(gè)相同成員中最小的score值作為結(jié)果集中該成員的score值;

? ? ? ? max將所有集合中某個(gè)相同成員最大的score值作為結(jié)果集中該成員的score值

? ? 返回保存到 destination 的結(jié)果集的基數(shù)。

zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

? ? 計(jì)算給定的一個(gè)或多個(gè)有序集的交集并將該交集(結(jié)果集)儲(chǔ)存到destination

? ? 參數(shù)的用法和zunionstore相同

3、ZSet運(yùn)算模型(可用于報(bào)表統(tǒng)計(jì))

4、應(yīng)用場(chǎng)景

4.1 ZSet集-自動(dòng)補(bǔ)齊功能

用戶首次進(jìn)入搜索abc進(jìn)行查詢

?//對(duì)abc進(jìn)行分詞 a:key,1:sorce(說(shuō)明當(dāng)用戶2也進(jìn)行abc搜索時(shí)對(duì)應(yīng)的key+1,實(shí)現(xiàn)熱度排序),abc:member

ZINCRBY a 1 abc? ?

ZINCRBY ab 1 abc? ?

ZINCRBY abc 1 abc? ?

用戶在輸入abd進(jìn)行查詢

ZINCRBY a 1 abd

ZINCRBY ab 1 abd

ZINCRBY abd 1 abd

用戶進(jìn)行搜索時(shí) 輸入 a,后臺(tái)執(zhí)行 ZREVRANGE a 0 -1 -->{abc,abd}?

4.1 ZSet集-單日排行榜

//點(diǎn)擊第一條“馬蓉怒斥王寶強(qiáng)?”,設(shè)置為熱詞

ZADD hotNews::{11-11} 1??

//給對(duì)應(yīng)熱詞+1

ZINCRBY hotNews::{11-11} 1?

//倒敘取10條

ZREVRANGE?hotNews::{11-11}? 0 10 WITHSCORES

4.1?ZSet集-周、月、年排行榜

//并集計(jì)算 11.19號(hào)-11.25號(hào)

ZUNIONSTORE hotNews{11.19-11.25}?hotNews{11.19}??hotNews{11.19-11.20} ...hotNews{11.25}?

//取11.19-11.25倒敘的前十

ZREVRANGE?hotNews{11.19-11.25} 0 10?WITHSCORES

最后編輯于
?著作權(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)容