1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
|
---
category: tool
tool: zfs
contributors:
- ["sarlalian", "http://github.com/sarlalian"]
translators:
- ["Alan Cheng", "https://github.com/kedaio"]
filename: LearnZfs-cn.txt
lang: zh-cn
---
[ZFS](http://open-zfs.org/wiki/Main_Page)
是重新思考与储存相关技术的结果,它把传统的文件系统和卷管理器集成到一个工具当中.
ZFS不但有把它和传统存储系统分开来的特有术语,也有很多聚焦于可用性的功能。
## ZFS概念
### 虚拟设备(Virtual Devices,VDEV)
对于操作系统来说,VDEV和传统的RAID阵列卡所呈现的raid设备类似。VDEV有几种不同的类型,每种类型
都有自己的优势,包括冗余和速度。一般来说,VDEV的可靠性和安全性比阵列卡要好。因此使用ZFS时不
建议使用阵列卡。让ZFS直接管理磁盘。
VDEV的类型
* 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](https://en.wikipedia.org/wiki/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))
```bash
# 创建一个raidz类型的存储池(名称为bucket)
$ zpool create zroot 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 (存储池状态)
```bash
# 获取全部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 (存储池属性)
```bash
# 获取某一存储池的全部属性。属性可能是系统提供,也可能是用户设置
$ 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 (删除存储池)
```bash
$ zpool destroy test
```
### Datasets (数据集)
Actions: (数据集相关操作)
* Create (创建)
* List (列举)
* Rename (重命名)
* Delete (删除)
* Get/Set properties (获取/设置属性)
Create datasets
```bash
# 创建数据集
$ zfs create zroot/root/data
$ mount | grep data
zroot/root/data on /data (zfs, local, nfsv4acls)
# 创建子数据集
$ zfs create zroot/root/data/stuff
$ mount | grep data
zroot/root/data on /data (zfs, local, nfsv4acls)
zroot/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
zroot/win_vm 4.13G 17.9G 64K -
```
List datasets (列举数据集)
```bash
# 列出所有数据集
$ 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 (重命名数据集)
```bash
$ zfs rename zroot/root/home zroot/root/old_home
$ zfs rename zroot/root/new_home zroot/root/home
```
Delete dataset (删除数据集)
```bash
# 数据集如果有快照则无法删除
$ zfs destroy zroot/root/home
```
Get / set properties of a dataset (获取/设置数据集属性)
```bash
# 获取数据集全部属性
$ zfs get all zroot/usr/home
NAME PROPERTY VALUE SOURCE
zroot/home type filesystem -
zroot/home creation Mon Oct 20 14:44 2014 -
zroot/home used 11.9G -
zroot/home available 94.1G -
zroot/home referenced 11.9G -
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和快照的区别可参看[这里](http://docs.oracle.com/cd/E19253-01/819-5461/gbcxz/index.html))
Create snapshots (创建快照)
```bash
# 为单一数据集创建快照
zfs snapshot zroot/home/sarlalian@now
# 为数据集及其子集创建快照
$ zfs snapshot -r zroot/home@now
$ zfs list -t snapshot
NAME USED AVAIL REFER MOUNTPOINT
zroot/home@now 0 - 26K -
zroot/home/sarlalian@now 0 - 259M -
zroot/home/alice@now 0 - 156M -
zroot/home/bob@now 0 - 156M -
...
```
Destroy snapshots (删除快照)
```bash
# 如何删除快照
$ zfs destroy zroot/home/sarlalian@now
# 删除某一数据集及其子集的快照
$ zfs destroy -r zroot/home/sarlalian@now
```
Renaming Snapshots (重命名)
```bash
# 重命名快照
$ zfs rename zroot/home/sarlalian@now zroot/home/sarlalian@today
$ zfs rename zroot/home/sarlalian@now today
$ zfs rename -r zroot/home@now @yesterday
```
Accessing snapshots (访问快照)
```bash
# cd进入一个快照目录
$ cd /home/.zfs/snapshot/
```
Sending and Receiving
```bash
# 备份快照到一个文件
$ zfs send zroot/home/sarlalian@now | gzip > backup_file.gz
# 发送快照到另一个数据集
$ zfs send zroot/home/sarlalian@now | zfs recv backups/home/sarlalian
# 发送快照到一个远程主机
$ zfs send zroot/home/sarlalian@now | ssh root@backup_server 'zfs recv zroot/home/sarlalian'
# 发送完整数据集及其快照到一个新主机
$ zfs send -v -R zroot/home@now | ssh root@backup_server 'zfs recv zroot/home'
```
Cloneing Snapshots (克隆快照)
```bash
# 克隆一个快照
$ zfs clone zroot/home/sarlalian@now zroot/home/sarlalian_new
# 提升克隆,让它不再依赖原始快照
$ zfs promote zroot/home/sarlalian_new
```
### 汇总
下面这个脚本使用了FreeBSD, jails和ZFS,来自动在一个mysql群集的热备主机上为一个mysq staging数据库
创建一份纯净的拷贝。
```bash
#!/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](http://www.bsdnow.tv/tutorials/zfs)
* [FreeBSD Handbook on ZFS](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/zfs.html)
* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs)
* [Oracle's Tuning Guide](http://www.oracle.com/technetwork/articles/servers-storage-admin/sto-recommended-zfs-settings-1951715.html)
* [OpenZFS Tuning Guide](http://open-zfs.org/wiki/Performance_tuning)
* [FreeBSD ZFS Tuning Guide](https://wiki.freebsd.org/ZFSTuningGuide)
|