1. Redis 是什么?
- 非關(guān)系型的內(nèi)存數(shù)據(jù)庫(kù),因?yàn)閿?shù)據(jù)存儲(chǔ)在內(nèi)存中,因此速度非???。
2. Redis 支持哪些數(shù)據(jù)類型?
- string:鍵值對(duì)存儲(chǔ),類似 Java 中的 HashMap,一個(gè) key 對(duì)應(yīng)一個(gè) value,value 最大為 512M;
- list:一個(gè)雙向鏈表,支持從兩端去操作數(shù)據(jù);
- set:無(wú)序不重復(fù)的集合,類似 Java 的 HashSet,可以方便地求兩個(gè)集合的交集差集并集等;
- zset:與 set 相比,多了一個(gè)表示優(yōu)先級(jí)的 score,可以用來(lái)做排行榜;
- hash:映射表,一個(gè) key 對(duì)應(yīng)一組鍵值對(duì),適合用來(lái)存儲(chǔ)對(duì)象;
3. Redis 有哪些應(yīng)用場(chǎng)景?
- 做緩存,存儲(chǔ)熱點(diǎn)數(shù)據(jù);
4. 說(shuō)說(shuō) Redis 的線程模型
- Redis 基于 Reactor 模式開(kāi)發(fā)了網(wǎng)絡(luò)事件處理器,被稱為文件事件處理器;
- Reactor 模式就是由一個(gè)非阻塞的線程來(lái)接收所有請(qǐng)求,然后再分派不同的 handler中去執(zhí)行具體邏輯;
- Redis 的文件事件處理器由多個(gè)套接字、IO多路復(fù)用程序、文件事件分派器和事件處理器構(gòu)成;
- Redis 的文件事件處理器首先使用 IO 多路復(fù)用程序監(jiān)聽(tīng)多個(gè)套接字,并根據(jù)套接字執(zhí)行的任務(wù)來(lái)為套接字關(guān)聯(lián)事件處理器;當(dāng)被監(jiān)聽(tīng)的套接字要執(zhí)行 accept、read、write 等操作時(shí),文件事件分派器就會(huì)調(diào)用之前關(guān)聯(lián)好的事件處理器來(lái)執(zhí)行相關(guān)操作。
5. Redis 到底是多線程的還是單線程的?
- 整個(gè) Redis 并不是單線程的,但是執(zhí)行命令的模塊是單線程的,所以我們說(shuō) Redis 是單線程的;另外,Redis 6.0 開(kāi)始,對(duì)于網(wǎng)絡(luò)事件的讀寫(xiě)也引入了多線程,不過(guò)執(zhí)行命令的模塊還是單線程的。
6. 對(duì)于 Redis 管道技術(shù)有了解嗎?
- 管道技術(shù)是一種客戶端技術(shù),通過(guò)客戶端執(zhí)行 redis 命令的時(shí)候,正常流程是客戶端請(qǐng)求服務(wù)端,服務(wù)端執(zhí)行完了給客戶端響應(yīng),客戶端收到響應(yīng)后繼續(xù)請(qǐng)求服務(wù)端發(fā)送下一個(gè)執(zhí)行的命令。就是每執(zhí)行一條命令就需要經(jīng)過(guò) “請(qǐng)求 --- 響應(yīng)” 這么一個(gè)來(lái)回。要執(zhí)行的命令一多,這樣的來(lái)回在網(wǎng)絡(luò)中的消耗也就變多了,管道技術(shù)的原理簡(jiǎn)單地說(shuō)就是把所有的命令先發(fā)送過(guò)去,然后等服務(wù)端執(zhí)行完統(tǒng)一響應(yīng),這樣就減少了網(wǎng)絡(luò)消耗。
7. 什么是 Redis 的事務(wù)?
- Redis 事務(wù)和關(guān)系型數(shù)據(jù)庫(kù)的事務(wù)不一樣,它是一組命令的集合,可以保證一組命令按照順序執(zhí)行,其他客戶端提交過(guò)來(lái)的命令不能插入到事務(wù)管理的命令集合中。它不保證原子性,單條命令的執(zhí)行是原子性的,但是不能保證一組命令的執(zhí)行的原子性,即事務(wù)管理的某個(gè)命令執(zhí)行失敗了,其他命令還是會(huì)執(zhí)行,也不支持回滾。事務(wù)相關(guān)命令有:watch,監(jiān)視一個(gè)或多個(gè) key,如果 key 被別的客戶端修改,則事務(wù)被打斷;multi,開(kāi)啟事務(wù);exec,執(zhí)行事務(wù);discard,丟棄事務(wù);unwatch,取消對(duì) key 的監(jiān)視。
8. 你是如何保證 Redis 數(shù)據(jù)的可靠性的? 對(duì) Redis 進(jìn)行持久化。持久化的方式有兩種,RDB 和 AOF。 - RDB 就是每隔一段時(shí)間以快照的方式將內(nèi)存中的數(shù)據(jù)保存到磁盤(pán)的 dump.rdb 文件中,默認(rèn)開(kāi)啟。觸發(fā) RDB 的方式有兩種,手動(dòng)觸發(fā)和自動(dòng)觸發(fā)。手動(dòng)觸發(fā)就是手動(dòng)執(zhí)行
SAVE 或者 BGSAVE 命令,SAVE 會(huì)阻塞服務(wù)器進(jìn)程,而 BGSAVE 會(huì)在后臺(tái)完成執(zhí)行。自動(dòng)觸發(fā)策略可以在 Redis 的配置文件中進(jìn)行配置,比如 save 1000 1 ,就是在 1000 秒內(nèi),至少有 1 條數(shù)據(jù)發(fā)生了變化,那就會(huì)觸發(fā) BGSAVE ,就數(shù)據(jù)寫(xiě)到磁盤(pán)中,這種策略可以配置多條。RDB 的缺點(diǎn)很明顯,就是可能會(huì)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失,優(yōu)點(diǎn)就是恢復(fù)數(shù)據(jù)比較快。 - AOF 就是會(huì)記錄寫(xiě)操作的命令,追加到 appendonly.aof 文件中,Redis 還會(huì)對(duì) appendonly.aof 文件進(jìn)行重寫(xiě),去掉重復(fù)命令,減小其體積。重寫(xiě)也可以手動(dòng)觸發(fā)和自動(dòng)觸發(fā),手動(dòng)觸發(fā)就是執(zhí)行
BGREWRITEAOF 命令即可重寫(xiě) AOF 文件,自動(dòng)觸發(fā)可以在配置文件中配置策略,比如 auto-aof-rewrite-percentage 100 表示文件增量大于 100% 時(shí)進(jìn)行重寫(xiě),auto-aof-rewrite-min-size 64mb 表示 AOF 文件體積大于 64m 時(shí)就進(jìn)行重寫(xiě)??梢栽谂渲梦募信渲?AOF 的寫(xiě)入命令的策略,appendfsync Everysec 表示每秒記錄一次,默認(rèn)就是該策略,還可以配置 appendfsync Always ,記錄每次寫(xiě)操作, appendfsync No ,由操作系統(tǒng)決定何時(shí)記錄寫(xiě)操作。AOF 的優(yōu)點(diǎn)是可以不造成數(shù)據(jù)的丟失,缺點(diǎn)是 IO 操作比較多。
一般會(huì)同時(shí)開(kāi)啟 RDB 和 AOF,同時(shí)開(kāi)啟的情況下,會(huì)優(yōu)先根據(jù) AOF 文件來(lái)恢復(fù)數(shù)據(jù)。
9. 如何保證 Redis 中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)? 當(dāng) Redis 中的數(shù)據(jù)集上升到一定程度后,會(huì)根據(jù)內(nèi)存淘汰策略淘汰數(shù)據(jù)。內(nèi)存淘汰策略有如下幾種: - noeviction:內(nèi)存不足時(shí)寫(xiě)操作報(bào)異常;
- allkeys lru:在所有 key 中選擇最近最少使用的進(jìn)行刪除;
- allkeys random:在所有 key 中隨機(jī)選擇一個(gè)進(jìn)行刪除;
- volatile lru:在過(guò)期 key 中選擇最近最少使用的進(jìn)行刪除;
- volatile random:在過(guò)期 key 中隨機(jī)選擇一個(gè)刪除;
- volatile ttf:優(yōu)先刪除更早過(guò)期的 key。
10. 對(duì)于過(guò)期的 key,Redis 是如何處理的? Redis 有三種過(guò)期鍵刪除策略: - 定時(shí)過(guò)期:到了過(guò)期時(shí)間就刪除,對(duì)內(nèi)存友好,但是對(duì) CPU 不太友好;
- 惰性過(guò)期:當(dāng)用到了 key 的時(shí)候去判斷是否過(guò)期了,過(guò)期了就刪除,對(duì) CPU 友好,但是對(duì)內(nèi)存不太友好;
- 定期過(guò)期:定期檢查 key 是否過(guò)期,過(guò)期就進(jìn)行刪除;
Redis 同時(shí)使用了惰性過(guò)期和定期過(guò)期兩種策略。
|