<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          redis的五大數(shù)據(jù)類型為什么這么受歡迎?別告訴我你不知道!

          共 3386字,需瀏覽 7分鐘

           ·

          2021-01-08 16:24

          Redis是一種基于鍵值對(duì)的NoSQL數(shù)據(jù)庫(kù),它的值主要由string(字符串),hash(哈希),list(列表),set(集合),zset(有序集合)五種基本數(shù)據(jù)結(jié)構(gòu)構(gòu)成,除此之外還支持一些其他的數(shù)據(jù)結(jié)構(gòu)和算法。key都是由字符串構(gòu)成的,那么這五種數(shù)據(jù)結(jié)構(gòu)的使用場(chǎng)景有哪些?一起來(lái)看看!

          一 字符串

          字符串類型是Redis最基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),字符串類型可以是JSONXML甚至是二進(jìn)制的圖片等數(shù)據(jù),但是最大值不能超過(guò)512MB。

          1.1 內(nèi)部編碼

          Redis會(huì)根據(jù)當(dāng)前值的類型和長(zhǎng)度決定使用哪種內(nèi)部編碼來(lái)實(shí)現(xiàn)。

          字符串類型的內(nèi)部編碼有3種:

          1. int:8個(gè)字節(jié)的長(zhǎng)整型。
          2. embstr:小于等于39個(gè)字節(jié)的字符串。
          3. raw:大于39個(gè)字節(jié)的字符串。

          1.2 使用場(chǎng)景

          1.2.1 緩存

          在web服務(wù)中,使用MySQL作為數(shù)據(jù)庫(kù),Redis作為緩存。由于Redis具有支撐高并發(fā)的特性,通常能起到加速讀寫和降低后端壓力的作用。web端的大多數(shù)請(qǐng)求都是從Redis中獲取的數(shù)據(jù),如果Redis中沒(méi)有需要的數(shù)據(jù),則會(huì)從MySQL中去獲取,并將獲取到的數(shù)據(jù)寫入redis。

          1.2.2 計(jì)數(shù)

          Redis中有一個(gè)字符串相關(guān)的命令incr key,incr命令對(duì)值做自增操作,返回結(jié)果分為以下三種情況:

          • 值不是整數(shù),返回錯(cuò)誤
          • 值是整數(shù),返回自增后的結(jié)果
          • key不存在,默認(rèn)鍵為0,返回1

          比如文章的閱讀量,視頻的播放量等等都會(huì)使用redis來(lái)計(jì)數(shù),每播放一次,對(duì)應(yīng)的播放量就會(huì)加1,同時(shí)將這些數(shù)據(jù)異步存儲(chǔ)到數(shù)據(jù)庫(kù)中達(dá)到持久化的目的。

          1.2.3 共享Session

          在分布式系統(tǒng)中,用戶的每次請(qǐng)求會(huì)訪問(wèn)到不同的服務(wù)器,這就會(huì)導(dǎo)致session不同步的問(wèn)題,假如一個(gè)用來(lái)獲取用戶信息的請(qǐng)求落在A服務(wù)器上,獲取到用戶信息后存入session。下一個(gè)請(qǐng)求落在B服務(wù)器上,想要從session中獲取用戶信息就不能正常獲取了,因?yàn)橛脩粜畔⒌膕ession在服務(wù)器A上,為了解決這個(gè)問(wèn)題,使用redis集中管理這些session,將session存入redis,使用的時(shí)候直接從redis中獲取就可以了。

          1.2.4 限速

          為了安全考慮,有些網(wǎng)站會(huì)對(duì)IP進(jìn)行限制,限制同一IP在一定時(shí)間內(nèi)訪問(wèn)次數(shù)不能超過(guò)n次。

          二 哈希

          Redis中,哈希類型是指一個(gè)鍵值對(duì)的存儲(chǔ)結(jié)構(gòu)。

          2.1 內(nèi)部編碼

          哈希類型的內(nèi)部編碼有兩種:

          • ziplist(壓縮列表):當(dāng)哈希類型元素個(gè)數(shù)小于hash-max-ziplist-entries配置(默認(rèn)512個(gè))同時(shí)所有值都小于hash-max-ziplist-value配置(默認(rèn)64字節(jié))時(shí)使用。ziplist使用更加緊湊的結(jié)構(gòu)實(shí)現(xiàn)多個(gè)元素的連續(xù)存儲(chǔ),所以比hashtable更加節(jié)省內(nèi)存。
          • hashtable(哈希表):當(dāng)ziplist不能滿足要求時(shí),會(huì)使用hashtable。

          2.2 使用場(chǎng)景

          由于hash類型存儲(chǔ)的是一個(gè)鍵值對(duì),比如數(shù)據(jù)庫(kù)有以下一個(gè)用戶表結(jié)構(gòu)

          idnameage
          1Java旅途18

          將以上信息存入redis,用表明:id作為key,用戶屬性作為值:

          hset?user:1?name?Java旅途?age?18

          使用哈希存儲(chǔ)會(huì)比字符串更加方便直觀

          三 列表

          列表類型用來(lái)存儲(chǔ)多個(gè)有序的字符串,一個(gè)列表最多可以存儲(chǔ)2^32-1個(gè)元素,列表的兩端都可以插入和彈出元素。

          3.1 內(nèi)部編碼

          列表的內(nèi)部編碼有兩種:

          • ziplist(壓縮列表):當(dāng)哈希類型元素個(gè)數(shù)小于list-max-ziplist-entries配置(默認(rèn)512個(gè))同時(shí)所有值都小于list-max-ziplist-value配置(默認(rèn)64字節(jié))時(shí)使用。ziplist使用更加緊湊的結(jié)構(gòu)實(shí)現(xiàn)多個(gè)元素的連續(xù)存儲(chǔ),所以比hashtable更加節(jié)省內(nèi)存。
          • linkedlist(鏈表):當(dāng)ziplist不能滿足要求時(shí),會(huì)使用linkedlist。

          3.2 使用場(chǎng)景

          3.2.1 消息隊(duì)列

          列表用來(lái)存儲(chǔ)多個(gè)有序的字符串,既然是有序的,那么就滿足消息隊(duì)列的特點(diǎn)。使用lpush+rpop或者rpush+lpop實(shí)現(xiàn)消息隊(duì)列。除此之外,redis支持阻塞操作,在彈出元素的時(shí)候使用阻塞命令來(lái)實(shí)現(xiàn)阻塞隊(duì)列。

          3.2.2 棧

          由于列表存儲(chǔ)的是有序字符串,滿足隊(duì)列的特點(diǎn),也就能滿足棧先進(jìn)后出的特點(diǎn),使用lpush+lpop或者rpush+rpop實(shí)現(xiàn)棧。

          3.2.3 文章列表

          因?yàn)榱斜淼脑夭坏怯行虻?,而且還支持按照索引范圍獲取元素。因此我們可以使用命令lrange key 0 9分頁(yè)獲取文章列表

          四 集合

          集合類型也可以保存多個(gè)字符串元素,與列表不同的是,集合中不允許有重復(fù)元素并且集合中的元素是無(wú)序的。一個(gè)集合最多可以存儲(chǔ)2^32-1個(gè)元素。

          4.1 內(nèi)部編碼

          集合類型的內(nèi)部編碼有兩種:

          • intset(整數(shù)集合):當(dāng)集合中的元素都是整數(shù)且元素個(gè)數(shù)小于set-max-intset-entries配置(默認(rèn)512個(gè))時(shí),redis會(huì)選用intset來(lái)作為集合的內(nèi)部實(shí)現(xiàn),從而減少內(nèi)存的使用。
          • hashtable(哈希表):當(dāng)intset不能滿足要求時(shí),會(huì)使用hashtable。

          4.2 使用場(chǎng)景

          4.2.1 用戶標(biāo)簽

          例如一個(gè)用戶對(duì)籃球、足球感興趣,另一個(gè)用戶對(duì)橄欖球、乒乓球感興趣,這些興趣點(diǎn)就是一個(gè)標(biāo)簽。有了這些數(shù)據(jù)就可以得到喜歡同一個(gè)標(biāo)簽的人,以及用戶的共同感興趣的標(biāo)簽。給用戶打標(biāo)簽的時(shí)候需要①給用戶打標(biāo)簽,②給標(biāo)簽加用戶,需要給這兩個(gè)操作增加事務(wù)。

          • 給用戶打標(biāo)簽
          sadd?user:1:tags?tag1?tag2
          • 給標(biāo)簽添加用戶
          sadd?tag1:users?user:1

          sadd?tag2:users?user:1

          使用交集(sinter)求兩個(gè)user的共同標(biāo)簽

          sinter?user:1:tags?user:2:tags

          4.2.2 抽獎(jiǎng)功能

          集合有兩個(gè)命令支持獲取隨機(jī)數(shù),分別是:

          • 隨機(jī)獲取count個(gè)元素,集合元素個(gè)數(shù)不變

          srandmember key [count]

          • 隨機(jī)彈出count個(gè)元素,元素從集合彈出,集合元素個(gè)數(shù)改變

          spop key [count]

          用戶點(diǎn)擊抽獎(jiǎng)按鈕,參數(shù)抽獎(jiǎng),將用戶編號(hào)放入集合,然后抽獎(jiǎng),分別抽一等獎(jiǎng)、二等獎(jiǎng),如果已經(jīng)抽中一等獎(jiǎng)的用戶不能參數(shù)抽二等獎(jiǎng)則使用spop,反之使用srandmember

          五 有序集合

          有序集合和集合一樣,不能有重復(fù)元素。但是可以排序,它給每個(gè)元素設(shè)置一個(gè)score作為排序的依據(jù)。最多可以存儲(chǔ)2^32-1個(gè)元素。

          5.1 內(nèi)部編碼

          有序集合類型的內(nèi)部編碼有兩種:

          • ziplist(壓縮列表):當(dāng)有序集合的元素個(gè)數(shù)小于list-max-ziplist-entries配置(默認(rèn)128個(gè))同時(shí)所有值都小于list-max-ziplist-value配置(默認(rèn)64字節(jié))時(shí)使用。ziplist使用更加緊湊的結(jié)構(gòu)實(shí)現(xiàn)多個(gè)元素的連續(xù)存儲(chǔ),更加節(jié)省內(nèi)存。

          • skiplist(跳躍表):當(dāng)不滿足ziplist的要求時(shí),會(huì)使用skiplist。

          5.2 使用場(chǎng)景

          5.2.1 排行榜

          用戶發(fā)布了n篇文章,其他人看到文章后給喜歡的文章點(diǎn)贊,使用score來(lái)記錄點(diǎn)贊數(shù),有序集合會(huì)根據(jù)score排行。流程如下

          用戶發(fā)布一篇文章,初始點(diǎn)贊數(shù)為0,即score為0

          zadd?user:article?0?a

          有人給文章a點(diǎn)贊,遞增1

          zincrby?user:article?1?a

          查詢點(diǎn)贊前三篇文章

          zrevrange?user:article?0?2

          查詢點(diǎn)贊后三篇文章

          zrange?user:article?0?2

          5.2.2 延遲消息隊(duì)列

          下單系統(tǒng),下單后需要在15分鐘內(nèi)進(jìn)行支付,如果15分鐘未支付則自動(dòng)取消訂單。將下單后的十五分鐘后時(shí)間作為score,訂單作為value存入redis,消費(fèi)者輪詢?nèi)ハM(fèi),如果消費(fèi)的大于等于這筆記錄的score,則將這筆記錄移除隊(duì)列,取消訂單。

          總結(jié)

          在開(kāi)發(fā)中,字符串類型是用的最多的數(shù)據(jù)類型,導(dǎo)致我們忽視了redis的其他四種數(shù)據(jù)類型,在具體場(chǎng)景下選擇具體的數(shù)據(jù)類型對(duì)提升redis性能有非常大的幫助。redis雖然支持消息隊(duì)列的實(shí)現(xiàn),但是并不支持ack。所以redis實(shí)現(xiàn)的消息隊(duì)列不能保證消息的可靠性,除非自己實(shí)現(xiàn)消息確認(rèn)機(jī)制,不過(guò)這非常麻煩,所以如果是重要的消息還是推薦使用專門的消息隊(duì)列去做

          瀏覽 13
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩一级片 | 日本嗯黄色网址 | 高清无码毛片在线看 | 麻豆影院91免费版 | 亚洲69视频 |