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

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

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

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

Надеюсь не нужно дополнительно объяснять, почему для современных многозадачных систем, для баз 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 ухудшается, конечно, но не катастрофически.

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

20/0.160

Данный блог не спонсируется, не аффилирован, и не санкционирован компанией NetApp, Inc. Излагаемая в этом блоге точка зрения выражает мнение исключительно его автора и может не совпадать с позицией NetApp, Inc.

This content is not endorsed, sponsored or affiliated with NetApp, Inc. The views expressed in this blog are solely those of the author and do not represent the views of NetApp, Inc.