摘要:因為文件重寫也需要用到子進程,所以快照持久化因為創建子進程而導致的性能問題和內存占用問題,在持久化中也同樣存在。上一篇文章實戰第四章數據安全與性能保障第節快照持久化下一篇文章實戰第四章數據安全與性能保障第節復制
上一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第2節:快照持久化AOF持久化
下一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第4節:復制
簡單來說,AOF持久化會將被執行的命令寫到AOF文件的末尾,以此來記錄數據發送的變化。因此,Redis只要從頭到尾重新執行一次AOF文件包含的所有寫命令,就可以恢復AOF文件所記錄的數據集。AOF持久化可以通過設置代碼appendonly yes配置選項來打開。
文件同步:在向硬盤寫入文件時,至少會發生三件事情,當調用file.write()方法(或其它編程語言里面的類似操作)對文件進行寫入時,寫入的內容首先會被存儲到緩沖區,然后操作系統會在將來的某個時候將緩沖區存儲的內容寫入硬盤,而數據只有在被寫入硬盤后,才算是真正地保存到了硬盤里面。用戶可以通過調用file.flush()方法來請求操作系統盡快地將緩沖區存儲的數據寫入硬盤里面,但具體地執行寫入操作仍然由系統決定。除此之外,用戶還可以命令操作系統將文件同步(sync)到硬盤,同步操作會一直阻塞直到指定的文件被寫入硬盤為止。當同步操作執行完畢之后,即使系統出現故障也不會對被同步的文件造成任何影響。
下表展示了appendfsync 配置選項對AOF文件的同步頻率的影響。
選項 | 同步頻率 |
---|---|
always | 每個Redis寫命令都要同步寫入硬盤。這樣做會嚴重降低Redis的速度。 |
everysec | 每秒執行一次同步,顯示地將多個寫命令同步到硬盤。 |
no | 讓操作系統來決定應該何時進行同步。 |
如果用戶使用appendfsync always 選項的話,那么每個Redis寫命令都會被寫入硬盤,從而將發生系統崩潰時出現的數據丟失減到最少。不過遺憾的是,因為這種同步策略需要對硬盤進行大量寫入,所以Redis處理命令的速度會受到硬盤性能的限制:轉盤式硬盤(spinning disk)在這種同步頻率下每秒只能處理大約200個寫命令,而固態硬盤(solid-state drive,SSD)每秒大概也只能處理幾萬個寫命令。
警告:固態硬盤和appendfsync always使用固態硬盤的用戶請謹慎使用appendfsync always選項,因為這個選項讓Redis每次只寫入一個命令,而不是像其他appendfsync選項那樣一次寫入多個命令,這種不斷地寫入少量數據的做法有可能會引發嚴重的寫入放大(write amplification)問題,在某些環境下甚至會將固態硬盤的壽命從原來的幾年降低為幾個月。
為了兼顧數據安全和寫入性能,用戶可以考慮使用appendfsync everysec選項,讓Redis以每秒一次的頻率對AOF文件進行同步。Redis每秒同步一次AOF文件時的性能和不使用任何持久化特性時的性能相差無幾,而通過每秒同步一次AOF文件,Redis可以保證,即使出現系統崩潰,用戶也最多只會丟失一秒之內產生的數據。當硬盤忙于執行寫入操作的時候,Redis還會優雅地放慢自己的速度以便適應硬盤的最大寫入速度。
最后,如果用戶使用appendfsync no選項,那么Redis將不對AOF文件執行任何顯示的同步操作,而是由操作系統來決定應該在何時對AOF文件進行同步。這個選項在一般情況下不會對Redis的性能帶來影響,但系統崩潰將導致使用這種選項的Redis服務器丟失不定數量的數據。另外,如果用戶的硬盤處理寫入操作的速度不夠快的話,那么當緩沖區被等待寫入磁盤的數據填滿時,Redis的寫入操作將被阻塞,并導致Redis處理命令請求的速度變慢。因為這個原因,一般來說并不推薦使用appendfsync no選項,在這里介紹了它只是為了完整列舉appendfsync選項的可用的3個值。
雖然AOF持久化非常靈活地提供了多種不同的選項來滿足不同應用程序對數據安全的不同要求,但AOF持久化也有缺陷:那就是AOF文件的體積大小。
重寫、壓縮AOF文件AOF持久化既可以將丟失數據的時間區間降低至1秒(甚至不丟失任何數據),又可以在極端的時間內完成定期的持久化操作,那么我們有什么理由不使用AOF持久化呢?但是這個問題實際上并沒有那么簡單,因為Redis會不斷地將被執行的寫命令記錄到AOF文件里面,所有隨著Redis不斷運行,AOF文件的體積會不斷增長,在極端情況下,體積不斷增大的AOF文件甚至可能會用完磁盤的所有可用空間。還有另一個問題是,因為Redis在重啟之后需要通過重新執行AOF文件記錄的所有寫命令的還原數據集,所以如果AOF文件的體積非常大,那么還原操作執行的時間就可能會非誠長。
為了解決AOF文件體積不斷增大的問題,用戶可以向Redis發送bgrewriteaof命令,這個命令會通過移除AOF文件中的冗余命令來重寫(rewrite)AOF文件,使AOF文件的體積變得盡可能地小。bgrewriteaof的工作原理和bgsave創建快照的工作原因非常相似:Redis會創建一個子進程,然后由子進程負責對AOF文件進行重寫。因為AOF文件重寫也需要用到子進程,所以快照持久化因為創建子進程而導致的性能問題和內存占用問題,在AOF持久化中也同樣存在。更糟糕的是,如果不加以控制的話,AOF文件的體積可能會比快照的體積大好幾倍,在進行AOF重寫并刪除舊AOF文件的時候,刪除一個體積達到數十GB大的舊AOF文件可能會導致操作系統掛起數秒。
跟快照持久化可以通過設置save選項來自動執行bgsave一樣,AOF持久化也可以通過設置auto-aof-rewrite-percentage選項和auto-aof-rewrite-min-size選項來自動執行bgrewriteaof。舉個例子,假設用戶對Redis設置了配置選項auto-aof-rewrite-percentage 100和auto-aof-rewrite-min-size 64mb,并且啟用了AOF持久化,那么當AOF文件的體積大于64MB,并且AOF文件的體積比上一次重寫之后的體積大了至少一倍(100%)的時候,Redis將執行bgrewriteaof命令。如果aof重寫執行得過于頻繁地話,那么用戶可以考慮將auto-aof-rewrite-percentage選項的值設置為100以上,這種做法可以讓Redis在AOF文件的體積變得更大之后才執行重寫操作,不過也會讓Redis在啟動時還原數據集所需的時間變得更長。
無論是使用AOF持久化還是快照持久化,將數據持久化到硬盤上都是非常有必要的,但除了進行持續化之外,用戶還必須對持久化所得的文件進行備份(最好是備份到不同的地方),這樣才能盡量避免數據丟失事故發生。如果條件允許的話,最好能夠將快照文件和最新重寫的AOF文件備份到不同的服務器上面。
通過使用AOF持久化或者快照持久化,用戶可以在系統重啟或者崩潰的情況下仍讓保留數據。隨著負載量的上升、或者數據的完整性變得越來越重要時,用戶可能需要使用復制性。
上一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第2節:快照持久化
下一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第4節:復制
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45027.html
摘要:為了讓讀者做好使用構建真實軟件的準備,本章將展示維護數據安全以及應對系統故障的方法。上一篇文章實戰第三章命令第七節其他命令下一篇文章實戰第四章數據安全與性能保障第節快照持久化 上一篇文章:Python--Redis實戰:第三章:Redis命令:第七節:其他命令下一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第2節:快照持久化 前面的幾章介紹了各式各樣的Redi...
摘要:上一篇文章實戰第四章數據安全與性能保障第節持久化選項下一篇文章實戰第四章數據安全與性能保障第節持久化可以通過創建快照來獲得存儲在內存里面的數據在某個時間點上的副本。 上一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第1節:持久化選項下一篇文章:Python--Redis實戰:第四章:數據安全與性能保障:第3節:AOF持久化 Redis可以通過創建快照來獲得存儲...
閱讀 2083·2021-11-15 17:57
閱讀 747·2021-11-11 16:54
閱讀 2595·2021-09-27 13:58
閱讀 4083·2021-09-06 15:00
閱讀 955·2021-09-04 16:45
閱讀 3511·2019-08-30 15:56
閱讀 1789·2019-08-30 15:53
閱讀 1620·2019-08-30 14:12