論Redis的永續性

2021-10-20 22:55:39 字數 2277 閱讀 3821

永續性一直是redis使用中的乙個重要話題。很多同學在使用redis的過程中,對於如何選擇永續性策略,如何配置永續性都有疑問。本文試圖對redis的永續性進行系統的分析和比較,以期正確認識redis的永續性,並結合實際應用選擇合理的永續性機制。

1.背景知識

永續性是資料儲存領域的乙個常見話題。永續性可以描述為將相關資料儲存在非易失性儲存器中的過程。資料持久化後,即使發生一定程度的故障,只要持久化的裝置沒有損壞,我們就可以使用持久化的資料進行恢復,在一定程度上減少了故障造成的損失。

我們使用的資料儲存,無論是傳統的關係型資料庫,還是類似redis的所謂nosql,都是在執行後執行在作業系統上的程式,應用程式傳送的資料需要經過這些資料儲存程式的處理,才能以某種格式持久儲存。在這個過程中,資料必須通過應用程式的記憶體,並由cpu操作,然後才能儲存在持久裝置上。所以要理解堅持,必須要有幾個方面的背景知識。

1.1使用者空間、核心空間和核心緩衝區

在linux中,為了保證作業系統穩定高效的執行,記憶體空間分為使用者空間和核心空間。簡單來說,每個應用通常位於使用者空間,而作業系統核心執行在核心空間。之所以這樣劃分,是因為呼叫作業系統的很多功能都會觸發敏感資源的操作,比如清空記憶體,設定時鐘等等。為了防止每個程式操作敏感資源而導致系統崩潰,記憶體空間按上述方式劃分。在使用者空間,應用程式沒有操作敏感資源的許可權(相應的指令受到限制),從而避免了可能出現的系統崩潰等異常現象。

眾所周知,大多數應用程式都無法避免處理底層資源,如從磁碟讀取資料、從網路讀取或接收訊息等。但是,在劃分使用者空間和系統空間後,應用程式無權訪問系統資源。為了解決這個問題,作業系統為應用程式公開了一系列的系統呼叫介面(system call inte***ce)來與底層資源進行互動,這樣應用程式就可以通過呼叫這些介面來訪問資源。我們常見的系統呼叫有write(),read()等等。

那麼當應用程式觸發系統呼叫介面時會發生什麼呢?我們以寫檔案為例。當應用程式呼叫寫操作時,系統不直接訪問硬碟寫檔案,而是先將檔案寫入核心緩衝區,然後定期將核心緩衝區中的資料批量寫入磁碟(這個過程也可以由應用程式通過觸發呼叫fsync()來完成)。顯然,核心緩衝區被劃分的原因主要是為了解決底層io讀寫速度和記憶體讀寫速度不匹配的問題。如果頻繁同步寫入硬碟,會嚴重降低程式的執行速度。

一般來說,要理解持久化的過程,需要知道在linux作業系統中,記憶體分為使用者空間和核心空間。當應用程式中的資料需要寫入檔案時,會依次通過應用程式記憶體和核心緩衝區寫入硬碟。此過程涉及的系統呼叫包括寫操作write()和強制硬碟同步操作fsync()。

1.2寫入時複製

眾所周知,在linux系統中,您可以通過呼叫fork()建立乙個與父程序完全相同的子程序副本。但是在fork的過程中,如果父程序占用的記憶體空間太大,可能需要很長時間來複製記憶體資料,這會使父程序無法響應其他命令,這對於乙個面向客戶端的伺服器程式來說是無法接受的。

為了解決這個問題,大佬們提出了寫時複製技術。簡單來說,寫時複製技術是指在fork的過程中,應用程式的記憶體沒有被完全複製,而是在子程序中建立乙個指向父程序對應記憶體位址的引用,只有在子程序讀取記憶體,發現資料是複製後新寫入的時候,才執行實際的複製動作。這樣,由於在fork的過程中不需要完成整個資料的複製,因此大大減少了fork()呼叫的時間消耗。

但實際上,寫時複製技術並沒有完全解決問題。比如一些大型應用占用了非常大的記憶體空間(比如乙個redis例項占用了幾十g的記憶體),只指向記憶體位址需要很長時間。

最後,對於redis持久化,我們只需要知道持久化過程中會涉及到fork call(發生在rdb模式和aof重寫的時候)。linux雖然採用了寫時複製技術,但是在例項記憶體佔用量較大的情況下,fork呼叫仍然可能帶來長期的阻塞。

前面我們簡單討論了linux的兩個背景知識點:記憶體空間分割槽和寫時複製(linux對fork呼叫的消耗做的乙個優化,即使做了這個優化,高記憶體占用的例項在fork期間可能還是會長時間阻塞)。接下來,我們分析持久化過程中的資料寫入過程。

2.持久資料寫入的過程

當我們使用某種資料儲存來儲存應用資料時,資料由應用程式通過網路傳送到資料儲存程式,然後由資料儲存程式進行處理和計算,然後以一定的格式儲存在硬碟等永續性裝置中。這個過程涉及很多步驟,比如網路呼叫、程式處理、作業系統寫檔案等。為了讓下面的討論更清晰,我們對這一步進行了一定程度的分解。簡而言之,應用程式資料從生成到儲存到永久裝置經歷了以下步驟:

客戶端向資料庫伺服器傳送寫入或更新資料的請求,此時資料位於客戶端記憶體中

當伺服器接收到寫命令時,資料位於伺服器資料庫的應用程式記憶體中(從伺服器的角度來看,資料位於應用程式(資料庫)記憶體中,即使用者模式記憶體中)

資料庫呼叫系統函式將資料寫入硬碟,此時資料位於核心的緩衝區

作業系統將資料從寫緩衝區傳輸到硬碟控制器,而資料位於硬碟快取中

硬碟控制器實際上將資料寫入物理介質

關係永續性建模

關係永續性建模 物件導向是偉大的技術。關聯式資料庫是偉大的技術。如果這兩種技術相互隔絕,那將是人類生活的一次災難,更是我們的巨大悲哀。幸運的是,這種假設沒有成為現實。上述兩種偉大的技術得到了人們的重視,同樣應該受到重視的還有如何將它們調和在一起。並不是世界上所有的東西都能夠輕而易舉地結合起來。關聯式...

Hibernate的Spring永續性

15章,441頁,38 99 本書僅供初學者使用,但是更有經驗的開發人員可以學習一兩個東西 本書涵蓋了hibernate和spring與永續性的關係 本書的範圍使它變得非常有趣。許多書籍談論hibernate,許多書籍談論spring。但是,我不知道有多少人在永續性方面談論兩者的使用。在沒有描述交易...

Mysql的原子性 永續性原理

一 mysql怎麼保證一致性的?一致性的話應該分兩個層面來保證。1.從資料庫層面,資料庫通過原子性 隔離性 永續性來保證一致性。也就是說acid四大特性之中,c 一致性 是目的,a 原子性 i 隔離性 d 永續性 是手段,是為了保證一致性,資料庫提供的手段。資料庫必須要實現aid三大特性,才有可能實...