1. 程式人生 > 其它 >Java 面試題-RabbitMQ、Kafka、Zookeeper、Redis

Java 面試題-RabbitMQ、Kafka、Zookeeper、Redis

1.RabbitMQ 的使用場景有哪些?
  • 搶購活動,削峰填谷,防止系統崩塌。
  • 延遲資訊處理,比如 10 分鐘之後給下單未付款的使用者傳送郵件提醒。
  • 解耦系統,對於新增的功能可以單獨寫模組擴充套件,比如使用者確認評價之後,新增了給使用者返積分的功能,這個時候不用在業務程式碼裡新增新增積分的功能,只需要把新增積分的介面訂閱確認評價的訊息佇列即可,後面再新增任何功能只需要訂閱對應的訊息佇列即可。
2.RabbitMQ 有哪些重要的角色?
  • 生產者:訊息的建立者,負責建立和推送資料到訊息伺服器;
  • 消費者:訊息的接收方,用於處理資料和確認訊息;
  • 代理:就是 RabbitMQ 本身,用於扮演“快遞”的角色,本身不生產訊息,只是扮演“快遞”的角色。
3.RabbitMQ 有哪些重要的元件?
  • ConnectionFactory(連線管理器):應用程式與Rabbit之間建立連線的管理器,程式程式碼中使用。
  • Channel(通道):訊息推送使用的通道。
  • Exchange(交換器):用於接受、分配訊息。
  • Queue(佇列):用於儲存生產者的訊息。
  • RoutingKey(路由鍵):用於把生成者的資料分配到交換器上。
  • BindingKey(繫結鍵):用於把交換器的訊息繫結到佇列上。
4.RabbitMQ 中 vhost 的作用是什麼?

    vhost:每個 RabbitMQ 都能建立很多 vhost,我們稱之為虛擬主機,每個虛擬主機其實都是 mini 版的RabbitMQ,它擁有自己的佇列,交換器和繫結,擁有自己的許可權機制。

5.RabbitMQ 的訊息是怎麼傳送的?

    首先客戶端必須連線到 RabbitMQ 伺服器才能釋出和消費訊息,客戶端和 rabbit server 之間會建立一個 tcp 連線,一旦 tcp 開啟並通過了認證(認證就是你傳送給 rabbit 伺服器的使用者名稱和密碼),你的客戶端和 RabbitMQ 就建立了一條 amqp 通道(channel),通道是建立在“真實” tcp 上的虛擬連線,amqp 命令都是通過通道傳送出去的,每個通道都會有一個唯一的 id,不論是釋出訊息,訂閱佇列都是通過這個通道完成的。

6.RabbitMQ 怎麼保證訊息的穩定性?
  • 提供了事務的功能。
  • 通過將 channel 設定為 confirm(確認)模式。
7.RabbitMQ 怎麼避免訊息丟失?
  • 把訊息持久化磁碟,保證伺服器重啟訊息不丟失。
  • 每個叢集中至少有一個物理磁碟,保證訊息落入磁碟。
8.要保證訊息持久化成功的條件有哪些?
  • 宣告佇列必須設定持久化 durable 設定為 true.
  • 訊息推送投遞模式必須設定持久化,deliveryMode 設定為 2(持久)。
  • 訊息已經到達持久化交換器。
  • 訊息已經到達持久化佇列。

    以上四個條件都滿足才能保證訊息持久化成功。

9.RabbitMQ 持久化有什麼缺點?

    持久化的缺地就是降低了伺服器的吞吐量,因為使用的是磁碟而非記憶體儲存,從而降低了吞吐量。可儘量使用 ssd 硬碟來緩解吞吐量的問題。

10.RabbitMQ 有幾種廣播型別?
  • direct(預設方式):最基礎最簡單的模式,傳送方把訊息傳送給訂閱方,如果有多個訂閱者,預設採取輪詢的方式進行訊息傳送。
  • headers:與 direct 類似,只是效能很差,此型別幾乎用不到。
  • fanout:分發模式,把消費分發給所有訂閱者。
  • topic:匹配訂閱模式,使用正則匹配到訊息佇列,能匹配到的都能接收到。
11.RabbitMQ 怎麼實現延遲訊息佇列?

    延遲佇列的實現有兩種方式:

  • 通過訊息過期後進入死信交換器,再由交換器轉發到延遲消費佇列,實現延遲功能;
  • 使用 RabbitMQ-delayed-message-exchange 外掛實現延遲功能。
12.RabbitMQ 叢集有什麼用?

    叢集主要有以下兩個用途:

  • 高可用:某個伺服器出現問題,整個 RabbitMQ 還可以繼續使用;
  • 高容量:叢集可以承載更多的訊息量。
13.RabbitMQ 節點的型別有哪些?
  • 磁碟節點:訊息會儲存到磁碟。
  • 記憶體節點:訊息都儲存在記憶體中,重啟伺服器訊息丟失,效能高於磁碟型別。
14.RabbitMQ 叢集搭建需要注意哪些問題?
  • 各節點之間使用“--link”連線,此屬性不能忽略。
  • 各節點使用的 erlang cookie 值必須相同,此值相當於“祕鑰”的功能,用於各節點的認證。
  • 整個叢集中必須包含一個磁碟節點。
15.RabbitMQ 每個節點是其他節點的完整拷貝嗎?為什麼?

    不是,原因有以下兩個:

  • 儲存空間的考慮:如果每個節點都擁有所有佇列的完全拷貝,這樣新增節點不但沒有新增儲存空間,反而增加了更多的冗餘資料;
  • 效能的考慮:如果每條訊息都需要完整拷貝到每一個叢集節點,那新增節點並沒有提升處理訊息的能力,最多是保持和單節點相同的效能甚至是更糟。
16.RabbitMQ 叢集中唯一一個磁碟節點崩潰了會發生什麼情況?

    如果唯一磁碟的磁碟節點崩潰了,不能進行以下操作:

  • 不能建立佇列
  • 不能建立交換器
  • 不能建立繫結
  • 不能新增使用者
  • 不能更改許可權
  • 不能新增和刪除叢集節點

    唯一磁碟節點崩潰了,叢集是可以保持執行的,但你不能更改任何東西。

17.RabbitMQ 對叢集節點停止順序有要求嗎?

    RabbitMQ 對叢集的停止的順序是有要求的,應該先關閉記憶體節點,最後再關閉磁碟節點。如果順序恰好相反的話,可能會造成訊息的丟失。

18.kafka 可以脫離 zookeeper 單獨使用嗎?為什麼?

    kafka 不能脫離 zookeeper 單獨使用,因為 kafka 使用 zookeeper 管理和協調 kafka 的節點伺服器。

19.kafka 有幾種資料保留的策略?

    kafka 有兩種資料儲存策略:按照過期時間保留和按照儲存的訊息大小保留。

20.kafka 同時設定了 7 天和 10G 清除資料,到第五天的時候訊息達到了 10G,這個時候 kafka 將如何處理?

    這個時候 kafka 會執行資料清除工作,時間和大小不論那個滿足條件,都會清空資料。

21.什麼情況會導致 kafka 執行變慢?
  • cpu 效能瓶頸
  • 磁碟讀寫瓶頸
  • 網路瓶頸
22.使用 kafka 叢集需要注意什麼?
  • 叢集的數量不是越多越好,最好不要超過 7 個,因為節點越多,訊息複製需要的時間就越長,整個群組的吞吐量就越低。
  • 叢集數量最好是單數,因為超過一半故障叢集就不能用了,設定為單數容錯率更高。
23.zookeeper 是什麼?

    zookeeper 是一個分散式的,開放原始碼的分散式應用程式協調服務,是 google chubby 的開源實現,是 hadoop 和 hbase 的重要元件。它是一個為分散式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分散式同步、組服務等。

24.zookeeper 都有哪些功能?
  • 叢集管理:監控節點存活狀態、執行請求等。
  • 主節點選舉:主節點掛掉了之後可以從備用的節點開始新一輪選主,主節點選舉說的就是這個選舉的過程,使用 zookeeper 可以協助完成這個過程。
  • 分散式鎖:zookeeper 提供兩種鎖:獨佔鎖、共享鎖。獨佔鎖即一次只能有一個執行緒使用資源,共享鎖是讀鎖共享,讀寫互斥,即可以有多線執行緒同時讀同一個資源,如果要使用寫鎖也只能有一個執行緒使用。zookeeper可以對分散式鎖進行控制。
  • 命名服務:在分散式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等資訊。
25.zookeeper 有幾種部署模式?

    zookeeper 有三種部署模式:

  • 單機部署:一臺叢集上執行;
  • 叢集部署:多臺叢集執行;
  • 偽叢集部署:一臺叢集啟動多個 zookeeper 例項執行。
26.zookeeper 怎麼保證主從節點的狀態同步?

    zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫做 zab 協議。 zab 協議有兩種模式,分別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰後,zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 server 具有相同的系統狀態。

27.叢集中為什麼要有主節點?

    在分散式環境中,有些業務邏輯只需要叢集中的某一臺機器進行執行,其他的機器可以共享這個結果,這樣可以大大減少重複計算,提高效能,所以就需要主節點。

28.叢集中有 3 臺伺服器,其中一個節點宕機,這個時候 zookeeper 還可以使用嗎?

    可以繼續使用,單數伺服器只要沒超過一半的伺服器宕機就可以繼續使用。

29.說一下 zookeeper 的通知機制?

    客戶端端會對某個 znode 建立一個 watcher 事件,當該 znode 發生變化時,這些客戶端會收到 zookeeper 的通知,然後客戶端可以根據 znode 變化來做出業務上的改變。

30.Redis 是什麼?都有哪些使用場景?

    Redis 是一個使用 C 語言開發的快取記憶體資料庫。

    Redis 使用場景:

  • 記錄帖子點贊數、點選數、評論數;
  • 快取近期熱帖;
  • 快取文章詳情資訊;
  • 記錄使用者會話資訊。
31.Redis 有哪些功能?
  • 資料快取功能
  • 分散式鎖的功能
  • 支援資料持久化
  • 支援事務
  • 支援訊息佇列
32.Redis 和 memcache 有什麼區別?
  • 儲存方式不同:memcache 把資料全部存在記憶體之中,斷電後會掛掉,資料不能超過記憶體大小;Redis 有部份存在硬碟上,這樣能保證資料的永續性。
  • 資料支援型別:memcache 對資料型別支援相對簡單;Redis 有複雜的資料型別。
  • 使用底層模型不同:它們之間底層實現方式,以及與客戶端之間通訊的應用協議不一樣,Redis 自己構建了 vm 機制,因為一般的系統呼叫系統函式的話,會浪費一定的時間去移動和請求。
  • value 值大小不同:Redis 最大可以達到 512mb;memcache 只有 1mb。
33.Redis 為什麼是單執行緒的?

    因為 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機器記憶體或者網路頻寬。既然單執行緒容易實現,而且 cpu 又不會成為瓶頸,那就順理成章地採用單執行緒的方案了。

    關於 Redis 的效能,官方網站也有,普通筆記本輕鬆處理每秒幾十萬的請求。

    而且單執行緒並不代表就慢 nginx 和 nodejs 也都是高效能單執行緒的代表。

34.什麼是快取穿透?怎麼解決?

    快取穿透:指查詢一個一定不存在的資料,由於快取是不命中時需要從資料庫查詢,查不到資料則不寫入快取,這將導致這個不存在的資料每次請求都要到資料庫去查詢,造成快取穿透。

    解決方案:最簡單粗暴的方法如果一個查詢返回的資料為空(不管是資料不存在,還是系統故障),我們就把這個空結果進行快取,但它的過期時間會很短,最長不超過五分鐘。

35.Redis 支援的資料型別有哪些?

    Redis 支援的資料型別:string(字串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。

36.Redis 支援的 Java 客戶端都有哪些?

    支援的 Java 客戶端有 Redisson、jedis、lettuce 等。

37.jedis 和 Redisson 有哪些區別?
  • jedis:提供了比較全面的 Redis 命令的支援。
  • Redisson:實現了分散式和可擴充套件的 Java 資料結構,與 jedis 相比Redisson 的功能相對簡單,不支援排序、事務、管道、分割槽等 Redis 特性。
38.怎麼保證快取和資料庫資料的一致性?
  • 合理設定快取的過期時間。
  • 新增、更改、刪除資料庫操作時同步更新 Redis,可以使用事物機制來保證資料的一致性。
39.Redis 持久化有幾種方式?

    Redis 的持久化有兩種方式,或者說有兩種策略:

  • RDB(Redis Database):指定的時間間隔能對你的資料進行快照儲存。
  • AOF(Append Only File):每一個收到的寫命令都通過write函式追加到檔案中。
40.Redis 怎麼實現分散式鎖?

    Redis 分散式鎖其實就是在系統裡面佔一個“坑”,其他程式也要佔“坑”的時候,佔用成功了就可以繼續執行,失敗了就只能放棄或稍後重試。

    佔坑一般使用 setnx(set if not exists)指令,只允許被一個程式佔有,使用完呼叫 del 釋放鎖。

41.Redis 分散式鎖有什麼缺陷?

    Redis 分散式鎖不能解決超時的問題,分散式鎖有一個超時時間,程式的執行如果超出了鎖的超時時間就會出現問題。

42.Redis 如何做記憶體優化?

    儘量使用 Redis 的散列表,把相關的資訊放到散列表裡面儲存,而不是把每個欄位單獨儲存,這樣可以有效的減少記憶體使用。比如將 Web 系統的使用者物件,應該放到散列表裡面再整體儲存到 Redis,而不是把使用者的姓名、年齡、密碼、郵箱等欄位分別設定 key 進行儲存。

43.Redis 淘汰策略有哪些?
  • volatile-lru:從已設定過期時間的資料集(server. db[i]. expires)中挑選最近最少使用的資料淘汰。
  • volatile-ttl:從已設定過期時間的資料集(server. db[i]. expires)中挑選將要過期的資料淘汰。
  • volatile-random:從已設定過期時間的資料集(server. db[i]. expires)中任意選擇資料淘汰。
  • allkeys-lru:從資料集(server. db[i]. dict)中挑選最近最少使用的資料淘汰。
  • allkeys-random:從資料集(server. db[i]. dict)中任意選擇資料淘汰。
  • no-enviction(驅逐)(預設策略):禁止驅逐資料。
44.Redis 常見的效能問題有哪些?該如何解決?
  • 主伺服器寫記憶體快照,會阻塞主執行緒的工作,當快照比較大時對效能影響是非常大的,會間斷性暫停服務,所以主伺服器最好不要寫記憶體快照。
  • Redis 主從複製的效能問題,為了主從複製的速度和連線的穩定性,主從庫最好在同一個區域網內。