定時任務自動維護Btrfs
開場白
如果你看過原子能的這一部影片(违背祖宗的软件设计【让编程再次伟大#17】)的話,你應該會瞥到一眼,那就是符合UNIX原則的cron。而這個cron是一個符合KISS原則的自動定時任務,我推薦去看這個文章——〈Linux-crontab 排程(定時任務)〉,而這個組件確實十分簡單,基礎應用教學一句話就結束了,如下:
分鐘(0-59)
│ 小時(0-23)
│ │ 日(1-31)
│ │ │ 月(1-12)
│ │ │ │ 星期 (0-7,其中0與7皆為星期日)
│ │ │ │ │
* * * * * command
那麼,我是要來用cron來為我的Btrfs設定一個自動化的維護嗎?其實也不是,我講的cron只是一個引子,而且這個組件在debian裡面,cron算是一個非必要的依賴(如果你是用systemd的,基本不需要)。我想要介紹相對簡單的做法,我們只需要稍微修改一下配置文件,我們就可以執行這個自動化任務。
安裝Btrfsmaintemance(針對Debian、Ubuntu)
我們打開終端機,執行一下下列命令完成安裝。
sudo apt install btrfsmaintenance
修改設定檔
- 使用你喜歡的編輯器打開,我是用nano。
sudo nano /etc/default/btrfsmaintenance
- 我的掛載點。
我講一下我的掛載點,接著我在來講要注意的事。可以得知,我的電腦除了ESP,剩下的就是一大塊的Btrfs分區(原因再這篇),而首要掛載點是/。我這裡要說一下,一般來說,btrfs有預設的掛載的子卷,以我來說,這就是@子卷,這個子卷對應的掛載點就是根目錄(/),因為這個level的數字最小,是屬於top level。後面我僅會列舉我有在用的參數。
xjd@XJD:~$ lsblk -T
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 476.9G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot/efi
└─nvme0n1p2 259:2 0 476.4G 0 part /var/log
/home
/var/cache
/
xjd@XJD:~$ sudo btrfs su list /
ID 256 gen 11570 top level 5 path @
ID 257 gen 11570 top level 5 path @home
ID 258 gen 11570 top level 5 path @var_log
ID 259 gen 11394 top level 5 path @var_cache
...
xjd@XJD:~$ sudo btrfs subvolume get-default /
ID 5 (FS_TREE)
xjd@XJD:~$ sudo btrfs subvolume get-default
- 碎片重組的掛載點。
預設是auto,我也推薦是auto。如果你是用auto,那麼只會碎片重組有被掛載的子卷,因此,如果有些設備、子卷是不會被自動掛載的,你需要手動添加。
預設
BTRFS_DEFRAG_PATHS="auto"
可以手動添加,例如這個是添加到/mnt下面的一個裝置
BTRFS_MOUNT_POINTS="/ /mnt/backup_disk"
- 重組週期。
一般來說,一個月一次就夠了,甚至,如果你是用SSD用戶,也可以考慮不要,但是基於btrfs的特性,我會推薦久久一次,太頻繁的畫會增加寫入次數,太少的話,因為寫時複製的特性,難免有些碎片化。
BTRFS_DEFRAG_PERIOD="none"
- 設定要進行負載均衡(btrfs balance)的掛載點。
設定方式同第3.步。有趣的是,btrfs的balance是一個很重要的功能,假設btrfs要在一個新的磁區上寫入資料,btrfs會先請求一個區塊(一般來說是1GB左右)作為這個子卷寫入資料的地方,如果滿了就再申請依此類推,基於寫時複製的特性,這麼做可以方便做快照、保留舊的資料(寫時複製通俗點說,就是不同的進程可以讀取同一塊資料,倘若A進程像要修改,那麼A進程就複製一份自己修改,這就是所謂的寫時複製,就是「要修改時,再複製一份」),但是,有些資料已經用不到、被刪掉了,而這些區塊的利用率會不足,這就是所謂的寫入碎片(這和磁區碎片不一樣),我們可以用balance來合併這些利用率不高的區塊,進而提升空間利用率。
這裡就要再提一嘴,既然你大致知道了寫入碎片,那麼,你在使用虛擬機時,你應該把虛擬機的目錄關掉寫時複製,以免大量讀寫、浪費空間,日後還需要花大量時間回收那些空間。還油,如果電腦的效能允許的話,我會推薦打開透明壓縮,我用zstd算法是打開3倍壓縮,儘量減少要寫入的量。再更甚者,如果你真的很在意寫入次數、影碟壽命、資料安全,你應該多備份,然後改用LVM+ext4。
BTRFS_BALANCE_MOUNTPOINTS="auto"
- 設定負載均衡的週期。
預設是一個月一次,我也就保持,你可以依照喜好設定,但也不推薦太頻繁,以免增加讀寫、IO負載。
BTRFS_BALANCE_PERIOD="monthly"
- 設定回收利用率。
我們需要設定回收(執行balance)的區塊的使用率要小於多少才可以執行,這個數字我們不會設定太大,以免頻繁回收,但也不應該太小,不然就沒有效果,我是覺得看個人,我是回收利用率不到15%的區塊。DUAGE是資料本身寫入區塊的回收,而MUSAGE是Metadata的寫入區塊的回收,我一併設定好。
BTRFS_BALANCE_DUSAGE="5 10 15"
BTRFS_BALANCE_MUSAGE="5 10 15"
- 資料校驗。
這應該也算是Btrfs的主打,就是校驗資料和,如果壞了一兩個bits,可以反推回去進而還原資料、保護資料,當然,壞掉大面積,那麼這個機制基本就很有限。一樣,我們就使用自動偵測要校驗的分區,並且一個月校驗一次,且利用閒置時校驗。
BTRFS_SCRUB_MOUNTPOINTS="auto"
BTRFS_SCRUB_PERIOD="monthly"
BTRFS_SCRUB_PRIORITY="idle"
- TRIM。
如果你是用SSD的話(HDD就不用設定,因為不適用這個參數),那麼你一定需要TRIM這個指令,用來向硬碟標示那些區塊是用不到、可以寫入新資料覆蓋的磁區,這個我推薦頻率可以比重組再高一些。一樣,設定好掛載點後,就是週期,我是一週一次。如果你的電腦已經有排程的話,那我推薦選none。
BTRFS_TRIM_MOUNTPOINTS="auto"
BTRFS_TRIM_PERIOD="weekly"
- 啟動這個服務。
sudo systemctl restart btrfsmaintenance-refresh.service
尾聲
我這裡介紹btrfsmaintenance,是因為有成熟的配置文件可以直觀地設定,當然,那些參數其實都有對應的命令,你可以用cron來寫一個,而我只是接著cron來說一個定時任務的應用。還有,我在發佈完沒多久做了一點修改。