摘要:?背景 Redis作為一款簡潔、高效的開源K/V數(shù)據(jù)庫,可以被用于內(nèi)存緩存、持久化存儲等不同場景,大量服務(wù)于各類互聯(lián)網(wǎng)應(yīng)用。同時也提供了豐富的功能配置,客戶可以根據(jù)各自業(yè)務(wù)需求,在讀寫性能、緩存容量、數(shù)據(jù)可靠性等方面作出靈活的選擇。
Redis作為一款簡潔、高效的開源K/V數(shù)據(jù)庫,可以被用于內(nèi)存緩存、持久化存儲等不同場景,大量服務(wù)于各類互聯(lián)網(wǎng)應(yīng)用。同時也提供了豐富的功能配置,客戶可以根據(jù)各自業(yè)務(wù)需求,在讀寫性能、緩存容量、數(shù)據(jù)可靠性等方面作出靈活的選擇。
Redis提供了RDB和AOF兩種持久化方式供選擇,4.0中更是引入了RDB-AOF混合持久化的方式,整合RDB和AOF的優(yōu)勢,提供更實(shí)時的數(shù)據(jù)持久化保證、更快的恢復(fù)速度和更緊湊的空間使用。針對AOF的寫入,Redis提供了兩種選項(xiàng)供選擇:
? always:aoflog實(shí)時寫入落盤,保證寫入數(shù)據(jù)的安全性,但寫入性能下降嚴(yán)重。
? everysec:buffer寫入aoflog,后臺定期刷盤,可以很好的保證寫入性能,但在failure場景下,需要承擔(dān)秒級新寫入數(shù)據(jù)丟失的風(fēng)險(xiǎn)。
這兩種模式需要用戶在性能和數(shù)據(jù)安全性之間做出取舍,魚和熊掌無法兼得。對一些對數(shù)據(jù)安全性有更高要求的場景,需要應(yīng)用層協(xié)同來保證數(shù)據(jù)安全,會給系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)帶來一定的復(fù)雜度。另一方面,在Redis發(fā)生failover的時候,會有一個緩存預(yù)熱重建的過程,期間對應(yīng)用會有一個可感知的不可服務(wù)時間、以及訪問延時抖動。
關(guān)于上述問題,很重要的一個原因在于目前DRAM和SSD(請忽略HDD)之間巨大的性能鴻溝。近幾年,備受學(xué)術(shù)界和工業(yè)界關(guān)注的NVM(Non-volatile Memory)?技術(shù),給這類問題的解決帶來了新的機(jī)遇。
?
圖1:NVM產(chǎn)品的存儲層次結(jié)構(gòu)
目前已有的NVM產(chǎn)品,對上層應(yīng)用提供DIMM形態(tài)的訪問接口。作為一種NVM設(shè)備,相比于DRAM具備掉電不丟數(shù)據(jù)的特性,容量上也會比DRAM高出一個數(shù)量級,成本優(yōu)勢明顯。相比于傳統(tǒng)SSD,不但讀寫速度更快(百ns量級),而且具備字節(jié)尋址的能力。同時也要看到,NVM產(chǎn)品仍然存在讀寫不對稱、順序和隨機(jī)訪問不對稱等特征。
從應(yīng)用場景上來看,NVM產(chǎn)品可以定位于替代部分DRAM功能,支撐持久Memory或In-Memory應(yīng)用。具體來說可被應(yīng)用在如下場景:
? 持久化內(nèi)存:作為數(shù)據(jù)持久層,對數(shù)據(jù)一致性要求很高的持久化系統(tǒng),同時兼顧數(shù)據(jù)可靠性和數(shù)據(jù)讀寫性能。
? 內(nèi)存數(shù)據(jù)庫:作為數(shù)據(jù)In Place空間,提供數(shù)據(jù)運(yùn)行和持久化存儲空間。
? 系統(tǒng)日志卷:作為日志卷,例如,在HPC系統(tǒng)中通常采用Checkpointing實(shí)現(xiàn)對計(jì)算中間狀態(tài)進(jìn)行持久化保存,這是一個耗時、耗系統(tǒng)吞吐量的過程。
?
基于NVM產(chǎn)品提供的字節(jié)尋址、持久化、高性能的能力,以及考慮到其讀寫、順序和隨機(jī)訪問不對稱等特性,對Redis作了細(xì)致的設(shè)計(jì)和深度的定制化改造,針對上面幾個問題取得非常好的測試效果。
性能分析
前面提到Redis的always模式通過實(shí)時flush操作確保AOF文件的實(shí)時持久化,但這會導(dǎo)致性能大幅下降。Everysec模式通過大幅減少flush操作的頻率,基于page cache緩沖對設(shè)備的讀寫訪問大幅提升QPS性能,但是這會引入秒級的數(shù)據(jù)丟失風(fēng)險(xiǎn)。而基于NVM產(chǎn)品提供的持久化能力可以非常優(yōu)雅地解決這個問題,兼顧性能和可靠性。整個的數(shù)據(jù)流圖如下:
?
圖2: 基于NVM產(chǎn)品的數(shù)據(jù)讀寫流程
首先將AOF文件直接放在基于NVM產(chǎn)品的PMEM-aware filesystem上(比如EXT4?DAX模式),通過mmap將AOF文件映射到用戶態(tài)地址空間,之后對AOF的訪問操作就變成了非常輕量的直接load/store方式,而且要確保數(shù)據(jù)持久化也僅需要在用戶態(tài)執(zhí)行persist操作(主要是cache?flush)??梢?,基于NVM產(chǎn)品的AOF持久化機(jī)制相比傳統(tǒng)的IO棧要輕量的多:
B? Bypass整個傳統(tǒng)IO棧(Block層->設(shè)備驅(qū)動等),實(shí)現(xiàn)直接load/store操作。
? 通過cache?flush操作即可實(shí)現(xiàn)持久化,取代了flush系統(tǒng)調(diào)用。
AOF機(jī)制的另一個問題是AOF文件的持續(xù)增大會造成巨大的空間浪費(fèi),所以阿里云Redis團(tuán)隊(duì)通過后臺線程的方式按照一定的策略(考慮吞吐和資源占用量等)對AOF文件進(jìn)行replay操作。即根據(jù)AOF命令在NVM產(chǎn)品上構(gòu)造持久化的KV數(shù)據(jù)結(jié)構(gòu),然后完成回放的AOF文件就可以刪除,從而解決了AOF占用空間的問題。
之所以選擇后臺線程異步replay的方式在NVM上構(gòu)建持久化數(shù)據(jù)結(jié)構(gòu),是因?yàn)樵撨^程需要通過事務(wù)操作來保證寫操作的原子性和數(shù)據(jù)結(jié)構(gòu)的一致性,耗時較大,所以數(shù)據(jù)先寫到DDR的方式可以保證客戶端寫操作的QPS不下降。考慮到NVM擁有出色的讀性能,數(shù)據(jù)異步replay到NVM之后,會根據(jù)數(shù)據(jù)冷熱和內(nèi)存占用量釋放部分value比較大的內(nèi)存副本,轉(zhuǎn)而直接基于NVM提供讀服務(wù)。所以DRAM逐漸演變?yōu)?/span>NVM的寫cache和熱數(shù)據(jù)的讀cache,以充分發(fā)揮NVM的讀性能和成本優(yōu)勢,同時規(guī)避NVM寫性能(相對)的短板問題。
在兩臺96核/384GB神龍服務(wù)器上,實(shí)測string數(shù)據(jù)結(jié)構(gòu)的SET操作,從結(jié)果數(shù)據(jù)來看幾乎與everysec模式的性能持平,同時兼顧了always模式的數(shù)據(jù)安全性和everysec模式的高性能。
圖3:Redis寫入性能對比
Redis在重啟時需要進(jìn)行數(shù)據(jù)恢復(fù)操作。原生Redis重啟后都需要從RDB和AOF中加載數(shù)據(jù)到內(nèi)存,完成加載后才可以正常提供服務(wù)。經(jīng)過實(shí)測,10GB左右數(shù)據(jù)的RDB加載時間大概為53秒左右,這段時間內(nèi)Redis服務(wù)處于不可用狀態(tài)。而在基于NVM的方案中,Redis重啟后可以先基于NVM的持久化數(shù)據(jù)結(jié)構(gòu)直接提供讀服務(wù),DRAM數(shù)據(jù)結(jié)構(gòu)重建完成后即可提供完整的讀寫服務(wù)。同樣針對10GB左右的數(shù)據(jù)集,系統(tǒng)shutdown?save后重啟,實(shí)測1秒內(nèi)可以提供只讀服務(wù),35秒內(nèi)可以提供完整讀寫服務(wù),整個數(shù)據(jù)恢復(fù)時間大幅下降。如下圖所示:
?
圖4: Redis?recovery時間對比
另外,原生Redis通過fork一個子進(jìn)程來保存全量DB數(shù)據(jù)到RDB或AOF文件,即使相比上次保存的數(shù)據(jù)僅有一個key的變更,也依然會全量保存整個DB,顯然這不是一種高效的實(shí)現(xiàn)方式。并且該過程會對Redis帶來較大的性能抖動。而基于NVM的方案是一種持續(xù)增量持久化的方式,更加高效和平滑,這點(diǎn)對于在線服務(wù)來說至關(guān)重要。
NVM相比DRAM能提供更高的存儲密度和更大容量的數(shù)據(jù)存儲空間,因此可以有效降低單位數(shù)據(jù)存儲成本。基于NVM的字節(jié)尋址能力和與DRAM的速度差異,我們設(shè)計(jì)了NVM非易失性內(nèi)存和DRAM易失性內(nèi)存間的數(shù)據(jù)換入與換出策略,能在不影響Redis基本性能的前提下,提高數(shù)據(jù)的存儲容量并節(jié)約成本。
結(jié)束語
整個方案中,充分發(fā)揮了NVM的字節(jié)尋址、持久化等能力,借助DRAM做cache來彌補(bǔ)NVM讀寫不對稱的問題,從而實(shí)現(xiàn)了高可靠、高性能、低成本的Redis數(shù)據(jù)庫,從測試數(shù)據(jù)可以看出NVM對Redis在持久化以及其他性能方面提升效果非常顯著。
除此之外,NVM相比DRAM能提供更高的存儲密度和更大容量的數(shù)據(jù)存儲空間,因此可以有效降低單位數(shù)據(jù)存儲成本。在不影響Redis基本讀寫性能的前提下,基于NVM和DRAM的動態(tài)數(shù)據(jù)輸入換出,是我們下一步工作的方向之一。
當(dāng)然,目前方案仍存在一些待優(yōu)化的點(diǎn),比如:對于高寫入場景,replay性能跟不上DRAM寫入速度;failover時候,需要等DRAM重建完成才能提供寫服務(wù)等。后續(xù)會繼續(xù)跟進(jìn)這些問題,結(jié)合技術(shù)和產(chǎn)品來一起合理改進(jìn)。
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
評論
查看更多