Про ZFS prefetch
Вынесу из комментариев, потому что это важное, чтобы потом самому было легче найти.
АХТУНГ. Все описанные ниже эксперименты (и прошлая серия экспериментов) - относятся ТОЛЬКО к FreeBSD-12. На 10.3-11.0 (релизных! со -stable все сложно) картина принципиально другая и деградации скорости чтения при маленькой глубине префетча нет.
Собрал я тут ZFS массив на следующие (я надеюсь) лет пять: 6x6Tb, в RAIDZ2 (2 - потому что я устал срочно бегать в магазин, покупать замену вылетевшему диску), диски HGST, правда разные (три гелиевых, два 7k6000, один Deskstar NAS), но довольно близкие по характеристикам (гелиевые похолоднее и помедленнее).
Достал линейку, стал мерять перформанс. И удивился:
- С записью все OK, длинные файлы пишутся примерно ~600-650Mb/sec. Ну хотелось бы 700, ну да ладно.
- С чтением все не OK:
- dd if=/zdata/bigfile of=/dev/null читает ~200Mb/sec
- zfs send zdata@1 (датасет на котором кроме этого бигфайла ничего нет) - опять медленно
- zfs send zdata/realdataset - ну ок, 500+
- Ладно, плюнул, временно пересобрал страйп из 6 этих же дисков:
- запись ~1100Mb/sec
- чтение ~550Mb/sec
В комментариях мне подсказали про vfs.zfs.zfetch.max_distance. И действительно, после увеличения его раз в 20 (со стандартных 8Mb до 160, пробовал и больше) - скорость чтения большого файла наладилась, стало 500-600Mb/sec, в пиках и побольше бывает (речь про raidz2, что там у страйпа - не тестировал и уже не буду). Цена тоже понятная, если мы читаем мало, то нам попрефетчат эти самые 80-160-... мегабайт, даже если они нам не нужны (ну там есть какая-то логика когда префетчить, но она скорее всего может ошибочно предсказывать).
Ну, казалось бы, все понятно, ну префетч, ну да.
Однако.
Я потестировал того же самого на других массивах:
- RAIDZ2 из восьми терабайтников ("рабочие данные")
- RAIDZ2 из пяти 4-терабайтников (не, я понимаю что нужно 6, но не было)
И в обоих случаях увеличение глубины prefetch практически не влияет на скорость линейного чтения большого файла. Стандартных 8Mb вполне хватает, увеличивать не нужно.
Правда есть разница и ее больше чем одна:
- Другая версия FreeBSD: на проблемном ящике была 10.3, потом 11 (от апгрейда ничего не изменилось)
- Другой контроллер, на проблемном ящике LSI-9211 (в dumb-mode, без BIOS для ускорения загрузки), на тестовом на котором все в порядке Adaptec 5805
Впрочем, когда на "проблемном" ящике был предыдущий массив (6 дисков в RAIDZ1), там скорость чтения была какой-то близкой к ожидаемой (в районе 500Mb/sec, но мерял давно), т.е. разница явно не только в адаптеке. - Другой процессор: на "проблемном" i3-2120, на втором i5-2400.
В общем, остаюсь пока в недоумении:
- То ли дело в Адаптеке (который в свой полугиговый кэш всегда читает дорожку целиком), а с 9211 - вот такие странные проблемы (но этих проблем нет с контроллером SATA на материнке)
- То ли дело в 6-терабайтных дисках (ну там увеличился размер дорожки и то что раньше влезало в эти 8Mb префетча - теперь не влезает)
Но мораль простая: если со скоростью чтения что-то не так, крутите префетч.
P.S. Крутил еще вот эти параметры на "проблемном" ящике, большой разницы в длинных линейных чтениях не увидел:
vfs.zfs.vdev.cache.size=64M
vfs.zfs.vdev.cache.max="16384"
vfs.zfs.vdev.cache.bshift="18"
Comments
Судя по: "Ладно, плюнул,
Судя по: "Ладно, плюнул, временно пересобрал страйп из 6 этих же дисков: запись ~1100Mb/sec, чтение ~550Mb/sec" с дисками всё нормально. Смущает конечно чтение, но чтобы снять все подозрения с аппаратной части:
#zpool export ***
#fio ./test_all | grep iops
test_all:
; job fio
[global]
rw=read
direct=1
bs=1M
runtime=100
group_reporting
thread
gtod_reduce=1
[0]
filename=/dev/da0
[1]
filename=/dev/da1
[2]
filename=/dev/da2
[3]
filename=/dev/da3
[4]
filename=/dev/da4
[5]
filename=/dev/da5
Диски (или разделы) поставь соответственно входящие в пул. Тест безопасный (будет одновременно читать 100 сек все диски с максимальной скоростью). Желательно проконтролировать (gstat) во время чтения загрузку дисков (должна быть близкой к 100%). Затем покажешь выведенную строчку.
Предположу, что будет ещё одна перезаливка данных :-).
Я их dd почитал по одному.
Я их dd почитал по одному. ~210Mb/s обычные, 185 - гелиевые, гелиевые чуть помедленнее - но это и ожидалось.
По одному - это по одному, а
По одному - это по одному, а все вместе - это все вместе :-). За одно сверим с этой цифрой 210+210+210+185+185+185=1185.
Ну вот сумма на 30 больше
Ну вот сумма на 30 больше даже.
По iostat -x/gstat у всех
По iostat -x/gstat у всех дисков 99% и ожидаемая скорость: ~215 у обычных, 200 (из того что ниже - получается 190) у He8
Вот результаты двух прогонов:
fiolog: read : io=121780MB, bw=1214.4MB/s, iops=1214, runt=100310msec
fiolog2: read : io=121780MB, bw=1214.3MB/s, iops=1214, runt=100294msec
А вот без group reporting:
fiolog3: read : io=21694MB, bw=221511KB/s, iops=216, runt=100287msec
fiolog3: read : io=21694MB, bw=221925KB/s, iops=216, runt=100100msec
fiolog3: read : io=18814MB, bw=192605KB/s, iops=188, runt=100026msec
fiolog3: read : io=18878MB, bw=193108KB/s, iops=188, runt=100105msec
fiolog3: read : io=18942MB, bw=193363KB/s, iops=188, runt=100312msec
fiolog3: read : io=21758MB, bw=222502KB/s, iops=217, runt=100135msec
He8 - на 4-6 градусов
He8 - на 4-6 градусов холоднее при одинаковом охлаждении, у меня (летом) это место близко к критичному бывает.
Ну вот и доказали, что с
Ну вот и доказали, что с аппаратной частью у тебя всё хорошо. У меня ещё такой пропускной способности в руках не было, но думаю можно попробовать настроить последовательное чтение до 1GB/s (какая символическая цифра :-)). Если всё таки надумаешь перезаливать данные, то предлагаю потратить дополнительные 30 мин для проверки данного допущения (и количество дисков подходящее и скорости дисков распределились как надо :-)).
По существу. Так как я не эксплуатирую raidz, то могу только сделать предположение. Похоже ты попал с данной конфигурацией raidz в "устойчиво не хорошее сочетание разных факторов". Предполагаю самое простое решение убрать один диск из конфигурации raidz или добавить. Для проверки можно воспользоваться и составным диском.
>> устойчиво не хорошее
>> устойчиво не хорошее сочетание разных факторов"
Ну вот казалось бы, 2^N+R (R-избыточность) - это ровно рекомендованное количество дисков.
При этом - хотелось бы конкретнее про "сочетание факторов", страйп то тоже не показал себя с default-настройками как я ожидал.
Прежде чем двигать эти терабайты еще раз, вот у меня лежат на подоконнике 8 терабайтников (вынутые из "рабочего ящика", туда пошли четверки). Путь им - в дискетки, но пока они просто пустые.
Можно ли, собирая массив из них, подвердить или опровергнуть гипотезу с "сочетанием факторов"?
Думаю, что можно и это самый
Думаю, что можно и это самый лучший вариант. Я бы без чёткого понимания ситуации даже бы и не дёргался. Единственное на чём бы я заострил внимание - это разница в скорости дисков. Не уверен, но она тоже могла бы немного "посодействовать". Из твоего iostat однозначно видно, что два диска из шести получали в два раза больше запросов, то есть данные так уже лежали на дисках. Наверно это самое важное. Меня тогда же ещё смутил средний размер запроса чтения с диска (в районе 32k). Вроде из твоих описаний про 1M recordsize на диски должны приходить в основном запросы в 128k. Откуда взялись эти средние ~32k?
Про "в два раза больше" - это
Про "в два раза больше" - это был исходный вопрос, с которого все и началось.
Тогда мы решили, что чексуммы не читаются - и так и надо.
Размер чтения зависит, вероятно, еще от драйвера?
>> получали в два раза больше
>> получали в два раза больше запросов
И вот эта загрузка она в моменте (без префетча) у двух дисков из 6 вообще 0. Но незагруженные диски - меняются.
Длинный префетч это размазывает, естественно.
Была констатация факта, что
Была констатация факта, что при "нормальном" чтении контрольные блоки не читаются. Этот факт говорит только о "мгновенном" неравномерном чтении. Как оно там дальше я не знаю. Из твоих описаний можно предположить, что raidz2 ведёт себя, как набранный из кусочков raid4, причём довольно больших. Что является поводом для смены положения контрольных блоков - малелькая запись (допустим метаданных) или принудительное смещение мне не известно.
Шедуллер zfs все запросы меньше 128k пытается агрегировать (объединять). При попадании запроса в подсистему geom все большие запросы нарезаются по модулю MAXPHYS (128k).
Так как я опасаюсь адаптека
Так как я опасаюсь адаптека (там при смене дисков надо их "инициализировать" и хрен знает что оно при этом затирает) - я заказал еще один 9211, благо копейки стоит, придет (через дней 10, я надеюсь) - и буду развлекаться.
Откуда взялись эти средние
А вот вам с другого ящика (tar cf - | mbuffer -o /dev/null mbuffer - чтобы видеть мгновенные скорости):
extended device statistics
device r/s w/s kr/s kw/s ms/r ms/w ms/o ms/t qlen %b
aacd0 529 0 90353.0 0.0 1 0 0 1 0 40
aacd1 529 0 90301.5 0.0 1 0 0 1 2 41
aacd2 531 0 90628.0 0.0 2 0 0 2 0 39
aacd3 528 0 90267.1 0.0 7 0 0 7 5 74
aacd4 532 0 90902.8 0.0 5 0 0 5 0 68
У меня получается ~170kb на запрос. Что тоже интересно.
Да, диски тут строго одной модели, но один куплен на полтора года позже прочих (вместо вылетевшего)
recordsize=1m, 5 дисков в raidz2
На счёт скорости дисков.
На счёт скорости дисков. Вполне нормально, если скорости будут отличаться. Просто при жесткой увязке (как у raidz) быстрые диски будут привязаны к скорости более медленных и будут потери производительности. Но моя мысль была связана с полосатостью патерна чтения. Допустим нужно прочитать блок данных (recordsize), как в твоём последнем случае. Будет сформирован запрос на чтение (zio) 1MB, затем опускаясь по стеку будут сформированы три дочерних запроса (zio) по ~340kB и так далее. К моменту прихода запроса на физический диск может сложиться такая ситуация, что допустим один диск может прочитать сектора сразу, а два других должны будут пролететь перед чтением контрольные блоки. То есть один диск будет опережать два других. Возникла мысль, а может ли возникнуть в процессе чтения ситуация, что один диск прочитал всю свою порцию чтения из окна префетчинга, а один ещё только читает свою первую часть порцию. Тогда наверно возможна ситуация, что следующий запрос на чтение придет на, выполнивший свою работу, диск когда тот уже пролетит над этими данными и ему потребуется сделать лишний оборот. Это конечно предположение и возможно диск всегда читает дорожку и складывает данные в свой кэш. Поэтому я написал, что разница скоростей могла бы немного "посодействовать" подобной ситуации. Кстати, у зеркала при чтении нет такого влияния разницы скоростей дисков, потому что алгоритм балансировки построен на загрузке дисков и также нет жёстких связей (весь блок (recordsize) читается только с одного диска). Поэтому при чтении может быть выбрана почти вся пропускная способность. Мало того, в zfs предусмотрена возможность работы в зеркале ssd и hdd одновременно. Специально подстроен алгоритм балансировки. Для этого даже сделали автоматическое определение типа диска (non_rotating), пока правда только во FreeBSD.
Размер запроса на диск. При входе в подсистему geom, в твоём случае запрос (zio) ~340kB, Будут сформированы три дочерних запроса (bio) - 128kB, 128kB и ~84kB. Почему средний размер запроса ~170kB ума не приложу :-). Хотя он конечно коррелирует с ~340kB.
Кстати, если ядро собрано с
Кстати, если ядро собрано с MAXPHYS=256k, то получится средний размер запроса в ~170kB.
defaults
defaults
И, удивительным образом, не нашел как этот параметр посмотреть у собранного. Ищу вот...
/sys/sys/param.h
/sys/sys/param.h
#define MAXPHYS (128 * 1024) /* max raw I/O transfer size */
У меня других мыслей нет.
У меня других мыслей нет. Разве, что я отстал от жизни :-).
Ну я собираю с MAXPHYS=1mb,
Ну я собираю с MAXPHYS=1mb, ща попробуем.
С точки зрения системы это
С точки зрения системы это наверно не очень хорошее решение, но мне тоже интересно :-).
Ничего не изменилось
Ничего не изменилось
extended device statistics
device r/s w/s kr/s kw/s ms/r ms/w ms/o ms/t qlen %b
aacd0 498 0 84884.6 0.0 11 0 0 11 5 94
aacd1 500 0 85200.8 0.0 10 0 0 10 6 93
aacd2 499 0 84995.4 0.0 10 0 0 10 6 94
aacd3 499 0 85062.8 0.0 11 0 0 11 6 94
aacd4 505 0 85950.7 0.0 10 0 0 10 6 95
Создал датасет test1M с
Создал датасет test1M с recordsize=1M.
dd if=/dev/zero of=/pdf/test1M/test_64G_1M bs=1M count=64k (347MB/s)
dd if=/pdf/test1M/test_64G_1M of=/dev/zero bs=1M count=64k (661MB/s)
extended device statistics
device r/s w/s kr/s kw/s ms/r ms/w ms/o ms/t qlen %b
ada0 0 0 0.0 1.6 0 0 0 0 0 0
ada1 0 0 0.0 0.0 0 0 0 0 0 0
ada2 1302 0 166770.1 0.0 15 0 0 15 17 98
ada3 1192 0 152696.8 0.0 16 0 0 16 23 99
ada4 1661 0 98314.7 0.0 7 0 0 7 9 77
ada5 0 0 0.0 0.0 0 0 0 0 0 0
ada6 1597 0 98254.0 0.0 9 0 0 9 24 83
ada7 977 0 125163.8 0.0 17 0 0 17 16 86
Пул страйп из двух зеркал. В одном зеркале один диск (временно) stripe из ada4 и ada6 (stripesize=64k).
ada2, ada7 - WD4002FYYZ (195MB/s), ada3 - WD4000FYYZ (170MB/s), ada4 и ada6 WD2002FAEX (140MB/s).
Когда пул был пустой при recordsize=128k скорость чтения вначале была - холодная 605MB/s и 704MB/s (метаданные в кеше).
Заметил gstat показывает при чтении средний размер запроса чуть меньше 128k, iostat чуть больше 128k. При записи размер среднего запроса такой же.
Ну я поиграюсь с 8 дисками
Ну я поиграюсь с 8 дисками так, сяк, наперекосяк - когда контроллер придет.
Пока у меня есть два raidz2 (5 и 6 дисков) и один radiz (4 диска). Во, вот raidz1 посмотрим:
ada2 544 0 61741.6 0.0 10 0 0 10 0 82
ada3 544 0 61919.2 0.0 12 0 0 12 8 89
ada4 546 0 61982.8 0.0 11 0 0 11 5 88
ada5 540 0 61461.6 0.0 12 0 0 12 8 89
113k. Ну наверное там 128 + мелкая метадата (она не в кэше была, свежезагруженная машина, холодные данные)
(128 + 128 + 84) / 3 = 113
(128 + 128 + 84) / 3 = 113
Ну значит 256+84 пополам
Ну значит 256+84 пополам равно 170
Я уже давно отказался от
Я уже давно отказался от дополнительных контроллеров и может это у меня пробелы в их использовании. Припоминаю, что mav@ когда то писал что из устройства вычитываются какие-то индивидуальные данные. Можно будет попробовать найти. Но в любом случае geom это абстрактный слой и до физического устройства ещё длинный путь (подсистема cam, драйвер устройства). Geom-у нужно от нижлежащего блочного устройства по большому счёту только mediasize и sectorsize, ну можно ещё оценить stripesize, stripeoffset, rotationrate или другие плюшки. Можно предположить, что у дополнительных контроллеров созданный ими geom может иметь отличный от MAXPHYS максимальный размер запроса, но в принципе это легко проверить.
1. Почитать dd напрямую диск, подключённый к контроллеру, с bs=128k, 256k, 512k и посмотреть.
2. И наверно сразу напрашивается - экспортнуть пул, переключить диски (там где 6) на набортные сата порты, загрузиться с чего нибудь и посмотреть. Что то мне подсказывает, что ..., нет лучше сначала увидеть результаты пункта 1 :-).
Ну вот запросто может быть,
Ну вот запросто может быть, что aac (адаптек) сам определяет request size и ему MAXPHYS не указ.
Но углубляться в это уже очень не хочется.
Не говоря о том, что если я отключаю "там где 6" - я оставляю дом без интернету и меня скоро уже будут за это бить.