Про ZFS L2ARC

В хорошую погоду zpool iostat -v zdata 5 выглядит теперь так

Но на самом деле, все как-то хуже. Не сильно, но все-таки.

Вот тут случился accidental reboot и я на пустом кэше попробовал так

tar cf /dev/null some-75Gb-folder

Ну и смотрю на скорости (на самом деле там tar cf - .. | mbuffer -s 16k -o /dev/null чтобы скорости видеть):

  • Первый проход: ~650MB/sec (ну так диски отдали), в L2ARC легла ~половина (и что-то в ARC)
  • Второй раз - 750, OK
  • А дальше началось через раз:
    • >1GB/sec и диски практически не трогаются
    • ~750-850Mb/sec и с дисков читается процентов 10-15 (на глазок), остальное из кэшей.

Не понимаю. Файлы не меняются эти,  а вот такая вот фигня.

Этот самый ~1Gb/sec - это столько примерно, сколько умеет кэш отдавать (Patriot Hellfire).

Настройки такие:

vfs.zfs.l2arc_norw=0
vfs.zfs.l2arc_noprefetch=0
vfs.zfs.l2arc_write_max=838860800
vfs.zfs.l2arc_write_boost=838860800

Впрочем, если не скорости мерять, а смотреть на реальную работу, то после прогрева рабочего каталога наступает счастье, даже не столько в bandwidth (даже полгигабайта/сек употребить - проблема), сколько в latency, то же большое количество превьюшек строится быстро. Не так быстро, как с локального SSD, но вполне вот удовлетворительно (конечно, если нужны только превьюшки, то спасал и просто ARC, но он размывался довольно легко). И тихо, диски в NAS не грохочут в процессе.

Пожалуй, это вторые  по важности вложенные в  NAS $250 после 10G (у меня тут вдруг десктоп пошел к ящику по гигабиту, этот ж ужас, как можно так жить...)

Comments

В зависимости от "старости" обращений к ... - либо читаем из кэша не глядя, либо сверяем "явки и пароли" (чек_суммы и пр.), либо честно перечитываем ...

Уверен, что Вы не служили, но ТЕМ НЕ МЕНЕЕ, поздравляю Вас с универсальным МУЖСКИМ праздником.

Чексуммы, по идее, сверяются всегда на zfs.

Возможно я неправильно понимаю или написана какая-то глупость. Данные на диски попасть мимо включённого кэша не могут, поэтому в кэше всегда актуальные данные и они не могут "протухнуть". Тогда "либо читаем из кэша не глядя, либо сверяем "явки и пароли" (чек_суммы и пр.), либо честно перечитываем ..." лишено всякого смысла. Если метаданные/данные есть в кэше читаем из него, иначе читаем с дисков :-).

Нет ли там искусственного разума "если кэш кажется нам медленным, то для стримовой нагрузки читанем еще и с блинов" ?

Вот строго через раз получается наутро:

$ tar cf - folder | mbuffer -s 16k -o /dev/null
summary: 79.0 GiByte in  1min 50.2sec - average of  733 MiB/s
$ tar cf - folder | mbuffer -s 16k -o /dev/null
summary: 79.0 GiByte in  1min 12.7sec - average of 1112 MiB/s
$ tar cf - folder | mbuffer -s 16k -o /dev/null
summary: 79.0 GiByte in  1min 45.1sec - average of  769 MiB/s
$ tar cf - folder | mbuffer -s 16k -o /dev/null
summary: 79.0 GiByte in  1min 11.9sec - average of 1125 MiB/s

 

При этом 700+ - с блинов читается процентов 10 (на глаз), 1100+ - соответственно 0.

Последний раз подходил к l2arc в момент http://blog.lexa.ru/2016/07/24/zfs_l2arc_performance.html. Там у меня и у тебя тоже наблюдалась подобная "скачущая" картинка. Поэтому похоже на "закономерность". Так как l2arc_noprefetch=0, то "искусственный разум" с моей колокольни маловероятен. Природа сего "явления" мне неизвестна, тем более через раз :-). Если очень хочешь разобраться, то я в первую очередь проверил бы - сколько он пишет в l2arc через раз. А так, да - падение на 30% при чтение 10% с hdd напрягает.

Пишет, в первом приближении "ничего" (смотрю по zpool iostat -v). Т.е. да, что-то пишется в L2ARC, но по порядку величины это - доли процента о того, что читается с блинов (это может быть просто вытеснение из ARC чего-то другого, у меня ж система живая, хоть под копеечной, но под нагрузкой).

UPD: нагрузка на этот dataset создается только моей WS и в моменты тестов там если что и "было", то совершенно грошовое, очень близкое к нулю. А вот ARC - вестимо общий с бэкапным dataset, куда со всего дома бэкапятся в какие-то моменты.

Посмотрел сегодня arc.c. Далее только комментарии:
...
* At this point, we have a level 1 cache miss. Try again in
* L2ARC if possible.
...
* Read from the L2ARC if the following are true:
* 1. The L2ARC vdev was previously cached.
* 2. This buffer still has L2ARC metadata.
* 3. This buffer isn't currently writing to the L2ARC.
* 4. The L2ARC entry wasn't evicted, which may
* also have invalidated the vdev.
* 5. This isn't prefetch and l2arc_noprefetch is set.
Твои настройки не запрещают ни один из пунктов.
...
Начиная с 5775 строки, как мне кажется, самый важный комментарий для твоего случая. Желательно его прочитатать полностью. Приведу только, что меня заинтересовало:
...
* Read requests are satisfied from the following sources, in order:
*
* 1) ARC
* 2) vdev cache of L2ARC devices
* 3) L2ARC devices
* 4) vdev cache of disks
* 5) disks
*
* Some L2ARC device types exhibit extremely slow write performance.
* To accommodate for this there are some significant differences between
* the L2ARC and traditional cache design:
*
* 1. There is no eviction path from the ARC to the L2ARC. Evictions from
* the ARC behave as usual, freeing buffers and placing headers on ghost
* lists. The ARC does not send buffers to the L2ARC during eviction as
* this would add inflated write latencies for all ARC memory pressure.
*
* 2. The L2ARC attempts to cache data from the ARC before it is evicted.
* It does this by periodically scanning buffers from the eviction-end of
* the MFU and MRU ARC lists, copying them to the L2ARC devices if they are
* not already there. It scans until a headroom of buffers is satisfied,
* which itself is a buffer for ARC eviction. If a compressible buffer is
* found during scanning and selected for writing to an L2ARC device, we
* temporarily boost scanning headroom during the next scan cycle to make
* sure we adapt to compression effects (which might significantly reduce
* the data volume we write to L2ARC). The thread that does this is
* l2arc_feed_thread(), illustrated below; example sizes are included to
* provide a better sense of ratio than this diagram:
...
* 3. If an ARC buffer is copied to the L2ARC but then hit instead of
* evicted, then the L2ARC has cached a buffer much sooner than it probably
* needed to, potentially wasting L2ARC device bandwidth and storage. It is
* safe to say that this is an uncommon case, since buffers at the end of
* the ARC lists have moved there due to inactivity.
*
* 4. If the ARC evicts faster than the L2ARC can maintain a headroom,
* then the L2ARC simply misses copying some buffers. This serves as a
* pressure valve to prevent heavy read workloads from both stalling the ARC
* with waits and clogging the L2ARC with writes. This also helps prevent
* the potential for the L2ARC to churn if it attempts to cache content too
* quickly, such as during backups of the entire pool.
*
* 5. After system boot and before the ARC has filled main memory, there are
* no evictions from the ARC and so the tails of the ARC_mfu and ARC_mru
* lists can remain mostly static. Instead of searching from tail of these
* lists as pictured, the l2arc_feed_thread() will search from the list heads
* for eligible buffers, greatly increasing its chance of finding them.
*
* The L2ARC device write speed is also boosted during this time so that
* the L2ARC warms up faster. Since there have been no ARC evictions yet,
* there are no L2ARC reads, and no fear of degrading read performance
* through increased writes.
*
* 6. Writes to the L2ARC devices are grouped and sent in-sequence, so that
* the vdev queue can aggregate them into larger and fewer writes. Each
* device is written to in a rotor fashion, sweeping writes through
* available space then repeating.
*
* 7. The L2ARC does not store dirty content. It never needs to flush
* write buffers back to disk based storage.
*
* 8. If an ARC buffer is written (and dirtied) which also exists in the
* L2ARC, the now stale L2ARC buffer is immediately dropped.
...
Осталось выработать гипотезу и придумать как её проверить :-).

Я прочитал (целиком комментарий, не только цитату).

Гипотеза получается странная, вот с середины теста (быстрый прогон).
- L2ARC - 90% (условная цифра), ARC - 10%. Блины не трогаем. читаем все с SSD+RAM.
- в процессе этого чтения, мы вытесняем все из ARC, но так, что оно не пишется в L2
- и следующий тест читает 10% уже с блинов. Эти 10% оказываются в ARC, их не вытесняет.
- на колу мочало, начинай с начала.

Но, блин.

Странная - не странная, но она мне тоже пришла в голову :-). Только думаю не 10%, а наверно побольше и наверно эта цифра всё таки постепенно уменьшается. Если картинка ещё повторяется, то стоит ещё добавить между прогонами iostat -Ix и показать значения для l2arc-диска. Думаю по объёму прочитанных данных с него, может всё и прояснится :-).

zpool iostat нормально ж показывает что там читается с L2.
Интересно будет попробовать с ограничением скорости прогрева. Так, по идее, если мы читаем медленно, то может помочь.

Я буду тут когда-то (в марте) электричество перекладывать, вот на пустом L2 тогда и попробую

А какая разница на пустом или заполненном? Важно только на повторяющейся картинке увидеть объём считанных данных с l2arc-диска при тестовом прогоне, сравнить с общим прочитанным объёмом и посмотреть на динамику изменения при следующих прогонах.

Меня волнует, скорее, рецепт "как заполнить". Во всяком случае, попробовать медленное чтение явно стоит.

А про объем - это попытка понять "сколько взялось из ARC" ? (все что не с блинов и не с SSD)

Если объём считывания из l2arc-диска не изменяется (или даже увеличивается от раза к разу), а скорость скачет, то гипотеза верна. А если известна причина, то можно поискать решение :-). На счёт медленного чтения у меня пока больше сомнений.

Другое умозрительное решение - это добиться ARC eviction. Путем чтения FS у которой secondarycache=metadata

P.S. перебутил тут ящик, руки чесались там диски переключить из daN в adaN, если вечером будет время - буду мерять IO.

Это ведь зависит от заложенной логики...

Ну так как l2arc имеет право отвалиться в любую секунду - логика должна быть такой.

Этот самый ~1Gb/sec - это столько примерно, сколько умеет кэш отдавать (Patriot Hellfire).
Почему 1Gb? Он же вроде по спецификации должен 3 отдавать?

Интересная картинка
https://3dnews.ru/assets/external/illustrations/2016/09/26/939978/graph-...

С vfs.zfs.vdev.max_pending игрались? Или как ещё в ZFS можно регулировать QD?

Я как-то боюсь, что при чтении из кэша - особо и никак.

Оно и не надо особо, с учетом скорости сети, гигабайт - в самый раз.

Если ещё актуальна идея - записывать всё, что выталкивается из arc в l2arc, то стоит обратить внимание на vfs.zfs.l2arc_feed_min_ms и vfs.zfs.l2arc_headroom.

Народ, у вас у всех 10гигабитные карты и коммутаторы, что вы так боретесь за скорость чтения?))

У меня - да, 10Gbit. И, AFAIK, не только у меня из тут читающих/комментирующих.

Ну и в принципе 5Gbit уже вполне пошли в народ. Да и 10Gbit карта медная системы "китайский интел" стоит сейчас баксов 100 же.

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

К двухпортовой карте в NAS можно подключить две рабочие станции напрямую, без коммутатора.

Ну и коммутатор вида 2 десятки (одна в NAS, другая в рабочую станцию) + 8 гигабитов - стоит вполне подъемных денег.