偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

用過Redis哪些數(shù)據(jù)類型?Redis String 類型的底層實(shí)現(xiàn)是什么?

數(shù)據(jù)庫 Redis
Redis 中的 Sting 類型底層實(shí)現(xiàn)主要基于 SDS(Simple Dynamic string 簡(jiǎn)單動(dòng)態(tài)字符串)結(jié)構(gòu),并結(jié)合 int、embstr、raw 等不同的編碼方式進(jìn)行優(yōu)化存儲(chǔ)。

基本數(shù)據(jù)類型:

  1. String:最常用的一種數(shù)據(jù)類型,String類型的值可以是字符串、數(shù)字或者二進(jìn)制,但值最大不能超過512MB。一般用于 緩存和計(jì)數(shù)器
  2. Hash:Hash 是一個(gè)鍵值對(duì)集合。存儲(chǔ)商品的各個(gè)屬性
  3. Set:無序去重的集合。Set 提供了交集、并集等方法,對(duì)于實(shí)現(xiàn)共同好友、共同關(guān)注等功能特別方便。
  4. List:有序可重復(fù)的集合,底層是依賴雙向鏈表實(shí)現(xiàn)的。用于消息隊(duì)列
  5. SortedSet:有序Set。內(nèi)部維護(hù)了一個(gè)score的參數(shù)來實(shí)現(xiàn)。適用于排行榜和帶權(quán)重的消息隊(duì)列等場(chǎng)景。

特殊的數(shù)據(jù)類型

  1. Bitmap:位圖,可以認(rèn)為是一個(gè)以位為單位數(shù)組,數(shù)組中的每個(gè)單元只能存0或者1,數(shù)組的下標(biāo)在 Bitmap 中叫做偏移量。Bitmap的長(zhǎng)度與集合中元素個(gè)數(shù)無關(guān),而是與基數(shù)的上限有關(guān)。
  2. Hyperloglog。HyperLogLog 是用來做基數(shù)統(tǒng)計(jì)的算法,其優(yōu)點(diǎn)是,在輸入元素的數(shù)量或者體積非常非常大時(shí),計(jì)算基數(shù)所需的空間總是固定的、并且是很小的。典型的使用場(chǎng)景是統(tǒng)計(jì)獨(dú)立訪客。
  3. Geospatial :主要用于存儲(chǔ)地理位置信息,并對(duì)存儲(chǔ)的信息進(jìn)行操作,適用場(chǎng)景如定位、附近的人等。
  4. Stream :一種日志數(shù)據(jù)結(jié)構(gòu),適合于存儲(chǔ)時(shí)間序列數(shù)據(jù)或消息流。支持高效的消息生產(chǎn)和消費(fèi)模式,具有持久性和序列化特性。

SortedSet和List異同點(diǎn)?

相同點(diǎn)

  1. 都是有序的;
  2. 都可以獲得某個(gè)范圍內(nèi)的元素。

不同點(diǎn):

  1. 列表基于鏈表實(shí)現(xiàn),獲取兩端元素速度快,訪問中間元素速度慢;
  2. 有序集合基于散列表和跳躍表實(shí)現(xiàn),訪問中間元素時(shí)間復(fù)雜度是OlogN;
  3. 列表不能簡(jiǎn)單的調(diào)整某個(gè)元素的位置,有序列表可以(更改元素的分?jǐn)?shù));
  4. 有序集合更耗內(nèi)存。

Redis 怎么實(shí)現(xiàn)消息隊(duì)列?

BLPOP queue 0  //0表示不限制等待時(shí)間

BLPOP和LPOP命令相似,唯一的區(qū)別就是當(dāng)列表沒有元素時(shí)BLPOP命令會(huì)一直阻塞連接,直到有新元素加入。

redis可以通過pub/sub主題訂閱模式實(shí)現(xiàn)一個(gè)生產(chǎn)者,多個(gè)消費(fèi)者,當(dāng)然也存在一定的缺點(diǎn),當(dāng)消費(fèi)者下線時(shí),生產(chǎn)的消息會(huì)丟失。

PUBLISH channel1 hi
SUBSCRIBE channel1
UNSUBSCRIBE channel1 //退訂通過SUBSCRIBE命令訂閱的頻道。

PSUBSCRIBE channel?* 按照規(guī)則訂閱。PUNSUBSCRIBE channel?* 退訂通過PSUBSCRIBE命令按照某種規(guī)則訂閱的頻道。其中訂閱規(guī)則要進(jìn)行嚴(yán)格的字符串匹配,PUNSUBSCRIBE *無法退訂channel?*規(guī)則。

如何在 Redis 中實(shí)現(xiàn)隊(duì)列和棧數(shù)據(jù)結(jié)構(gòu)?

可以通過 List 類型 來實(shí)現(xiàn) 隊(duì)列 和 棧

實(shí)現(xiàn)隊(duì)列(FIFO):隊(duì)列是一種 先進(jìn)先出(FIFO)的數(shù)據(jù)結(jié)構(gòu)。在Redis中,可以使用 PUSH 和 RPOP命令組合來實(shí)現(xiàn)隊(duì)列。LPUSH 向列表的左側(cè)推入元素,而 RPOP從列表的右側(cè)彈出元素,這樣可以保證最先進(jìn)入的元素最先被彈出

實(shí)現(xiàn)棧(LIFO):棧是一種 后進(jìn)先出(LIFO)的數(shù)據(jù)結(jié)構(gòu)。在Redis 中,可以使用 LPUSH和 LPoP命令組合來實(shí)現(xiàn)棧。LPUSH 向列表的左側(cè)推入元素,而 LPoP從列表的左側(cè)彈出元素,這樣可以保證最后進(jìn)入的元素最先被彈出。

Redis 怎么實(shí)現(xiàn)延時(shí)隊(duì)列

使用sortedset,拿時(shí)間戳作為score,消息內(nèi)容作為key,調(diào)用zadd來生產(chǎn)消息,消費(fèi)者用zrangebyscore指令獲取N秒之前的數(shù)據(jù)輪詢進(jìn)行處理。

如何使用 Redis 快速實(shí)現(xiàn)排行榜?

使用 Redis 實(shí)現(xiàn)排行榜的方式主要利用 Sorted Set(有序集合),它可以高效地存儲(chǔ)、更新、以及獲取排名數(shù)據(jù)。實(shí)現(xiàn)排行榜的主要步驟:

  1. 使用 Sorted Set 存儲(chǔ)分?jǐn)?shù)和成員:使用 Redis 的 ADD命令,將用戶和對(duì)應(yīng)的分?jǐn)?shù)添加到有序集合中。例如:add leaderboard 1000 user1,將用戶 user1 的分?jǐn)?shù)設(shè)置為 1000。
  2. 獲取排名:使用 ZRANK命令獲取某個(gè)用戶的排名。例如:zrank leaderboard user1,返回用戶user1 的排名(從0開始)。
  3. 獲取前 N 名:使用 ZREVRANGE 命令獲取分?jǐn)?shù)最高的前N名。例如:REVRANGE leaderboard  0 9 WITHSCORES ,獲取排行榜前 10 名用戶及其分?jǐn)?shù)。
  4. 更新分?jǐn)?shù):如果用戶的分?jǐn)?shù)需要更新,可以使用 ZINCRBY 命令對(duì)其分?jǐn)?shù)進(jìn)行加減操作。例如:ZINCRBY leaderboard 500 user1,將用戶 user1 的分?jǐn)?shù)增加 500。

如何使用 Redis 快速實(shí)現(xiàn)布隆過濾器?

可以通過使用 位圖(Bitmap)或使用 Redis 模塊 RedisBloom。

  • 使用位圖實(shí)現(xiàn)布隆過濾器:使用 Redis 的位圖結(jié)構(gòu) SETBIT 和 GETBIT 操作來實(shí)現(xiàn)布隆過濾器。位圖本質(zhì)上是一個(gè)比特?cái)?shù)組,用于標(biāo)識(shí)元素是否存在對(duì)于給定的數(shù)據(jù),通過多個(gè) 哈希函數(shù) 計(jì)算位置索引,將位圖中的相應(yīng)位置設(shè)置為 1,表示該元素可能存在。
  • 使用 RedisBloom 模塊:Redis 提供了一個(gè)官方模塊 RedisBloom,封裝了哈希函數(shù)、位圖大小等操作,可以直接用于創(chuàng)建和管理布隆過濾器。使用 BF.ADD 來向布隆過濾器添加元素,使用 BF.EXISTS 來檢查某個(gè)元素是否可能存在,

如何使用 Redis 統(tǒng)計(jì)大量用戶唯一訪問量(UV)?

Redis 中 HyperLogLog 結(jié)構(gòu),可以快速實(shí)現(xiàn)網(wǎng)頁UV、PV 等統(tǒng)計(jì)場(chǎng)景。它是一種基數(shù)估算算法的概率性數(shù)據(jù)結(jié)構(gòu),可以用極少的內(nèi)存統(tǒng)計(jì)海量用戶唯一訪問量的近似值。

Set 也可以實(shí)現(xiàn),用于精確統(tǒng)計(jì)唯一用戶訪問量,但是但當(dāng)用戶數(shù)非常大時(shí),內(nèi)存開銷較高。

Redis 中的 Geo 數(shù)據(jù)結(jié)構(gòu)是什么?

Redis中的 Geo(Geoloaton的簡(jiǎn)寫形式,代表地理坐標(biāo)) 數(shù)據(jù)結(jié)構(gòu)主要用于地理位置信息的存儲(chǔ),通過這個(gè)結(jié)構(gòu),可以方便地進(jìn)行地理位置的存儲(chǔ)、檢索、以及計(jì)算地理距離等課作,GeO 數(shù)據(jù)結(jié)內(nèi)存層使用了 Sorted set, 并結(jié)合了Geohash 編碼算法來對(duì)地理位置進(jìn)行處理。

Redis String 類型的底層實(shí)現(xiàn)是什么?(SDS)

Redis 中的 Sting 類型底層實(shí)現(xiàn)主要基于 SDS(Simple Dynamic string 簡(jiǎn)單動(dòng)態(tài)字符串)結(jié)構(gòu),并結(jié)合 int、embstr、raw 等不同的編碼方式進(jìn)行優(yōu)化存儲(chǔ)。

Redis 中的 Ziplist 和 Quicklist 數(shù)據(jù)結(jié)構(gòu)的特點(diǎn)是什么?

Ziplist:

  • 簡(jiǎn)單、緊湊、連續(xù)存儲(chǔ),適用于小數(shù)據(jù)量場(chǎng)景,但對(duì)大量數(shù)據(jù)或頻繁的修改操作不太友好。
  • 適合小數(shù)據(jù)量場(chǎng)景,例如短列表、小哈希表等,因?yàn)樗膬?nèi)存緊湊,可以大幅減少內(nèi)存使用

Quicklist:

  • 通過將鏈表和 Ziplist 結(jié)合,既實(shí)現(xiàn)了鏈表的靈活操作,又能節(jié)省內(nèi)存,在 Redis 3.2 之后成為 List 的默認(rèn)實(shí)現(xiàn)。
  • Quicklist是為了替代純而設(shè)計(jì)的,適用于需要頻繁對(duì)列表進(jìn)行插入、刪除、查找等提作的場(chǎng)景,并目數(shù)據(jù)量可能較大,它在存儲(chǔ)多個(gè)元素時(shí),既保留了鏈表的靈活性,又具備壓縮列表的內(nèi)存優(yōu)勢(shì)

Redis Zset 的實(shí)現(xiàn)原理是什么?

Redis 中的Zset(有序集合,Sorted set)是一種由 跳表 (Skip List)和哈希表 (Hash Table)組成的數(shù)據(jù)結(jié)構(gòu),Zset 結(jié)合了集合 (Set)的特性和排序功能,能夠存儲(chǔ)具有唯一性的成員,并根據(jù)成員的分?jǐn)?shù) (score) 進(jìn)行排序

ZSet 的實(shí)現(xiàn)由兩個(gè)核心數(shù)據(jù)結(jié)構(gòu)組成:

  1. 跳表(Skip List):用于存儲(chǔ)數(shù)據(jù)的排序和快速查找。
  2. 哈希表(Hash Table):用于存儲(chǔ)成員與其分?jǐn)?shù)的映射,提供快速查找

當(dāng) Zset 元素?cái)?shù)量較少時(shí),Redis 會(huì)使用壓縮列表(Zip List)來節(jié)省內(nèi)存

  • 即元素個(gè)數(shù)≤ zset-max-ziplist-entries(默認(rèn) 128)
  • 元素成員名和分值的長(zhǎng)度 ≤ zset-max-ziplist-value(默認(rèn) 64 字節(jié))

如果任何一個(gè)條件不滿足,Zset 將使用 跳表 +哈希表 作為底層實(shí)現(xiàn),

Redis 的有序集合底層為什么要用跳表,而不用平衡樹、紅黑樹或者 B+樹?

這道面試題很多大廠比較喜歡問,難度還是有點(diǎn)大的。

  • 平衡樹 vs 跳表:平衡樹的插入、刪除和查詢的時(shí)間復(fù)雜度和跳表一樣都是 **O(log n)**。對(duì)于范圍查詢來說,平衡樹也可以通過中序遍歷的方式達(dá)到和跳表一樣的效果。但是它的每一次插入或者刪除操作都需要保證整顆樹左右節(jié)點(diǎn)的絕對(duì)平衡,只要不平衡就要通過旋轉(zhuǎn)操作來保持平衡,這個(gè)過程是比較耗時(shí)的。跳表誕生的初衷就是為了克服平衡樹的一些缺點(diǎn)。跳表使用概率平衡而不是嚴(yán)格強(qiáng)制的平衡,因此,跳表中的插入和刪除算法比平衡樹的等效算法簡(jiǎn)單得多,速度也快得多。
  • 紅黑樹 vs 跳表:相比較于紅黑樹來說,跳表的實(shí)現(xiàn)也更簡(jiǎn)單一些,不需要通過旋轉(zhuǎn)和染色(紅黑變換)來保證黑平衡。并且,按照區(qū)間來查找數(shù)據(jù)這個(gè)操作,紅黑樹的效率沒有跳表高。
  • B+樹 vs 跳表:B+樹更適合作為數(shù)據(jù)庫和文件系統(tǒng)中常用的索引結(jié)構(gòu)之一,它的核心思想是通過盡可能少的 IO 定位到盡可能多的索引來獲得查詢數(shù)據(jù)。對(duì)于 Redis 這種內(nèi)存數(shù)據(jù)庫來說,它對(duì)這些并不感冒,因?yàn)?Redis 作為內(nèi)存數(shù)據(jù)庫它不可能存儲(chǔ)大量的數(shù)據(jù),所以對(duì)于索引不需要通過 B+樹這種方式進(jìn)行維護(hù),只需按照概率進(jìn)行隨機(jī)維護(hù)即可,節(jié)約內(nèi)存。而且使用跳表實(shí)現(xiàn) zset 時(shí)相較前者來說更簡(jiǎn)單一些,在進(jìn)行插入時(shí)只需通過索引將數(shù)據(jù)插入到鏈表中合適的位置再隨機(jī)維護(hù)一定高度的索引即可,也不需要像 B+樹那樣插入時(shí)發(fā)現(xiàn)失衡時(shí)還需要對(duì)節(jié)點(diǎn)分裂與合并。

Redis 中跳表的實(shí)現(xiàn)原理是什么?

跳表主要是通過多層鏈表來實(shí)現(xiàn),底層鏈表保存所有元素,而每一層鏈表都是下一層的子集。

插入時(shí),首先從最高層開始查找插入位置,然后隨機(jī)決定新節(jié)點(diǎn)的層數(shù),最后在相應(yīng)的層中插入節(jié)點(diǎn)并更新指針

刪除時(shí),同樣從最高層開始查找要?jiǎng)h除的節(jié)點(diǎn),并在各層中更新指針,以保持跳表的結(jié)構(gòu)。

查找時(shí),從最高層開始,逐層向下,直到找到目標(biāo)元素或確定元素不存在。查找效率高,時(shí)間復(fù)雜度為 O(logn)

圖片

Redis中的跳表是兩步兩步跳的嗎?

如果采用新增節(jié)點(diǎn)或者刪除節(jié)點(diǎn)時(shí),來調(diào)整跳表節(jié)點(diǎn)以維持比例2:1的方法的話,顯然是會(huì)帶來額外開銷的。

跳表在創(chuàng)建節(jié)點(diǎn)時(shí)候,會(huì)生成范圍為[0-1]的一個(gè)隨機(jī)數(shù),如果這個(gè)隨機(jī)數(shù)小于 0.25(相當(dāng)于概率 25%),那么層數(shù)就增加 1 層,然后繼續(xù)生成下一個(gè)隨機(jī)數(shù),直到隨機(jī)數(shù)的結(jié)果大于 0.25 結(jié)束,最終確定該節(jié)點(diǎn)的層數(shù)。因?yàn)殡S機(jī)數(shù)取值在[0,0.25)范圍內(nèi)概率不會(huì)超過25%,所以這也說明了增加一層的概率不會(huì)超過25%。這樣的話,當(dāng)插入一個(gè)新結(jié)點(diǎn)時(shí),只需修改前后結(jié)點(diǎn)的指針,而其它結(jié)點(diǎn)的層數(shù)就不需要隨之改變了,這樣就降低插入操作的復(fù)雜度。

// #define ZSKIPLIST_P 0.25
int zslRandomLevel(void) {
    static const int threshold = ZSKIPLIST_P*RAND_MAX;
    int level = 1; //初始化為一級(jí)索引
    while (random() < threshold)
        level += 1;//隨機(jī)數(shù)小于 0.25就增加一層
 //如果level 沒有超過最大層數(shù)就返回,否則就返回最大層數(shù)
    return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

Redis遇到哈希沖突怎么辦?

當(dāng)有兩個(gè)或以上數(shù)量的鍵被分配到了哈希表數(shù)組的同一個(gè)索引上面時(shí), 我們稱這些鍵發(fā)生了沖突(collision)。

關(guān)于解決hash沖突問題可以看這篇文章:解決哈希沖突的三種方法

而redis是先通過拉鏈法解決,再通過rehash來解決hash沖突問題的,即再hash法,只不過redis的hash使?jié)u進(jìn)式hash

rehash原理?

漸進(jìn)式 rehash 步驟如下:

  1. 先給哈希表 2分配空間;
  2. 在 rehash 進(jìn)行期間,每次哈希表元素進(jìn)行新增、刪除、查找或者更新操作時(shí),Redis 除了會(huì)執(zhí)行對(duì)應(yīng)的操作之外,還會(huì)順序?qū)?/span>哈希表 1中索引位置上的所有 key-value 遷移到哈希表 2上;
  3. 隨著處理客戶端發(fā)起的哈希表操作請(qǐng)求數(shù)量越多,最終在某個(gè)時(shí)間點(diǎn)會(huì)把哈希表 1的所有 key-value 遷移到哈希表 2,從而完成 rehash 操作。

這樣就把一次性大量數(shù)據(jù)遷移工作的開銷,分?jǐn)偟搅硕啻翁幚碚?qǐng)求的過程中,避免了一次性 rehash 的耗時(shí)操作。

在進(jìn)行漸進(jìn)式 rehash 的過程中,會(huì)有兩個(gè)哈希表,所以在漸進(jìn)式 rehash 進(jìn)行期間,哈希表元素的刪除、查找、更新等操作都會(huì)在這兩個(gè)哈希表進(jìn)行。比如,在漸進(jìn)式 rehash 進(jìn)行期間,查找一個(gè) key 的值的話,先會(huì)在哈希表 1里面進(jìn)行查找,如果沒找到,就會(huì)繼續(xù)到哈希表 2 里面進(jìn)行找到。新增一個(gè) key-value 時(shí),會(huì)被保存到哈希表 2里面,而哈希表 1則不再進(jìn)行任何添加操作,這樣保證了哈希表 1的 key-value 數(shù)量只會(huì)減少,隨著 rehash 操作的完成,最終哈希表 1就會(huì)變成空表。

rehash的觸發(fā)條件?

負(fù)載因子 = 哈希表已保存節(jié)點(diǎn)數(shù)量/哈希表大小

觸發(fā) rehash 操作的條件,主要有兩個(gè):

  • 當(dāng)負(fù)載因子大于等于 1 ,并且 Redis 沒有在執(zhí)行 bgsave 命令或者 bgrewiteaof 命令,也就是沒有執(zhí)行 RDB 快照或沒有進(jìn)行 AOF 重寫的時(shí)候,就會(huì)進(jìn)行 rehash 操作。
  • 當(dāng)負(fù)載因子大于等于 5 時(shí),此時(shí)說明哈希沖突非常嚴(yán)重了,不管有沒有有在執(zhí)行 RDB 快照或 AOF 重寫,都會(huì)強(qiáng)制進(jìn)行 rehash 操作

一個(gè)REDIS實(shí)例最多能存放多少KEYS

redis 的每個(gè)實(shí)例最多可以存放約 2^32 - 1 個(gè)keys,即大約 42 億個(gè)keys。這是由 Redis 內(nèi)部使用的哈希表實(shí)現(xiàn)決定的,它使用 32 位有符號(hào)整數(shù)作為索引。Redis 使用的哈希函數(shù)和負(fù)載因子等因素也會(huì)影響實(shí)際可存放鍵的數(shù)量。

需要注意的是,盡管 Redis 允許存儲(chǔ)數(shù)量龐大的鍵,但在實(shí)踐中,存儲(chǔ)過多的鍵可能會(huì)導(dǎo)致性能下降和內(nèi)存消耗增加。因此,在設(shè)計(jì)應(yīng)用程序時(shí),需要根據(jù)實(shí)際需求和硬件資源來合理規(guī)劃鍵的數(shù)量,避免過度使用 Redis 實(shí)例造成負(fù)擔(dān)。如果需要存儲(chǔ)更多的鍵值對(duì),可以考慮使用 Redis 集群或分片技術(shù),以擴(kuò)展整體存儲(chǔ)容量。

責(zé)任編輯:武曉燕 來源: SevenCoding
相關(guān)推薦

2023-05-26 00:02:31

SDS數(shù)據(jù)編碼

2022-05-23 08:19:19

Redis數(shù)據(jù)結(jié)構(gòu)內(nèi)存

2025-01-15 12:58:29

2023-11-13 08:31:25

SpringRedis存儲(chǔ)

2019-12-18 14:41:07

Redis數(shù)據(jù)結(jié)構(gòu)

2024-03-01 18:43:55

Redis數(shù)據(jù)實(shí)際場(chǎng)景

2021-06-09 11:41:10

RateLimiterJava代碼

2009-08-27 15:47:00

C#數(shù)據(jù)類型string

2023-09-14 08:16:50

Lazy注解null

2010-05-31 10:35:12

MySQL數(shù)據(jù)類型

2021-03-04 09:20:20

數(shù)據(jù)Redis 架構(gòu)

2019-11-11 14:55:25

Redis數(shù)據(jù)類型命令

2021-06-15 09:20:08

Redis數(shù)據(jù)類型

2019-08-12 11:40:48

數(shù)據(jù)庫SQLite3數(shù)據(jù)類型

2021-03-12 08:02:34

Redis數(shù)據(jù)類型.

2020-12-14 09:55:17

Redis數(shù)據(jù)庫命令

2024-05-28 11:44:54

Redis數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)庫

2021-06-08 08:51:50

Redis 數(shù)據(jù)類型數(shù)據(jù)統(tǒng)計(jì)

2020-11-04 07:34:02

Redis數(shù)據(jù)類型

2009-09-01 16:35:55

C#操作String數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)