面試題百日百刷-Redis篇(三)
====Redis中Pipeline有什么好處,為什么要用pipeline?
可以將多次 IO 往返的時(shí)間縮減為一次,前提是 pipeline 執(zhí)行的指令之間沒(méi)有因果相關(guān)性。使用redis-benchmark 進(jìn)行壓測(cè)的時(shí)候可以發(fā)現(xiàn)影響 redis 的 QPS 峰值的一個(gè)重要因素是 pipeline 批次指令的數(shù)目。
?
====是否使用過(guò) Redis 集群,集群的原理是什么?
1. 、Redis Sentinal 著眼于高可用, 在 master 宕機(jī)時(shí)會(huì)自動(dòng)將 slave 提升為master, 繼續(xù)提供服務(wù)。
2. 、Redis Cluster 著眼于擴(kuò)展性, 在單個(gè) redis 內(nèi)存不足時(shí), 使用 Cluster 進(jìn)行分片存儲(chǔ)。
?
====Redis 集群方案什么情況下會(huì)導(dǎo)致整個(gè)集群不可用?
有 A,B,C 三個(gè)節(jié)點(diǎn)的集群,在沒(méi)有復(fù)制模型的情況下,如果節(jié)點(diǎn) B 失敗了,那么整個(gè)集群就會(huì)以為缺少 5501-11000 這個(gè)范圍的槽而不可用。
?
====Redis 支持的Java 客戶(hù)端都有哪些?官方推薦用哪個(gè)?
Redisson、Jedis、lettuce 等等, 官方推薦使用 Redisson。
?
====Jedis 與 Redisson 對(duì)比有什么優(yōu)缺點(diǎn)?
Jedis 是 Redis 的 Java 實(shí)現(xiàn)的客戶(hù)端, 其 API 提供了比較全面的 Redis 命令的支持;Redisson 實(shí)現(xiàn)了分布式和可擴(kuò)展的 Java 數(shù)據(jù)結(jié)構(gòu),和 Jedis 相比,功能較為簡(jiǎn)單, 不支持字符串操作, 不支持排序、事務(wù)、管道、分區(qū)等 Redis 特性。Redisson 的宗旨是促進(jìn)使用者對(duì) Redis 的關(guān)注分離,從而讓使用者能夠?qū)⒕Ω械胤旁谔幚順I(yè)務(wù)邏輯上。
?
====Redis 如何設(shè)置密碼及驗(yàn)證密碼?
設(shè)置密碼: config set requirepass 123456 授權(quán)密碼:auth 123456
?
====說(shuō)說(shuō) Redis 哈希槽的概念?
Redis 集群沒(méi)有使用一致性 hash,而是引入了哈希槽的概念, Redis 集群有2的14次方(16384)個(gè)哈希槽,每個(gè)key 通過(guò) CRC16 校驗(yàn)后對(duì) 16384 取模來(lái)決定放置哪個(gè)槽, 集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分 hash 槽。
用了哈希槽的概念,而沒(méi)有用一致性哈希算法,不都是哈希么?這樣做的原因是為什么呢
?
====Redis用了哈希槽的概念,而沒(méi)有用一致性哈希算法,這樣做的原因是為什么呢?
Redis Cluster是自己做的crc16的簡(jiǎn)單hash算法,沒(méi)有用一致性hash。Redis的作者認(rèn)為它的crc16(key) mod 16384的效果已經(jīng)不錯(cuò)了,雖然沒(méi)有一致性hash靈活,但實(shí)現(xiàn)很簡(jiǎn)單,節(jié)點(diǎn)增刪時(shí)處理起來(lái)也很方便。
?
====Redis 集群的主從復(fù)制模型是怎樣的?
為了使在部分節(jié)點(diǎn)失敗或者大部分節(jié)點(diǎn)無(wú)法通信的情況下集群仍然可用,所以集群使用了主從復(fù)制模型,每個(gè)節(jié)點(diǎn)都會(huì)有 N-1 個(gè)復(fù)制品。
?
====Redis 集群會(huì)有寫(xiě)操作丟失嗎?為什么?
Redis 并不能保證數(shù)據(jù)的強(qiáng)一致性,這意味這在實(shí)際中集群在特定的條件下可能會(huì)丟失寫(xiě)操作。
?
====Redis 集群之間是如何復(fù)制的?
異步復(fù)制
?
====Redis 集群最大節(jié)點(diǎn)個(gè)數(shù)是多少?
2的14次方(16384)
?
====Redis 集群如何選擇數(shù)據(jù)庫(kù)?
?Redis 集群目前無(wú)法做數(shù)據(jù)庫(kù)選擇, 默認(rèn)在 0 數(shù)據(jù)庫(kù)。
?
====說(shuō)一說(shuō)Redis中的事務(wù)?
1、Redis 事務(wù)可以一次執(zhí)行多個(gè)命令, 并且?guī)в幸韵氯齻€(gè)重要的保證:
1)批量操作在發(fā)送 EXEC 命令前被放入隊(duì)列緩存。
2)收到 EXEC 命令后進(jìn)入事務(wù)執(zhí)行,事務(wù)中任意命令執(zhí)行失敗,其余的命令依然被執(zhí)行。
3)在事務(wù)執(zhí)行過(guò)程,其他客戶(hù)端提交的命令請(qǐng)求不會(huì)插入到事務(wù)執(zhí)行命令序列中。
2、一個(gè)事務(wù)從開(kāi)始到執(zhí)行會(huì)經(jīng)歷以下三個(gè)階段:
開(kāi)始事務(wù)。
命令入隊(duì)。
執(zhí)行事務(wù)。
3、redis中相關(guān)的指令有:
DISCARD
取消事務(wù),放棄執(zhí)行事務(wù)塊內(nèi)的所有命令。
EXEC
執(zhí)行所有事務(wù)塊內(nèi)的命令。
MULTI
標(biāo)記一個(gè)事務(wù)塊的開(kāi)始。
UNWATCH
取消 WATCH 命令對(duì)所有 key 的監(jiān)視。
WATCH key [key ...]
監(jiān)視一個(gè)(或多個(gè)) key ,如果在事務(wù)執(zhí)行之前這個(gè)(或這些) key 被其他命令所改動(dòng),那么事務(wù)將被打斷。
4、單個(gè) Redis 命令的執(zhí)行是原子性的,但 Redis 沒(méi)有在事務(wù)上增加任何維持原子性的機(jī)制,所以 Redis 事務(wù)的執(zhí)行并不是原子性的。
事務(wù)可以理解為一個(gè)打包的批量執(zhí)行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會(huì)導(dǎo)致前面已做指令的回滾,也不會(huì)造成后續(xù)的指令不做。
redis 127.0.0.1:7000> multi
OK
redis 127.0.0.1:7000> set a aaa
QUEUED
redis 127.0.0.1:7000> set b bbb
QUEUED
redis 127.0.0.1:7000> set c ccc
QUEUED
redis 127.0.0.1:7000> exec
1) OK
2) OK
3) OK
?
====Redis key 的過(guò)期時(shí)間和永久有效分別怎么設(shè)置?
使用EXPIRE 和 PERSIST 命令。
?
====Redis 如何做內(nèi)存優(yōu)化?
盡可能使用散列表( hashes), 散列表( 是說(shuō)散列表里面存儲(chǔ)的數(shù)少) 使用的內(nèi)存非常小, 所以你應(yīng)該盡可能的將你的數(shù)據(jù)模型抽象到一個(gè)散列表里面。比如你的 web 系統(tǒng)中有一個(gè)用戶(hù)對(duì)象, 不要為這個(gè)用戶(hù)的名稱(chēng), 姓氏, 郵箱, 密碼設(shè)置單獨(dú)的 key,而是應(yīng)該把這個(gè)用戶(hù)的所有信息存儲(chǔ)到一張散列表里面.