0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一文掌握redis知識(shí)點(diǎn)

我快閉嘴 ? 來(lái)源:CSDN技術(shù)社區(qū) ? 作者:兔老大RabbitMQ ? 2022-10-08 11:58 ? 次閱讀

前言

大家好,這里是浩道linux,主要給大家分享linux、python、網(wǎng)絡(luò)通信相關(guān)的IT知識(shí)平臺(tái)。

今天浩道跟大家分享硬核干貨,關(guān)于redis總結(jié),讓你一文掌握redis大體知識(shí)點(diǎn)!

1、什么是redis?

Redis 本質(zhì)上是一個(gè) Key-Value 類(lèi)型的內(nèi)存數(shù)據(jù)庫(kù), 整個(gè)數(shù)據(jù)庫(kù)加載在內(nèi)存當(dāng)中進(jìn)行操作, 定期通過(guò)異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù) flush 到硬盤(pán)上進(jìn)行保存。

因?yàn)槭羌儍?nèi)存操作, Redis 的性能非常出色, 每秒可以處理超過(guò) 10 萬(wàn)次讀寫(xiě)操作, 是已知性能最快的 Key-Value DB。

Redis 的出色之處不僅僅是性能, Redis 最大的魅力是支持保存多種數(shù)據(jù)結(jié)構(gòu), 此外單個(gè)value 的最大限制是 1GB, 不像 memcached 只能保存 1MB 的數(shù)據(jù), 因此 Redis 可以用來(lái)實(shí)現(xiàn)很多有用的功能,比方說(shuō)用他的 List 來(lái)做 FIFO 雙向鏈表,實(shí)現(xiàn)一個(gè)輕量級(jí)的高性 能消息隊(duì)列服務(wù), 用他的 Set 可以做高性能的 tag 系統(tǒng)等等。

另外 Redis 也可以對(duì)存入的Key-Value 設(shè)置 expire 時(shí)間, 因此也可以被當(dāng)作一 個(gè)功能加強(qiáng)版的 memcached 來(lái)用。Redis 的主要缺點(diǎn)是數(shù)據(jù)庫(kù)容量受到物理內(nèi)存的限制, 不能用作海量數(shù)據(jù)的高性能讀寫(xiě), 因此 Redis 適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上。

2、相比 memcached 有哪些優(yōu)勢(shì)?

redis支持更豐富的數(shù)據(jù)類(lèi)型(支持更復(fù)雜的應(yīng)用場(chǎng)景)
Redis不僅僅支持簡(jiǎn)單的k/v類(lèi)型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。

memcache支持簡(jiǎn)單的數(shù)據(jù)類(lèi)型,String。Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤(pán)中,重啟的時(shí)候可以再次加載進(jìn)行使用,而Memecache把數(shù)據(jù)全部存在內(nèi)存之中。

集群模式:
memcached沒(méi)有原生的集群模式,需要依靠客戶(hù)端來(lái)實(shí)現(xiàn)往集群中分片寫(xiě)入數(shù)據(jù);
但是 redis 目前是原生支持 cluster 模式的.

Memcached是多線程,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型;Redis使用單線程的多路 IO 復(fù)用模型。

88ce3884-4279-11ed-96c9-dac502259ad0.jpg

3、Redis 的全稱(chēng)是什么?

Remote Dictionary Server。

4、支持哪幾種數(shù)據(jù)類(lèi)型?

String、 List、 Set、 Sorted Set、 hashes

5、Redis 有哪幾種數(shù)據(jù)淘汰策略?

noeviction:返回錯(cuò)誤當(dāng)內(nèi)存限制達(dá)到并且客戶(hù)端嘗試執(zhí)行會(huì)讓更多內(nèi)存被使用的命令(大部分的寫(xiě)入指令, 但 DEL 和幾個(gè)例外)

allkeys-lru: 嘗試回收最少使用的鍵(LRU), 使得新添加的數(shù)據(jù)有空間存放。

volatile-lru: 嘗試回收最少使用的鍵(LRU), 但僅限于在過(guò)期集合的鍵,使得新添加的數(shù)據(jù)有空間存放。

allkeys-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放。

volatile-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放,但僅限于在過(guò)期集合的鍵。

volatile-ttl: 回收在過(guò)期集合的鍵, 并且優(yōu)先回收存活時(shí)間(TTL) 較短的鍵,使得新添加的數(shù)據(jù)有空間存放。

6、redis為什么采用跳表而不是紅黑樹(shù)

在做范圍查找的時(shí)候,平衡樹(shù)比skiplist操作要復(fù)雜。在平衡樹(shù)上,我們找到指定范圍的小值之后,還需要以中序遍歷的順序繼續(xù)尋找其它不超過(guò)大值的節(jié)點(diǎn)。如果不對(duì)平衡樹(shù)進(jìn)行一定的改造,這里的中序遍歷并不容易實(shí)現(xiàn)。而在skiplist上進(jìn)行范圍查找就非常簡(jiǎn)單,只需要在找到小值之后,對(duì)第1層鏈表進(jìn)行若干步的遍歷就可以實(shí)現(xiàn)。

平衡樹(shù)的插入和刪除操作可能引發(fā)子樹(shù)的調(diào)整,邏輯復(fù)雜,而skiplist的插入和刪除只需要修改相鄰節(jié)點(diǎn)的指針,操作簡(jiǎn)單又快速。

從內(nèi)存占用上來(lái)說(shuō),skiplist比平衡樹(shù)更靈活一些。一般來(lái)說(shuō),平衡樹(shù)每個(gè)節(jié)點(diǎn)包含2個(gè)指針(分別指向左右子樹(shù)),而skiplist每個(gè)節(jié)點(diǎn)包含的指針數(shù)目平均為1/(1-p),具體取決于參數(shù)p的大小。如果像Redis里的實(shí)現(xiàn)一樣,取p=1/4,那么平均每個(gè)節(jié)點(diǎn)包含1.33個(gè)指針,比平衡樹(shù)更有優(yōu)勢(shì)。

查找單個(gè)key,skiplist和平衡樹(shù)的時(shí)間復(fù)雜度都為O(log n),大體相當(dāng);而哈希表在保持較低的哈希值沖突概率的前提下,查找時(shí)間復(fù)雜度接近O(1),性能更高一些。所以我們平常使用的各種Map或dictionary結(jié)構(gòu),大都是基于哈希表實(shí)現(xiàn)的。

算法實(shí)現(xiàn)難度上來(lái)比較,skiplist比平衡樹(shù)要簡(jiǎn)單得多。

7、介紹一下HyperLogLog?

HyperLogLog 是一種概率數(shù)據(jù)結(jié)構(gòu),用來(lái)估算數(shù)據(jù)的基數(shù)。數(shù)據(jù)集可以是網(wǎng)站訪客的 IP 地址,E-mail 郵箱或者用戶(hù) ID。

基數(shù)就是指一個(gè)集合中不同值的數(shù)目,比如 a, b, c, d 的基數(shù)就是 4,a, b, c, d, a 的基數(shù)還是 4。雖然 a 出現(xiàn)兩次,只會(huì)被計(jì)算一次。

使用 Redis 統(tǒng)計(jì)集合的基數(shù)一般有三種方法,分別是使用 Redis 的 HashMap,BitMap 和 HyperLogLog。前兩個(gè)數(shù)據(jù)結(jié)構(gòu)在集合的數(shù)量級(jí)增長(zhǎng)時(shí),所消耗的內(nèi)存會(huì)大大增加,但是 HyperLogLog 則不會(huì)。

Redis 的 HyperLogLog 通過(guò)犧牲準(zhǔn)確率來(lái)減少內(nèi)存空間的消耗,只需要12K內(nèi)存,在標(biāo)準(zhǔn)誤差0.81%的前提下,能夠統(tǒng)計(jì)2^64個(gè)數(shù)據(jù)。所以 HyperLogLog 是否適合在比如統(tǒng)計(jì)日活月活此類(lèi)的對(duì)精度要不不高的場(chǎng)景。

這是一個(gè)很驚人的結(jié)果,以如此小的內(nèi)存來(lái)記錄如此大數(shù)量級(jí)的數(shù)據(jù)基數(shù)。

8、為什么 Redis 需要把所有數(shù)據(jù)放到內(nèi)存中?

Redis 為了達(dá)到最快的讀寫(xiě)速度將數(shù)據(jù)都讀到內(nèi)存中, 并通過(guò)異步的方式將數(shù)據(jù)寫(xiě)入磁盤(pán)。

所以 Redis 具有快速和數(shù)據(jù)持久化的特征。如果不將數(shù)據(jù)放在內(nèi)存中, 磁盤(pán) I/O 速度為嚴(yán)重影響 Redis 的性能。在內(nèi)存越來(lái)越便宜的今天, Redis 將會(huì)越來(lái)越受歡迎。

9、Redis支持的數(shù)據(jù)類(lèi)型?

String字符串:

格式: set key value

string類(lèi)型是二進(jìn)制安全的。意思是redis的string可以包含任何數(shù)據(jù)。比如jpg圖片或者序列化的對(duì)象 。

string類(lèi)型是Redis最基本的數(shù)據(jù)類(lèi)型,一個(gè)鍵最大能存儲(chǔ)512MB。

Hash(哈希)

格式: hmset name key1 value1 key2 value2

Redis hash 是一個(gè)鍵值(key=>value)對(duì)集合。

Redis hash是一個(gè)string類(lèi)型的field和value的映射表,hash特別適合用于存儲(chǔ)對(duì)象。

List(列表)

Redis 列表是簡(jiǎn)單的字符串列表,按照插入順序排序。你可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)

格式: lpush name value

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

格式: rpush name value

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

格式: lrem name index

key 對(duì)應(yīng) list 中刪除 count 個(gè)和 value 相同的元素

格式: llen name

返回 key 對(duì)應(yīng) list 的長(zhǎng)度

Set(集合)

格式: sadd name value

Redis的Set是string類(lèi)型的無(wú)序集合。

集合是通過(guò)哈希表實(shí)現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。

zset(sorted set:有序集合)

格式: zadd name score value

Redis zset 和 set 一樣也是string類(lèi)型元素的集合,且不允許重復(fù)的成員。

不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類(lèi)型的分?jǐn)?shù)。redis正是通過(guò)分?jǐn)?shù)來(lái)為集合中的成員進(jìn)行從小到大的排序。

zset的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)。

10、sds相對(duì)c的改進(jìn)?

獲取長(zhǎng)度:c字符串并不記錄自身長(zhǎng)度,所以獲取長(zhǎng)度只能遍歷一遍字符串,redis直接讀取len即可。

緩沖區(qū)安全:c字符串容易造成緩沖區(qū)溢出,比如:程序員沒(méi)有分配足夠的空間就執(zhí)行拼接操作。而redis會(huì)先檢查sds的空間是否滿(mǎn)足所需要求,如果不滿(mǎn)足會(huì)自動(dòng)擴(kuò)充。

內(nèi)存分配:由于c不記錄字符串長(zhǎng)度,對(duì)于包含了n個(gè)字符的字符串,底層總是一個(gè)長(zhǎng)度n+1的數(shù)組,每一次長(zhǎng)度變化,總是要對(duì)這個(gè)數(shù)組進(jìn)行一次內(nèi)存重新分配的操作。因?yàn)閮?nèi)存分配涉及復(fù)雜算法并且可能需要執(zhí)行系統(tǒng)調(diào)用,所以它通常是比較耗時(shí)的操作。

11、redis鏈表源碼?有什么特性?

雙端、無(wú)環(huán)、帶長(zhǎng)度記錄、

多態(tài):使用 void* 指針來(lái)保存節(jié)點(diǎn)值, 可以通過(guò) dup 、 free 、 match 為節(jié)點(diǎn)值設(shè)置類(lèi)型特定函數(shù), 可以保存不同類(lèi)型的值。

12、字典是如何實(shí)現(xiàn)的?

其實(shí)字典這種數(shù)據(jù)結(jié)構(gòu)也內(nèi)置在很多高級(jí)語(yǔ)言中,但是c語(yǔ)言沒(méi)有,所以redis自己實(shí)現(xiàn)了。

應(yīng)用也比較廣泛,比如redis的數(shù)據(jù)庫(kù)就是字典實(shí)現(xiàn)的。不僅如此,當(dāng)一個(gè)哈希鍵包含的鍵值對(duì)比較多,或者都是很長(zhǎng)的字符串,redis就會(huì)用字典作為哈希鍵的底層實(shí)現(xiàn)。

13、LRU?redis里的具體實(shí)現(xiàn)?

LRU全稱(chēng)是Least Recently Used,即最近最久未使用的意思。

LRU算法的設(shè)計(jì)原則是:如果一個(gè)數(shù)據(jù)在最近一段時(shí)間沒(méi)有被訪問(wèn)到,那么在將來(lái)它被訪問(wèn)的可能性也很小。也就是說(shuō),當(dāng)限定的空間已存滿(mǎn)數(shù)據(jù)時(shí),應(yīng)當(dāng)把最久沒(méi)有被訪問(wèn)到的數(shù)據(jù)淘汰。

redis原始的淘汰算法簡(jiǎn)單實(shí)現(xiàn):當(dāng)需要淘汰一個(gè)key時(shí),隨機(jī)選擇3個(gè)key,淘汰其中間隔時(shí)間最長(zhǎng)的key。**基本上,我們隨機(jī)選擇key,淘汰key效果很好。后來(lái)隨機(jī)3個(gè)key改成一個(gè)配置項(xiàng)"N隨機(jī)key"。但把默認(rèn)值提高改成5個(gè)后效果大大提高??紤]到它的效果,你根本不用修改他。

14、redis的持久化?

RDB持久化可以手動(dòng)執(zhí)行,也可以配置定期執(zhí)行,可以把某個(gè)時(shí)間的數(shù)據(jù)狀態(tài)保存到RDB文件中,反之,我們可以用RDB文件還原數(shù)據(jù)庫(kù)狀態(tài)。

AOF持久化是通過(guò)保存服務(wù)器執(zhí)行的命令來(lái)記錄狀態(tài)的。還原的時(shí)候再執(zhí)行一遍即可。

15、如何選擇合適的持久化方式?

一般來(lái)說(shuō), 如果想達(dá)到足以媲美 PostgreSQL 的數(shù)據(jù)安全性, 你應(yīng)該同時(shí)使用兩種持久化功能。如果你非常關(guān)心你的數(shù)據(jù), 但仍然可以承受數(shù)分鐘以?xún)?nèi)的數(shù)據(jù)丟失, 那么你可以只使用 RDB 持久化。

有很多用戶(hù)都只使用 AOF 持久化, 但并不推薦這種方式:因?yàn)槎〞r(shí)生成 RDB 快照(snapshot) 非常便于進(jìn)行數(shù)據(jù)庫(kù)備份, 并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)的速度要快, 除此之外, 使用 RDB 還可以避免之前提到的 AOF 程序的 bug。

16、Redis 集群方案應(yīng)該怎么做?都有哪些方案?

1.twemproxy, 大概概念是, 它類(lèi)似于一個(gè)代理方式, 使用方法和普通 Redis 無(wú)任何區(qū)別,設(shè) 置 好它 下 屬 的多 個(gè) Redis 實(shí) 例 后, 使 用 時(shí)在 本 需 要 連接 Redis 的 地 方改 為 連接twemproxy, 它會(huì)以一個(gè)代理的身份接收請(qǐng)求并使用一致性 hash 算法, 將請(qǐng)求轉(zhuǎn)接到具體 Redis, 將結(jié)果再返回 twemproxy。使用方式簡(jiǎn)便(相對(duì) Redis 只需修改連接端口), 對(duì)舊項(xiàng)目擴(kuò)展的首選。問(wèn)題:twemproxy 自身單端口實(shí)例的壓力, 使用一致性 hash 后, 對(duì)Redis 節(jié)點(diǎn)數(shù)量改變時(shí)候的計(jì)算值的改變, 數(shù)據(jù)無(wú)法自動(dòng)移動(dòng)到新的節(jié)點(diǎn)。

2.codis, 目前用的最多的集群方案, 基本和 twemproxy 一致的效果, 但它支持在 節(jié)點(diǎn)數(shù)量改變情況下, 舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新 hash 節(jié)點(diǎn)。

3.Redis cluster3.0 自帶的集群, 特點(diǎn)在于他的分布式算法不是一致性 hash, 而是 hash槽的概念, 以及自身支持節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)。具體看官方文檔介紹。

4.在業(yè)務(wù)代碼層實(shí)現(xiàn), 起幾個(gè)毫無(wú)關(guān)聯(lián)的 Redis 實(shí)例, 在代碼層, 對(duì) key 進(jìn)行 hash 計(jì)算,然后去對(duì)應(yīng)的 Redis 實(shí)例操作數(shù)據(jù)。這種方式對(duì) hash 層代碼要求比較高, 考慮部分包括,節(jié)點(diǎn)失效后的替代算法方案, 數(shù)據(jù)震蕩后的自動(dòng)腳本恢復(fù), 實(shí)例的監(jiān)控, 等等。

17、MySQL 里有 2000w 數(shù)據(jù), Redis 中只存 20w 的數(shù)據(jù),如何保證 Redis 中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)?

Redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候, 就會(huì)施行數(shù)據(jù)淘汰策略;

18、Redis 有哪些適合的場(chǎng)景?

1、會(huì)話(huà)緩存(Session Cache)

最常用的一種使用 Redis 的情景是會(huì)話(huà)緩存(session cache)。用 Redis 緩存會(huì)話(huà)比其他存儲(chǔ)(如 Memcached) 的優(yōu)勢(shì)在于:Redis 提供持久化。當(dāng)維護(hù)一個(gè)不是嚴(yán)格要求一致性的緩存時(shí), 如果用戶(hù)的購(gòu)物車(chē)信息全部丟失, 大部分人都會(huì)不高興的, 現(xiàn)在, 他們還會(huì)這樣嗎?
幸運(yùn)的是, 隨著 Redis 這些年的改進(jìn), 很容易找到怎么恰當(dāng)?shù)氖褂?Redis 來(lái)緩存會(huì)話(huà)的文檔。甚至廣為人知的商業(yè)平臺(tái) Magento 也提供 Redis 的插件。

2、全頁(yè)緩存(FPC

除基本的會(huì)話(huà) token 之外, Redis 還提供很簡(jiǎn)便的 FPC 平臺(tái)?;氐揭恢滦詥?wèn)題, 即使重啟了 Redis 實(shí)例, 因?yàn)橛写疟P(pán)的持久化, 用戶(hù)也不會(huì)看到頁(yè)面加載速度的下降, 這是一個(gè)極大改進(jìn), 類(lèi)似 PHP 本地 FPC。再次以 Magento 為例, Magento 提供一個(gè)插件來(lái)使用 Redis 作為全頁(yè)緩存后端。

此外, 對(duì) WordPress 的用戶(hù)來(lái)說(shuō), Pantheon 有一個(gè)非常好的插件 wp-Redis, 這個(gè)插件能幫助你以最快速度加載你曾瀏覽過(guò)的頁(yè)面。

3、隊(duì)列

Reids 在內(nèi)存存儲(chǔ)引擎領(lǐng)域的一大優(yōu)點(diǎn)是提供 list 和 set 操作,這使得 Redis 能作為一個(gè)很好的消息隊(duì)列平臺(tái)來(lái)使用。Redis 作為隊(duì)列使用的操作, 就類(lèi)似于本地程序語(yǔ)言(如Python) 對(duì) list 的 push/pop 操作。

如果你快速的在 Google 中搜索“Redis queues”, 你馬上就能找到大量的開(kāi)源項(xiàng)目, 這些項(xiàng)目的目的就是利用 Redis 創(chuàng)建非常好的后端工具, 以滿(mǎn)足各種隊(duì)列需求。例如, Celery有一個(gè)后臺(tái)就是使用 Redis 作為 broker, 你可以從這里去查看。

4、排行榜/計(jì)數(shù)器

Redis在內(nèi)存中對(duì)數(shù)字進(jìn)行遞增或遞減的操作實(shí)現(xiàn)的非常好。集合(Set)和有序集合(SortedSet) 也使得我們?cè)趫?zhí)行這些操作的時(shí)候變的非常簡(jiǎn)單, Redis 只是正好提供了這兩種數(shù)據(jù)結(jié)構(gòu)。

所以, 我們要從排序集合中獲取到排名最靠前的 10 個(gè)用戶(hù)–我們稱(chēng)之為“user_scores”, 我們只需要像下面一樣執(zhí)行即可:當(dāng)然, 這是假定你是根據(jù)你用戶(hù)的分?jǐn)?shù)做遞增的排序。如果你想返回用戶(hù)及用戶(hù)的分?jǐn)?shù),。

你需要這樣執(zhí)行:ZRANGE user_scores 0 10 WITHSCORES Agora Games 就是一個(gè)很好的例子, 用 Ruby 實(shí)現(xiàn)的, 它的排行榜就是使用 Redis 來(lái)存儲(chǔ)數(shù)據(jù)的, 你可以在這里看到。

5、發(fā)布/訂閱

最后 是 Redis 的發(fā)布/訂閱功能。發(fā)布/訂閱的使用場(chǎng)景確實(shí)非常多。我已看見(jiàn)人們?cè)谏缃痪W(wǎng)絡(luò)連接中使用, 還可作為基于發(fā)布/訂閱的腳本觸發(fā)器, 甚至用 Redis 的發(fā)布/訂閱功能來(lái)建立聊天系統(tǒng)。

19、說(shuō)說(shuō) Redis 哈希槽的概念?

Redis 集群沒(méi)有使用一致性 hash,而是引入了哈希槽的概念, Redis 集群有 16384 個(gè)哈希槽,每個(gè) key 通過(guò) CRC16 校驗(yàn)后對(duì) 16384 取模來(lái)決定放置哪個(gè)槽, 集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分hash 槽

20、為什么Redis集群有16384個(gè)槽

1、如果槽位為65536,發(fā)送心跳信息的消息頭達(dá)8k,發(fā)送的心跳包過(guò)于龐大。

如上所述,在消息頭中,最占空間的是myslots[CLUSTER_SLOTS/8]。當(dāng)槽位為65536時(shí),這塊的大小是: 65536÷8÷1024=8kb 因?yàn)槊棵腌?,redis節(jié)點(diǎn)需要發(fā)送一定數(shù)量的ping消息作為心跳包,如果槽位為65536,這個(gè)ping消息的消息頭太大了,浪費(fèi)帶寬。

2、redis的集群主節(jié)點(diǎn)數(shù)量基本不可能超過(guò)1000個(gè)。

如上所述,集群節(jié)點(diǎn)越多,心跳包的消息體內(nèi)攜帶的數(shù)據(jù)越多。如果節(jié)點(diǎn)過(guò)1000個(gè),也會(huì)導(dǎo)致網(wǎng)絡(luò)擁堵。因此redis作者,不建議redis cluster節(jié)點(diǎn)數(shù)量超過(guò)1000個(gè)。那么,對(duì)于節(jié)點(diǎn)數(shù)在1000以?xún)?nèi)的redis cluster集群,16384個(gè)槽位夠用了。沒(méi)有必要拓展到65536個(gè)。

3、槽位越小,節(jié)點(diǎn)少的情況下,壓縮比高

Redis主節(jié)點(diǎn)的配置信息中,它所負(fù)責(zé)的哈希槽是通過(guò)一張bitmap的形式來(lái)保存的,在傳輸過(guò)程中,會(huì)對(duì)bitmap進(jìn)行壓縮,但是如果bitmap的填充率slots / N很高的話(huà)(N表示節(jié)點(diǎn)數(shù)),bitmap的壓縮率就很低。如果節(jié)點(diǎn)數(shù)很少,而哈希槽數(shù)量很多的話(huà),bitmap的壓縮率就很低。

21、Redis 集群會(huì)有寫(xiě)操作丟失嗎?為什么?

Redis 并不能保證數(shù)據(jù)的強(qiáng)一致性, 這意味著在實(shí)際中集群在特定的條件下可能會(huì)丟失寫(xiě)操作。

22、Redis 集群方案應(yīng)該怎么做?都有哪些方案?

1.twemproxy,大概概念是,它類(lèi)似于一個(gè)代理方式, 使用時(shí)在本需要連接 redis 的地方改為連接 twemproxy, 它會(huì)以一個(gè)代理的身份接收請(qǐng)求并使用一致性 hash 算法,將請(qǐng)求轉(zhuǎn)接到具體 redis,將結(jié)果再返回 twemproxy。

缺點(diǎn):twemproxy 自身單端口實(shí)例的壓力,使用一致性 hash 后,對(duì) redis 節(jié)點(diǎn)數(shù)量改變時(shí)候的計(jì)算值的改變,數(shù)據(jù)無(wú)法自動(dòng)移動(dòng)到新的節(jié)點(diǎn)。

2.codis,目前用的最多的集群方案,基本和 twemproxy 一致的效果,但它支持在 節(jié)點(diǎn)數(shù)量改變情況下,舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新 hash 節(jié)點(diǎn)

3.redis cluster3.0 自帶的集群,特點(diǎn)在于他的分布式算法不是一致性 hash,而是 hash 槽的概念,以及自身支持節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)。具體看官方文檔介紹。

23、為什么要做 Redis 分區(qū)?

分區(qū)可以讓 Redis 管理更大的內(nèi)存, Redis 將可以使用所有機(jī)器的內(nèi)存。如果沒(méi)有分區(qū), 你最多只能使用一臺(tái)機(jī)器的內(nèi)存。分區(qū)使 Redis 的計(jì)算能力通過(guò)簡(jiǎn)單地增加計(jì)算機(jī)得到成倍提升,Redis 的網(wǎng)絡(luò)帶寬也會(huì)隨著計(jì)算機(jī)和網(wǎng)卡的增加而成倍增長(zhǎng)。

24、Redis 分區(qū)有什么缺點(diǎn)?

涉及多個(gè) key 的操作通常不會(huì)被支持。例如你不能對(duì)兩個(gè)集合求交集, 因?yàn)樗麄兛赡鼙淮鎯?chǔ)到不同的 Redis 實(shí)例(實(shí)際上這種情況也有辦法, 但是不能直接使用交集指令)。

同時(shí)操作多個(gè) key,則不能使用 Redis 事務(wù).分區(qū)使用的粒度是key,不能使用一個(gè)非常長(zhǎng)的排序key存儲(chǔ)一個(gè)數(shù)據(jù)集(The partitioning granularity is the key, so it is not possible to shard a dataset with a single huge key like a very big sorted set) .

當(dāng)使用分區(qū)的時(shí)候, 數(shù)據(jù)處理會(huì)非常復(fù)雜, 例如為了備份你必須從不同的 Redis 實(shí)例和主機(jī)同時(shí)收集 RDB / AOF 文件。

分區(qū)時(shí)動(dòng)態(tài)擴(kuò)容或縮容可能非常復(fù)雜。Redis 集群在運(yùn)行時(shí)增加或者刪除 Redis 節(jié)點(diǎn), 能做到最大程度對(duì)用戶(hù)透明地?cái)?shù)據(jù)再平衡,但其他一些客戶(hù)端分區(qū)或者代理分區(qū)方法則不支持這種特性。然而, 有一種預(yù)分片的技術(shù)也可以較好的解決這個(gè)問(wèn)題。

25、Redis 與其他 key-value 存儲(chǔ)有什么不同?

Redis 有著更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)并且提供對(duì)他們的原子性操作,這是一個(gè)不同于其他數(shù)據(jù)庫(kù)的進(jìn)化路徑。Redis 的數(shù)據(jù)類(lèi)型都是基于基本數(shù)據(jù)結(jié)構(gòu)的同時(shí)對(duì)程序員透明, 無(wú)需進(jìn)行額外的抽象。

Redis 運(yùn)行在內(nèi)存中但是可以持久化到磁盤(pán),所以在對(duì)不同數(shù)據(jù)集進(jìn)行高速讀寫(xiě)時(shí)需要權(quán)衡內(nèi)存, 應(yīng)為數(shù)據(jù)量不能大于硬件內(nèi)存。在內(nèi)存數(shù)據(jù)庫(kù)方面的另一個(gè)優(yōu)點(diǎn)是, 相比在磁盤(pán)上相同的復(fù)雜的數(shù)據(jù)結(jié)構(gòu), 在內(nèi)存中操作起來(lái)非常簡(jiǎn)單, 這樣 Redis 可以做很多內(nèi)部復(fù)雜性很強(qiáng)的事情。同時(shí), 在磁盤(pán)格式方面他們是緊湊的以追加的方式產(chǎn)生的, 因?yàn)樗麄儾⒉恍枰M(jìn)行隨機(jī)訪問(wèn)。

26、Redis 的內(nèi)存用完了會(huì)發(fā)生什么?

如果達(dá)到設(shè)置的上限, Redis 的寫(xiě)命令會(huì)返回錯(cuò)誤信息(但是讀命令還可以正常返回。) 或者你可以將 Redis 當(dāng)緩存來(lái)使用配置淘汰機(jī)制,當(dāng) Redis 達(dá)到內(nèi)存上限時(shí)會(huì)沖刷掉舊的內(nèi)容。

27、Redis 是單線程的, 如何提高多核 CPU 的利用率?

可以在同一個(gè)服務(wù)器部署多個(gè) Redis 的實(shí)例, 并把他們當(dāng)作不同的服務(wù)器來(lái)使用, 在某些時(shí)候, 無(wú)論如何一個(gè)服務(wù)器是不夠的,所以, 如果你想使用多個(gè) CPU, 你可以考慮一下分片(shard)。

28、一個(gè) Redis 實(shí)例最多能存放多少的 keys?List、 Set、Sorted Set 他們最多能存放多少元素?

理論上 Redis 可以處理多達(dá) 232 的 keys, 并且在實(shí)際中進(jìn)行了測(cè)試, 每個(gè)實(shí)例至少存放了 2億 5 千萬(wàn)的 keys。我們正在測(cè)試一些較大的值。

任何 list、 set、 和 sorted set 都可以放 232 個(gè)元素。

換句話(huà)說(shuō), Redis 的存儲(chǔ)極限是系統(tǒng)中的可用內(nèi)存值。

29、修改配置不重啟 Redis 會(huì)實(shí)時(shí)生效嗎?

針對(duì)運(yùn)行實(shí)例, 有許多配置選項(xiàng)可以通過(guò) CONFIG SET 命令進(jìn)行修改, 而無(wú)需執(zhí)行任何形式的重啟。從 Redis 2.2 開(kāi)始, 可以從 AOF 切換到 RDB 的快照持久性或其他方式而不需要重啟 Redis。檢索 ‘CONFIG GET *’ 命令獲取更多信息。

但偶爾重新啟動(dòng)是必須的, 如為升級(jí) Redis 程序到新的版本, 或者當(dāng)你需要修改某些目前CONFIG 命令還不支持的配置參數(shù)的時(shí)候。

30、哨兵

Redis sentinel 是一個(gè)分布式系統(tǒng)中監(jiān)控 redis 主從服務(wù)器,并在主服務(wù)器下線時(shí)自動(dòng)進(jìn)行故障轉(zhuǎn)移。其中三個(gè)特性:

監(jiān)控(Monitoring):Sentinel 會(huì)不斷地檢查你的主服務(wù)器和從服務(wù)器是否運(yùn)作正常。

提醒(Notification):被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問(wèn)題時(shí), Sentinel 可以通過(guò) API 向管理員或者其他應(yīng)用程序發(fā)送通知。

自動(dòng)故障遷移(Automatic failover):當(dāng)一個(gè)主服務(wù)器不能正常工作時(shí), Sentinel 會(huì)開(kāi)始一次自動(dòng)故障遷移操作。

特點(diǎn):

保證高可用

監(jiān)控各個(gè)節(jié)點(diǎn)

自動(dòng)故障遷移

缺點(diǎn):

主從模式,切換需要時(shí)間丟數(shù)據(jù),沒(méi)有解決 master 寫(xiě)的壓力

31、緩存穿透

一般的緩存系統(tǒng),都是按照key去緩存查詢(xún),如果不存在對(duì)應(yīng)的value,就去后端系統(tǒng)查找(比如DB)。

一些惡意的請(qǐng)求會(huì)故意查詢(xún)不存在的key,請(qǐng)求量很大,就會(huì)對(duì)后端系統(tǒng)造成很大的壓力。這就叫做緩存穿透。

如何避免?

對(duì)查詢(xún)結(jié)果為空的情況也進(jìn)行緩存,這樣,再次訪問(wèn)時(shí),緩存層會(huì)直接返回空值。緩存時(shí)間設(shè)置短一點(diǎn),或者該key對(duì)應(yīng)的數(shù)據(jù)insert了之后清理緩存。

對(duì)一定不存在的key進(jìn)行過(guò)濾。具體請(qǐng)看布隆過(guò)濾器。

32、緩存擊穿

是針對(duì)緩存中沒(méi)有但數(shù)據(jù)庫(kù)有的數(shù)據(jù)。

場(chǎng)景是,當(dāng)Key失效后,假如瞬間突然涌入大量的請(qǐng)求,來(lái)請(qǐng)求同一個(gè)Key,這些請(qǐng)求不會(huì)命中Redis,都會(huì)請(qǐng)求到DB,導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大,甚至扛不住,掛掉。

解決辦法

設(shè)置熱點(diǎn)Key,自動(dòng)檢測(cè)熱點(diǎn)Key,將熱點(diǎn)Key的過(guò)期時(shí)間加大或者設(shè)置為永不過(guò)期,或者設(shè)置為邏輯上永不過(guò)期

加互斥鎖。當(dāng)發(fā)現(xiàn)沒(méi)有命中Redis,去查數(shù)據(jù)庫(kù)的時(shí)候,在執(zhí)行更新緩存的操作上加鎖,當(dāng)一個(gè)線程訪問(wèn)時(shí),其它線程等待,這個(gè)線程訪問(wèn)過(guò)后,緩存中的數(shù)據(jù)會(huì)被重建,這樣其他線程就可以從緩存中取值。

33、緩存雪崩

是指大量Key同時(shí)失效,對(duì)這些Key的請(qǐng)求又會(huì)打到DB上,同樣會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大甚至掛掉。

解決辦法

讓Key的失效時(shí)間分散開(kāi),可以在統(tǒng)一的失效時(shí)間上再加一個(gè)隨機(jī)值,或者使用更高級(jí)的算法分散失效時(shí)間。

構(gòu)建多個(gè)redis實(shí)例,個(gè)別節(jié)點(diǎn)掛了還有別的可以用。

多級(jí)緩存:比如增加本地緩存,減小redis壓力。

對(duì)存儲(chǔ)層增加限流措施,當(dāng)請(qǐng)求超出限制,提供降級(jí)服務(wù)(一般就是返回錯(cuò)誤即可)

34、單線程的 redis 為什么這么快

純內(nèi)存操作

單線程操作,避免了頻繁的上下文切換

采用了非阻塞I/O多路復(fù)用機(jī)制

35、redis采用的刪除策略

redis采用的是定期刪除+惰性刪除策略。

36、為什么不用定時(shí)刪除策略?

定時(shí)刪除,用一個(gè)定時(shí)器來(lái)負(fù)責(zé)監(jiān)視key,過(guò)期則自動(dòng)刪除。雖然內(nèi)存及時(shí)釋放,但是十分消耗CPU資源。在大并發(fā)請(qǐng)求下,CPU要將時(shí)間應(yīng)用在處理請(qǐng)求,而不是刪除key,因此沒(méi)有采用這一策略。

37、定期刪除+惰性刪除是如何工作的呢?

定期刪除,redis默認(rèn)每個(gè)100ms檢查,是否有過(guò)期的key,有過(guò)期key則刪除。需要說(shuō)明的是,redis不是每個(gè)100ms將所有的key檢查一次,而是隨機(jī)抽取進(jìn)行檢查(如果每隔100ms,全部key進(jìn)行檢查,redis豈不是卡死)。因此,如果只采用定期刪除策略,會(huì)導(dǎo)致很多key到時(shí)間沒(méi)有刪除。

于是,惰性刪除派上用場(chǎng)。也就是說(shuō)在你獲取某個(gè)key的時(shí)候,redis會(huì)檢查一下,這個(gè)key如果設(shè)置了過(guò)期時(shí)間那么是否過(guò)期了?如果過(guò)期了此時(shí)就會(huì)刪除。

38、為什么Redis的操作是原子性的,怎么保證原子性的?

對(duì)于Redis而言,命令的原子性指的是:一個(gè)操作的不可以再分,操作要么執(zhí)行,要么不執(zhí)行。
Redis的操作之所以是原子性的,是因?yàn)镽edis是單線程的。

Redis本身提供的所有API都是原子操作,Redis中的事務(wù)其實(shí)是要保證批量操作的原子性。
多個(gè)命令在并發(fā)中也是原子性的嗎?

不一定, 將get和set改成單命令操作,incr 。使用Redis的事務(wù),或者使用Redis+Lua==的方式實(shí)現(xiàn)。

39、消息隊(duì)列

不要使用redis去做消息隊(duì)列,這不是redis的設(shè)計(jì)目標(biāo)。但實(shí)在太多人使用redis去做去消息隊(duì)列,redis的作者看不下去。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3752

    瀏覽量

    64233
  • Memcached
    +關(guān)注

    關(guān)注

    0

    文章

    12

    瀏覽量

    7002
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    370

    瀏覽量

    10830

原文標(biāo)題:【建議收藏】一文爆肝Redis總結(jié)!

文章出處:【微信號(hào):浩道linux,微信公眾號(hào):浩道linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    【信盈達(dá)】C語(yǔ)言知識(shí)點(diǎn)的總結(jié)

    、算法說(shuō)明:學(xué)習(xí)單片機(jī)C般只需要前9個(gè)知識(shí)點(diǎn)即可進(jìn)行產(chǎn)品開(kāi)發(fā),但要學(xué)習(xí)嵌入式C還需要要掌握:指針、結(jié)構(gòu)體、鏈表、宏定義等知識(shí)點(diǎn)。二、單片機(jī)C、嵌入式C、標(biāo)準(zhǔn)C區(qū)別:這三種C語(yǔ)言都來(lái)源
    發(fā)表于 10-08 14:41

    請(qǐng)問(wèn)學(xué)習(xí)LLC電源需要掌握些什么知識(shí)點(diǎn)

    我是個(gè)剛學(xué)習(xí)電源的萌新,請(qǐng)問(wèn)學(xué)習(xí)LLC電源需要掌握些什么知識(shí)點(diǎn)
    發(fā)表于 03-05 21:42

    做嵌入式開(kāi)發(fā)需要掌握哪些知識(shí)點(diǎn)?

    做嵌入式開(kāi)發(fā)需要掌握哪些知識(shí)點(diǎn)?
    發(fā)表于 09-26 08:16

    請(qǐng)問(wèn)下嵌入式LinuxC需要掌握哪些知識(shí)點(diǎn)

    請(qǐng)問(wèn)下嵌入式LinuxC需要掌握哪些知識(shí)點(diǎn)呢?
    發(fā)表于 11-10 07:15

    學(xué)會(huì)stm32需要掌握知識(shí)點(diǎn)有哪些?

    學(xué)會(huì)stm32需要掌握知識(shí)點(diǎn)有哪些?
    發(fā)表于 12-17 07:17

    計(jì)算機(jī)組成原理考研知識(shí)點(diǎn)歸納

    計(jì)算機(jī)組成原理考研知識(shí)點(diǎn)歸納 寫(xiě)在前面的話(huà):理科知識(shí)重在于理解知識(shí)點(diǎn)本身,對(duì)于每個(gè)知識(shí)點(diǎn),大家都有自己理解的方式。這篇
    發(fā)表于 04-13 14:06 ?1916次閱讀

    一數(shù)學(xué)知識(shí)點(diǎn)總結(jié)

    一數(shù)學(xué)知識(shí)點(diǎn)總結(jié)高一數(shù)學(xué)知識(shí)點(diǎn)總結(jié)高一數(shù)學(xué)知識(shí)點(diǎn)總結(jié)
    發(fā)表于 02-23 15:27 ?0次下載

    高二數(shù)學(xué)知識(shí)點(diǎn)總結(jié)

    高二數(shù)學(xué)知識(shí)點(diǎn)總結(jié)高二數(shù)學(xué)知識(shí)點(diǎn)總結(jié)高二數(shù)學(xué)知識(shí)點(diǎn)總結(jié)
    發(fā)表于 02-23 15:27 ?0次下載

    關(guān)于紅外通信的些問(wèn)題知識(shí)點(diǎn)

    關(guān)于紅外通信的些問(wèn)題知識(shí)點(diǎn)。
    發(fā)表于 05-05 17:40 ?4次下載

    PWM知識(shí)點(diǎn)詳解

    PWM知識(shí)點(diǎn)
    發(fā)表于 03-16 08:00 ?44次下載

    嵌入式知識(shí)點(diǎn)總結(jié)

    嵌入式知識(shí)點(diǎn)總結(jié)(arm嵌入式開(kāi)發(fā)led過(guò)程)-嵌入式知識(shí)點(diǎn)總結(jié)? ? ? ? ? ? ? ? ? ??
    發(fā)表于 07-30 14:20 ?23次下載
    嵌入式<b class='flag-5'>知識(shí)點(diǎn)</b>總結(jié)

    單片機(jī)開(kāi)發(fā)零基礎(chǔ)可不行,還需掌握這些知識(shí)點(diǎn)

    單片機(jī)開(kāi)發(fā)很多人都說(shuō)零基礎(chǔ)也可以做,但會(huì)非常難。想要順利入門(mén),那么大家還需要有定的基礎(chǔ),掌握些必備的知識(shí)點(diǎn)、那今天通程創(chuàng)品就來(lái)給大家分享單片機(jī)開(kāi)發(fā)中需要用到的
    的頭像 發(fā)表于 02-17 15:43 ?1983次閱讀

    數(shù)字電路知識(shí)點(diǎn)總結(jié)

    本文整理了數(shù)字電路課程中的相關(guān)基本的知識(shí)點(diǎn)和較為重要的知識(shí)點(diǎn),用于求職的數(shù)電部分的知識(shí)準(zhǔn)備,差缺補(bǔ)漏。
    的頭像 發(fā)表于 05-30 15:07 ?4614次閱讀
    數(shù)字電路<b class='flag-5'>知識(shí)點(diǎn)</b>總結(jié)

    SystemVerilog實(shí)用知識(shí)點(diǎn):覆蓋率之Function Coverage

    SystemVerilog是名芯片驗(yàn)證工程師,必須掌握門(mén)語(yǔ)言,其中Function Coverage是必須要懂的知識(shí)點(diǎn);
    的頭像 發(fā)表于 06-04 16:30 ?7187次閱讀
    SystemVerilog實(shí)用<b class='flag-5'>知識(shí)點(diǎn)</b>:覆蓋率之Function Coverage

    淺談初級(jí)電工必備知識(shí)點(diǎn)

    對(duì)于初學(xué)電工的朋友來(lái)說(shuō),掌握些基礎(chǔ)且實(shí)用的知識(shí)點(diǎn)是非常重要的。本文旨在分享初級(jí)電工應(yīng)該掌握的核心知識(shí),幫助新手電工更好地入門(mén)和提升技能。
    的頭像 發(fā)表于 12-26 10:44 ?1001次閱讀