Apache Cassandra 在 Facebook 的应用
誰說 Facebook 棄用 Cassandra?相反 Facebook 擁有全世界最大的單個 Cassandra 集群部署,而且他們對 Cassandra 做了很多性能優化,包括 Cassandra on RocksDB 以提升 Cassandra 的響應時間。
在 Instagram (Instagram是Facebook公司旗下一款免費提供在線圖片及視頻分享的社交應用軟件,于2010年10月發布。)上,我們擁有世界上最大的 Apache Cassandra 數據庫部署。我們在 2012 年開始使用 Cassandra 取代 Redis ,在生產環境中支撐欺詐檢測,Feed 和 Direct inbox 等產品。起初我們在 AWS 環境中運行了 Cassandra 集群,但是當 Instagram 架構發生變化時,我們將 Cassandra 集群遷移到Facebook 的基礎架構中。我們對 Cassandra 的可靠性和可用性有了非常好的體驗,但是在讀取數據延遲方面我們覺得他需要改進。
去年 Instagram 的 Cassandra 團隊開始著手這個項目,以顯著減少 Cassandra 的讀取延遲,我們稱之為 Rocksandra。 在這篇文章中,我將描述該項目的動機,我們克服的挑戰以及內部和公共云環境中的性能指標。
動機
在 Instagram 上,我們大量使用 Apache Cassandra 作為通用鍵值存儲服務。Instagram 的大多數 Cassandra 請求都是在線的,因此為了向數億 Instagram 用戶提供可靠且響應迅速的用戶體驗,我們有很高的 SLA 要求。
Instagram 可靠性 SLA 保持為5-9s,這意味著在任何給定時間,請求失敗率應小于0.001%。為了提高性能,我們主動監控不同 Cassandra 集群的吞吐量和延遲,尤其是 P99 讀取延遲。
下面的圖顯示了一個生產 Cassandra 集群的客戶端延遲。藍線是平均讀取延遲(5ms),橙色線是 P99 讀取延遲(在25ms到60ms的范圍內)。
經過調查,我們發現 JVM 垃圾收集器(GC)對延遲峰值做出了很大貢獻。我們定義了一個稱為 GC 停滯百分比的度量,用于衡量Cassandra 服務器執行 GC(Young Gen GC)并且無法響應客戶端請求的時間百分比。結果顯示我們生產 Cassandra 服務器上的 GC 停滯百分比。在最低請求流量時間窗口期間為1.25%,在高峰時段可能高達2.5%。
這表明 Cassandra 服務器實例在垃圾收集上花費 2.5% 的運行時間,而這段時間是不能服務客戶端請求的。GC 開銷顯然對我們的 P99 延遲有很大影響,因此如果我們可以降低 GC 停頓百分比,我們將能夠顯著降低P99延遲。
解決辦法
Apache Cassandra 是一個分布式數據庫,并用 Java 編寫了基于 LSM 樹的存儲引擎。 我們發現存儲引擎中的組件,如memtable,壓縮,讀/寫路徑等,在 Java 堆中創建了很多對象,并為 JVM 產生了大量開銷。為了減少來自存儲引擎的GC影響,我們考慮了不同的方法,并最終決定開發C++存儲引擎來替換現有的引擎。
我們不想從頭開始構建新的存儲引擎,因此我們決定在 RocksDB 之上構建新的存儲引擎。
RocksDB 是一個開源的,高性能嵌入式鍵值數據庫。它是用 C++ 編寫的,并為 C++,C 和 Java 提供官方 API。RocksDB 針對性能進行了優化,尤其是在 SSD 等快速存儲方面。它在業界廣泛用作 MySQL,mongoDB 和其他流行數據庫的存儲引擎。
挑戰
在 RocksDB 上實現新的存儲引擎時,我們克服了三個主要挑戰:
第一個挑戰是 Cassandra 還沒有可插拔的存儲引擎架構,這意味著現有的存儲引擎與數據庫中的其他組件耦合在一起。為了在大規模重構和快速迭代之間找到平衡點,我們定義了一個新的存儲引擎 API,包括最常見的讀/寫和流接口。這樣我們就可以在 API 后面實現新的存儲引擎,并將其注入 Cassandra 內部的相關代碼路徑。
其次,Cassandra 支持豐富的數據類型和表模式,而 RocksDB 提供純粹的鍵值接口。我們仔細定義了編碼/解碼算法,使得我們使用 RocksDB 數據結構來構建 Cassandra 數據模型,并支持與原始 Cassandra 相同的查詢語義。
第三個挑戰是關于 streaming。 Streaming 在 Cassandra 這樣的分布式數據庫是很重要組件。每當我們從 Cassandra 集群加入或刪除節點時,Cassandra 都需要在不同節點之間傳輸數據以平衡集群中的負載。現有的 streaming 實現基于當前存儲引擎的。因此,我們必須將它們彼此分離,創建一個抽象層,并使用 RocksDB API 重新實現 streaming 傳輸。對于高 streaming 吞吐量,我們現在首先將數據流式傳輸到臨時 sst 文件,然后使用 RocksDB 提取文件 API 立即將它們批量加載到 RocksDB 實例中。
性能指標
經過大約一年的開發和測試,我們已經完成了第一個版本的實現,并成功將其推廣到 Instagram 中的幾個生產 Cassandra 集群。在我們的一個生產集群中,P99讀取延遲從60ms降至20ms。 我們還觀察到該集群上的GC停滯從2.5%下降到0.3%,這減少了10倍!
我們還想驗證 Rocksandra 在公共云環境中是否表現良好。我們在 AWS 環境中使用三個 i3.8 xlarge EC2 實例部署了一個 Cassandra 集群,每個實例具有 32 個核,244GB內存和 帶有4個nvme閃存盤的raid0。
我們使用 NDBench 作為基準測試,并使用這個框架中的默認表模式:
TABLE emp (emp_uname text PRIMARY KEY, emp_dept text, emp_first text, emp_last text)我們將 250M 6KB 行數據預先加載到數據庫中(每個服務器在磁盤上存儲大約500GB的數據)。我們在 NDBench 中配置了128個讀客戶端和128個寫客戶端。
我們測試了不同的工作負載并測量了 avg/P99/P999 讀/寫延遲。如我們所見,Rocksandra 提供了更低且一致的讀/寫延遲。
我們還測試了一個只讀工作負載并觀察到,在類似的P99讀取延遲(2ms)下,Rocksandra 讀取吞吐量提高了10倍(Rocksandra為300K/s,C * 3.0為 30K/s)。
未來工作
我們開源了 Rocksandra 代碼庫和基準框架,您可以從Github下載(https://github.com/Instagram/cassandra/tree/rocks_3.0),在您自己的環境中試用!
下一步,我們正在積極開發更多 C?功能,如二級索引,修復等。我們還在開發一個 C?可插拔存儲引擎架構,以便將我們的工作貢獻給Apache Cassandra 社區。
原文鏈接
本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的Apache Cassandra 在 Facebook 的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Data Lake Analytics:
- 下一篇: 最强NLP模型BERT可视化学习