1. 簡(jiǎn)單地說(shuō)一說(shuō) Redis 的主從。
主從是指一臺(tái) Redis 做 master,在 master 下面掛 n 個(gè) slave,master 用來(lái)寫(xiě)數(shù)據(jù),寫(xiě)完同步到 slave 上,slave 用來(lái)讀數(shù)據(jù)。Redis 主從主要有兩種種模式:
一主n從:一個(gè) master 下面掛 n 個(gè) slave,缺點(diǎn)就是這 n 個(gè) slave 都是掛同一個(gè) master 下,master 掛了從機(jī)還是從機(jī),不會(huì)變成主機(jī),那么這個(gè)主從也就不可用了,可以手動(dòng)執(zhí)行 slave of one 命令在 slave 中選出新的 master; 串聯(lián)主從:A 下面掛著 B,B下面掛著 C,一脈相承;
2. Redis 主從復(fù)制的原理是什么?
master 會(huì)生成一個(gè) RDB 文件發(fā)送給 slave,slave 接收到 RDB 后先寫(xiě)入磁盤(pán),然后再讀取 RDB 同步數(shù)據(jù)。
3. Redis 集群有哪些方案?
哨兵:一主 n 從的自動(dòng)版,上面說(shuō)的 master 掛了需要手動(dòng)選出新的 master,哨兵就是 Redis 會(huì)有一個(gè) sentinel 集群去監(jiān)控 Redis 的節(jié)點(diǎn),一旦發(fā)現(xiàn) master 掛了,就會(huì)投票選舉出新的 master。優(yōu)點(diǎn)就是簡(jiǎn)單易用,缺點(diǎn)就是只有一個(gè) master 寫(xiě)數(shù)據(jù),容易成為性能瓶頸。 Redis-cluster:Redis 官方出的集群模式,它是有 n 個(gè) master,每個(gè) master下面掛 n 個(gè) slave,也就是有 n 個(gè)主從。每個(gè) master 之間不會(huì)同步數(shù)據(jù),但是可以共享數(shù)據(jù)。寫(xiě)數(shù)據(jù)的時(shí)候,只會(huì)寫(xiě)到其中一個(gè) master 上,然后會(huì)同步到這個(gè) master 所屬的 slave 上。讀數(shù)據(jù)的時(shí)候,如果你是在沒(méi)有那個(gè) key 的節(jié)點(diǎn)上操作的,就會(huì)將命令轉(zhuǎn)發(fā)到有那個(gè) key 的節(jié)點(diǎn)上。由于要轉(zhuǎn)發(fā)命令,每個(gè) master 之間采用 gossip 協(xié)議進(jìn)行通信,因此每個(gè) master 都需要開(kāi)放兩個(gè)端口,比如一個(gè)是 6379, 那么還要一個(gè)加一萬(wàn)的 16379,用來(lái)進(jìn)行通信。redis-cluster 的原理是,它采用了哈希槽的概念,總共有 16384 個(gè)哈希槽,然后將其分配給 Redis 的 master 節(jié)點(diǎn),寫(xiě)數(shù)據(jù)時(shí),用 crc16 算法對(duì) key 進(jìn)行計(jì)算,然后再對(duì) 16384 取余,就知道要寫(xiě)到哪個(gè) master 上。這種方式優(yōu)點(diǎn)就是性能好,支持動(dòng)態(tài)擴(kuò)容,缺點(diǎn)就是只能使用 0 號(hào)庫(kù),且不支持管道技術(shù)。 基于客戶端分片:寫(xiě)數(shù)據(jù)的時(shí)候,在程序中就對(duì) key 進(jìn)行計(jì)算,判斷好要寫(xiě)到哪個(gè)節(jié)點(diǎn)上。優(yōu)點(diǎn)就是每個(gè) Redis 實(shí)例之間沒(méi)有關(guān)聯(lián),容易線性擴(kuò)展,缺點(diǎn)就是 Redis 實(shí)例一旦增加,key 的映射規(guī)則就需要改。 基于代理分片:客戶端請(qǐng)求都發(fā)到代理中,代理再去判斷要發(fā)往哪臺(tái)節(jié)點(diǎn)。優(yōu)點(diǎn)是程序不需要關(guān)心有多少臺(tái) Redis 節(jié)點(diǎn),不需要對(duì) key 做映射規(guī)則,缺點(diǎn)就是多了一層代理,有性能損耗。常見(jiàn)的代理有豌豆莢開(kāi)源的 codis 和推特開(kāi)源的 Twemproxy。
4. 你是如何處理雙寫(xiě)一致性問(wèn)題的?
雙寫(xiě)一致性是指數(shù)據(jù)庫(kù)數(shù)據(jù)與 Redis 中數(shù)據(jù)的一致性問(wèn)題。一般是先寫(xiě)數(shù)據(jù)庫(kù),再寫(xiě) Redis,不過(guò)這樣會(huì)有問(wèn)題,假如寫(xiě)完數(shù)據(jù)庫(kù),還沒(méi)來(lái)得及更新 Redis 的時(shí)候,請(qǐng)求進(jìn)來(lái)了,讀取到的就是 Redis 中的舊數(shù)據(jù)??梢圆捎秒p刪延遲策略來(lái)處理雙寫(xiě)一致性問(wèn)題。具體流程:
先刪 Redis 中的數(shù)據(jù); 然后更新數(shù)據(jù)庫(kù); 線程休眠一段時(shí)間; 再刪 Redis 中的數(shù)據(jù); 休眠一段時(shí)間再刪的目的是,假如請(qǐng)求 A 進(jìn)來(lái)先刪了 Redis 中的數(shù)據(jù),然后再還沒(méi)來(lái)得及更新數(shù)據(jù)庫(kù)的時(shí)候,請(qǐng)求 B 進(jìn)來(lái)了,讀取到的是數(shù)據(jù)庫(kù)的舊數(shù)據(jù);接著請(qǐng)求 A 更新完了 DB,再刪 Redis;然后請(qǐng)求 B 再把讀取到的舊數(shù)據(jù)寫(xiě)到 Redis 中,這樣還是會(huì)導(dǎo)致數(shù)據(jù)庫(kù)和 Redis 數(shù)據(jù)不一致。休眠一段時(shí)間就可以保證請(qǐng)求 B 能把讀取數(shù)據(jù)庫(kù)和寫(xiě) Redis 的步驟執(zhí)行完,執(zhí)行完后請(qǐng)求 A 再去刪 Redis,就可以把 Redis 中的舊數(shù)據(jù)刪除。所以休眠的時(shí)間應(yīng)該大于請(qǐng)求 B 讀數(shù)據(jù)庫(kù)和寫(xiě) Redis 的總時(shí)間。如果不是要求強(qiáng)一致性,不推薦這種做法,休眠一段時(shí)間體驗(yàn)不太好。
5. 如何處理并發(fā)競(jìng)爭(zhēng) key 的問(wèn)題?
并發(fā)競(jìng)爭(zhēng) key 是指多個(gè)客戶端同時(shí)對(duì)同一個(gè) key 進(jìn)行操作,可以用分布式鎖,也可以用消息隊(duì)列將請(qǐng)求變成串行的,或者寫(xiě)入的 value 值加個(gè)時(shí)間戳,寫(xiě)之前判斷有沒(méi)有晚與當(dāng)前時(shí)間的時(shí)間戳存在,若有,則不寫(xiě)入。
6. 什么是緩存雪崩?如何解決?
緩存雪崩就是同一時(shí)刻緩存大面積失效,大量的請(qǐng)求直接落到數(shù)據(jù)庫(kù),把數(shù)據(jù)庫(kù)壓垮。解決辦法是為 key 設(shè)置不同的過(guò)期時(shí)間,避免同一時(shí)刻失效,操作數(shù)據(jù)庫(kù)的方法加鎖,讓請(qǐng)求串行。
7. 什么是緩存穿透?如何解決?
緩存穿透就是大量請(qǐng)求數(shù)據(jù)庫(kù)和緩存中都沒(méi)有的數(shù)據(jù),造成數(shù)據(jù)庫(kù)崩掉。解決辦法是做好參數(shù)校驗(yàn),非法請(qǐng)求直接擋掉;用布隆過(guò)濾器,將數(shù)據(jù)庫(kù)的數(shù)據(jù)緩存到布隆過(guò)濾器中,請(qǐng)求數(shù)據(jù)庫(kù)之前先判斷布隆過(guò)濾器中有沒(méi)有,沒(méi)有就直接擋掉。
8. 什么是緩存擊穿?如何解決?
緩存擊穿就是同時(shí)大量請(qǐng)求 Redis 中沒(méi)有的一個(gè) key,所有這個(gè) key 的請(qǐng)求都落到數(shù)據(jù)庫(kù),導(dǎo)致數(shù)據(jù)庫(kù)崩掉。解決辦法就是用布隆過(guò)濾器,設(shè)置熱點(diǎn)數(shù)據(jù)永不過(guò)期等。
9. 如何在一億個(gè) key 中找出指定前綴的 key?
keys prefix*:這種方式會(huì)阻塞 Redis,直至查詢完成; scan 0 match prefix* count 10:利用游標(biāo),不會(huì)阻塞 Redis。這個(gè)就表示從 0 開(kāi)始查詢出 10 條符合條件的 key,第二次就是 scan 10 match prefix* 20。
掃描二維碼
聯(lián)系客服