Tại sao ZFS chậm hơn nhiều so với ext4 và btrfs?


11

Vấn đề

Gần đây tôi đã cài đặt một đĩa mới và tạo một zpool trên đó:

/# zpool create morez /dev/sdb

Sau khi sử dụng một lúc, tôi nhận thấy nó khá chậm:

/morez# fio --name rw --rw rw --size 10G
   read: IOPS=19.6k, BW=76.6MiB/s (80.3MB/s)(5120MiB/66834msec)
  write: IOPS=19.6k, BW=76.6MiB/s (80.3MB/s)(5120MiB/66834msec)

Thử nghiệm này khá giống với trường hợp sử dụng thực tế của tôi. Tôi đang đọc một số lượng vừa phải (~ 10k) hình ảnh (~ 2 MiB mỗi hình) từ đĩa. Chúng được ghi tất cả cùng một lúc khi đĩa hầu hết trống, vì vậy tôi không mong đợi chúng bị phân mảnh.

Để so sánh, tôi đã thử nghiệm ext4:

/# gdisk /dev/sdb
...
/# mkfs.ext4 -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# fio --name rw --rw rw --size 10G
   read: IOPS=48.3k, BW=189MiB/s (198MB/s)(5120MiB/27135msec)
  write: IOPS=48.3k, BW=189MiB/s (198MB/s)(5120MiB/27135msec)

Và btrfs:

/# mkfs.btrfs -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# fio --name rw --rw rw --size 10G
   read: IOPS=51.3k, BW=201MiB/s (210MB/s)(5120MiB/25528msec)
  write: IOPS=51.3k, BW=201MiB/s (210MB/s)(5120MiB/25528msec)

Điều gì có thể gây ra vấn đề về hiệu năng với ZFS và làm cách nào tôi có thể làm cho nó nhanh hơn?

Thất bại trong một giải pháp

Tôi cũng đã cố gắng thiết lập rõ ràng kích thước cung cấp cho zpool, vì đĩa của tôi ( Seagate ST1000DM003 ) sử dụng 4096 byte vật lý:

/# zpool create -o ashift=12 morez /dev/sdb

Điều này đã không cải thiện hiệu suất:

/morez# fio --name rw --rw rw --size 10G
   read: IOPS=21.3k, BW=83.2MiB/s (87.2MB/s)(5120MiB/61573msec)
  write: IOPS=21.3k, BW=83.2MiB/s (87.2MB/s)(5120MiB/61573msec)

Quan sát

Thật kỳ lạ, sử dụng zvol có hiệu suất tuyệt vời:

/# zfs create -V 20G morez/vol
/# fio --name rw --filename /dev/zvol/morez/vol --rw rw --size 10G
   read: IOPS=52.7k, BW=206MiB/s (216MB/s)(5120MiB/24852msec)
  write: IOPS=52.7k, BW=206MiB/s (216MB/s)(5120MiB/24852msec)

Tại sao điều này chỉ ảnh hưởng đến các hệ thống tập tin ZFS chứ không phải zvols?

Thử nghiệm mở rộng cho btrfs

Trong các ý kiến, nó đã được đề xuất sự khác biệt có thể là do bộ nhớ đệm. Sau khi thử nghiệm thêm, tôi không tin đây là trường hợp. Tôi đã tăng kích thước của bài kiểm tra btrfs cao hơn dung lượng bộ nhớ mà máy tính của tôi có và hiệu suất của nó vẫn lớn hơn đáng kể so với ZFS:

/# mkfs.btrfs -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# $ fio --name rw --rw rw --size 500G --runtime 3600 --time_based --ramp_time 900
   read: IOPS=41.9k, BW=164MiB/s (172MB/s)(576GiB/3600003msec)
  write: IOPS=41.9k, BW=164MiB/s (172MB/s)(576GiB/3600003msec)

Thông tin hệ thống

Phần mềm

  • Arch Linux, phiên bản kernel 4.11.6
  • ZFS trên Linux 0.6.5.10
  • fio 2.21

Phần cứng

Thông tin ZFS

Đây là những gì các thuộc tính ZFS trông giống như trước khi chạy fio. Đây chỉ là kết quả của việc tạo một zpool với các cài đặt mặc định.

# zpool get all morez
NAME   PROPERTY                    VALUE            SOURCE
morez  size                        928G             -
morez  capacity                    0%               -
morez  altroot                     -                default
morez  health                      ONLINE           -
morez  guid                        [removed]        default
morez  version                     -                default
morez  bootfs                      -                default
morez  delegation                  on               default
morez  autoreplace                 off              default
morez  cachefile                   -                default
morez  failmode                    wait             default
morez  listsnapshots               off              default
morez  autoexpand                  off              default
morez  dedupditto                  0                default
morez  dedupratio                  1.00x            -
morez  free                        928G             -
morez  allocated                   276K             -
morez  readonly                    off              -
morez  ashift                      0                default
morez  comment                     -                default
morez  expandsize                  -                -
morez  freeing                     0                default
morez  fragmentation               0%               -
morez  leaked                      0                default
morez  feature@async_destroy       enabled          local
morez  feature@empty_bpobj         enabled          local
morez  feature@lz4_compress        active           local
morez  feature@spacemap_histogram  active           local
morez  feature@enabled_txg         active           local
morez  feature@hole_birth          active           local
morez  feature@extensible_dataset  enabled          local
morez  feature@embedded_data       active           local
morez  feature@bookmarks           enabled          local
morez  feature@filesystem_limits   enabled          local
morez  feature@large_blocks        enabled          local

# zfs get all morez
NAME   PROPERTY              VALUE                  SOURCE
morez  type                  filesystem             -
morez  creation              Thu Jun 29 19:34 2017  -
morez  used                  240K                   -
morez  available             899G                   -
morez  referenced            96K                    -
morez  compressratio         1.00x                  -
morez  mounted               yes                    -
morez  quota                 none                   default
morez  reservation           none                   default
morez  recordsize            128K                   default
morez  mountpoint            /morez                 default
morez  sharenfs              off                    default
morez  checksum              on                     default
morez  compression           off                    default
morez  atime                 on                     default
morez  devices               on                     default
morez  exec                  on                     default
morez  setuid                on                     default
morez  readonly              off                    default
morez  zoned                 off                    default
morez  snapdir               hidden                 default
morez  aclinherit            restricted             default
morez  canmount              on                     default
morez  xattr                 on                     default
morez  copies                1                      default
morez  version               5                      -
morez  utf8only              off                    -
morez  normalization         none                   -
morez  casesensitivity       sensitive              -
morez  vscan                 off                    default
morez  nbmand                off                    default
morez  sharesmb              off                    default
morez  refquota              none                   default
morez  refreservation        none                   default
morez  primarycache          all                    default
morez  secondarycache        all                    default
morez  usedbysnapshots       0                      -
morez  usedbydataset         96K                    -
morez  usedbychildren        144K                   -
morez  usedbyrefreservation  0                      -
morez  logbias               latency                default
morez  dedup                 off                    default
morez  mlslabel              none                   default
morez  sync                  standard               default
morez  refcompressratio      1.00x                  -
morez  written               96K                    -
morez  logicalused           72.5K                  -
morez  logicalreferenced     40K                    -
morez  filesystem_limit      none                   default
morez  snapshot_limit        none                   default
morez  filesystem_count      none                   default
morez  snapshot_count        none                   default
morez  snapdev               hidden                 default
morez  acltype               off                    default
morez  context               none                   default
morez  fscontext             none                   default
morez  defcontext            none                   default
morez  rootcontext           none                   default
morez  relatime              off                    default
morez  redundant_metadata    all                    default
morez  overlay               off                    default

Không có chi tiết nào như phần cứng đang sử dụng, HĐH và phiên bản, bộ điều khiển, cài đặt hệ thống, v.v. Tôi không chắc chúng tôi có thể nói gì với bạn!
ewwhite

2
Là gì ổ đĩa riêng của mình? Đó là ổ đĩa SATA dành cho người tiêu dùng sẵn có. Bạn còn một chặng đường dài để chứng minh rằng nó thực sự có thể xử lý hơn 200 MB / giây được duy trì. Hầu hết các ổ đĩa SATA cấp độ người tiêu dùng trong điều kiện thực tế sẽ may mắn nhận được hơn 70-80 thao tác I / O mỗi giây, hoặc hơn 100-120 MB / giây. Và nếu bạn thực hiện các thao tác I / O khối nhỏ ngẫu nhiên cho một ổ đĩa như vậy, bạn có thể sẽ nhận được khoảng 30-40 KB / giây. 10 GB tất cả có thể dễ dàng cuộn lên trong bộ nhớ cache.
Andrew Henle

1
@ewwhite Không có cài đặt điều chỉnh nào xuất hiện trong/etc/modprobe.d/zfs.conf
Snowball

1
@ewwhite Họ là. Tôi lau bảng phân vùng giữa mỗi bài kiểm tra. Trong mọi trường hợp, phân vùng có độ lệch 1 MiB từ đầu đĩa.
Quả cầu tuyết

1
Lưu ý đến bản thân / bất kỳ ai khác vấp phải câu hỏi này: cài đặt điều chỉnh mà ewwhite đề cập được ghi lại man 5 zfs-module-parameters.
Snowball

Câu trả lời:


6

Mặc dù cũ, tôi cảm thấy câu hỏi này xứng đáng có câu trả lời.

fiocác vấn đề, theo mặc định, các IOP có kích thước 4KB; Thay vào đó, bộ dữ liệu ZFS sử dụng bản ghi 128KB theo mặc định. Sự không phù hợp này có nghĩa là mỗi lần ghi 4K gây ra đọc / sửa đổi / ghi toàn bộ bản ghi 128K.

ZVOL, mặt khác, sử dụng 8K volblocksize theo mặc định. Điều này có nghĩa là việc ghi 4K gây ra chu kỳ đọc / sửa đổi / ghi nhỏ hơn của bản ghi 8K và, may mắn thay, hai lần ghi 4K có thể được kết hợp thành một lần ghi 8K ( không yêu cầu đọc / sửa đổi / ghi).

Có thể thay đổi bản ghi dữ liệu ZFS với zfs set recordize=8K <dataset>và trong trường hợp này, nó sẽ cung cấp hiệu năng tương đương nhiều hơn hoặc ít hơn ZVOL. Tuy nhiên, khi được sử dụng cho các lần chuyển tương đối lớn (OP đã nói về các tệp 2 MB, là hình ảnh, nên được đọc hoàn toàn mỗi khi chúng được truy cập), tốt hơn là nên ghi kích thước lớn / volblocksize, đôi khi còn lớn hơn cài đặt mặc định (128K).


4

Lưu ý: vì công việc fio thiếu direct=1( http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ) một số lượng I / O được thực hiện (cả đọc ghi) có thể được lưu trữ bởi hệ điều hành, làm sai lệch kết quả của bạn (và làm cho con số cao một cách giả tạo). Điều này tự nó phức tạp hơn bởi những điều sau đây:

Lưu ý rằng O_DIRECTvẫn thực hiện I / O được đệm vẫn được cho phép vì trên Linux O_DIRECTcó nhiều gợi ý hơn (xem phần tài liệu tham khảo của /programming//a/46377629/2732969 ).

Nếu bạn đang ở trong tình huống không thể bỏ qua chính xác bộ nhớ cache, điều quan trọng là bạn phải thực hiện đủ I / O trên một khu vực đủ lớn để giảm thiểu tác động của bộ nhớ đệm (tất nhiên, trừ khi, bạn thực sự muốn kiểm tra bộ nhớ đệm) ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.