ZFS на linux - L2ARC не читается

Сегодня я провел несколько тестов на L2ARC с использованием последней версии ZFS на Linux 0.7.10. Я видел, что L2ARC заполняется данными, но с настройками модуля по умолчанию данные, находящиеся в кэше L2ARC, никогда не затрагиваются. Вместо этого данные считываются из vdev главного пула. Я также видел такое поведение в 0.7.9, и я не уверен, что это ожидаемое поведение.

Сегодня я провел несколько тестов на L2ARC с использованием последней версии ZFS для Linux 0.7.10. Я видел, что L2ARC заполняется данными, но с настройками модуля по умолчанию данные, находящиеся в кэше L2ARC, никогда не затрагиваются. Вместо этого данные считываются из vdev главного пула. Я также видел такое поведение в 0.7.9, и я не уверен, что это ожидаемое поведение.

Сегодня я провел несколько тестов на L2ARC с использованием последней версии ZFS для Linux 0.7.10. Я видел, что L2ARC заполняется данными, но с настройками модуля по умолчанию данные, находящиеся в кэше L2ARC, никогда не затрагиваются. Вместо этого данные считываются из vdev главного пула. Я также видел такое поведение в 0.7.9, и я не уверен, что это ожидаемое поведение.
Даже если это было бы ожидаемым поведением, я думаю, что странно портить L2ARC данными, которые никогда не читаются.


Тестовая установка представляет собой виртуальную машину:

  • CentOS 7.5 с последними исправлениями
  • ZFS на Linux 0.7 .10
  • 2 ГБ ОЗУ

Я сделал несколько настроек ZFS:

  • l2arc_headroom = 1024 и l2arc_headroom = 1024 , чтобы ускорить пополнение L2ARC

Вот как пул Создан и макет. Я знаю, что это довольно странно для реальной установки, но это было предназначено только для тестирования L2ARC.

[root@host ~]# zpool create tank raidz2 /dev/sda /dev/sdb /dev/sdc cache sdd -f
[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G   333K  2.95G         -     0%     0%  1.00x  ONLINE  -
  raidz2  2.95G   333K  2.95G         -     0%     0%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M    512  1009M         -     0%     0%

Теперь запишите некоторые данные в файл и посмотрите, как используется устройство.

[root@host ~]# dd if=/dev/urandom of=/tank/testfile bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 9.03607 s, 59.4 MB/s

[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G  1.50G  1.45G         -    10%    50%  1.00x  ONLINE  -
  raidz2  2.95G  1.50G  1.45G         -    10%    50%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M   208M   801M         -     0%    20%

Хорошо, некоторые данные уже были перемещены в L2ARC, но не все. Итак, прочтите его еще несколько раз, чтобы полностью преобразовать его в L2ARC.

[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 # until L2ARC is populated with the 512MB testfile

[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G  1.50G  1.45G         -    11%    50%  1.00x  ONLINE  -
  raidz2  2.95G  1.50G  1.45G         -    11%    50%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M   512M   498M         -     0%    50%

Хорошо, L2ARC заполнен и готов к чтению. Но сначала нужно избавиться от L1ARC. Я сделал следующее, Итак, снова запустив команду dd if = / tank / testfile of = / dev / null bs = 512 , я наблюдал за zpool iostat -v 5 во втором терминале.

К моему удивлению, файл был прочитан из обычных vdev вместо L2ARC, хотя файл находится в L2ARC. Это единственный файл в файловой системе, и во время моих тестов не было никаких других действий.

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G    736     55  91.9M  96.0K
  raidz2    1.50G  1.45G    736     55  91.9M  96.0K
    sda         -      -    247     18  30.9M  32.0K
    sdb         -      -    238     18  29.8M  32.0K
    sdc         -      -    250     18  31.2M  32.0K
cache           -      -      -      -      -      -
  sdd        512M   498M      0      1  85.2K  1.10K
----------  -----  -----  -----  -----  -----  -----

Затем я поигрался с некоторыми настройками, такими как zfetch_array_rd_sz , zfetch_max_distance , zfetch_max_streams , l2arc_write_boost и l2arc_write_max , устанавливая их на нечетное большое число. Но ничего не изменилось.

После изменения

  • l2arc_noprefetch = 0 (по умолчанию 1 )
  • или zfs_prefetch_disable = 1 (по умолчанию 0 )
  • переключить оба с их значений по умолчанию

чтение обслуживается из L2ARC. Снова запускаем dd if = / tank / testfile of = / dev / null bs = 512 и просматриваем zpool iostat -v 5 во втором терминале и избавляемся от L1ARC.

[root@host ~]# echo 0 > /sys/module/zfs/parameters/l2arc_noprefetch 
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
...
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 

И результат:

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G      0     57    921   102K
  raidz2    1.50G  1.45G      0     57    921   102K
    sda         -      -      0     18      0  34.1K
    sdb         -      -      0     18      0  34.1K
    sdc         -      -      0     19    921  34.1K
cache           -      -      -      -      -      -
  sdd        512M   497M    736      0  91.9M   1023
----------  -----  -----  -----  -----  -----  -----

Теперь данные читаются из L2ARC, но только после переключения упомянутых выше параметров модуля.

Я также читал, что L2ARC может иметь слишком большой размер. Но темы, которые я обнаружил по этой теме, касались проблем с производительностью или карты пространства для L2ARC, портящей L1ARC.
Снова запускаем dd if = / tank / testfile of = / dev / null bs = 512 и просматриваем zpool iostat -v 5 во втором терминале и избавляемся от L1ARC.

[root@host ~]# echo 0 > /sys/module/zfs/parameters/l2arc_noprefetch 
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
...
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 

И результат:

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G      0     57    921   102K
  raidz2    1.50G  1.45G      0     57    921   102K
    sda         -      -      0     18      0  34.1K
    sdb         -      -      0     18      0  34.1K
    sdc         -      -      0     19    921  34.1K
cache           -      -      -      -      -      -
  sdd        512M   497M    736      0  91.9M   1023
----------  -----  -----  -----  -----  -----  -----

Теперь данные читаются из L2ARC, но только после переключения параметров модуля, упомянутых выше.

Я также читал, что L2ARC может иметь слишком большой размер. Но темы, которые я обнаружил по этой теме, касались проблем с производительностью или карты пространства для L2ARC, портящей L1ARC.
Снова запускаем dd if = / tank / testfile of = / dev / null bs = 512 и просматриваем zpool iostat -v 5 во втором терминале и избавляемся от L1ARC.

[root@host ~]# echo 0 > /sys/module/zfs/parameters/l2arc_noprefetch 
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
...
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 

И результат:

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G      0     57    921   102K
  raidz2    1.50G  1.45G      0     57    921   102K
    sda         -      -      0     18      0  34.1K
    sdb         -      -      0     18      0  34.1K
    sdc         -      -      0     19    921  34.1K
cache           -      -      -      -      -      -
  sdd        512M   497M    736      0  91.9M   1023
----------  -----  -----  -----  -----  -----  -----

Теперь данные читаются из L2ARC, но только после переключения упомянутых выше параметров модуля.

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

[root@host ~]# grep hdr /proc/spl/kstat/zfs/arcstats 
hdr_size                        4    279712
l2_hdr_size                     4    319488

Как уже упоминалось, я не уверен, является ли это предполагаемым поведением или я что-то упускаю.

2
задан 9 September 2018 в 18:31
2 ответа

Итак, после прочтения этой темы, в основном этого сообщения , кажется, что это стандартное поведение ZFS.

Что происходит, так это то, что файл пробивает себе дорогу в L1ARC после чтения и из-за доступа к блокам он считается помещенным в L2ARC.
Теперь при втором чтении файла ZFS выполняет предварительную выборку файла, минуя L2ARC, хотя блоки файла хранятся в L2ARC.

Если полностью отключить предварительную выборку с помощью zfs_prefetch_disable = 1 или указать ZFS выполнить предварительную выборку на L2ARC с помощью l2arc_noprefetch = 0 , при чтении будут использоваться блоки файла, находящиеся в L2ARC.
Это может быть желательно, если ваш L2ARC достаточно велик по сравнению с размерами файлов, которые читаются.
Но можно было бы поместить только метаданные в L2ARC с zfs, установленным вторичным кэшем = резервуар метаданных . Это предотвращает попадание больших файлов в L2ARC и невозможность их чтения. Поскольку это испортит L2ARC и может вытеснить блоки файлов меньшего размера, которые не были предварительно загружены, и метаданные, которые вы хотите сохранить в L2ARC.

Я не нашел способа указать ZFS помещать только небольшие файлы в L2ARC и не объединять кандидатов предварительной выборки в L2ARC. Так что на данный момент, в зависимости от размеров файлов и размера L2ARC, приходится идти на компромисс.
Похоже, что в версии ZoL 0.8.0 доступен другой подход, где можно использовать разные классы распределения и сделать возможным, например, размещайте метаданные на быстрых SSD, а блоки данных оставляйте на медленных вращающихся дисках. Это по-прежнему оставит конкуренцию маленьких файлов против больших файлов для L2ARC, но решит проблему быстрого доступа к метаданным.

2
ответ дан 3 December 2019 в 10:33

В этом случае происходит то, что ZFS пытается сохранить полосу пропускания L2ARC для случайных / непотоковых операций чтения, когда попадание в физические диски может нанести ущерб производительности. Потоковое чтение достаточно хорошо обслуживается с механических жестких дисков, и любой пул с дисками 6/8 +, вероятно, превзойдет любое устройство SATA L2ARC для последовательного чтения. И любой zpool среднего размера (например, 24/48 + дисков) даст достаточную последовательную реальную полосу пропускания.

Как вы обнаружили, вы можете изменить L2ARC, чтобы он вел себя как кэш жертвы ( то есть:хранить все, что выселено из ARC; если блок обнаружен на L2ARC, даже не пытайтесь получить доступ к основному пулу). В некоторых случаях это может быть хорошо; однако ZFS была (правильно) спроектирована так, чтобы сохранить износ / использование L2ARC там, где это может быть действительно выгодно: кэшировать действительно использованные блоки для более быстрой производительности произвольного чтения.

1
ответ дан 3 December 2019 в 10:33

Теги

Похожие вопросы