歡迎光臨
每天分享高質量文章

基於NVM持久化高效能Redis資料庫

 

背景: Redis作為一款簡潔、高效的開源K/V資料庫,可以被用於記憶體快取、持久化儲存等不同場景,大量服務於各類網際網路應用。同時也提供了豐富的功能配置,客戶可以根據各自業務需求,在讀寫效能、快取容量、資料可靠性等方面作出靈活的選擇。

Redis提供了RDB和AOF兩種持久化方式供選擇,4.0中更是引入了RDB-AOF混合持久化的方式,整合RDB和AOF的優勢,提供更實時的資料持久化保證、更快的恢復速度和更緊湊的空間使用。針對AOF的寫入,Redis提供了兩種選項供選擇:

•    always:aoflog實時寫入落盤,保證寫入資料的安全性,但寫入效能下降嚴重。

•    everysec:buffer寫入aoflog,後臺定期刷盤,可以很好的保證寫入效能,但在failure場景下,需要承擔秒級新寫入資料丟失的風險。

這兩種樣式需要使用者在效能和資料安全性之間做出取捨,魚和熊掌無法兼得。對一些對資料安全性有更高要求的場景,需要應用層協同來保證資料安全,會給系統設計和實現帶來一定的複雜度。另一方面,在Redis發生failover的時候,會有一個快取預熱重建的過程,期間對應用會有一個可感知的不可服務時間、以及訪問延時抖動。

 

關於上述問題,很重要的一個原因在於目前DRAM和SSD(請忽略HDD)之間巨大的效能鴻溝。近幾年,備受學術界和工業界關註的NVM(Non-volatile Memory) 技術,給這類問題的解決帶來了新的機遇。

圖1:NVM產品的儲存層次結構

目前已有的NVM產品,對上層應用提供DIMM形態的訪問介面。作為一種NVM裝置,相比於DRAM具備掉電不丟資料的特性,容量上也會比DRAM高出一個數量級,成本優勢明顯。相比於傳統SSD,不但讀寫速度更快(百ns量級),而且具備位元組定址的能力。同時也要看到,NVM產品仍然存在讀寫不對稱、順序和隨機訪問不對稱等特徵。

從應用場景上來看,NVM產品可以定位於替代部分DRAM功能,支撐持久Memory或In-Memory應用。具體來說可被應用在如下場景:

•    持久化記憶體:作為資料持久層,對資料一致性要求很高的持久化系統,同時兼顧資料可靠性和資料讀寫效能。

•    記憶體資料庫:作為資料In Place空間,提供資料執行和持久化儲存空間。

•    系統日誌捲:作為日誌捲,例如,在HPC系統中通常採用Checkpointing實現對計算中間狀態進行持久化儲存,這是一個耗時、耗系統吞吐量的過程。

 

基於NVM產品提供的位元組定址、持久化、高效能的能力,以及考慮到其讀寫、順序和隨機訪問不對稱等特性,對Redis作了細緻的設計和深度的定製化改造,針對上面幾個問題取得非常好的測試效果。

效能分析: 前面提到Redis的always樣式透過實時flush操作確保AOF檔案的實時持久化,但這會導致效能大幅下降。Everysec樣式透過大幅減少flush操作的頻率,基於page cache緩衝對裝置的讀寫訪問大幅提升QPS效能,但是這會引入秒級的資料丟失風險。而基於NVM產品提供的持久化能力可以非常優雅地解決這個問題,兼顧效能和可靠性。整個的資料流圖如下:

圖2: 基於NVM產品的資料讀寫流程

首先將AOF檔案直接放在基於NVM產品的PMEM-aware filesystem上(比如EXT4 DAX樣式),透過mmap將AOF檔案對映到使用者態地址空間,之後對AOF的訪問操作就變成了非常輕量的直接load/store方式,而且要確保資料持久化也僅需要在使用者態執行persist操作(主要是cache flush)。可見,基於NVM產品的AOF持久化機制相比傳統的IO棧要輕量的多:

Bypass整個傳統IO棧(Block層->裝置驅動等),實現直接load/store操作。

透過cache flush操作即可實現持久化,取代了flush系統呼叫。

 

AOF機制的另一個問題是AOF檔案的持續增大會造成巨大的空間浪費,所以阿裡雲Redis團隊透過後臺執行緒的方式按照一定的策略(考慮吞吐和資源佔用量等)對AOF檔案進行replay操作。即根據AOF命令在NVM產品上構造持久化的KV資料結構,然後完成回放的AOF檔案就可以刪除,從而解決了AOF佔用空間的問題。

之所以選擇後臺執行緒非同步replay的方式在NVM上構建持久化資料結構,是因為該過程需要透過事務操作來保證寫操作的原子性和資料結構的一致性,耗時較大,所以資料先寫到DDR的方式可以保證客戶端寫操作的QPS不下降。考慮到NVM擁有出色的讀效能,資料非同步replay到NVM之後,會根據資料冷熱和記憶體佔用量釋放部分value比較大的記憶體副本,轉而直接基於NVM提供讀服務。所以DRAM逐漸演變為NVM的寫cache和熱資料的讀cache,以充分發揮NVM的讀效能和成本優勢,同時規避NVM寫效能(相對)的短板問題。

在兩臺96核/384GB神龍伺服器上,實測string資料結構的SET操作,從結果資料來看幾乎與everysec樣式的效能持平,同時兼顧了always樣式的資料安全性和everysec樣式的高效能。

圖3:Redis寫入效能對比

Redis在重啟時需要進行資料恢復操作。原生Redis重啟後都需要從RDB和AOF中載入資料到記憶體,完成載入後才可以正常提供服務。經過實測,10GB左右資料的RDB載入時間大概為53秒左右,這段時間內Redis服務處於不可用狀態。而在基於NVM的方案中,Redis重啟後可以先基於NVM的持久化資料結構直接提供讀服務,DRAM資料結構重建完成後即可提供完整的讀寫服務。

 

同樣針對10GB左右的資料集,系統shutdown save後重啟,實測1秒內可以提供只讀服務,35秒內可以提供完整讀寫服務,整個資料恢復時間大幅下降。如下圖所示:

圖4: Redis recovery時間對比

另外,原生Redis透過fork一個子行程來儲存全量DB資料到RDB或AOF檔案,即使相比上次儲存的資料僅有一個key的變更,也依然會全量儲存整個DB,顯然這不是一種高效的實現方式。並且該過程會對Redis帶來較大的效能抖動。而基於NVM的方案是一種持續增量持久化的方式,更加高效和平滑,這點對於線上服務來說至關重要。

NVM相比DRAM能提供更高的儲存密度和更大容量的資料儲存空間,因此可以有效降低單位資料儲存成本。基於NVM的位元組定址能力和與DRAM的速度差異,我們設計了NVM非易失性記憶體和DRAM易失性記憶體間的資料換入與換出策略,能在不影響Redis基本效能的前提下,提高資料的儲存容量並節約成本。

結束語: 整個方案中,充分發揮了NVM的位元組定址、持久化等能力,藉助DRAM做cache來彌補NVM讀寫不對稱的問題,從而實現了高可靠、高效能、低成本的Redis資料庫,從測試資料可以看出NVM對Redis在持久化以及其他效能方面提升效果非常顯著。

除此之外,NVM相比DRAM能提供更高的儲存密度和更大容量的資料儲存空間,因此可以有效降低單位資料儲存成本。在不影響Redis基本讀寫效能的前提下,基於NVM和DRAM的動態資料輸入換出,是我們下一步工作的方向之一。

當然,目前方案仍存在一些待最佳化的點,比如:對於高寫入場景,replay效能跟不上DRAM寫入速度;failover時候,需要等DRAM重建完成才能提供寫服務等。後續會繼續跟進這些問題,結合技術和產品來一起合理改進。

 

文章來源:雲棲社群

已同步到看一看
贊(0)

分享創造快樂