В последний раз о фрагментации файлов и производительности

Я много раз в этом блоге трогал тему о влиянии фрагментации на производительность работы системы хранения (см. например раз, два, три). Но как-то все это были слова, а как насчет “покажь логи”? Так как я до недавних пор был “безлошадный”, а все мои знакомые “с оборудованием” все как на подбор были “ленивы и нелюбопытны”, чтобы дать документальный ответ на этот вопрос, то поэтому пришлось отвечать самому.

Тут вот, как вы уже заметили, я, наконец, обзавелся на хозяйстве маленьким нетаппчиком, и, пока мы его в продакшн не ввели, гоняю в хвост и в гриву, в том числе отвечаю на назревшие вопросы. ?? первый – о том, влияет ли фрагментация данных на производительность доступа к ним при рандомном характере доступа.

Выше в постах, на которые я сослался, я уже ответил на этот вопрос и прояснил свою позицию. Вкратце: при рандомном доступе производительность от фрагментации данных не зависит. Так как система хранения обращается к данным рандомно, в произвольном, случайном порядке, то нет никакой особенной разницы в том, будут ли блоки данных лежать упорядоченно, или беспорядочно – их всегда будут читать “беспорядочно”. А рандомность обращения, помноженная на рандомность размещения не дает “рандомность в квадрате”, она остается обычной рандомностью, “в первой степени”.

Надеюсь не нужно дополнительно объяснять, почему для современных многозадачных систем, для баз OLTP, для виртуализованных серверных сред почти 100% доступа к данным является рандомным? Последовательный, “секвентальный” доступ встречается в очень узком сегменте, это бэкапы (а у NetApp, к слову, задача бэкапа, как вы помните, решается другим способом, а не последовательным копированием и передачей данных), это базы с характером доступа DSS, и это, отчасти, логи баз данных. Вот, в общем, и все использование секвентального доступа. Остальное все – более или менее чистый рандом.

Поэтому я взял паттерн доступа VM-сервер (40%-write/60%-read, 45%-sequental/55%-random, 4KB block). Секвентальность в последнем случае берется вследствие работы локального кэша хоста. Паттерны эти определил не я, они довольно широко распространены. Вот его и будем кушать мерять.

Тестировал я с помощью IOmeter, который, несмотря на некоторые его недостатки, знаю и люблю. В качестве load-generator использовались виртуальные машины, работающие с достаточно мощного хоста (IBM 3850 X5), который был подключен к стораджу по NFS. Для OS в VM диск выглядел “физическим” LUN без файловой системы, который делался MBR-разделом и форматировался в NTFS со стандартным размером блока (4KB). Раздел делался размером 40GB, на нем создавался тестовый файл IOmeter (iobw.tst), размером 16GB (для гарантированного “пробоя кэша”). На каждой VM делался 4-процессорный vCPU, и, соответственно, запускались 4 Worker, на каждом из которых пускался тестовый паттерн на созданный диск, в 16 потоков ввода-вывода (Outstanding IOs) на каждый Worker, то есть 64 одновременных потока ввода-вывода на диски (контроллер NetApp). Загрузка хост-сервера тестом не превышала при этом 15% (мощная зверюга этот 3850), загрузка стораджа колебалась, но также не превышала 80%. То есть заведомо мы в “потолки” нигде не упирались.

Для минимизации эффектов “прогрева WAFL” (о котором еще будет пост, это также была одна из тем “исследовательской недели”) я делал длинный ramp-up (10 минут), а затем начинался собственно измеряемый тест, длиной 30 минут. Я брал для оценки значение в steady state, ближе к концу теста, и для оценки параллельно проверяемого эффекта “падения производительности” при прогреве – ближе к его началу.

Однако, перед исследователем, в моем лице, встала проблема: как обеспечить “фрагментацию” файла тестирования? Если создать последовательный, упорядоченный файл просто: запускай IOmeter на пустом диске – вот он и создаст свой iobw.tst, то с фрагментацией “на заказ” сложнее.

Для того, чтобы сделать фрагментированный файл я нашел любопытную утилитку, под названием MyDefragmenter, которая, как ясно из названия – дефрагментатор. Но у нее в комплекте есть также программка MyFragmenter :). Она делает вполне ожидаемую из названия вещь :)

Я взял созданный IOmeter тестовый файл и качественно замесил его с помощью этой утилитки. Я фрагментировал с ее помощью этот файл на 250 тысяч кусочков по 64KB каждый (ну, чтоб не было претензий, что гранаты у нас не той системы;), а потом повторно провел тестирование описанными выше паттернами.

Также я проанализировал ситуацию с фрагментацией не только файла на NTFS, но и в WAFL, а затем измерил эффект от работы reallocate в WAFL.

Хочу отдельно отметить, что в данном случае измеренные “попугаи”  не могут рассматриваться по абсолютной величине, я не проводил никакого (необходимого) тюнинга системы, и настройки ее “по уму” и по best practices (это я  сделаю позже, ту у меня есть некоторые бюрократические процедуры для этого). Целью теста было сравнить два достигнутых параметра производительности: “А” и”Б”, то есть их соотношение, а не достижение абсолютного рекорда, поэтому реплики с мест “чота как-то иопсев маловата!” мы отметем как неорганизованные ;).

Вот какие результаты я получил:

[VM-initial-contiguous-state]

[ramp-up]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
59%    8469       0       0   16340  23734   26540  23808       0      0    49s
58%    8403       0       0   15951  23798   26476  25972       0      0    49s
60%    8634       0       0   16875  23979   27100  26656       0      0    50s
60%    8940       0       0   17524  24786   26952  25600       0      0    50s
59%    8518       0       0   16531  23780   26200  21140       0      0    51s
73%    7420       0       0   14155  21114   24678  23500       0      0    52s
93%    6721       0       0   13053  18576   21729  22283       0      0    52s

[starting test: 10 min from beginning]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
84%    6296       0       0   12053  17708   21164  21356       0      0    58s
87%    6626       0       0   12627  18662   21784  22264       0      0    58s
56%    7773       0       0   15366  21460   24116  25608       0      0    59s
56%    7992       0       0   15547  22282   24344  23552       0      0    59s
56%    7609       0       0   14877  21145   23552  24652       0      0    59s
55%    7904       0       0   15507  21925   24520  23552       0      0    59s

[after 15 min of test]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
50%    6947       0       0   13300  19589   21792  22304       0      0     1
53%    7107       0       0   13716  19946   22120  21376       0      0     1
49%    7152       0       0   13541  20323   22216  11672       0      0     1
49%    7221       0       0   13806  20392   22072     24       0      0     1
53%    7293       0       0   14059  20528   22524   2794       0      0     1
99%    5265       0       0   10141  14766   17919  40182       0      0     1
64%    6603       0       0   12549  18560   21603  22357       0      0     1
48%    6537       0       0   12832  18125   19492  19584       0      0     1

[finish 30 min of test]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
68%    6305       0       0   12071  17845   20643  22980       0      0     1
99%    5446       0       0   10335  15399   17551  22568       0      0     1
55%    7032       0       0   13896  19289   21480  20164       0      0     1
51%    6657       0       0   12933  18608   20668  22920       0      0     1
72%    6426       0       0   12237  18150   20240  22204       0      0     1
52%    6820       0       0   13055  19230   21452  22016       0      0     1


Summary Statistics ( 2306 samples  0 secs/sample)
CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
Min
  0%       0       0       0       1      0       4      0       0      0     0s
Avg
58%    7079       0       0   13690  19819   22136  20414       0      0     1
Max
99%    9116       0       0   18031  25295   28900  63498       0      0     1

Далее я запустил фрагментатор, который после нескольких часов работы создал мне почти идеально фрагментированный файл тестирования IOmeter (iobw.tst), размером 16TB, разделенный на 250 тысяч фрагментов

fragmented1fragmented2

?? провел те же тесты:

Предварительно измерим состояние WAFL

>reallocate measure /vol/ds_fast

Allocation check on ‘/vol/ds_fast’ is 23, hotspot 0 (threshold 4), consider running reallocate.

Все плохо, “23” это довольно сильная фрагментация, я, вдобавок, не реаллоцировал данные на томе после предыдущего получаса интенсивных записей.

[VM-2ndphase-fragmented-noncontiguous-state]

[ramp-up]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
58%    8667       0       0   16723  24273   20112  22536       0      0    28s
56%    8503       0       0   16512  23753   20100  28192       0      0    28s
59%    8296       0       0   16388  22890   18944  39764       0      0    27s
57%    8369       0       0   16307  23297   19772  25472       0      0    26s
56%    8341       0       0   16129  23334   19576  32408       0      0    26s
58%    8847       0       0   17132  24760   20416   4384       0      0    27s

[start of test 10 min]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
47%    6516       0       0   12565  18286   17444  23584       0      0     1
49%    6434       0       0   12543  17940   16624  28832       0      0     1
42%    6568       0       0   12691  18432   17416      0       0      0     1
80%    6010       0       0   11815  16629   15881  39465       0      0     1
94%    5768       0       0   11144  16082   16324  22250       0      0     1
47%    6864       0       0   13629  18887   17496  21000       0      0     1

[end of test 30 min]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
43%    6383       0       0   12416  17813   18672     24       0      0     1
75%    5556       0       0   10910  15416   17714  37909       0      0     1
99%    5191       0       0    9787  14718   16491  21065       0      0     1
50%    6132       0       0   12082  16920   17922  22018       0      0     1
45%    6050       0       0   11886  16791   17936  22016       0      0     1
45%    5950       0       0   11346  16849   18020  21832       0      0     1


Summary Statistics ( 2597 samples  0 secs/sample)
CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
Min
  0%       0       0       0       0      0       0      0       0      0     0s
Avg
50%    5898       0       0   11419  16509   16151  20626       0      0     4
Max
99%    9301       0       0   18077  26100   23728  87549       0      0   >60

Allocation check on ‘/vol/ds_fast’ is 37, hotspot 0 (threshold 4), consider running reallocate.

В процессе теста, характеризующегося интенсивной записью в тестовый файл, величина фрагментированности на уровне WAFL еще подросла, и составила 37 внутрионтаповских попугая.

Затем я решил проверить то, какое влияние оказывает пресловутая “фрагментация WAFL”, и после отработки второго теста я запустил reallocate start –f /vol/testvol и дождался, пока реаллокация блоков WAFL будет закончена (как видите ниже, она не идеальна, остановилась на “9”, но все же лучше чем была), а затем запусил тест на по-прежнему “фрагментированном” на уровне NTFS файле.

[VM-3rdphase-fragmented-contiguous-state]

Allocation check on ‘/vol/ds_fast’ is 9, hotspot 0 (threshold 4), consider running reallocate.

DSB-NETAPP2> reallocate status -v /vol/ds_fast
Reallocation scans are on
/vol/ds_fast:
        State: Idle
        Flags: whole_vol,measure_only,repeat
    Threshold: 4
     Schedule: n/a
     Interval: 1 day
      NextRun: Fri Oct 19 11:01:16 SGT 2012
Optimization: 9
  Measure Log: n/a

[ramp-up]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
56%    7769       0       0   15198  21572   23137  24943       0      0    55s
54%    7617       0       0   14298  21749   23772  26776       0      0    55s
55%    7384       0       0   14346  20632   21996  30632       0      0    54s
57%    8169       0       0   16216  22459   23572  28296       0      0    54s
56%    7532       0       0   14507  21124   22960  28312       0      0    54s
57%    7821       0       0   15236  21811   23320  26880       0      0    54s
54%    7908       0       0   15333  22097   23948  18324       0      0    54s

[beginning of test]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
72%    6989       0       0   13550  19434   21184  21846       0      0    59s
53%    7385       0       0   14268  20693   22896  21376       0      0    59s
53%    7258       0       0   14200  20176   21572  22144       0      0    59s
53%    7370       0       0   14210  20699   22360  22068       0      0    59s
54%    7446       0       0   14269  21031   22625  22633       0      0    59s
54%    7670       0       0   15007  21295   22448  22272       0      0    59s
54%    7360       0       0   14119  20686   22318  21123       0      0    58s

[end of test]

CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
51%    6652       0       0   12674  18838   20464  22280       0      0     1
45%    6475       0       0   12417  18228   19936   2188       0      0     1
47%    6653       0       0   12913  18593   20432     36       0      0     1
96%    5249       0       0   10205  14650   17732  50947       0      0     1
82%    6035       0       0   11746  16749   19777  22056       0      0     1
47%    6371       0       0   12104  18062   20408  20768       0      0     1
50%    6664       0       0   12870  18699   20228  22739       0      0     1


Summary Statistics ( 2324 samples  0 secs/sample)
CPU     NFS    CIFS    HTTP     Net   kB/s    Disk   kB/s    Tape   kB/s  Cache
                                  in    out    read  write    read  write    age
Min
  0%       0       0       0       0      0       0      0       0      0     0s
Avg
57%    6664       0       0   12893  18658   20621  22416       0      0    58s
Max
99%    8304       0       0   16329  23168   25024 157234       0      0     1

Как видите, производительность на “реаллоцированном”, но фрагментированном файле фактически вернулась к показателям нефрагментированного, свежесозданного файла, что убедительно показывает, что основной вклад в некоторое падение производительности при активной перезаписи вносит именно “фрагментация WAFL”, и после отработки на системе хранения reallocate производительность работы с чудовищно и намеренно фрагментированного файла (25 тысяч фрагментов, разбросанных по диску! В реальной жизни вы такого, уверен, не получите никогда) возвращается к уровню нефрагментированного файла.

Выводы и lessons learned:

Фрагментация данных на диске прикладной системы, лежащей на NetApp, не играет существенной роли роли и не приводит к снижению производительности не только при 100% random, но и при, в значительной мере, смешанном профиле, со значительным (до 40%) секвентальным компонентом. Некоторый наблюдаемый эффект снижения показателей производительности вызывается non-contiguous allocate блоков WAFL, что, вероятно, мешает правильному их кэшированию и read-ahead. Тем не менее даже при ОЧЕНЬ сильно искусственно проявленном эффекте (с уровнем, которого вы никогда в реальной жизни не достигнете) это снижение не превышает 17% от пиковой производительности (снизилась с 7079 до 5898) и достаточно эффективно парируется процедурой WAFL reallocate, работающей как по расписанию, так и при превышении порога. WAFL reallocate, отдельно отмечу, никак не упорядочивает фрагментированный уровнем выше файл на файловой системе поверх WAFL, который остается фрагментированным, а работает только со структурами самого WAFL. Разница на реаллоцированном томе с очень сильно фрагментированным файлом и реаллоцированном, но дефрагментированным, непрерывным (на уровне файловой системы хоста) составляет, как можно видеть выше, менее 8%.

Сим считаю в данном блоге вопрос “влияет ли при практической эксплуатации системы хранения NetApp фрагментация файлов на производительность работы с ними” закрытым: нет, не влияет.

Комментарии (13)

  1. Алексей:

    Хороший труд.
    Что подробнее почитать по reallocate? можно из netapp источников, логин есть.
    Не совсем понимаю что это и как работает.

  2. Я уже года два собираюсь написать все, что удалось разрыть по поводу reallocate, но все собираюсь.
    Проблема внутренних ресурсов NetApp в том, что до определенных источников имеют доступ люди, обладающие только определенным уровнем посвящения, и я лично далек от высших, поэтому что-то для меня остается скрытым :) Но что-то разобрать удалось. Может таки соберусь и напишу, но попозже. Но в этом году, обещаю. :)

  3. Киселев Сергей:

    Роман, а если выделить не 40ГБ диск для хранения 16ГБ тестового файла, а 17ГБ?
    ?? ещё вопрос какой размер датасторе выделялся на NetApp? По хорошему, при выполении тестирования его заполненность должна быть близка к 80-90%.

  4. Киселев Сергей:

    > По хорошему

    По хорошему для кого?
    Я считаю, что тестирование должно давать релевантные решаемой задаче результаты, чтобы его результаты можно было использовать для оценки.
    Я не считаю, что тестирование во что бы то ни стало должно демонстрировать максимально плохой, из всех возможных, результат, измеренный в наихудших из возможных условиях. Я считаю, что измерять надо в близких к реальным условиях, по крайней мере соответствующих рекомендованным производителем best practices.
    Тогда результат будет иллюстрировать практически достижимые показатели, в реально применимых условиях.

    Переводя на любимые в этом блоге автомобильные аналогии: можно нагрузить весь салон легковушки кирпичами, включить первую передачу и втопить газ в пол. Но будет ли полученный результат релевантен задачам легковушки, и что полученный таким образом результат покажет?

    > при выполении тестирования его заполненность должна быть близка к 80-90%.

    Кому она это должна?

  5. bbk:

    Былобы неплохо знать версию датаонтапа на ваших файлерах.

  6. sl0n:

    А как на счет значений для latency, было бы интересно это знать, ??МХО нет смысле в 7K IOPS при, скажем, 50ms latency.

  7. Peter Sergeev:

    > Кому она это должна?

    То, что фрагментация не влияет на производительность при относительно хороших условиях это не так интересно.
    ??нтересно когда она начинает деградировать.
    Заполненность агрегатов на 90-95% это часто данность, с которой нужно жить продолжительное время, без возможности её снизить.
    Какая будет производительность в таких условиях?

  8. Peter Sergeev:

    > Заполненность агрегатов на 90-95% это часто данность, с которой нужно жить

    Работа в нерекомендованных производителем режимах - это плохая “данность”, и bad practice.

  9. Киселев Сергей:

    Роман,
    условия, при которых проводилось тестирование, мало применимы на практике и поэтому мало интересны Заказчику. Было бы интереснее увидеть как поведет себя система в более сложных ситуациях, которые, как ни странно, чаще встречаются в жизни, чем описанные в Best Practices.

  10. Киселев Сергей:

    Сергей, если пользователь игнорирует вендорские рекомендации, то он, конечно, в своем праве, но сам себе злобный буратино. Довольно бессмысленно требовать от вендора испытания микроскопа в качестве инструмента для заколачивания гвоздей, просто потому что покупателю так хочется столь странным способом его использовать. на то и пишутся вендорские Best Practices, чтобы ими руководствоваться при создании системы, а если есть какие-то партнеры, или интеграторы, или конечные пользователи, которые их прямо и осознанно нарушают, руководствуясь какими-то своими представлениями о “правильности”, то нам с такими не по пути :)

  11. Alex:

    А можно узнать значение latency в мс при всех этих тестах? На хосте и на самой СХД. ?? размер очереди тоже был бы полезен. Нигде не указано… Если использовался Iometer, то там это видно.

  12. Обязательно, как-то я этот момент пропустил в статье, но сейчас данные не под руками, а на следующей неделе я дополню пост. Latency ухудшается, конечно, но не катастрофически.

Оставить комментарий