位元組跳動+阿里+華為+騰訊等大廠Java面試題
1、背景
首先,讓我們簡要地討論下每個系統,以瞭解它們的高階設計和架構,看下每個系統所做的權衡。
Kafka 是一個開源的分散式事件流處理平臺,也是 Apache 軟體基金會下五個最活躍的專案之一。在其核心,Kafka 被設計成一個多副本的分散式持久化提交日誌,用於支撐事件驅動的微服務或大規模流處理應用程式。客戶端向代理叢集提供事件或使用代理叢集的事件,而代理會向底層檔案系統寫入或從底層檔案系統讀取事件,並自動在叢集中同步或非同步地複製事件,以實現容錯性和高可用性。
Pulsar 是一個開源的分散式釋出 / 訂閱訊息系統,最初是服務於佇列用例的。最近,它又增加了事件流處理功能。Pulsar 被設計為一個(幾乎)無狀態代理例項層,它連線到單獨的 BookKeeper 例項層,由它實際地讀取 / 寫入訊息,也可以選擇持久地儲存 / 複製訊息。Pulsar 並不是唯一的同類系統,還有其他類似的訊息傳遞系統,如 Apache DistributedLog 和 Pravega,它們都是在 BookKeeper 之上構建的,也是旨在提供一些類似 Kafka 的事件流處理功能。
BookKeeper 是一個開源的分散式儲存服務,最初是為 Apache Hadoop 的 NameNode 而設計的預寫日誌。它跨伺服器例項 bookies,在 ledgers 中提供訊息的持久儲存。為了提供可恢復性,每個 bookie 都會同步地將每條訊息寫入本地日誌,然後非同步地寫入其本地索引 ledger 儲存。與 Kafka 代理不同,bookie 之間不進行通訊,BookKeeper 客戶端使用 quorum 風格的協議在 bookie 之間複製訊息。
RabbitMQ 是一個開源的傳統訊息中介軟體,它實現了 AMQP 訊息標準,滿足了低延遲佇列用例的需求。RabbitMQ 包含一組代理程序,它們託管著釋出訊息的“交換器”,以及從中消費訊息的佇列。可用性和永續性是其提供的各種佇列型別的屬性。經典佇列提供的可用性保證最少。經典映象佇列將訊息複製到其他代理並提高可用性。最近引入的仲裁佇列提供了更強的永續性,但是以效能為代價。由於這是一篇面向效能的博文,所以我們將評估限制在經典佇列和映象佇列。
2、分散式系統的永續性
單節點儲存系統(例如 RDBMS)依靠 fsync 寫磁碟來確保最大的永續性。但在分散式系統中,永續性通常來自複製,即資料的多個副本獨立失效。資料 fsync 只是在發生故障時減少故障影響的一種方法(例如,更頻繁地同步可能縮短恢復時間)。相反,如果有足夠多的副本失敗,那麼無論是否使用 fsync,分散式系統都可能無法使用。因此,我們是否使用 fsync 只是這樣一個問題,即每個系統選擇基於什麼方式來實現其複製設計。有些系統非常依賴於從不丟失寫入到磁碟的資料,每次寫入時都需要 fsync,但其他一些則是在其設計中處理這種情況。
Kafka 的複製協議經過精心設計,可以確保一致性和永續性,而無需通過跟蹤什麼已 fsync 到磁碟什麼未 fsync 到磁碟來實現同步 fsync。Kafka 假設更少,可以處理更大範圍的故障,比如檔案系統級的損壞或意外的磁碟移除,並且不會想當然地認為尚不知道是否已 fsync 的資料是正確的。Kafka 還能夠利用作業系統批量寫入磁碟,以獲得更好的效能。
我們還不能十分確定,BookKeeper 是否在不 fsync 每個寫操作的情況下提供了相同的一致性保證——特別是在沒有同步磁碟持久化的情況下,它是否可以依賴複製來實現容錯。關於底層複製演算法的文件或文章中沒有提及這一點。基於我們的觀察,以及 BookKeeper 實現了一個分組 fsync 演算法的事實,我們相信,它確實依賴於 fsync 每個寫操作來確保其正確性,但是,社群中可能有人比我們更清楚我們的結論是否正確,我們希望可以從他們那裡獲得反饋。
無論如何,由於這可能是一個有爭議的話題,所以我們分別給出了這兩種情況下的結果,以確保我們的測試儘可能的公平和完整,儘管執行帶有同步 fsync 功能的 Kafka 極其罕見,也是不必要的。
3、基準測試框架
對於任何基準測試,人們都想知道使用的是什麼框架以及它是否公平。為此,我們希望使用 OpenMessaging Benchmark Framework(OMB),該框架很大一部分最初是由 Pulsar 貢獻者編寫的。OMB 是一個很好的起點,它有基本的工作負載規範、測試結果指標收集 / 報告,它支援我們選擇的三種訊息系統,它還有針對每個系統定製的模組化雲部署工作流。但是需要注意,Kafka 和 RabbitMQ 實現確實存在一些顯著的缺陷,這些缺陷影響了這些測試的公平性和可再現性。最終的基準測試程式碼,包括下面將要詳細介紹的修復程式,都是開源的。
OMB 框架修復
我們升級到 Java 11 和 Kafka 2.6、RabbitMQ 3.8.5 和 Pulsar 2.6(撰寫本文時的最新版本)。藉助 Grafana/Prometheus 監控棧,我們顯著增強了跨這三個系統的監控能力,讓我們可以捕獲跨訊息系統、JVM、Linux、磁碟、CPU 和網路的指標。這很關鍵,讓我們既能報告結果,又能解釋結果。我們增加了只針對生產者的測試和只針對消費者的測試,並支援生成 / 消耗積壓,同時修復了當主題數量小於生產者數量時生產者速率計算的一個重要 Bug。
OMB Kafka 驅動程式修復
我們修復了 Kafka 驅動程式中一個嚴重的 Bug,這個 Bug 讓 Kafka 生產者無法獲得 TCP 連線,存在每個工作者例項一個連線的瓶頸。與其他系統相比,這個補丁使得 Kafka 的數值更公平——也就是說,現在所有的系統都使用相同數量的 TCP 連線來與各自的代理通訊。我們還修復了 Kafka 基準消費者驅動程式中的一個關鍵 Bug,即偏移量提交的過於頻繁及同步導致效能下降,而其他系統是非同步執行的。我們還優化了 Kafka 消費者的 fetch-size 和複製執行緒,以消除在高吞吐量下獲取訊息的瓶頸,並配置了與其他系統相當的代理。
OMB RabbitMQ 驅動程式修復
我們增強了 RabbitMQ 以使用路由鍵和可配置的交換型別(DIRECT
交換和TOPIC
交換),還修復了 RabbitMQ 叢集設定部署工作流中的一個 Bug。路由鍵被引入用來模仿主題分割槽的概念,實現與 Kafka 和 Pulsar 相當的設定。我們為 RabbitMQ 部署添加了一個 TimeSync 工作流,以同步客戶端例項之間的時間,從而精確地測量端到端延遲。此外,我們還修復了 RabbitMQ 驅動程式中的另一個 Bug,以確保可以準確地測量端到端延遲。
OMB Pulsar 驅動程式修復
對於 OMB Pulsar 驅動程式,我們添加了為 Pulsar 生產者指定最大批次大小的功能,並關閉了那些在較高目標速率下、可能人為地限制跨分割槽生產者佇列吞吐量的全侷限制。我們不需要對 Pulsar 基準驅動程式做任何其他重大的更改。
4、測試平臺
OMB 包含基準測試的測試平臺定義(例項型別和 JVM 配置)和工作負載驅動程式配置(生產者 / 消費者配置和伺服器端配置),我們將其用作測試的基礎。所有測試都部署了四個驅動工作負載的工作者例項,三個代理 / 伺服器例項,一個監視例項,以及一個可選的、供 Kafka 和 Pulsar 使用的三例項 Apache ZooKeeper 叢集。在實驗了幾種例項型別之後,我們選定了網路 / 儲存經過優化的 Amazon EC2 例項,它具有足夠的 CPU 核心和網路頻寬來支援磁碟 I/O 密集型工作負載。在本文接下來的部分,我們會列出我們在不同的測試中對這些基線配置所做的更改。
磁碟
具體來說,我們選擇了i3en.2xlarge
(8 vCore,64GB RAM,2x 2500 GB NVMe SSD
),我們看中了它高達 25 Gbps 的網路傳輸限額,可以確保測試設定不受網路限制。這意味著這些測試可以測出相應伺服器的最大效能指標,而不僅僅是網速多快。i3en.2xlarge
例項在兩塊磁碟上支援高達 約 655 MB/s 的寫吞吐量,這給伺服器帶來了很大的壓力。有關詳細資訊,請參閱完整的 例項型別定義。根據一般建議和最初的 OMB 設定,Pulsar 把一個磁碟用於 journal,另一個用於 ledger 儲存。Kafka 和 RabbitMQ 的磁碟設定沒有變化。
最後
小編利用空餘時間整理了一份《MySQL效能調優手冊》,初衷也很簡單,就是希望能夠幫助到大家,減輕大家的負擔和節省時間。
關於這個,給大家看一份學習大綱(PDF)檔案,每一個分支裡面會有詳細的介紹。
這裡都是以圖片形式展示介紹,如要下載原檔案以及更多的效能調優筆記(MySQL+Tomcat+JVM)可以直接【點選 “效能調優”】免費下載!