Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất

Mùa xuân này chúng ta đã thảo luận về một số chủ đề giới thiệu, ví dụ, cách kiểm tra tốc độ ổ đĩa của bạn и ĐỘT KÍCH là gì. Trong phần thứ hai, chúng tôi thậm chí còn hứa sẽ tiếp tục nghiên cứu hiệu suất của các cấu trúc liên kết đa đĩa khác nhau trong ZFS. Đây là hệ thống tệp thế hệ tiếp theo hiện đang được triển khai ở mọi nơi: từ Apple để Ubuntu.

Chà, hôm nay là ngày tốt nhất để làm quen với ZFS, những độc giả ham học hỏi. Chỉ biết rằng theo ý kiến ​​khiêm tốn của nhà phát triển OpenZFS, Matt Ahrens, "nó thực sự rất khó."

Nhưng trước khi chúng ta đi đến những con số - và tôi hứa chúng sẽ như vậy - đối với tất cả các tùy chọn cho cấu hình ZFS tám đĩa, chúng ta cần nói về như Nói chung, ZFS lưu trữ dữ liệu trên đĩa.

Zpool, vdev và thiết bị

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Sơ đồ nhóm đầy đủ này bao gồm ba vdev phụ trợ, một cho mỗi lớp và bốn cho RAIDz2

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Thường không có lý do gì để tạo một nhóm các loại và kích cỡ vdev không khớp - nhưng không có gì ngăn cản bạn làm như vậy nếu bạn muốn.

Để thực sự hiểu hệ thống tệp ZFS, bạn cần xem xét kỹ cấu trúc thực tế của nó. Đầu tiên, ZFS thống nhất các mức quản lý hệ thống tệp và âm lượng truyền thống. Thứ hai, nó sử dụng cơ chế sao chép khi ghi giao dịch. Các tính năng này có nghĩa là hệ thống có cấu trúc rất khác so với các hệ thống tệp và mảng RAID thông thường. Tập hợp các khối xây dựng cơ bản đầu tiên cần hiểu là nhóm lưu trữ (zpool), thiết bị ảo (vdev) và thiết bị thực (thiết bị).

zpool

Nhóm lưu trữ zpool là cấu trúc ZFS trên cùng. Mỗi nhóm chứa một hoặc nhiều thiết bị ảo. Đổi lại, mỗi người trong số họ chứa một hoặc nhiều thiết bị thực (thiết bị). Nhóm ảo là các khối khép kín. Một máy tính vật lý có thể chứa hai hoặc nhiều nhóm riêng biệt, nhưng mỗi nhóm hoàn toàn độc lập với các nhóm khác. Nhóm không thể chia sẻ thiết bị ảo.

Sự dư thừa của ZFS ở cấp độ thiết bị ảo, không phải ở cấp độ nhóm. Hoàn toàn không có dự phòng ở cấp nhóm - nếu bất kỳ ổ đĩa vdev hoặc vdev đặc biệt nào bị mất, thì toàn bộ nhóm sẽ bị mất cùng với nó.

Nhóm lưu trữ hiện đại có thể tồn tại khi mất bộ đệm hoặc nhật ký thiết bị ảo - mặc dù chúng có thể mất một lượng nhỏ dữ liệu bẩn nếu mất nhật ký vdev trong khi mất điện hoặc sự cố hệ thống.

Có một quan niệm sai lầm phổ biến rằng "sọc dữ liệu" ZFS được ghi trên toàn bộ nhóm. Đây không phải là sự thật. Zpool không buồn cười RAID0 chút nào, nó khá buồn cười JBOD với một cơ chế phân phối biến phức tạp.

Phần lớn, các bản ghi được phân phối giữa các thiết bị ảo có sẵn theo không gian trống có sẵn, vì vậy về lý thuyết, tất cả chúng sẽ được lấp đầy cùng một lúc. Trong các phiên bản sau của ZFS, mức sử dụng (sử dụng) vdev hiện tại được tính đến - nếu một thiết bị ảo bận rộn hơn đáng kể so với thiết bị ảo khác (ví dụ: do tải đọc), thì thiết bị đó sẽ tạm thời bị bỏ qua để ghi, mặc dù có mức miễn phí cao nhất. tỷ lệ không gian.

Cơ chế phát hiện sử dụng được tích hợp trong các phương pháp phân bổ ghi ZFS hiện đại có thể giảm độ trễ và tăng thông lượng trong thời gian tải cao bất thường - nhưng không phải vậy carte blanche về việc vô tình trộn lẫn ổ cứng chậm và ổ SSD nhanh trong một nhóm. Một nhóm không đồng đều như vậy sẽ vẫn hoạt động ở tốc độ của thiết bị chậm nhất, nghĩa là, như thể nó hoàn toàn bao gồm các thiết bị như vậy.

vdev

Mỗi nhóm lưu trữ bao gồm một hoặc nhiều thiết bị ảo (thiết bị ảo, vdev). Đổi lại, mỗi vdev chứa một hoặc nhiều thiết bị thực. Hầu hết các thiết bị ảo được sử dụng để lưu trữ dữ liệu đơn giản, nhưng có một số lớp trình trợ giúp vdev, bao gồm CACHE, LOG và SPECIAL. Mỗi loại vdev này có thể có một trong năm cấu trúc liên kết: thiết bị đơn (single-device), RAIDz1, RAIDz2, RAIDz3, hoặc máy nhân bản (mirror).

RAIDz1, RAIDz2 và RAIDz3 là những biến thể đặc biệt của cái mà những người xưa gọi là RAID chẵn lẻ kép (đường chéo). 1, 2 và 3 đề cập đến số lượng khối chẵn lẻ được phân bổ cho mỗi dải dữ liệu. Thay vì các đĩa riêng biệt cho tính chẵn lẻ, các thiết bị ảo RAIDz phân phối tính chẵn lẻ này bán đồng đều trên các đĩa. Một mảng RAIDz có thể mất nhiều đĩa như nó có các khối chẵn lẻ; nếu nó mất một cái khác, nó sẽ bị sập và mang theo nhóm lưu trữ.

Trong các thiết bị ảo được nhân đôi (mirror vdev), mỗi khối được lưu trữ trên mỗi thiết bị trong vdev. Mặc dù gương hai chiều là phổ biến nhất, bất kỳ số lượng thiết bị tùy ý nào cũng có thể nằm trong gương - bộ ba thường được sử dụng trong các cài đặt lớn để cải thiện hiệu suất đọc và khả năng chịu lỗi. Một máy nhân bản vdev có thể sống sót sau bất kỳ sự cố nào miễn là ít nhất một thiết bị trong vdev tiếp tục hoạt động.

Các vdev độc thân vốn đã nguy hiểm. Một thiết bị ảo như vậy sẽ không tồn tại sau một lần hỏng hóc - và nếu được sử dụng làm bộ lưu trữ hoặc một vdev đặc biệt, thì sự cố của nó sẽ dẫn đến sự phá hủy toàn bộ nhóm. Hãy rất, rất cẩn thận ở đây.

CACHE, LOG và VA ĐẶC BIỆT có thể được tạo bằng cách sử dụng bất kỳ cấu trúc liên kết nào ở trên - nhưng hãy nhớ rằng việc mất VA ĐẶC BIỆT có nghĩa là mất nhóm, do đó, cấu trúc liên kết dự phòng rất được khuyến khích.

thiết bị

Đây có lẽ là thuật ngữ dễ hiểu nhất trong ZFS - nó thực sự là một thiết bị truy cập ngẫu nhiên theo khối. Hãy nhớ rằng các thiết bị ảo được tạo thành từ các thiết bị riêng lẻ, trong khi một nhóm được tạo thành từ các thiết bị ảo.

Đĩa - ở trạng thái từ tính hoặc rắn - là thiết bị khối phổ biến nhất được sử dụng làm khối xây dựng của vdev. Tuy nhiên, bất kỳ thiết bị nào có bộ mô tả trong /dev đều được, vì vậy toàn bộ mảng RAID phần cứng có thể được sử dụng làm thiết bị riêng biệt.

Tệp thô đơn giản là một trong những thiết bị khối thay thế quan trọng nhất mà vdev có thể được tạo từ đó. Nhóm thử nghiệm từ tập tin thưa thớt là một cách rất tiện dụng để kiểm tra các lệnh nhóm và xem có bao nhiêu dung lượng có sẵn trong một nhóm hoặc thiết bị ảo của một cấu trúc liên kết nhất định.

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Bạn có thể tạo một nhóm thử nghiệm từ các tệp thưa thớt chỉ trong vài giây - nhưng đừng quên xóa toàn bộ nhóm và các thành phần của nó sau đó

Giả sử bạn muốn đặt một máy chủ trên tám ổ đĩa và dự định sử dụng ổ đĩa 10 TB (~9300 GiB) - nhưng bạn không chắc cấu trúc liên kết nào phù hợp nhất với nhu cầu của mình. Trong ví dụ trên, chúng tôi xây dựng nhóm thử nghiệm từ các tệp thưa thớt trong vài giây - và bây giờ chúng tôi biết rằng RAIDz2 vdev gồm tám đĩa 10 TB cung cấp 50 TiB dung lượng khả dụng.

Một loại thiết bị đặc biệt khác là SPARE (phụ tùng). Các thiết bị có thể hoán đổi nóng, không giống như các thiết bị thông thường, thuộc về toàn bộ nhóm chứ không thuộc về một thiết bị ảo nào. Nếu một vdev trong nhóm bị lỗi và một thiết bị dự phòng được kết nối với nhóm và khả dụng, thì thiết bị đó sẽ tự động tham gia cùng vdev bị ảnh hưởng.

Sau khi kết nối với vdev bị ảnh hưởng, thiết bị dự phòng bắt đầu nhận các bản sao hoặc bản tái tạo dữ liệu lẽ ra phải có trên thiết bị bị thiếu. Trong RAID truyền thống, điều này được gọi là xây dựng lại, trong khi ở ZFS, nó được gọi là phục hồi.

Điều quan trọng cần lưu ý là các thiết bị dự phòng không thay thế vĩnh viễn các thiết bị bị lỗi. Đây chỉ là sự thay thế tạm thời để giảm thời gian vdev bị xuống cấp. Sau khi quản trị viên thay thế vdev bị lỗi, tính năng dự phòng sẽ được khôi phục cho thiết bị cố định đó và SPARE bị ngắt kết nối khỏi vdev và quay trở lại hoạt động như một thiết bị dự phòng cho toàn bộ nhóm.

Tập dữ liệu, khối và lĩnh vực

Tập hợp các khối xây dựng tiếp theo cần hiểu trên hành trình ZFS của chúng tôi không phải là về phần cứng mà là về cách tổ chức và lưu trữ dữ liệu. Chúng tôi đang bỏ qua một vài cấp độ ở đây - chẳng hạn như metaslab - để không làm lộn xộn các chi tiết trong khi vẫn duy trì sự hiểu biết về cấu trúc tổng thể.

Bộ dữ liệu (dataset)

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Khi chúng tôi tạo một tập dữ liệu lần đầu tiên, nó sẽ hiển thị tất cả không gian nhóm có sẵn. Sau đó, chúng tôi đặt hạn ngạch - và thay đổi điểm gắn kết. Ảo thuật!

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Zvol phần lớn chỉ là một tập dữ liệu bị loại bỏ khỏi lớp hệ thống tệp của nó, lớp mà chúng tôi sẽ thay thế ở đây bằng một hệ thống tệp ext4 hoàn toàn bình thường.

Tập dữ liệu ZFS gần giống với hệ thống tệp được gắn tiêu chuẩn. Giống như một hệ thống tệp thông thường, thoạt nhìn có vẻ như "chỉ là một thư mục khác". Nhưng cũng giống như các hệ thống tệp có thể gắn kết thông thường, mỗi bộ dữ liệu ZFS có một bộ thuộc tính cơ bản riêng.

Trước hết, một tập dữ liệu có thể có hạn ngạch được chỉ định. Nếu đặt zfs set quota=100G poolname/datasetname, thì bạn sẽ không thể ghi vào thư mục được gắn kết /poolname/datasetname hơn 100 GiB.

Lưu ý sự hiện diện - và vắng mặt - của dấu gạch chéo ở đầu mỗi dòng? Mỗi bộ dữ liệu có vị trí riêng trong cả hệ thống phân cấp ZFS và hệ thống phân cấp gắn kết hệ thống. Không có dấu gạch chéo ở đầu trong hệ thống phân cấp ZFS - bạn bắt đầu với tên nhóm và sau đó là đường dẫn từ tập dữ liệu này sang tập dữ liệu tiếp theo. Ví dụ, pool/parent/child cho một tập dữ liệu có tên child dưới tập dữ liệu gốc parent trong một nhóm có tên sáng tạo pool.

Theo mặc định, điểm gắn kết của tập dữ liệu sẽ tương đương với tên của nó trong hệ thống phân cấp ZFS, với dấu gạch chéo ở đầu - nhóm có tên pool gắn kết như /pool, tập dữ liệu parent gắn vào /pool/parent, và tập dữ liệu con child gắn vào /pool/parent/child. Tuy nhiên, điểm gắn kết hệ thống của tập dữ liệu có thể được thay đổi.

Nếu chúng tôi chỉ định zfs set mountpoint=/lol pool/parent/child, thì tập dữ liệu pool/parent/child gắn trên hệ thống như /lol.

Ngoài tập dữ liệu, chúng ta nên đề cập đến khối lượng (zvols). Một ổ đĩa gần giống như một tập dữ liệu, ngoại trừ việc nó không thực sự có hệ thống tệp—nó chỉ là một thiết bị khối. Ví dụ, bạn có thể tạo zvol Với tên mypool/myzvol, sau đó định dạng nó bằng một hệ thống tệp ext4, rồi gắn hệ thống tệp đó - bây giờ bạn có một hệ thống tệp ext4, nhưng với tất cả các tính năng bảo mật của ZFS! Điều này có vẻ ngớ ngẩn trên một máy duy nhất, nhưng có ý nghĩa hơn nhiều với vai trò phụ trợ khi xuất thiết bị iSCSI.

Khối

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Tệp được đại diện bởi một hoặc nhiều khối. Mỗi khối được lưu trữ trên một thiết bị ảo. Kích thước khối thường bằng tham số hồ sơ kích thước, nhưng có thể giảm xuống 2^canếu nó chứa siêu dữ liệu hoặc một tệp nhỏ.

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Chúng tôi thực sự thực sự không đùa về hình phạt hiệu suất lớn nếu bạn đặt ashift quá nhỏ

Trong nhóm ZFS, tất cả dữ liệu, bao gồm cả siêu dữ liệu, được lưu trữ trong các khối. Kích thước khối tối đa cho mỗi tập dữ liệu được xác định trong thuộc tính recordsize (kích thước kỷ lục). Kích thước bản ghi có thể được thay đổi, nhưng điều này sẽ không thay đổi kích thước hoặc vị trí của bất kỳ khối nào đã được ghi vào tập dữ liệu - nó chỉ ảnh hưởng đến các khối mới khi chúng được ghi.

Trừ khi có quy định khác, kích thước bản ghi mặc định hiện tại là 128 KiB. Đó là một sự đánh đổi khó khăn khi hiệu suất không hoàn hảo, nhưng nó cũng không tệ trong hầu hết các trường hợp. Recordsize có thể được đặt thành bất kỳ giá trị nào từ 4K đến 1M (với cài đặt nâng cao recordsize bạn có thể cài đặt nhiều hơn, nhưng điều này hiếm khi là một ý tưởng hay).

Bất kỳ khối nào đề cập đến dữ liệu của chỉ một tệp - bạn không thể nhồi nhét hai tệp khác nhau vào một khối. Mỗi tệp bao gồm một hoặc nhiều khối, tùy thuộc vào kích thước. Nếu kích thước tệp nhỏ hơn kích thước bản ghi, nó sẽ được lưu trữ ở kích thước khối nhỏ hơn - ví dụ: một khối có tệp 2 KiB sẽ chỉ chiếm một cung 4 KiB trên đĩa.

Nếu tệp đủ lớn và yêu cầu nhiều khối, thì tất cả các bản ghi với tệp này sẽ có kích thước recordsize - bao gồm mục cuối cùng, phần chính của mục đó có thể là không gian chưa sử dụng.

zvols không có tài sản recordsize - thay vào đó họ có một tài sản tương đương volblocksize.

lĩnh vực

Khối xây dựng cơ bản cuối cùng là khu vực. Nó là đơn vị vật lý nhỏ nhất có thể được ghi vào hoặc đọc từ thiết bị bên dưới. Trong nhiều thập kỷ, hầu hết các đĩa đã sử dụng các cung 512 byte. Gần đây, hầu hết các ổ đĩa được định cấu hình cho 4 cung KiB và một số - đặc biệt là SSD - có 8 cung KiB trở lên.

Hệ thống ZFS có một thuộc tính cho phép bạn đặt kích thước cung theo cách thủ công. tài sản này ashift. Hơi khó hiểu, ashift là một sức mạnh của hai. Ví dụ, ashift=9 có nghĩa là kích thước cung là 2^9 hoặc 512 byte.

ZFS truy vấn hệ điều hành để biết thông tin chi tiết về từng thiết bị khối khi nó được thêm vào vdev mới và về mặt lý thuyết sẽ tự động cài đặt ashift đúng cách dựa trên thông tin đó. Thật không may, nhiều ổ đĩa nói dối về kích thước cung từ của chúng để duy trì khả năng tương thích với Windows XP (không thể hiểu được các ổ đĩa có kích thước cung từ khác).

Điều này có nghĩa là quản trị viên ZFS nên biết kích thước cung thực tế của thiết bị của họ và đặt thủ công ashift. Nếu ashift được đặt quá thấp, thì số lượng thao tác đọc / ghi sẽ tăng lên rất nhiều. Vì vậy, viết "sector" 512 byte vào một sector 4 KiB thực có nghĩa là phải viết "sector" đầu tiên, sau đó đọc sector 4 KiB, sửa đổi nó bằng một "sector" 512 byte thứ hai, viết nó trở lại cái mới. 4 khu vực KiB, v.v. cho mỗi mục nhập.

Trong thế giới thực, một hình phạt như vậy ảnh hưởng đến SSD Samsung EVO, mà ashift=13, nhưng các ổ SSD này nói dối về kích thước cung từ của chúng và do đó, giá trị mặc định được đặt thành ashift=9. Nếu quản trị viên hệ thống có kinh nghiệm không thay đổi cài đặt này thì ổ SSD này sẽ hoạt động Chậm hơn ổ cứng từ thông thường.

Để so sánh, đối với kích thước quá lớn ashift thực tế không có hình phạt. Không có hình phạt hiệu suất thực tế và sự gia tăng không gian không sử dụng là vô cùng nhỏ (hoặc bằng 512 khi kích hoạt tính năng nén). Do đó, chúng tôi thực sự khuyên rằng ngay cả những ổ đĩa sử dụng các cung từ XNUMX byte cũng nên cài đặt ashift=12 hoặc thậm chí ashift=13để đối mặt với tương lai với sự tự tin.

Bất động sản ashift được đặt cho từng thiết bị ảo vdev và không cho hồ bơi, như nhiều người lầm tưởng - và không thay đổi sau khi cài đặt. Nếu bạn vô tình đánh ashift khi bạn thêm một vdev mới vào một nhóm, bạn đã làm ô nhiễm nhóm đó một cách không thể khắc phục bằng một thiết bị hiệu suất thấp và thường không có lựa chọn nào khác ngoài việc phá hủy nhóm đó và bắt đầu lại. Ngay cả việc xóa vdev cũng sẽ không cứu bạn khỏi cấu hình bị hỏng ashift!

Cơ chế sao chép khi ghi

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Nếu một hệ thống tệp thông thường cần ghi đè dữ liệu, nó sẽ thay đổi từng khối ở vị trí của nó

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Hệ thống tệp sao chép khi ghi ghi phiên bản khối mới và sau đó mở khóa phiên bản cũ

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Tóm lại, nếu chúng ta bỏ qua vị trí thực tế của các khối, thì "sao chổi dữ liệu" của chúng ta được đơn giản hóa thành "sâu dữ liệu" di chuyển từ trái sang phải trên bản đồ không gian có sẵn

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Bây giờ chúng ta có thể hiểu rõ về cách thức hoạt động của ảnh chụp nhanh sao chép khi ghi - mỗi khối có thể được sở hữu bởi nhiều ảnh chụp nhanh và sẽ tồn tại cho đến khi tất cả ảnh chụp nhanh liên quan bị hủy

Cơ chế Copy on Write (CoW) là nền tảng cơ bản khiến ZFS trở thành một hệ thống tuyệt vời như vậy. Khái niệm cơ bản rất đơn giản - nếu bạn yêu cầu hệ thống tệp truyền thống thay đổi tệp, nó sẽ thực hiện chính xác những gì bạn yêu cầu. Nếu bạn yêu cầu một hệ thống tệp sao chép khi ghi cũng làm như vậy, nó sẽ nói "ok" nhưng nói dối bạn.

Thay vào đó, hệ thống tệp sao chép khi ghi ghi một phiên bản mới của khối đã sửa đổi và sau đó cập nhật siêu dữ liệu của tệp để hủy liên kết khối cũ và liên kết khối mới mà bạn vừa ghi vào nó.

Việc tách khối cũ và liên kết khối mới được thực hiện trong một thao tác, vì vậy nó không thể bị gián đoạn - nếu bạn tắt nguồn sau khi điều này xảy ra, bạn sẽ có phiên bản mới của tệp và nếu tắt nguồn sớm, bạn sẽ có phiên bản cũ . Trong mọi trường hợp, sẽ không có xung đột trong hệ thống tệp.

Sao chép khi ghi trong ZFS không chỉ xảy ra ở cấp hệ thống tệp mà còn ở cấp quản lý đĩa. Điều này có nghĩa là ZFS không bị ảnh hưởng bởi khoảng trắng (một lỗ hổng trong RAID) - một hiện tượng khi dải chỉ có thời gian ghi một phần trước khi hệ thống gặp sự cố, với mảng bị hỏng sau khi khởi động lại. Ở đây, sọc được viết nguyên tử, vdev luôn tuần tự và Bob là chú của bạn.

ZIL: Nhật ký mục đích ZFS

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Hệ thống ZFS xử lý ghi đồng bộ theo một cách đặc biệt - nó lưu trữ tạm thời nhưng ngay lập tức chúng trong ZIL trước khi ghi chúng vĩnh viễn sau đó cùng với ghi không đồng bộ.

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Thông thường, dữ liệu được ghi vào ZIL sẽ không bao giờ được đọc lại. Nhưng có thể xảy ra sau sự cố hệ thống

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
SLOG, hoặc thiết bị LOG phụ, chỉ là một vdev đặc biệt - và tốt nhất là rất nhanh, nơi ZIL có thể được lưu trữ riêng biệt với bộ lưu trữ chính

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Sau khi gặp sự cố, tất cả dữ liệu bẩn trong ZIL được phát lại - trong trường hợp này, ZIL nằm trên SLOG, vì vậy nó được phát lại từ đó

Có hai loại thao tác ghi chính - đồng bộ (sync) và không đồng bộ (async). Đối với hầu hết các khối lượng công việc, phần lớn các thao tác ghi là không đồng bộ - hệ thống tệp cho phép chúng được tổng hợp và phát hành theo lô, giúp giảm tình trạng phân mảnh và tăng đáng kể thông lượng.

Bản ghi được đồng bộ hóa là một vấn đề hoàn toàn khác. Khi một ứng dụng yêu cầu ghi đồng bộ, nó sẽ thông báo cho hệ thống tệp: "Bạn cần cam kết điều này với bộ nhớ không bay hơi ngay bây giờcho đến lúc đó, tôi không thể làm gì khác." Do đó, việc ghi đồng bộ phải được cam kết vào đĩa ngay lập tức—và nếu điều đó làm tăng khả năng phân mảnh hoặc giảm thông lượng, thì hãy cứ làm như vậy.

ZFS xử lý việc ghi đồng bộ khác với các hệ thống tệp thông thường—thay vì ngay lập tức đưa chúng vào bộ lưu trữ thông thường, ZFS đưa chúng vào một khu vực lưu trữ đặc biệt có tên là ZFS Intent Log hoặc ZIL. Bí quyết là những bản ghi này cũng vẫn còn trong bộ nhớ, được tổng hợp cùng với các yêu cầu ghi không đồng bộ thông thường, để sau đó được chuyển sang bộ lưu trữ dưới dạng TXG (Nhóm giao dịch) hoàn toàn bình thường.

Trong hoạt động bình thường, ZIL được ghi vào và không bao giờ được đọc lại. Khi, sau một lúc, các bản ghi từ ZIL được cam kết vào bộ lưu trữ chính trong TXG thông thường từ RAM, chúng sẽ được tách ra khỏi ZIL. Lần duy nhất một cái gì đó được đọc từ ZIL là khi nhóm được nhập.

Nếu ZFS không thành công - sự cố hệ điều hành hoặc mất điện - trong khi có dữ liệu trong ZIL, thì dữ liệu đó sẽ được đọc trong lần nhập nhóm tiếp theo (ví dụ: khi hệ thống khẩn cấp được khởi động lại). Mọi thứ trong ZIL sẽ được đọc, được nhóm thành TXG, được chuyển giao cho bộ lưu trữ chính và sau đó được tách ra khỏi ZIL trong quá trình nhập.

Một trong các lớp trợ giúp vdev được gọi là LOG hoặc SLOG, thiết bị phụ của LOG. Nó có một mục đích - cung cấp cho nhóm một vdev riêng biệt, và tốt nhất là nhanh hơn nhiều, có khả năng chống ghi rất cao để lưu trữ ZIL, thay vì lưu trữ ZIL trên cửa hàng vdev chính. Bản thân ZIL hoạt động giống nhau cho dù nó được lưu trữ ở đâu, nhưng nếu LOG ​​vdev có hiệu suất ghi rất cao, thì việc ghi đồng bộ sẽ nhanh hơn.

Thêm một vdev với LOG vào nhóm không hoạt động không thể cải thiện hiệu suất ghi không đồng bộ - ngay cả khi bạn buộc tất cả ghi vào ZIL với zfs set sync=always, chúng sẽ vẫn được liên kết với bộ lưu trữ chính trong TXG theo cách thức và tốc độ giống như khi không có nhật ký. Cải thiện hiệu suất trực tiếp duy nhất là độ trễ của quá trình ghi đồng bộ (vì nhật ký nhanh hơn tăng tốc độ hoạt động). sync).

Tuy nhiên, trong một môi trường vốn đã yêu cầu nhiều thao tác ghi đồng bộ, vdev LOG có thể gián tiếp tăng tốc độ ghi không đồng bộ và đọc không lưu trong bộ nhớ cache. Giảm tải các mục nhập ZIL sang nhật ký vdev riêng biệt có nghĩa là ít tranh chấp hơn đối với IOPS trên bộ nhớ chính, giúp cải thiện hiệu suất của tất cả các lần đọc và ghi ở một mức độ nào đó.

ảnh chụp nhanh

Cơ chế sao chép khi ghi cũng là nền tảng cần thiết cho ảnh chụp nhanh nguyên tử ZFS và sao chép không đồng bộ gia tăng. Hệ thống tệp đang hoạt động có một cây con trỏ đánh dấu tất cả các bản ghi có dữ liệu hiện tại - khi bạn chụp nhanh, bạn chỉ cần tạo một bản sao của cây con trỏ này.

Khi một bản ghi bị ghi đè trên hệ thống tệp đang hoạt động, ZFS trước tiên sẽ ghi phiên bản khối mới vào không gian chưa sử dụng. Sau đó, nó tách phiên bản cũ của khối khỏi hệ thống tệp hiện tại. Nhưng nếu một số ảnh chụp liên quan đến khối cũ, thì nó vẫn không thay đổi. Khối cũ sẽ không thực sự được khôi phục dưới dạng không gian trống cho đến khi tất cả ảnh chụp nhanh tham chiếu đến khối này bị hủy!

nhân rộng

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Thư viện Steam của tôi năm 2015 là 158 GiB và bao gồm 126 tệp. Điều này khá gần với tình huống tối ưu cho rsync - Sao chép ZFS qua mạng "chỉ" nhanh hơn 927%.

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Trên cùng một mạng, sao chép một tệp hình ảnh máy ảo Windows 40 7 GB là một câu chuyện hoàn toàn khác. Bản sao ZFS nhanh hơn 289 lần so với rsync - hoặc "chỉ" nhanh hơn 161 lần nếu bạn đủ hiểu biết để gọi rsync bằng --inplace.

Khái niệm cơ bản về ZFS: Lưu trữ và hiệu suất
Khi hình ảnh máy ảo được chia tỷ lệ, rsync sẽ phát hành quy mô với hình ảnh đó. 1,9 TiB không quá lớn đối với hình ảnh VM hiện đại - nhưng nó đủ lớn để sao chép ZFS nhanh hơn 1148 lần so với rsync, ngay cả với đối số --inplace của rsync

Khi bạn hiểu cách thức hoạt động của ảnh chụp nhanh, bạn sẽ dễ dàng nắm bắt được bản chất của sao chép. Vì ảnh chụp nhanh chỉ là một cây các con trỏ tới các bản ghi, nên nếu chúng ta thực hiện zfs send ảnh chụp nhanh, sau đó chúng tôi gửi cả cây này và tất cả các bản ghi được liên kết với nó. Khi chúng tôi gửi cái này zfs send в zfs receive trên đích, nó ghi cả nội dung thực tế của khối và cây con trỏ tham chiếu đến các khối vào tập dữ liệu đích.

Mọi thứ thậm chí còn thú vị hơn vào lần thứ hai zfs send. Bây giờ chúng tôi có hai hệ thống, mỗi hệ thống chứa poolname/datasetname@1, và bạn chụp ảnh mới poolname/datasetname@2. Do đó, trong nhóm ban đầu, bạn có datasetname@1 и datasetname@2và trong nhóm mục tiêu cho đến nay chỉ có ảnh chụp nhanh đầu tiên datasetname@1.

Vì chúng tôi có ảnh chụp nhanh chung giữa nguồn và đích datasetname@1, chúng ta có thể làm được gia tăng zfs send hơn nó. Khi chúng ta nói với hệ thống zfs send -i poolname/datasetname@1 poolname/datasetname@2, nó so sánh hai cây con trỏ. Mọi con trỏ chỉ tồn tại trong @2, rõ ràng là đề cập đến các khối mới - vì vậy chúng tôi cần nội dung của các khối này.

Trên một hệ thống từ xa, xử lý một gia tăng send chỉ đơn giản như vậy. Đầu tiên, chúng tôi viết tất cả các mục mới có trong luồng send, sau đó thêm con trỏ vào các khối đó. Thì đấy, chúng ta có @2 trong hệ thống mới!

Sao chép gia tăng không đồng bộ ZFS là một cải tiến lớn so với các phương pháp không dựa trên ảnh chụp nhanh trước đó như rsync. Trong cả hai trường hợp, chỉ dữ liệu đã thay đổi được chuyển - nhưng rsync trước tiên phải đọc từ đĩa tất cả dữ liệu của cả hai bên để kiểm tra tổng và so sánh nó. Ngược lại, bản sao ZFS không đọc gì ngoài cây con trỏ - và bất kỳ khối nào không có trong ảnh chụp nhanh được chia sẻ.

Nén tích hợp

Cơ chế copy-on-write cũng đơn giản hóa hệ thống nén nội tuyến. Trong một hệ thống tệp truyền thống, việc nén có vấn đề - cả phiên bản cũ và phiên bản mới của dữ liệu đã sửa đổi đều nằm trong cùng một không gian.

Nếu chúng ta coi một phần dữ liệu ở giữa tệp bắt đầu hoạt động dưới dạng một megabyte gồm các số không từ 0x00000000, v.v., thì rất dễ dàng nén nó vào một khu vực trên đĩa. Nhưng điều gì sẽ xảy ra nếu chúng ta thay thế megabyte số 256 đó bằng một megabyte dữ liệu không thể nén được như JPEG hoặc nhiễu giả ngẫu nhiên? Thật bất ngờ, megabyte dữ liệu này sẽ không yêu cầu một mà là 4 cung XNUMX KiB và ở vị trí này trên đĩa chỉ có một cung được dành riêng.

ZFS không gặp vấn đề này, vì các bản ghi đã sửa đổi luôn được ghi vào không gian chưa sử dụng - khối ban đầu chỉ chiếm một khu vực 4 KiB và bản ghi mới sẽ chiếm 256, nhưng đây không phải là vấn đề - một đoạn được sửa đổi gần đây từ " giữa" của tệp sẽ được ghi vào không gian chưa sử dụng bất kể kích thước của nó có thay đổi hay không, vì vậy đối với ZFS, đây là một tình huống khá bình thường.

Tính năng nén ZFS gốc bị tắt theo mặc định và hệ thống cung cấp các thuật toán có thể cắm—hiện tại là LZ4, gzip (1-9), LZJB và ZLE.

  • LZ4 là một thuật toán phát trực tuyến mang lại các lợi ích về hiệu suất và nén và giải nén cực nhanh cho hầu hết các trường hợp sử dụng - ngay cả trên các CPU khá chậm.
  • GZIP là một thuật toán đáng kính mà tất cả người dùng Unix đều biết và yêu thích. Nó có thể được triển khai với các mức nén 1-9, với tỷ lệ nén và mức sử dụng CPU tăng lên khi đạt đến mức 9. Thuật toán rất phù hợp với tất cả các trường hợp sử dụng văn bản (hoặc các trường hợp có khả năng nén cao khác), nhưng nếu không thì thường gây ra sự cố CPU – hãy sử dụng nó cẩn thận, đặc biệt là ở cấp cao hơn.
  • LZJB là thuật toán gốc trong ZFS. Nó đã lỗi thời và không còn được sử dụng nữa, LZ4 vượt trội hơn nó về mọi mặt.
  • ZLE - mã hóa mức không, Mã hóa mức không. Nó hoàn toàn không chạm vào dữ liệu bình thường, nhưng nén các chuỗi số không lớn. Hữu ích cho các bộ dữ liệu hoàn toàn không nén được (chẳng hạn như JPEG, MP4 hoặc các định dạng đã được nén khác) vì nó bỏ qua dữ liệu không nén được nhưng nén không gian không sử dụng trong các bản ghi kết quả.

Chúng tôi khuyến nghị nén LZ4 cho hầu hết các trường hợp sử dụng; hình phạt hiệu suất khi gặp phải dữ liệu không thể nén được là rất nhỏ và sự phát triển hiệu suất cho dữ liệu điển hình là đáng kể. Sao chép hình ảnh máy ảo để cài đặt mới hệ điều hành Windows (HĐH mới được cài đặt, chưa có dữ liệu bên trong) với compression=lz4 vượt qua nhanh hơn 27% so với compression=noneTrong kỳ thi này năm 2015.

ARC - bộ đệm thay thế thích ứng

ZFS là hệ thống tệp hiện đại duy nhất mà chúng tôi biết sử dụng cơ chế bộ nhớ đệm đọc riêng của nó, thay vì dựa vào bộ đệm trang của hệ điều hành để lưu trữ các bản sao của các khối đã đọc gần đây trong RAM.

Mặc dù bộ đệm gốc không phải không có vấn đề - ZFS không thể đáp ứng các yêu cầu cấp phát bộ nhớ mới nhanh như kernel, vì vậy thách thức mới malloc() về cấp phát bộ nhớ có thể không thành công nếu nó cần RAM hiện đang bị ARC chiếm giữ. Nhưng có những lý do chính đáng để sử dụng bộ nhớ cache của riêng bạn, ít nhất là vào lúc này.

Tất cả các hệ điều hành hiện đại đã biết, bao gồm MacOS, Windows, Linux và BSD, đều sử dụng thuật toán LRU (Ít được sử dụng gần đây nhất) để triển khai bộ đệm trang. Đây là một thuật toán nguyên thủy giúp đẩy khối được lưu trong bộ nhớ cache "lên hàng đợi" sau mỗi lần đọc và đẩy các khối "xuống hàng đợi" khi cần để thêm các lỗi bộ đệm mới (các khối lẽ ra phải được đọc từ đĩa chứ không phải từ bộ đệm) hướng lên.

Thuật toán thường hoạt động tốt, nhưng trên các hệ thống có bộ dữ liệu hoạt động lớn, LRU dễ dẫn đến tình trạng phá vỡ - loại bỏ các khối thường xuyên cần thiết để nhường chỗ cho các khối sẽ không bao giờ được đọc lại từ bộ đệm.

ARC là một thuật toán ít ngây thơ hơn nhiều có thể được coi là bộ đệm "có trọng số". Mỗi lần một khối được lưu trong bộ nhớ cache được đọc, nó sẽ "nặng hơn" một chút và khó gỡ bỏ hơn - và ngay cả sau khi gỡ bỏ một khối theo dõi trong một khoảng thời gian nhất định. Một khối đã bị loại bỏ nhưng sau đó cần được đọc lại vào bộ đệm cũng sẽ trở nên "nặng nề" hơn.

Kết quả cuối cùng của tất cả điều này là một bộ đệm có tỷ lệ lần truy cập cao hơn nhiều, tỷ lệ giữa lần truy cập bộ đệm (lần đọc được thực hiện từ bộ đệm) và lần bỏ lỡ bộ đệm (lần đọc từ đĩa). Đây là một thống kê cực kỳ quan trọng - không chỉ bản thân các lần truy cập bộ đệm được phục vụ theo thứ tự cường độ nhanh hơn, mà các lần bỏ lỡ bộ đệm cũng có thể được phục vụ nhanh hơn, vì càng nhiều lần truy cập bộ đệm, càng ít yêu cầu đĩa đồng thời và độ trễ cho những lần bỏ lỡ còn lại càng thấp. ăn kèm đĩa.

Kết luận

Sau khi tìm hiểu ngữ nghĩa cơ bản của ZFS - cách hoạt động của tính năng sao chép khi ghi, cũng như mối quan hệ giữa nhóm lưu trữ, thiết bị ảo, khối, cung và tệp - chúng ta sẵn sàng thảo luận về hiệu suất trong thế giới thực với các con số thực.

Trong phần tiếp theo, chúng ta sẽ xem xét hiệu suất thực tế của các nhóm với vdev và RAIDz được nhân đôi, so với nhau, cũng như so với các cấu trúc liên kết RAID nhân Linux truyền thống mà chúng ta đã khám phá. sớm hơn.

Lúc đầu, chúng tôi chỉ muốn đề cập đến những điều cơ bản - bản thân các cấu trúc liên kết ZFS - nhưng sau đó như vậy chúng ta hãy sẵn sàng nói về thiết lập và điều chỉnh ZFS nâng cao hơn, bao gồm việc sử dụng các loại vdev phụ trợ như L2ARC, SLOG và Phân bổ đặc biệt.

Nguồn: www.habr.com

Thêm một lời nhận xét