Redis、ES、Nginx和RabbitMQ面试回忆
文章目錄
- Nginx
- 為什么要用Nginx,有什么特點?
- 什么是正向代理和反向代理
- Nginx 有哪些負載均衡策略?
- 為什么要做動靜分離?
- RabbitMQ
- AMQP是什么?
- AMQP模型的幾大組件?
- 為什么使用MQ?MQ的優(yōu)點
- MQ如何快速實現(xiàn)流量削峰填谷?
- MQ怎么解決消息的重復問題
- RabbitMQ中有哪組件?
- RabbitMQ的工作模式
- MQ消息如何分發(fā)?
- 如何確保消息正確地發(fā)送至 RabbitMQ?
- 如何確保消息接收方消費了消息?
- 如何保證RabbitMQ消息的可靠傳輸?
- 什么是死信隊列?
- 死信隊列的來源
- 如何配置死信隊列?
- 什么是延時隊列
- 延時隊列的設(shè)置
- 消費者消息確認機制
- 消費者消息拒絕
- 消費者消費模式
- 大量堆積消息如何處理
- MQ是如何解決消息有序性的
- MQ是如何實現(xiàn)限流的?
- ES
- 什么是ElasticSearch?
- ES的分詞器?
- 倒排索引?
- ES和Mysql的區(qū)別?
- Redis
- 1、 什么是Redis
- 2、 Redis有哪些優(yōu)缺點
- 3、 為什么要用 Redis /為什么要用緩存
- 4、 Redis的應(yīng)用場景
- 5、 什么是Redis持久化?有哪些方式
- 6、 Redis的過期鍵的刪除策略
- 7、 MySQL里有2000w數(shù)據(jù),redis中只存20w的數(shù)據(jù),如何保證redis中的數(shù)據(jù)都是熱點數(shù)據(jù)
- 8、 Redis的內(nèi)存淘汰策略有哪些
- 9、 Redis增量復制,全量復制?
- 10、 Redis的內(nèi)存用完了會發(fā)生什么?
- 11、 Redis如何做內(nèi)存優(yōu)化?
- 12、 Redis事務(wù)相關(guān)命令有哪些? (該成功的成功,該失敗的失敗)
- 13、 Redis事務(wù)的三個階段?
- 14、 如何解決 Redis 的并發(fā)競爭 Key 問題
- 15、 說說Redis的主從復制,讀寫分離,哨兵機制 ,集群
- 16、 如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?
- 17、 說說Redis哈希槽的概念?
- 18、 Redis集群最大節(jié)點個數(shù)是多少 ?
- 19、 緩存穿透
- 20、 緩存擊穿
- 21、 緩存雪崩
- 22、 緩存傾斜
- 23、 緩存預熱
Nginx
為什么要用Nginx,有什么特點?
穩(wěn)定性強,占用內(nèi)存小,并發(fā)量高(5W),負載均衡,動靜分離,反向代理。
什么是正向代理和反向代理
- 正向代理是設(shè)立在客戶端的,客戶端向代理發(fā)送請求,代理向目標服務(wù)器轉(zhuǎn)交請求并將返回結(jié)果返回給客戶端。(翻墻軟件,VPN等等)
- 反向代理是配置在服務(wù)端的,作用是讓客戶端不知道訪問的是哪一臺服務(wù)器,隱藏服務(wù)器真正的ip地址。
Nginx 有哪些負載均衡策略?
- 輪詢:平均的分配給每一臺服務(wù)器。
- 權(quán)重:根據(jù)服務(wù)器分配的權(quán)重值分配。
- ip_hash:根據(jù)客戶端請求的ip,分配到不同的服務(wù)器上。
為什么要做動靜分離?
Nginx通過動靜分離,來提升Nginx的并發(fā)能力,給用戶更快地響應(yīng)。
RabbitMQ
AMQP是什么?
AMQP是一種協(xié)議,RabbitMQ 中的交換器、交換器類型、隊列、綁定、路由鍵等都是遵循的 AMQP 協(xié)議中相 應(yīng)的概念。
AMQP模型的幾大組件?
- 交換器 (Exchange):消息代理服務(wù)器中用于把消息路由到隊列的組件。
- 隊列 (Queue):用來存儲消息的數(shù)據(jù)結(jié)構(gòu),位于硬盤或內(nèi)存中。
- 綁定 (Binding):一套規(guī)則,告知交換器消息應(yīng)該將消息投遞給哪個隊列。
為什么使用MQ?MQ的優(yōu)點
解耦,異步,削峰
- 解耦(降低模塊與模塊之間的耦合):當A系統(tǒng)的接口被多個系統(tǒng)調(diào)用,A系統(tǒng)需要考慮調(diào)用接口的系統(tǒng)有沒有掛了,需不需要重發(fā)等問題,但是如果有了MQ消息隊列,A系統(tǒng)只需要把消息發(fā)送給MQ,如果有系統(tǒng)要調(diào)用直接消費MQ消息即可,如果沒有就取消消費,這樣A系統(tǒng)就不需要考慮到底要給誰發(fā)消息,也不需要考慮發(fā)送是否成功,發(fā)送超時等問題。
- 異步(提高效率):異步發(fā)送消息,從而提高效率。
- 削峰(降低并發(fā)請求量):用MQ來降低并發(fā)請求到數(shù)據(jù)庫的數(shù)據(jù),給數(shù)據(jù)庫一定的時間去處理。
MQ如何快速實現(xiàn)流量削峰填谷?
改變MQ的削峰模式,將推模式改為拉模式,定時或者批量拉取可以削平流量,實現(xiàn)自我保護的作用。
但是如果發(fā)送流量過大,MQ拉取的速度過慢,就會導致消息的堆積,所以還需要優(yōu)化消費者,可以采用批量處理的方法提高吞吐量。
MQ怎么解決消息的重復問題
- 重復消費場景:消費者正常消費后正準備發(fā)送應(yīng)答ACK,但此時出現(xiàn)了網(wǎng)絡(luò)閃斷,channel斷開連接,消息被再次放入隊列中,導致重復消費。
- 冪等性(例如刪除操作,執(zhí)行一次和執(zhí)行多次的操作是一樣的,所以不需要考慮重復消費的問題)
- 使用redis,在消息被消費前,將其采用key為id_0的形式保存在redis中,0代表正在消費,1代表已消費。
RabbitMQ中有哪組件?
RabitMQServer、Vhost、Channel、Exchange、Routing、Queue、Provider、Consumer、Binding
RabbitMQ的工作模式
- Hello-Word(一個生產(chǎn)者,一個默認的交換機,一個隊列,一個消費者)
- Work(一個生產(chǎn)者,一個默認的交換機,一個隊列,兩個消費者)
- 交換機采用輪詢發(fā)送消息,給第一個發(fā)一條,另一個發(fā)下一條
- publish(一個生產(chǎn)者,一個交換機,兩個隊列,兩個消費者)
- Routing(一個生產(chǎn)者,一個交換機,兩個隊列,兩個消費者)
- Topic(一個生產(chǎn)者,一個交換機,兩個隊列,兩個消費者)
MQ消息如何分發(fā)?
根據(jù)交換機的路由鍵進行分發(fā)到MQ中。
如何確保消息正確地發(fā)送至 RabbitMQ?
開啟Confirm確認機制,當消息由提供者送到交換機時,調(diào)用回調(diào)函數(shù)確認已送達到交換機。
開啟Return返回機制,確認消息被送達到對應(yīng)的隊列中。
如何確保消息接收方消費了消息?
手動ACK
如何保證RabbitMQ消息的可靠傳輸?
在生產(chǎn)者發(fā)送消息的時候,使用confirm確認機制確保消息到達exchange,采用return返回機制來確保消息抵達queue,最后使用redis避免重復消費消息。
什么是死信隊列?
死信隊列的作用就是避免消息的丟失。一般來說,consumer從隊列中取出消息進行消費,但由于某些原因?qū)е玛犃兄械哪承┫o法被消費,這種消息如果沒有后續(xù)的處理,如果配置了死信隊列就會丟進死信隊列中,如果沒有配置死信隊列則被丟棄。
死信隊列的來源
- 消息被拒絕,也就是Reject/Nack,并且requeue=false;
- ttl時間過期;
- 隊列中滿了,無法繼續(xù)添加數(shù)據(jù)到MQ中。
如何配置死信隊列?
@Beanpublic Queue businessQueue(){Map<String, Object> args = new HashMap<>();//這里聲明當前隊列綁定的死信交換機args.put("x-dead-letter-exchange", "deadLetterExchange");//這里聲明當前隊列的死信路由keyargs.put("x-dead-letter-routing-key", "dle.err");return new Queue("businessQueue",true,false,false,args);}什么是延時隊列
延時隊列存儲的就是延時消息,延時消息就是當消息發(fā)送后,不讓消費者第一時間立即消費,而是等待一段時間后,消費者才拿到消息消費。
延時隊列的設(shè)置
Map<String, Object> args = new HashMap<String, Object>(); args.put("x-message-ttl", 6000);// 但是毫秒 channel.queueDeclare(queueName, durable, exclusive, autoDelete, args);消費者消息確認機制
自動ACK:MQ只需要確認消息發(fā)送成功,不需要等待應(yīng)答直接丟棄消息。(如果出現(xiàn)斷電或者網(wǎng)絡(luò)異常就會出現(xiàn)消息丟失的問題)
手動ACK:如果消費者端出現(xiàn)了異常,那么大量消息就會堆積在Unacked消息中,導致消息阻塞。
NACK:通知MQ把消息放回隊列頭部。(如果消費者有問題,就算放回頭部,消費者再次消費,還是出錯又被放回隊列,陷入死循環(huán)中)
消費者消息拒絕
basicReject/basicNack
消費者消費模式
MQ的消費模式分為兩種,一種是MQ把消息推給消費者,另外一種是消費者從MQ隊列中拉去消息。
推模式采用BasicConsume,拉模式采用BasicGet
大量堆積消息如何處理
出現(xiàn)的原因:網(wǎng)絡(luò)異常,消費者出現(xiàn)異常,沒有ACK。
采用多線程發(fā)送到更多的MQ中,提高吞吐量
MQ是如何解決消息有序性的
- 在發(fā)送消息的時候就要確定消息的有序性。
- 在消費者消費消息的時候判斷一下他的上一個是否被消費了。
- 如果上一個消費了,可以被消費,消費完后需要將消費記錄放到Redis中存儲,如果上一個消息還未被消費,直接返回Nack。
MQ是如何實現(xiàn)限流的?
設(shè)置MQ隊列的最大長度。
ES
什么是ElasticSearch?
Elasticsearch是一個基于Lucene的搜索引擎框架。
ES的分詞器?
比如說“蘋果”,將其分成“蘋”和“果”和“蘋果”進行匹配,出現(xiàn)次數(shù)最多的匹配度最高。
倒排索引?
在搜索引擎中,每一個文檔都有一個對應(yīng)的文檔Id,文檔內(nèi)容表現(xiàn)為一系列關(guān)鍵詞的集合。那么,倒排索引就是關(guān)鍵詞對文檔Id的映射,每個關(guān)鍵詞都對應(yīng)著一系列的文件。其中記錄了關(guān)鍵詞Id,在文檔中出現(xiàn)的次數(shù)以及在文檔中的位置。
ES和Mysql的區(qū)別?
- Mysql的庫對應(yīng)ES的索引。
- Mysql的表對應(yīng)ES的類型。
- Mysql的一條數(shù)據(jù)對應(yīng)ES的Document。
- Mysql的屬性字段對應(yīng)ES的Field。
Redis
1、 什么是Redis
- 關(guān)系型數(shù)據(jù)庫以表格形式存儲,數(shù)據(jù)表可以彼此關(guān)聯(lián)協(xié)作存儲。
- 非關(guān)系型數(shù)據(jù)庫不適合存儲在數(shù)據(jù)表的行和列中,而是大塊組合在一起,一般強調(diào)的是數(shù)據(jù)最終一致性。
- Redis是一個高性能的key-value非關(guān)系型數(shù)據(jù)庫。
- 支持數(shù)據(jù)持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,重啟的時候可以重新加載使用。
- 除了支持key-value類型的數(shù)據(jù)外,還支持set,list,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲。
- 支持數(shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
2、 Redis有哪些優(yōu)缺點
優(yōu)勢:
- 性能高,Redis讀寫的速度非常快。
- 豐富的數(shù)據(jù)類型,支持String,List,Hash,Set等數(shù)據(jù)類型。
- 事務(wù)。
- 持久化。
- 支持主從模式備份,讀寫分離。
缺點:
一旦Redis宕機后,沒有任何容錯機制。
3、 為什么要用 Redis /為什么要用緩存
高性能,高并發(fā),減少和數(shù)據(jù)庫的交互。
4、 Redis的應(yīng)用場景
- 服務(wù)注冊和發(fā)現(xiàn)
- 緩存服務(wù)器。
- 自增自減
5、 什么是Redis持久化?有哪些方式
RDB(Redis DataBase):
用快照的方式,保存內(nèi)存結(jié)構(gòu)(二進制文件)
- 優(yōu)點:加載速度快。
- 缺點:數(shù)據(jù)安全性低。
AOF(Append-only-file):
把寫的命令全部保存到文件。
- 優(yōu)點:數(shù)據(jù)安全。
- 缺點:AOF文件大,且數(shù)據(jù)恢復速度慢。
6、 Redis的過期鍵的刪除策略
- 惰性刪除:每次獲取鍵的時候,檢查鍵是否過期,如果鍵過期就刪除鍵,沒過期就返回鍵。
- 定期刪除:每隔一段時間就對redis數(shù)據(jù)庫進行檢查,刪除里面的過期鍵,但刪除多少過期鍵和檢查多少個數(shù)據(jù)庫由算法決定。
- 定時刪除:太消耗資源不推薦。
7、 MySQL里有2000w數(shù)據(jù),redis中只存20w的數(shù)據(jù),如何保證redis中的數(shù)據(jù)都是熱點數(shù)據(jù)
- 1.當?shù)谝淮螐腗ySql獲取數(shù)據(jù)的時候,將其存在redis中并設(shè)置過期時間,以后每次查詢redis中的數(shù)據(jù)時判斷是否還在redis中,如果存在就給他延長過期時間,以此來保證redis中的數(shù)據(jù)都是熱點數(shù)據(jù)。
- 2.使用淘汰策略。
8、 Redis的內(nèi)存淘汰策略有哪些
- LRU(Least Recently Used):最近最少使用。
- LFU(Least Frequently Used):最近最少頻繁使用。
- TTL(Time To Live):生存時間最少。
- RANDOM:隨機淘汰。
- 抽取樣本進行淘汰。
9、 Redis增量復制,全量復制?
1.全量復制:
用于節(jié)點初始化的情況下,將主節(jié)點的所有數(shù)據(jù)發(fā)送給從節(jié)點,當數(shù)據(jù)量特別大的時候,會對主節(jié)點和網(wǎng)絡(luò)造成很大的一個開銷。
2.增量復制
10、 Redis的內(nèi)存用完了會發(fā)生什么?
要么會發(fā)生報錯,要么會調(diào)用淘汰策略清除一些key來保證redis的正常運行。
11、 Redis如何做內(nèi)存優(yōu)化?
- 1.給每個key都設(shè)置生存時間。
- 2.爭對業(yè)務(wù)場景給出對應(yīng)的淘汰策略。
- 3.正確使用Redis數(shù)據(jù)結(jié)構(gòu)。
12、 Redis事務(wù)相關(guān)命令有哪些? (該成功的成功,該失敗的失敗)
- multi:開啟事務(wù)。
- exec:執(zhí)行事務(wù)塊內(nèi)的所有命令。
- discard:取消事務(wù)。
- watch:監(jiān)聽key在事務(wù)執(zhí)行之前是否改變,若已修改則事務(wù)內(nèi)的事務(wù)取消執(zhí)行。
- unwatch:取消對key的監(jiān)聽。
13、 Redis事務(wù)的三個階段?
- 1.multi:開啟事務(wù)。
- 2.添加命令到事務(wù)塊中。
- 3.exec/discard:執(zhí)行事務(wù)塊中的命令/取消執(zhí)行事務(wù)塊中的命令。
14、 如何解決 Redis 的并發(fā)競爭 Key 問題
setnx
15、 說說Redis的主從復制,讀寫分離,哨兵機制 ,集群
集群解決單點故障(有狀態(tài)和無狀態(tài))
管調(diào)哪臺服務(wù)器返回的結(jié)果是一樣的(無)
需要服務(wù)器共享數(shù)據(jù)的(redis,eureka,zookeeper)
- 主從架構(gòu):一主多從,作用只是數(shù)據(jù)備份方案。
- 讀寫分離:主只提供寫的操作,從只提供讀的操作。2.提高Redis讀的速度
- 哨兵機制:對Redis節(jié)點的監(jiān)視和選舉,哨兵數(shù)量至少為3個,只要有一半哨兵投票通過,那么選舉出來的就為主節(jié)點。
- redis集群沒有主從一說,去中心化,使用hash槽讓key每次訪問的都是同一個redis服務(wù)器。
16、 如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?
先刪除緩存,然后更新數(shù)據(jù)庫,如果這時候有請求發(fā)送過來,他會訪問到空的緩存,然后去數(shù)據(jù)庫中拿數(shù)據(jù),如果此時數(shù)據(jù)庫未更新成功,那么此時緩存中的數(shù)據(jù)還是舊數(shù)據(jù),導致數(shù)據(jù)庫和緩存中數(shù)據(jù)不一致,那么就需要延遲一段時間后再刪除一次緩存。(雙刪延遲)
17、 說說Redis哈希槽的概念?
首先,Redis集群中總共有16384個hahs槽,執(zhí)行寫命令的時候會將key按照一種算法得到一個結(jié)果,然后將這個結(jié)果對hash槽個數(shù)進行取余,然后將key放到這個位置的hash槽中。(Nigix負載均衡中ip_hash用到了hash槽,類似hashmap底層)
18、 Redis集群最大節(jié)點個數(shù)是多少 ?
16384
19、 緩存穿透
1.出現(xiàn)的原因:
redis中沒有,mysql中也沒有(比如查詢的id為1)
2.如何解決:
設(shè)置一個默認值(如果在數(shù)據(jù)庫中也沒有查詢到數(shù)據(jù),就在緩存中存放一個默認值)
對id進行過濾,過濾掉一些不合法的id(比如負數(shù))
20、 緩存擊穿
1.出現(xiàn)的原因:
- 數(shù)據(jù)庫中有,但redis中沒有(熱點數(shù)據(jù)突然過期)
- 并發(fā)查詢數(shù)據(jù)庫
2.如何解決:
- 分布式鎖
- 設(shè)值熱點數(shù)據(jù)不過期
21、 緩存雪崩
1.出現(xiàn)的原因:
大量數(shù)據(jù)在同一時間過期
2.如何解決:
設(shè)置數(shù)據(jù)的過期時間隨機分布在30-60秒內(nèi),不讓數(shù)據(jù)同時過期。
22、 緩存傾斜
1.出現(xiàn)的原因:
高并發(fā)請求訪問一個redis服務(wù)
2.如何解決:
搭建redis集群和主從架構(gòu)
23、 緩存預熱
1.出現(xiàn)的原因:
發(fā)生在項目上線之前,熱數(shù)據(jù)需要提前存放在redis中
2.如何解決:
數(shù)據(jù)量不大可以人工手動導入
定時熱刷新
總結(jié)
以上是生活随笔為你收集整理的Redis、ES、Nginx和RabbitMQ面试回忆的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 36 个JS 面试题为你助力金九银十(面
- 下一篇: 奋斗的意义