Apache Cassandra 在 Facebook 的應用

摘要: 在 Instagram (Instagram是Facebook公司旗下一款免費提供在線圖片及視頻分享的社交應用軟件,於2010年10月發佈。)上,咱們擁有世界上最大的 Apache Cassandra 數據庫部署。

誰說 Facebook 棄用 Cassandra?相反 Facebook 擁有全世界最大的單個 Cassandra 集羣部署,並且他們對 Cassandra 作了不少性能優化,包括 Cassandra on RocksDB 以提高 Cassandra 的響應時間。git

在 Instagram (Instagram是Facebook公司旗下一款免費提供在線圖片及視頻分享的社交應用軟件,於2010年10月發佈。)上,咱們擁有世界上最大的 Apache Cassandra 數據庫部署。咱們在 2012 年開始使用 Cassandra 取代 Redis ,在生產環境中支撐欺詐檢測,Feed 和 Direct inbox 等產品。起初咱們在 AWS 環境中運行了 Cassandra 集羣,可是當 Instagram 架構發生變化時,咱們將 Cassandra 集羣遷移到Facebook 的基礎架構中。咱們對 Cassandra 的可靠性和可用性有了很是好的體驗,可是在讀取數據延遲方面咱們以爲他須要改進。github

去年 Instagram 的 Cassandra 團隊開始着手這個項目,以顯着減小 Cassandra 的讀取延遲,咱們稱之爲 Rocksandra。 在這篇文章中,我將描述該項目的動機,咱們克服的挑戰以及內部和公共雲環境中的性能指標。算法

動機

在 Instagram 上,咱們大量使用 Apache Cassandra 做爲通用鍵值存儲服務。Instagram 的大多數 Cassandra 請求都是在線的,所以爲了向數億 Instagram 用戶提供可靠且響應迅速的用戶體驗,咱們有很高的 SLA 要求。數據庫

Instagram 可靠性 SLA 保持爲5-9s,這意味着在任何給定時間,請求失敗率應小於0.001%。爲了提升性能,咱們主動監控不一樣 Cassandra 集羣的吞吐量和延遲,尤爲是 P99 讀取延遲。apache

下面的圖顯示了一個生產 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 社區。

本文翻譯自:https://instagram-engineering.com/open-sourcing-a-10x-reduction-in-apache-cassandra-tail-latency-d64f86b43589



本文做者:明惠

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索