Mua hàng tại Link Shopee hoặc Hotline 0345-148-136.

Hệ thống tệp ZFS và các bản sao lưu đơn giản

bởi

trong

Nội dung viết về Hệ thống tệp ZFS và cách sử dụng nó trong máy chủ gia đình (home server) để sao lưu và phục hồi. Các thông tin chủ yếu phục vụ mục đích sao lưu và phục hồi.

Vì lý do ZFSBootMenu chưa ổn định (on Void Linux – a Rolling Release Linux Distribution) nên chúng tôi vẫn dùng Btrfs trên máy chủ Void Linux một ổ cứng. ZFS là lựa chọn hợp lý hơn khi:

  • Không chạy ZFS trên rootfs (Root filesystem)
  • Chạy trên các bản phân phối Linux phát hành tiêu chuẩn (Standard Release Linux Distribution)
  • Chạy trên nhiều ổ cứng với RAID (Redundant Arrays of Inexpensive Disks / Redundant Arrays of Independent Disks)

ZFS là một hệ thống tệp nâng cao được thiết kế để giải quyết các vấn đề lớn được tìm thấy trong phần mềm hệ thống con lưu trữ trước đó.

1. Các thành phần

1.1. vdev

Một vdev bao gồm một hoặc nhiều ổ đĩa vật lý (cũng có thể là những thứ khác ngoài ổ cứng, như tệp). Chúng có thể được kết hợp với nhau trong máy nhân bản hoặc RAIDZ.

1.2. Pool

Một pool bao gồm một hoặc nhiều vdev và chúng thường chứa một volume hoặc dataset (mà bạn tạo sau khi tạo pool). Bạn tạo/xác định vdev của mình khi tạo một pool (bằng lệnh zpool mà chúng ta sẽ thấy sau). Điều này cho phép bạn kết hợp các loại vdev với nhau để đạt được các cấp độ RAIDZ khác (xem ví dụ bên dưới):

1.3. Dataset

Dataset là phần hệ thống tệp của ZFS (cho đến nay chúng ta đã thấy các thành phần LVM). Tại đây bạn có thể xác định quyền truy cập của người dùng, hạn ngạch, nén, snapshot, v.v.

1.4. Volume

Volume là anh em của dataset nhưng ở dạng biểu diễn thiết bị khối. Nó cung cấp một số tính năng mà dataset có, nhưng không phải tất cả. Các ổ đĩa có thể hữu ích để chạy các hệ thống tệp khác trên ZFS hoặc để xuất các phạm vi iSCSI.

2. Các loại RAIDZ

  • Dynamic/Simple Stripe (RAID0) – Phân phối dữ liệu không có tính chẵn lẻ. Mất máy đồng nghĩa với việc mất toàn bộ dữ liệu
  • MIRROR (RAID1) – Ổ đĩa được nhân đôi. Dùng với 2 đến 4 đĩa (hoặc nhiều hơn)
  • RAIDZ-1 (RAID5) – Phân phối tính chẵn lẻ cùng với dữ liệu và có thể mất một ổ đĩa vật lý trước khi xảy ra đột kích. RAIDZ yêu cầu ít nhất 3 đĩa
  • RAIDZ-2 (RAID6) – Phân phối tính chẵn lẻ cùng với dữ liệu và có thể mất tới 2 ổ đĩa vật lý. RAIDZ-2 yêu cầu ít nhất 4 đĩa
  • RAIDZ-3 – Phân phối tính chẵn lẻ cùng với dữ liệu và có thể mất tới 3 ổ đĩa vật lý. RAIDZ-3 yêu cầu ít nhất 4, nhưng nên sử dụng ít nhất 5 đĩa

3. Cài đặt

ZFS có trong repo của hầu hết các bản phân phối phổ biến. Ở đây chúng tôi sẽ sử dụng một máy chủ chạy Debian.

Để cài đặt ZFS chạy lệnh sau:

# apt update
# apt install dpkg-dev linux-headers-generic linux-image-generic
# apt install zfs-dkms zfsutils-linux

Kiểm tra xem ZFS đã cài đặt chưa:

$ sudo zpool status

4. Pool

ZFS được những người tạo ra nó coi là hệ thống tệp “không quản trị”; do đó, việc định cấu hình ZFS rất đơn giản. Việc cấu hình được thực hiện chủ yếu bằng hai lệnh: zfs và zpool.

4.1. Xác định đĩa

OpenZFS khuyến nghị sử dụng ID thiết bị khi tạo nhóm lưu trữ ZFS dưới 10 thiết bị. Sử dụng Persistent block device naming#by-id và by-path để xác định danh sách các ổ đĩa sẽ được sử dụng cho nhóm ZFS.

ID đĩa sẽ trông giống như sau:

# ls -lh /dev/disk/by-id/
---
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0JKRR -> ../../sdc
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0JTM1 -> ../../sde
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0KBP8 -> ../../sdd
lrwxrwxrwx 1 root root  9 Aug 12 16:26 ata-ST3000DM001-9YN166_S1F0KDGY -> ../../

4.1.1. Sử dụng GPT label:

Các ổ đĩa được phân vùng bằng GPT có nhãn và UUID, để xem chúng chạy lệnh sau.

# ls -l /dev/disk/by-partlabel
# ls -l /dev/disk/by-partuuid

Để tạo một non-redundant pool đơn giản bằng một thiết bị đĩa đơn:

4.2. Tạo ZFS pool

Để tạo ZFS pool:

# zpool create -m <mount> <pool> [raidz(2|3)|mirror] <ids>
  • create: Lệnh phụ để tạo pool.
  • -m: Điểm gắn kết của pool. Nếu điều này không được chỉ định thì pool sẽ được gắn vào /<pool>.
  • pool: Tên của pool
  • raidz(2|3)|mirror: RAID level
  • ids: ID của ổ đĩa hoặc phân vùng sẽ được đưa vào pool.

Xem chi tiết zpool create tại đây. Tham khảo RAID levels tại đây.

Vài ví dụ cụ thể như sau:

4.2.1. Tạo pool đĩa đơn

Để tạo một non-redundant pool đơn giản bằng một thiết bị đĩa đơn:

# zpool create ten_pool sda

4.2.2. Tạo pool lưu trữ RAID-Z

Lệnh sau tạo một nhóm có một vdev gốc raidz duy nhất bao gồm sáu đĩa:

# zpool create ten_pool raidz sda sdb sdc sdd sde sdf

4.2.3. Tạo một pool lưu trữ được nhân bản

Lệnh sau tạo một nhóm có hai nhân bản (RAID 1), trong đó mỗi nhân bản (RAID 1) chứa hai đĩa:

# zpool create ten_pool mirror sda sdb mirror sdc sdd

4.3. Xác minh trạng thái pool

Nếu lệnh thành công sẽ không có kết quả đầu ra. Sử dụng lệnh mount sẽ cho thấy rằng pool đã được gắn kết. Sử dụng trạng thái zpool sẽ hiển thị rằng nhóm đã được tạo:

# zpool status -v

4.4. Xóa pool

ZFS giúp dễ dàng phá hủy pool lưu trữ được gắn, xóa tất cả siêu dữ liệu về thiết bị ZFS.

Để phá hủy pool:

# zpool destroy <ten_pool>

4.5. Liệt kê pool

# zpool list

5. Dataset

Người dùng có thể tùy ý tạo dataset trong zpool thay vì tạo thủ công các thư mục trong zpool. Dataset cho phép tăng mức độ kiểm soát (ví dụ như hạn ngạch) và snapshot. Để có thể tạo và gắn kết dataset, thư mục cùng tên không được tồn tại trước trong zpool. Để tạo một dataset, hãy sử dụng:

# zfs create <ten_pool>/<ten_dataset>

6. Snapshot

Snapshot cho phép bạn lưu trạng thái của hệ thống tệp vào thời điểm hiện tại mà không cần sao chép bộ nhớ (tệp không được sao chép). Nó gắn cờ dữ liệu hiện có là “chỉ đọc” trong khi cho phép thêm dữ liệu mới vào hệ thống tệp mà không ảnh hưởng đến các khối dữ liệu hiện có được bảo vệ bởi snapshot (toàn bộ quá trình phức tạp hơn thế này một chút).

Chúng ta hãy xem hình ảnh dưới đây làm ví dụ. Bạn có một hệ thống tệp với dữ liệu hiện có (Dữ liệu A) và bạn snapshot (Snapshot 1). Sau đó, bạn thực hiện một số thay đổi, thêm tệp mới (Dữ liệu B) và chụp một snapshot khác (Snapshot 2). Sau đó, bạn thực hiện nhiều thay đổi hơn nữa (Dữ liệu C).

Snapshot 1 bảo vệ dữ liệu gốc (Dữ liệu A), trong khi Snapshot 2 bảo vệ Thay đổi dữ liệu (B) cũng như dữ liệu gốc (Dữ liệu A). Như vậy bạn có thể xóa snapshot 1 mà dữ liệu (A) vẫn sẽ được bảo vệ.

Lưu ý: Lượng dữ liệu được sử dụng cho snapshot là rất nhỏ vì chúng tôi không sao chép tệp mà thay vào đó là khối siêu dữ liệu cấp cao nhất của hệ thống tệp cho biết chúng thuộc về snapshot.

Và đây là một số tình huống xảy ra khi bạn xóa tệp và snapshot:

Snapshot rất tốt để kiểm tra quá trình phát triển phần mềm hoặc tạo bản dự phòng an toàn trước khi nâng cấp.

6.1. Tạo snapshot

zfs snapshot create [pool/dataset@ten_snapshot]

6.2. Liệt kê snapshot

# zfs list -t snapshot

6.3. So sánh snapshot

# zfs diff [snapshot_cu] [snapshot_moi]

6.4. Phục hồi snapshot

zfs rollback [pool/dataset@ten_snapshot]

7. ZFS Send và ZFS Recv

Có thể chuyển các snapshot ZFS đến một mục tiêu tùy ý bằng cách ghép nối zfs send và zfs recv. Điều này được thực hiện thông qua đầu ra tiêu chuẩn, cho phép dữ liệu được gửi đến bất kỳ tệp, thiết bị nào, qua mạng hoặc được xử lý ở giữa luồng bằng cách kết hợp các chương trình bổ sung trong đường ống.

7.1. ZFS Send cơ bản

Trước tiên, hãy tạo snapshot của một số hệ thống tệp ZFS:

# zfs snapshot zpool0/archive/books@snap

Bây giờ hãy gửi snapshot đến một vị trí mới trên một zpool khác

# zfs send -v zpool0/archive/books@snap | zfs recv zpool4/library

Nội dung của zpool0/archive/books@snap hiện có tại zpool4/library

7.1.1. Đến và đi từ các tập tin

Ghi snapshot vào tệp gzip:

# zfs send zpool0/archive/books@snap > /tmp/mybooks.gz

Bây giờ khôi phục snapshot từ tệp:

# gzcat /tmp/mybooks.gz | zfs recv -F zpool0/archive/books

7.2. Gửi qua ssh

Chúng tôi chuyển lưu lượng “gửi” qua phiên ssh đang chạy “recv”:

# zfs send -v zpool1/filestore@snap | ssh $HOST zfs recv coldstore/backups

7.3. Sao lưu gia tăng

Bạn có thể muốn cập nhật hệ thống tệp ZFS đã gửi trước đó mà không cần truyền lại tất cả dữ liệu. Ngoài ra, có thể cần phải giữ hệ thống tệp trực tuyến trong quá trình truyền tải kéo dài và bây giờ là lúc gửi các bản ghi được thực hiện kể từ snapshot đầu tiên.

Trước tiên, hãy tạo ảnh chụp nhanh của một số hệ thống tệp ZFS:

# zfs snapshot zpool1/filestore@initial

Tiếp theo, chúng tôi chuyển lưu lượng “gửi” qua phiên ssh đang chạy “recv”:

# zfs send -v -R zpool1/filestore@initial | ssh $HOST zfs recv coldstore/backups

Khi các thay đổi được viết, hãy tạo một ảnh chụp nhanh khác:

# zfs snapshot zpool1/filestore@snap2

Phần sau đây sẽ gửi những khác biệt tồn tại cục bộ giữa zpool1/filestore@initial và zpool1/filestore@snap2 và tạo một ảnh chụp nhanh bổ sung cho kho lạnh/sao lưu hệ thống tệp từ xa:

# zfs send -v -i -R zpool1/filestore@initial | ssh $HOST zfs recv coldstore/backups

Bây giờ cả zpool1/filestore và coldstore/backups đều có ảnh chụp nhanh @initial và @snap2.

Trên máy chủ từ xa, giờ đây bạn có thể quảng bá ảnh chụp nhanh mới nhất để trở thành hệ thống tệp hoạt động:

# rollback coldstore/backups@snap2

8. Snapshot tự động

Snapshot tự động có thể lên lịch zfs snap thủ công từ cron hoặc các công cụ khác với nhiều tính năng sau đây.

  • Sanoid – These are policy-driven snapshot management and replication tools which use OpenZFS for underlying next-gen storage.
  • ZFS-autobackup – ZFS autobackup is used to periodicly backup ZFS filesystems to other locations. Easy to use and very reliable
  • ZnapZend – zfs backup with remote capabilities and mbuffer integration
  • zrepl – One-stop ZFS backup & replication solution

Ở đây chúng tôi sẽ sử dụng ZFS-autobackup để ví dụ về cách sao lưu và phục hồi dữ liệu một cách đơn giản.

8.1. Snapshot dữ liệu cần sao lưu hàng giờ

Sử dụng ZFS-autobackup Local Usage, tham khảo tại đây.

8.2. Sao lưu về máy khác hàng ngày

Tự động khởi động máy backup vào 3g sáng, sử dụng SSH pull dữ liệu về mỗi khi khởi động, tự động tắt máy khi việc sao lưu hoàn thành. Tham khảo tại đây.

Sử dụng Wake on LAN trên một máy backup và đặt lịch crontab @reboot.

8.3. Phục hồi khi gặp sự cố

Sử dụng zfs send như 7.2. Gửi qua SSH.


Bình luận

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *