Slow ZFS read: проблема не в коде а в данных на диске

Картинка, вероятно, уже надоела, но вот вам очередная порция тестов.

Ящик: Intel i5-2400, 16Gb RAM, Adaptec 5805, 5x4Tb (HGST NAS) в JBOD, собраны в RAIDZ2.

Свободного места достаточно:

$ zpool list
NAME      SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
zdata    18,1T  5,11T  13,0T         -     9%    28%  1.00x  ONLINE  -

настройки в loader.conf:

vm.kmem_size="15G"
vfs.zfs.arc_max="14G"

Загружаем FreeBSD 11.0-RELENG:

$ uname -a
FreeBSD iscsi.lexa.ru 11.0-RELEASE-p3 FreeBSD 11.0-RELEASE-p3 #7 r309605: Tue Dec  6 12:21:10 MSK 2016 lexa@iscsi.lexa.ru:/usr/obj/usr/src/sys/GENERIC  amd64

Создаем отдельный датасет для первого теста:

# zfs create -o recordsize=1m  -o mountpoint=/test-11releng zdata/11releng

И пишем 100-гиговый файл

# dd if=/dev/zero of=/test-11releng/100g-created-on-11releng bs=1m count=100k
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 257.686751 secs (416684917 bytes/sec)

Перезагружаемся еще раз (версия та же) и смотрим на скорость холодного чтения:

$ dd if=/test-11releng/100g-created-on-11releng of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 250.526067 secs (428594850 bytes/sec)

Дальше читаем еще раз, чтобы увидеть эффект от кэшированных метаданных:

$ dd if=/test-11releng/100g-created-on-11releng of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 243.992662 secs (440071358 bytes/sec)

Эффект небольшой, но есть, процента три.

Загружаем 11-STABLE:

$ uname -a
FreeBSD iscsi.lexa.ru 11.0-STABLE FreeBSD 11.0-STABLE #0 r309616: Tue Dec  6 16:15:48 MSK 2016     lexa@iscsi.lexa.ru:/usr/obj/usr/src11/sys/GENERIC  amd64

и читаем тот же файл данных:

$ dd if=/test-11releng/100g-created-on-11releng of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 250.640950 secs (428398402 bytes/sec)

Все хорошо, скорость чтения та же.

Создаем новый датасет и в нем - 100-гиговый файл:

# zfs create -o recordsize=1m  -o mountpoint=/test-11stable zdata/11stable
# dd if=/dev/zero of=/test-11stable/100g-created-on-11stable bs=1m count=100k
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 246.409501 secs (435755041 bytes/sec)

Cкорость записи нормальная.

Перезагружаемся - и читаем этот же файл:

$ dd if=/test-11stable/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 524.488506 secs (204721707 bytes/sec)

Опаньки, половина скорости.

Опять читаем первый файл данных:

$ dd if=/test-11releng/100g-created-on-11releng of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 250.591102 secs (428483620 bytes/sec)

С ним все нормально.

Вывод - проблема в структуре на диске.

Загружаемся обратно в (быструю) 11.0-releng

$ uname -a
FreeBSD iscsi.lexa.ru 11.0-RELEASE-p3 FreeBSD 11.0-RELEASE-p3 #7 r309605: Tue Dec  6 12:21:10 MSK 2016     lexa@iscsi.lexa.ru:/usr/obj/usr/src/sys/GENERIC  amd64

и пытаемся понять, как вернуть скорость.

Попробуем zfs send | recv (на "быстрой" системе):

# zfs snapshot zdata/11stable@1
# zfs send zdata/11stable@1 | zfs recv zdata/11stable-sendrecv-on11releng  # slow because same dataset used
# zfs destroy zdata/11stable-sendrecv-on11releng@1
# zfs destroy zdata/11stable@1
# zfs set mountpoint=/test-11stable-sendrecv-on11releng zdata/11stable-sendrecv-on11releng

Перезагружаемся (в "быструю") и читаем:

$ dd if=/test-11stable-sendrecv-on11releng/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 336.193935 secs (319381676 bytes/sec)

Опаньки - мы получили ПРОМЕЖУТОЧНУЮ скорость. Стало лучше, но недостаточно хорошо.

Попробуем пофайловое копирование:

# zfs create -o recordsize=1m -o mountpoint=/test-11stable-copy-on11releng zdata/11stable-copy-on11releng
# cd /test-11stable
# tar cf - . | (cd /test-11stable-copy-on11releng/; tar xvf - )

Опять перегружаемся, смотрим:

$ dd if=/test-11stable-copy-on11releng/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 261.484845 secs (410632526 bytes/sec)

Ура, пофайловое копирование исправило проблему (как и ожидалось).

Проверим еще раз на "быстрой" 11.0-RELENG:

Хороший быстрый файл:

$ dd if=/test-11releng/100g-created-on-11releng of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 249.435476 secs (430468770 bytes/sec)

Плохой, медленный файл:

$ dd if=/test-11stable/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 525.558477 secs (204304920 bytes/sec)

Промежуточный файл, результат send | recv:

$ dd if=/test-11stable-sendrecv-on11releng/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 336.570705 secs (319024148 bytes/sec)

Загрузимся в 11-STABLE и еще раз:

Хороший

$ dd if=/test-11releng/100g-created-on-11releng of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 256.322824 secs (418902151 bytes/sec)

Плохой

$ dd if=/test-11stable/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 529.918422 secs (202623985 bytes/sec)

Злой Восстановленный tar

$ dd if=/test-11stable-copy-on11releng/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 260.234944 secs (412604783 bytes/sec)

Промежуточный:

$ dd if=/test-11stable-sendrecv-on11releng/100g-created-on-11stable of=/dev/null bs=1m
102400+0 records in
102400+0 records out
107374182400 bytes transferred in 336.240919 secs (319337047 bytes/sec)

Все скорости - как ожидалось.

Выводы

  1. ZFS в 11-STABLE поломан
  2. Поломка происходит при записи - на диск пишется что-то такое, что потом медленно читается
  3. Поэтому если вы обновились, но ничего не писали - то надо просто сделать даунгрейд обратно
  4. А вот если писали - то датасеты надо лечить пофайловым копированием :(

Comments

Первая загрузка -- 11.0-pN, т.е. RELENG, а написано STABLE

"Скриншоты" все реальные, а текст "не курьером" - это обратный перевод в спешке письма в freebsd-fs.
Исправил, спасибо.

Это всё бы в багтрекер, не?

Я никогда не слал PR (но если надо - научусь).

Написано в freebsd-fs, mav в курсе (и отреагировал), может быть достаточно?

Это теперь не PR, это теперь https://bugs.freebsd.org/ ;)

Значит я никогда не пошлю PR!
С другой стороны, готовый лог уже есть, переведен, можно и запузырить в bugs.

Подумаю.

А где, кстати, Саша отвечал? Или тебе лично?

Личная переписка, да.

BTW, я могу попробовать собрать стенд на работе в ближайшие дни, только там будет не более 4 дисков

Я не думаю что тут дело в дисках.
Во всяком случае, на stripe - то же самое говно (я пробовал 5-8 дисков), я просто его неверно понимал до сегодняшнего дня.

Вот Гапон хочет свежего пула: https://lists.freebsd.org/pipermail/freebsd-fs/2016-December/024167.html
А мне его быстро сделать не на чем (нужно разобрать ящик, ткнуть ненужные диски - это довольно долго все)
Если ты его удовлетворишь, то будет конечно хорошо, потому что мне совсем не с руки, у меня третий день вся работа стоит, занимаюсь этой вот херней.

то что есть под рукой довольно слабенькое, главное, памяти всего 4G, но, надеюсь, на тесты сгодится.

попросил коллег ткнуть дисочков, пошол строить.

Ну, вот, пошла движуши, вот и Стив подтянулся, так что я своё ставлю on hold (но если что -- готов какие-нибудь эксперименты попроводить, если ты short of resources)

Мне чтобы проводить эксперименты на пустом пуле - надо разобрать ящик, сунуть туда другой контроллер и другие диски и пока оно так работает - ящик невозможно использовать (а вообще у меня там активный а не архивный сторадж).

То есть вот если там есть лаба с 12-ю дисками у кого-то, то вот им и карты в руки.

Как отрепортят что починили - ну да, один раз проверю.

...тестовый стенд называется!
-
А почему Гугл вовсю юзал именно RAID 10? (не знаю, как сейчас)
А почему машина с ZFS "никогда не спит"?

Кстати, у Вас реальной инфы - море! --> создайте 96GB файл = архив реальных данных
его и гоняйте туда-сюда.
...и на "НИЗКО"_отформатированных дисках. А то мало ли..! ...вдруг старую ФС читают! ...

Опять же, если "однопоточное чтение" = 4 файла по ~100МБ, то и тестовая нагрузка должна соответствовать этому; а не 1005000 Гиговый файл гонять. Нет?

Вроде бы это починили в 11.0-STABLE пару недель назад: https://svnweb.freebsd.org/base?view=revision&revision=310105