,
(西安郵電大學 計算機學院,西安 710061)
Android是一款基于Linux內核的開源操作系統,一經提出便在移動設備上迅速普及,目前Android系統已經占據了全球智能手機五成份額[1]。Android智能手機廣泛使用體積小、功耗低的eMMC(Embedded Multi Media Card)作為數據存儲設備,區別于傳統機械硬盤,eMMC使用閃存芯片作為存儲介質[2]。同時因手機電源不穩定的特點,Android默認使用EXT4文件系統[3],作為Linux中最常用的日志文件系統,采用JBD2(Journal Block Device 2)軟件[4]進行日志記錄,因此擁有良好的故障恢復能力,能夠保證Android系統的穩定性以及數據的安全性。目前Android存儲系統架構與Linux存儲系統架構類似,有著用戶空間與內核空間兩部分。內核空間中主要包括EXT4文件系統與eMMC存儲設備兩個部分,EXT4文件系統通過虛擬文件系統向用戶空間提供系統調用接口,而EXT4文件系統底層則通過通用塊層、塊設備驅動層與eMMC塊設備關聯起來[5]。
目前針對Android系統存儲性能優化的方案主要有兩個方面:一方面是用戶空間中對應用軟件或者軟件依賴運行庫的優化;另一方面是內核空間中對文件系統的優化。用戶空間中的優化主要集中于對Android中大量使用的SQLite數據庫技術的改進,例如通過消除SQLite的WAL模式下數據庫checkpoints的寫冗余部分,獲取存儲性能的提升[6],但是這樣的方案只能夠提升軟件利用SQLite技術存儲數據時的存儲效率,無法對Android系統中文本文件、多媒體文件等多種類型的文件讀寫產生有效提升。內核空間中的優化主要包括對Android默認使用的EXT4文件系統的優化以及針對Android使用的閃存設備設計專門的文件系統兩種方案,前者優化調整EXT4文件系統中的重要參數從而提升文件系統的整體存儲性能,但是方案中并沒有考慮到EXT4文件系統的日志功能用于閃存設備所造成的影響,而且效果并不理想[7];后者則有著著名的F2FS(Flash Friendly File System)[8],此方案雖然在小文件的隨機讀寫上有著較大的提升,但是由于開發時間尚短,在系統穩定性、軟件兼容性等方面仍無法與EXT4文件系統相比,因此目前尚未廣泛使用。
針對Android智能手機普遍采用的eMMC存儲設備掛載EXT4文件系統的存儲系統架構,本文分析了EXT4文件系統日志特性導致其對閃存設備文件讀寫性能衰減的問題,提出了一種能夠消除此問題的EXT4文件系統日志功能優化方案。
EXT4文件系統借用了數據庫中事務的思想,為需同步至磁盤的數據建立相關的日志數據,以便能夠在發生系統崩潰后可以利用日志數據恢復,重新使文件系統保持一致的狀態[9]。EXT4文件系統掛載時將磁盤空間劃出一小塊空間作為日志數據區域,專門用于存儲日志數據。文件系統讀寫文件時,保持原有的讀寫磁盤邏輯不變,通過JBD2進程將影響文件系統一致性的元數據塊及時寫入到日志數據區域中。

表1 EXT4文件系統數據同步事務狀態表
圖1描述了EXT4文件系統日志數據流。虛線箭頭表示了當文件系統讀寫數據中途崩潰時的修復過程,重新掛載分區時根據日志數據區域中的數據,逐一將記錄下的元數據寫回到磁盤原始位置,保證文件系統的一致性。實線箭頭表示每次EXT4文件系統讀寫磁盤時的邏輯,首先由JBD2進程將每次需要寫入的數據中元數據部分拷貝一份,將元數據封裝成日志數據后提交到日志數據區域,之后EXT4文件系統對磁盤進行正常讀寫數據流程,這樣的一次流程被稱為一次事務。表1為一個事務幾種狀態的描述[10],以區分事務的執行程度。

圖1 EXT4文件系統日志數據流圖
EXT4的日志數據區域以文件系統的塊為單位組織日志數據,有著類似于通用數據區域的結構劃分,但是相比通用數據區域更加簡單,起始位置存放了日志數據的超級塊,用于組織管理日志數據區域,隨后便是按順序以及一定規則存放的各次事務日志數據。一次事務的日志數據主要由描述塊、數據塊和提交塊組成,其中描述塊標識了一份日志數據的起始位置,數據塊則存儲了日志數據內容,提交塊用于表明本次事務是一次完整的事務,在文件系統崩潰恢復時只會使用完整的事務數據。在進行文件系統崩潰恢復時,需要找到日志數據的數據塊所在原文件系統的塊地址進行回寫修復,因此日志數據中的各個數據塊與原文件系統的目標塊的對應關系就尤為重要,這種對應關系存放在描述塊中。由于數據塊數量不定,JBD2在描述塊中通過一個數據結構表明一組對應關系,該數據結構為:
typedef struct journal_block_tag_s
{
__be32 t_blocknr;
__be32 t_flags;
__be32 t_blocknr_high;
} journal_block_tag_t;
該結構體通過其在描述塊中序號標識代表的數據塊號,通過t_blocknr字段標識對應的原文件系統塊地址。每個描述塊中都包含了一個或多個journal_block_tag_t結構體用于表明本次事務日志數據中各數據塊對應的文件系統原始位置。
閃存轉換層(Flash Translation Layer,簡稱FTL)是一種通過塊設備模擬方式實現閃存設備存儲系統的技術。將底層NAND閃存介質的管理及操作封裝起來,為文件系統提供塊設備讀寫接口,從而讓文件系統訪問NAND型閃存就像訪問傳統機械硬盤一樣[11]。閃存轉換層的功能主要有兩點:地址映射及垃圾回收。一般情況下,閃存轉換層通過維護兩個靜態表來完成它的功能[12],如圖2所示。

圖2 閃存轉換層結構圖
閃存轉換層通過其內部維護的地址映射表和空間管理表來管理邏輯地址轉換以及閃存的物理空間。當文件系統通過塊設備讀寫接口讀寫塊設備時,由閃存設備接收對邏輯區塊地址的讀寫請求,根據讀寫請求中的邏輯區塊地址,在閃存轉換層中通過地址映射表找到對應的物理區塊地址進行訪問,這就是閃存轉換層的地址映射功能。垃圾回收即對閃存中的無用數據進行回收,閃存轉換層指定一個閃存塊進行垃圾回收,通過空間管理表中的頁面狀態判斷當前頁中的數據是否需要保留,對需要保留的數據頁(Live,頁面狀態中記錄了物理頁面對應的邏輯區塊地址)暫時拷貝至緩存或其他區域,等待塊擦除完成再次寫入原位置,對于處于已經無用的數據頁面(頁面狀態為dead)則無需拷貝,直接擦除[13]。
EXT4文件系統掛載時對塊設備劃分的日志數據區域是對邏輯區塊地址的劃分,即針對閃存轉換層維護的地址映射表中邏輯區塊地址進行了通用數據區域與日志數據區域的劃分。但是當實際數據同步至閃存設備時,邏輯區塊地址實際映射的閃存物理地址是根據閃存設備自身損耗均衡等機制確定并建立映射的,這樣就會導致在EXT4文件系統提出IO請求的邏輯區塊地址上,通用數據與日志數據嚴格分離,但是在閃存設備中,兩種數據卻可能是混雜在同一個閃存塊中的。
如圖3所示,日志數據區域是邏輯區塊地址范圍為100至149的區域,當EXT4文件系統開始將數據同步至閃存設備時,文件數據寫入到通用數據區域,而日志數據寫入到日志數據區域,兩個區域都是連續且嚴格分離的,但是數據寫入到閃存設備具體頁時,數據會由閃存設備根據自身的策略選擇一個空白頁進行寫入,這就導致了在一個閃存設備的物理塊中,日志數據的頁與通用數據的頁是混雜的。

圖3 通用數據及日志數據存儲狀況
EXT4文件系統通過JBD2將日志數據提交到日志數據區域,JBD2軟件通過函數jbd2_journal_next_lob_block函數獲取下一個可寫入的邏輯區塊地址,此函數的實現決定了日志數據以何種順序記錄在日志數據區域中。 jbd2_journal_next_log_block函數中由j_head變量作為日志數據區域的寫指針,用于指向下一個可寫的邏輯區塊地址,在每次寫入一個邏輯塊后通過自增的方式改變寫指針位置。當指針指向日志數據區域尾部即日志數據區域全部寫滿后,指針會重新指向日志數據區域頭部,即日志數據再次從區域頭部開始寫入。采用這樣方式能夠利用傳統機械硬盤的可覆寫特性,不對以往寫入的日志數據執行刪除操作,直接覆蓋寫入新的日志數據。如圖4所示。

圖4 JBD2日志數據區域循環結構原理
根據以上情況可以看出,EXT4文件系統可以在日志數據區域不斷的循環寫入日志數據,在滿足日志數據寫指針到達日志數據區域尾部之前,日志數據不會主動刪除,對于閃存設備而言,這些數據隨機分散在閃存設備的各個塊中,并且與通用數據混雜在一起,閃存設備進行垃圾回收時,這些數據所在頁的狀態仍為Live,導致閃存設備垃圾回收時仍然需要拷貝這部分無用日志數據,造成文件系統讀寫閃存文件性能衰減的現象,本文對此問題提出相應解決方案。
本文針對以上描述的問題,提出主動刪除事務日志數據策略,根據EXT4文件系統數據同步事務處于Finished狀態時,通用數據以及日志數據已經全部寫入磁盤的含義,結合JBD2日志數據區域循環結構的特性,在事務狀態變為Finished時記錄本次事務日志數據的結束邏輯區塊地址,多次數據同步事務的過程中,通過上次事務與本次事務保存下來的邏輯區塊地址確定本次事務的日志數據位置,進行主動刪除操作。對于開啟日志功能的EXT4文件系統,優化后單次數據同步操作的基本流程如圖5所示。

圖5 優化后EXT4單次數據同步事務流程
通過多次數據同步事務中對圖5中描述的流程不斷循環,達到及時刪除無用日志數據的目的,消除因日志功能導致的EXT4文件系統讀寫性能衰減問題。根據事務的Finished狀態記錄下本次事務日志數據的結束邏輯區塊地址,同時檢查是否存在有效的上次事務日志數據的結束邏輯區塊地址,若存在,則兩地址之間的頁保存了本次事務的日志數據,將這段邏輯區域地址對應的閃存物理頁面無效化,從而將日志數據刪除;若不存在,則不進行閃存頁面無效化操作,本次事務保存的地址在下次事務時標記了日志數據的起始區塊地址,從而實現下次事務的日志數據刪除操作。

圖6 主動刪除事務日志數據策略原理
如圖6所示,在日志數據區域中,事務日志數據的主動刪除策略通過j_invalid_begin與j_invalid_end兩個變量記錄事務日志數據的邏輯區塊地址,將日志數據刪除,完成后將j_invalid_end向后移動,作為下次刪除操作的起始位置。當日志數據的刪除指針到達日志數據區域尾部時,采取與日志循環寫入結構相同的策略,刪除指針重新指向日志數據區域頭部。
本文為EXT4文件系統的日志功能實現了一個額外的循環結構,將不會再被使用到的日志數據刪除,無用的日志數據基于事務Finished狀態進行刪除,Finished狀態即表示正式數據已經寫入完畢,不再需要該事務的日志數據預防宕機、EXT4文件系統崩潰等情況,因此不會出現有用的日志數據被刪除的情況,保證系統穩定性的同時提高文件系統讀寫性能。
為驗證本文提出的EXT4文件系統日志功能優化方案,進行實機測試比較,所用機型為Samsung Galaxy S5,具體環境參數如表2所示。

表2 測試環境
對Linux內核修改后編譯并移植至測試機器中,進行相應測試。
首先通過A1 SD Bench進行測試,這是一款Android手機存儲性能測試工具,能夠測試手機內置閃存、RAM等設備的性能。執行50次A1 SD Bench閃存性能測試,每次分別進行100秒讀取及寫入操作,統計讀取與寫入的數據量計算出對閃存讀取速度與寫入速度。如圖7、8所示,圖中橫坐標為測試次數序號,縱坐標為讀、寫速度。
通過圖7可以看到,灰色線條表示優化前讀取速度折線圖,黑色線條則表示優化后讀取速度。優化前EXT4讀取速度范圍約為166.6 Mb/s至181.3 Mb/s,而優化后讀取速度范圍約為187.4 Mb/s至199.8 Mb/s,雖然速度存在一定波動,但是從圖中可以看出,優化后的讀取速度相比優化前有著明顯的提升。

圖7 優化前后讀取速度比較

圖8 優化前后寫入速度比較
通過圖8可以看到,與讀取速度類似,寫入速度也存在波動的現象,優化前的EXT4寫入速度范圍約為20.2 Mb/s至22.2 Mb/s,優化后的寫入速度范圍約為22.6 Mb/s至24.63 Mb/s。雖然優化前寫入速度最大值與優化后寫入速度的最小值之間的差距并不大,甚至在第18次的測試中,優化前后的寫入速度差僅為0.49 Mb/s,但是在整體折線圖的分布上,優化后寫入性能有著明顯提升。此外通過以上測試可以看出,讀取速度明顯優于寫入速度,這主要是由于Android所使用NAND閃存介質本身讀取性能遠高于寫入性能導致的。對以上測試數據進行統計計算后,本方案優化后文件系統的讀寫性能提升約11.8%。接下來編寫程序測試優化前后EXT4對不同大小文件的讀寫時間,通過O_DIRECT標志繞過文件系統緩存,對各種大小的文件分別測試10次統計平均值,測試結果如圖9所示。

圖9 不同文件大小讀寫時間測試
如圖9所示,縱坐標代表不同大小文件的讀寫速度,修改后EXT4對相同大小文件的讀寫花費的時間相比于原內核更短。在文件較小時,優化前后花費的時間差別較?。坏钱斘募^大時,優化后所花費的時間有著明顯的減少。這是因為對于小文件來說,可能觸發的垃圾回收過程較少甚至不需要進行垃圾回收,因此本方案優化效果不明顯,但是在進行大文件的讀寫時,會觸發更多的閃存垃圾回收,本方案能夠減少閃存垃圾回收中對無用日志數據的拷貝消耗,因此提升效果較為明顯。
本文提出一種提高EXT4文件系統性能優化方案,首先記錄數據同步事務處于Finished狀態時日志數據的邏輯區塊地址,結合上一事務記錄下的邏輯區塊地址,令本次日志數據所在閃存物理頁面無效,最后在垃圾回收時清除閃存設備的無用日志數據,從而避免日志數據的冗余拷貝。
通過實驗對比,本文方法能夠減輕閃存設備因日志數據造成的“寫放大”現象,同時能夠在增強EXT4文件系統讀寫效率的同時,延長閃存設備的使用壽命。
在本文研究基礎上,下一步研究工作主要有以下幾個方面,考慮除日志數據以外導致Android存儲性能下降的其他因素,例如針對SQLite與EXT4的日志記錄不協調問題進行優化研究等,實現Android I/O棧從應用程序至底層硬件設備的一整套優化方案,進一步提高Android智能手機的存儲性能。