SSD(固態硬碟)的優化是個老議題了,不外乎就是4K對齊、減少寫入次數並清理「髒掉的」磁區。那麼這些事項在Linux作業系統下要如何進行呢?
4K對齊
使用SSD在切割分割區時,因SSD內部最小的寫入單位是4KB(1 page),要注意分割區一定得4K對齊,不然會嚴重影響到SSD的存取效能和壽命。Linux的磁碟分割軟體,在預設情況下切割出來的分割區就已經有4K對齊了。
如果不放心的話,可以利用fdisk
工具在終端機內查看SSD分割區的起始位置的磁區數量是否能整除8
。查看的指令如下:
為什麼SSD分割區的起始位置磁區數能整除8就有4K對齊?
實際上磁區還分為真實體磁區(Physical Sector)和邏輯磁區(Logical Sector),會有這樣的區別跟後來出現的「先進格式(Advanced Format)」有關。簡單來說,以前1個磁區只有512個位元組,但是後來往上增加了,作業系統必須也要有支援邏輯磁區的功能才能正常使用。為了使得新規格的硬碟可以相容於舊的作業系統上,於是廠商便直接把「邏輯磁區」這種模擬技術直接做在硬碟上了。有了這樣的技術就可以將4K大小的磁區模擬成8個512位元組的磁區,這就是為什麼我們要讓磁區數量能整除8啦!
減少寫入次數
SSD顆粒的寫入次數是有限的,因此若我們想辦法減少SSD的寫入次數,就可以延長SSD的生命。
關閉上次存取時間的記錄
現代的檔案系統幾乎都有記錄檔案最後一次被開啟的時間的功能,也就是說,每當檔案被讀取一次,硬碟也要跟著被寫入一次,這對SSD的壽命來說是十分不友善的。在Linux下,我們可以在掛載檔案系統時,替檔案系統加上noatime
參數,來關閉「存取時間」(Access Time)的功能。
如下圖,便是直接在/etc/fstab
設定檔的options
欄位中加上noatime
參數。
有些人在加入noatime
參數時會連nodiratime
參數也一併加入,這是不必要的,因為noatime
參數已經包含了nodiratime
參數的功能。
我們原先可以利用ls
或是ll
指令,加上-u
參數,來查看檔案的上次存取時間。在加入noatime
參數之後,檔案的上次存取時間就不會被更新了。
啟用硬碟寫入快取(Write Caching)功能
Linux作業系統有內建硬碟寫入快取的功能,可以增加硬碟表面上的寫入速度,應該也可以減少硬碟的寫入次數。
hdparm
指令工具可以取得或是設定SATA或是IDE裝置的參數。注意,它不能支援NVME硬碟。
Debian系的Linux發行版安裝hdparm
的指令如下:
紅帽系的Linux發行版安裝hdparm
的指令如下:
hdparm
指令的-W
參數可以用來查看或臨時修改該裝置是否要開啟寫入快取功能,如下圖:
如果要永久更改設定,比較推薦用發行版的桌面環境自帶的工具來設定。
開啟寫入快取功能後要注意電腦不能隨便斷電,因為斷電很可能會造成檔案毀損。
把/tmp
掛在RAMDisk上
/tmp
是Linux作業系統用來存放暫存檔案的目錄,是專門給程式讀寫檔案用的位置,使用者一般不需要將這個目錄裡的檔案保存下來。將/tmp
掛在RAMDisk上,就可以直接把這些暫存檔存到記憶體中,不會寫入硬碟,而耗損硬碟的壽命,也能起到加速的作用。
紅帽系的Linux發行版似乎預設就會將/tmp
掛在RAMDisk上,如果Debian系的Linux發行版也要這樣做的話,可以使用其自帶的systemd mount unit設定檔,用法如以下指令:
清理「髒掉的」磁區
Linux常用的檔案系統為Ext4、Btrfs、XFS,它們都支援SSD的Trim功能,Trim可以使作業系統主動通知SSD哪些區塊(block)是不要的,SSD會在閒置的情況時將不要的區塊給擦除成0。為什麼要這樣做呢?因為SSD只能將資料寫入至完全淨空的Page中,如果沒有Trim,SSD在寫入資料前,不像HDD可以直接覆寫資料,它必須先擦除掉原先早已刪掉不要的的資料,而且SSD只能以區塊為單位,區塊為許多個pages組成,可能有64 pages或更多,SSD緩慢的擦除效率會連帶讓寫入效率下降,這也就是為什麼SSD用久了就愈慢的原因(變髒啦)。
就算檔案系統有支援,Linux預設也並不一定會開啟SSD的Trim功能,因為老實說它似乎並不是那麼的穩定,可能會有資料毀損的問題。
如果我們還是想要啟用SSD的Trim功能,可以選用以下兩種方式之一。
fstrim
fstrim
是Linux作業系統自帶的指令工具,可以將檔案系統中沒有用到的區塊進行擦除的動作。搭配systemd來使用,可以實現自動每週一次進行完整擦除的功能。
Linux發行版大多會內建fstrim.timer
和fstrim.service
這兩個systemd unit設定檔,且通常預設是啟用的。我們可以利用以下指令來判斷我們的fstrim.timer
有無被啟用了:
如果沒有啟用的話,可以用以下指令來永久啟用。
sudo systemctl start fstrim.timer
如果想要立刻進行擦除的話,可以直接使用以下指令:
discard
替檔案系統加上discard
參數,可以在刪除檔案時就去觸發SSD的Trim功能。在絕大部分的情況下,這個作法都是不被推薦的,因為會讓SSD的壽命快速減少。
如下圖,便是直接在/etc/fstab
設定檔的options
欄位中加上discard
參數。注意這邊有也替SWAP分割區加上discard
參數哦!
驗證Trim功能是否有成功擦除磁區
如何驗證Trim功能是否有成功擦除磁區?很簡單,就是查看被刪除的檔案原本在硬碟內的位置是不是已經被清空為0,可以使用以下方式來測試。
首先使用dd指令,建立一個亂數產生的檔案,檔名為magictest
,檔案大小為512K x 100也就是50MiB。
如果是SATA或是IDE硬碟,就可用hdparm
指令查詢這個檔案在硬碟中的位置,實際上查到的是LBA(邏輯區塊位址, Logical Block Address),輸入以下指令:
記下第一行,byte_offset
為0
的begin_LBA
,這就是magictest
這個檔案的開始位址。
如果您還不知道自己的SSD裝置是在哪個路徑下,可以用以下指令查看。
接著輸入以下指令,查看指定位址下硬碟存放的內容。
以筆者的為例:
如果執行成功,應該會看到一堆以16進制表示的數值,這就是檔案內容了。
接著輸入以下指令將magictest
檔案刪除:
如果您並不是使用discard
參數的方式來使用Trim功能,那麼在刪除magictest
檔案檔案之後要手動執行一次fstrim
。
因為Linux作業系統可能會使用記憶體來暫存實際硬碟的資料,需要使用以下指令來建議Linux作業系統將所有更變寫入至硬碟:
接著再一次使用相同的hdparm
指令查看剛才的LBA位址下的檔案內容。
如果Trim開啟成功,應該會顯示出一堆0。如果沒有的話也不必擔心,可能是SSD尚未執行Trim功能,也可能是SSD已經執行Trim功能了,但這塊空間又在短時間內被其他檔案佔用,所以可以重做幾遍看看。