博客 / 詳情

返回

Y 分鐘速成 zfs

源代碼下載: LearnZfs-cn.txt

ZFS
是重新思考與儲存相關技術的結果,它把傳統的文件系統和卷管理器集成到一個工具當中.
ZFS不但有把它和傳統存儲系統分開來的特有術語,也有很多聚焦於可用性的功能。

ZFS概念

虛擬設備(Virtual Devices,VDEV)

對於操作系統來説,VDEV和傳統的RAID陣列卡所呈現的raid設備類似。VDEV有幾種不同的類型,每種類型
都有自己的優勢,包括冗餘和速度。一般來説,VDEV的可靠性和安全性比陣列卡要好。因此使用ZFS時不
建議使用陣列卡。讓ZFS直接管理磁盤。

VDEV的類型

  • stripe (條帶。單個磁盤,沒有冗餘)
  • mirror (鏡像。支持n-way鏡像)
  • raidz

    • raidz1 (一個奇偶校驗磁盤, 類似於RAID 5)
    • raidz2 (兩個奇偶校驗磁盤, 類似於RAID 6)
    • raidz3 (三個奇偶校驗磁盤, 沒有類似RAID等級)
  • disk (磁盤)
  • file (文件。不推薦在生產環境中使用,因為中間又多了一層不必要的文件系統)

數據會以條帶方式存儲於存儲池中的所有VDEV上。因此一個存儲池中的VDEV越多,IOPS就越高。

storage pool (存儲池)

ZFS 使用存儲池來作為底層存儲提供者(VDEV)的抽象。這樣可以把用户可見的文件系統和底層的物理磁盤
佈局分離開來。

ZFS 數據集(Dataset)

ZFS 數據集類似於傳統的文件系統(譯者注:或者説是目錄),但是提供了更多的功能。ZFS的很多優勢也是
在這一層體現出來的。數據集支持 Copy on Write
快照, 配額, 壓縮和重複消除(de-duplication).

限制

一個目錄最多可包含 2^48個文件, 每個文件最大可以是16 exabytes. 一個存儲池最大可包含256 zettabytes 、
(2^78) 的空間, 可以條帶化地分佈於2^64 設備上. 單一主機最多可以創建2^64個存儲池。這些限制可以説是相
當大。

命令

存儲池

Actions: (存儲池操作)

  • List (列舉)
  • Status (查看狀態)
  • Destroy (刪除)
  • Get/Set properties (獲取/設置屬性)

List zpools (列舉存儲池(也叫zpool))

# 創建一個raidz類型的存儲池(名稱為bucket)
$ zpool create bucket raidz1 gpt/zfs0 gpt/zfs1 gpt/zfs2

# 列出所有存儲池
$ zpool list
NAME    SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
zroot   141G   106G  35.2G         -    43%    75%  1.00x  ONLINE  -

# 列出某一存儲池的詳細信息
$ zpool list -v zroot
NAME                                     SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP HEALTH  ALTROOT
zroot                                    141G   106G  35.2G         -    43%    75%  1.00x ONLINE  -
  gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655   141G   106G  35.2G         -    43%    75%

Status of zpools (存儲池狀態)

# 獲取全部zpool狀態信息
$ zpool status
  pool: zroot
 state: ONLINE
  scan: scrub repaired 0 in 2h51m with 0 errors on Thu Oct  1 07:08:31 2015
config:

        NAME                                          STATE     READ WRITE CKSUM
        zroot                                         ONLINE       0     0     0
          gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655  ONLINE       0     0     0

errors: No known data errors

# 用scrub來更正存儲池錯誤信息
$ zpool scrub zroot
$ zpool status -v zroot
  pool: zroot
 state: ONLINE
  scan: scrub in progress since Thu Oct 15 16:59:14 2015
        39.1M scanned out of 106G at 1.45M/s, 20h47m to go
        0 repaired, 0.04% done
config:

        NAME                                          STATE     READ WRITE CKSUM
        zroot                                         ONLINE       0     0     0
          gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655  ONLINE       0     0     0

errors: No known data errors

Properties of zpools (存儲池屬性)


# 獲取某一存儲池的全部屬性。屬性可能是系統提供,也可能是用户設置
$ zpool get all zroot
NAME   PROPERTY                       VALUE                          SOURCE
zroot  size                           141G                           -
zroot  capacity                       75%                            -
zroot  altroot                        -                              default
zroot  health                         ONLINE                         -
...

# 設置存儲池屬性,下例這是設置comment(備註)屬性
$ zpool set comment="Storage of mah stuff" zroot
$ zpool get comment
NAME   PROPERTY  VALUE                 SOURCE
tank   comment   -                     default
zroot  comment   Storage of mah stuff  local

Remove zpool (刪除存儲池)

$ zpool destroy test

Datasets (數據集)

Actions: (數據集相關操作)

  • Create (創建)
  • List (列舉)
  • Rename (重命名)
  • Delete (刪除)
  • Get/Set properties (獲取/設置屬性)

Create datasets

# 創建數據集
$ zfs create tank/root/data
$ mount | grep data
tank/root/data on /data (zfs, local, nfsv4acls)

# 創建子數據集
$ zfs create tank/root/data/stuff
$ mount | grep data
tank/root/data on /data (zfs, local, nfsv4acls)
tank/root/data/stuff on /data/stuff (zfs, local, nfsv4acls)


# 創建卷
$ zfs create -V zroot/win_vm
$ zfs list zroot/win_vm
NAME                 USED  AVAIL  REFER  MOUNTPOINT
tank/win_vm         4.13G  17.9G    64K  -

List datasets (列舉數據集)

# 列出所有數據集
$ zfs list
NAME                                                                       USED  AVAIL  REFER  MOUNTPOINT
zroot                                                                      106G  30.8G   144K  none
zroot/ROOT                                                                18.5G  30.8G   144K  none
zroot/ROOT/10.1                                                              8K  30.8G  9.63G  /
zroot/ROOT/default                                                        18.5G  30.8G  11.2G  /
zroot/backup                                                              5.23G  30.8G   144K  none
zroot/home                                                                 288K  30.8G   144K  none
...

# 列舉某一數據集的信息
$ zfs list zroot/home
NAME         USED  AVAIL  REFER  MOUNTPOINT
zroot/home   288K  30.8G   144K  none

# 列出快照
$ zfs list -t snapshot
zroot@daily-2015-10-15                                                                  0      -   144K  -
zroot/ROOT@daily-2015-10-15                                                             0      -   144K  -
zroot/ROOT/default@daily-2015-10-15                                                     0      -  24.2G  -
zroot/tmp@daily-2015-10-15                                                           124K      -   708M  -
zroot/usr@daily-2015-10-15                                                              0      -   144K  -
zroot/home@daily-2015-10-15                                                             0      -  11.9G  -
zroot/var@daily-2015-10-15                                                           704K      -  1.42G  -
zroot/var/log@daily-2015-10-15                                                       192K      -   828K  -
zroot/var/tmp@daily-2015-10-15                                                          0      -   152K  -

Rename datasets (重命名數據集)

$ zfs rename tank/root/home tank/root/old_home
$ zfs rename tank/root/new_home tank/root/home

Delete dataset (刪除數據集)

# 數據集如果有快照則無法刪除
zfs destroy tank/root/home

Get / set properties of a dataset (獲取/設置數據集屬性)

# 獲取數據集全部屬性
$ zfs get all  zroot/usr/home                                                                                              │157 # Create Volume
NAME            PROPERTY              VALUE                  SOURCE                                                                          │158 $ zfs create -V zroot/win_vm
zroot/home      type                  filesystem             -                                                                               │159 $ zfs list zroot/win_vm
zroot/home      creation              Mon Oct 20 14:44 2014  -                                                                               │160 NAME                 USED  AVAIL  REFER  MOUNTPOINT
zroot/home      used                  11.9G                  -                                                                               │161 tank/win_vm         4.13G  17.9G    64K  -
zroot/home      available             94.1G                  -                                                                               │162 ```
zroot/home      referenced            11.9G                  -                                                                               │163
zroot/home      mounted               yes                    -
...

# 獲取數據集屬性
$ zfs get compression zroot/usr/home
NAME            PROPERTY     VALUE     SOURCE
zroot/home      compression  off       default

# 設置數據集屬性(下例為設置壓縮屬性compression)
$ zfs set compression=gzip-9 mypool/lamb

# 列舉所有數據集的名稱、配額和預留屬性
$ zfs list -o name,quota,reservation
NAME                                                               QUOTA  RESERV
zroot                                                               none    none
zroot/ROOT                                                          none    none
zroot/ROOT/default                                                  none    none
zroot/tmp                                                           none    none
zroot/usr                                                           none    none
zroot/home                                                          none    none
zroot/var                                                           none    none
...

Snapshots (快照)

快照是ZFS 的一個非常重要的功能

  • 快照佔用的空間等於它和原始數據的差異量
  • 創建時間以秒計
  • 恢復時間和寫入速度相同
  • 易於自動化

Actions: (快照相關操作)

  • Create (創建)
  • Delete (刪除)
  • Rename (重命名)
  • Access snapshots (訪問)
  • Send / Receive (發送/接收)
  • Clone (克隆。譯者注:關於clone和快照的區別可參看這裏)

Create snapshots (創建快照)

# 為單一數據集創建快照
zfs snapshot tank/home/sarlalian@now

# 為數據集及其子集創建快照
$ zfs snapshot -r tank/home@now
$ zfs list -t snapshot
NAME                       USED  AVAIL  REFER  MOUNTPOINT
tank/home@now                 0      -    26K  -
tank/home/sarlalian@now       0      -   259M  -
tank/home/alice@now           0      -   156M  -
tank/home/bob@now             0      -   156M  -
...

Destroy snapshots (刪除快照)

# 如何刪除快照
$ zfs destroy tank/home/sarlalian@now

# 刪除某一數據集及其子集的快照
$ zfs destroy -r tank/home/sarlalian@now

Renaming Snapshots (重命名)

# 重命名快照
$ zfs rename tank/home/sarlalian@now tank/home/sarlalian@today
$ zfs rename tank/home/sarlalian@now today

# zfs rename -r tank/home@now @yesterday

Accessing snapshots (訪問快照)

# cd進入一個快照目錄
$ cd /home/.zfs/snapshot/

Sending and Receiving

# 備份快照到一個文件
$ zfs send tank/home/sarlalian@now | gzip > backup_file.gz

# 發送快照到另一個數據集
$ zfs send tank/home/sarlalian@now | zfs recv backups/home/sarlalian

# 發送快照到一個遠程主機
$ zfs send tank/home/sarlalian@now | ssh root@backup_server 'zfs recv tank/home/sarlalian'

# 發送完整數據集及其快照到一個新主機
$ zfs send -v -R tank/home@now | ssh root@backup_server 'zfs recv tank/home'

Cloneing Snapshots (克隆快照)

# 克隆一個快照
$ zfs clone tank/home/sarlalian@now tank/home/sarlalian_new

# 提升克隆,讓它不再依賴原始快照
$ zfs promote tank/home/sarlalian_new

彙總

下面這個腳本使用了FreeBSD, jails和ZFS,來自動在一個mysql羣集的熱備主機上為一個mysq staging數據庫
創建一份純淨的拷貝。

#!/bin/sh

echo "==== Stopping the staging database server ===="
jail -r staging

echo "==== Cleaning up existing staging server and snapshot ===="
zfs destroy -r zroot/jails/staging
zfs destroy zroot/jails/slave@staging

echo "==== Quiescing the slave database ===="
echo "FLUSH TABLES WITH READ LOCK;" | /usr/local/bin/mysql -u root -pmyrootpassword -h slave

echo "==== Snapshotting the slave db filesystem as zroot/jails/slave@staging ===="
zfs snapshot zroot/jails/slave@staging

echo "==== Starting the slave database server ===="
jail -c slave

echo "==== Cloning the slave snapshot to the staging server ===="
zfs clone zroot/jails/slave@staging zroot/jails/staging

echo "==== Installing the staging mysql config ===="
mv /jails/staging/usr/local/etc/my.cnf /jails/staging/usr/local/etc/my.cnf.slave
cp /jails/staging/usr/local/etc/my.cnf.staging /jails/staging/usr/local/etc/my.cnf

echo "==== Setting up the staging rc.conf file ===="
mv /jails/staging/etc/rc.conf.local /jails/staging/etc/rc.conf.slave
mv /jails/staging/etc/rc.conf.staging /jails/staging/etc/rc.conf.local

echo "==== Starting the staging db server ===="
jail -c staging

echo "==== Makes the staging database not pull from the master ===="
echo "STOP SLAVE;" | /usr/local/bin/mysql -u root -pmyrootpassword -h staging
echo "RESET SLAVE;" | /usr/local/bin/mysql -u root -pmyrootpassword -h staging

延伸閲讀

  • BSDNow's Crash Course on ZFS
  • FreeBSD Handbook on ZFS
  • BSDNow's Crash Course on ZFS
  • Oracle's Tuning Guide
  • OpenZFS Tuning Guide
  • FreeBSD ZFS Tuning Guide

有建議?或者發現什麼錯誤?在Github上開一個issue,或者發起pull request!

原著sarlalian,並由0個好心人修改。
© 2022 sarlalian
Translated by: Alan Cheng
本作品採用 CC BY-SA 3.0 協議進行許可。

user avatar b_a_r_a_n 頭像 xiaojt 頭像 xiaoping_5b9bd7cd1b5c6 頭像
3 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.