Заполнение кеша ZFS L2ARC в Solaris 11.3

Есть ли хороший способ заполнить кэш ZFS L2ARC на Solaris 11.3?

L2ARC предназначен для игнорирования блоков, которые были последовательно прочитаны из файла. Это имеет смысл для текущей работы, но затрудняет заполнение кеша для первоначального прогрева или тестирования производительности.

Кроме того, для сильно фрагментированных файлов может быть очень полезно последовательное чтение, кэшируемое в L2ARC (потому что на диске это случайное чтение), но при текущей эвристике эти файлы никогда не будут кэшироваться, даже если L2ARC заполнен только на 10%.

В предыдущих выпусках Solaris 10 и 11 я успешно пользовался dd дважды по каждому файлу. Первый dd прочитайте файл в ARC, а второй dd казалось, щекотали буферы, поэтому они стали подходящими для кэширования L2ARC. Эта же техника не работает в Solaris 11.3.

Я подтвердил, что данные файлы имеют размер записи 8 Кб, и я попытался установить zfs_prefetch_disable но это не повлияло на поведение L2ARC ОБНОВИТЬ: zfs_prefetch_disable оказывается важным, см. мой ответ ниже.

Если нет хорошего способа сделать это, я бы рассмотрел использование инструмента, который генерирует случайное чтение более 100% файла. Это может стоить времени, учитывая, что кэш-память сохраняется в 11.3. Существуют ли подобные инструменты?

2 ответа

Немного поэкспериментировав, я нашел четыре возможных решения.

При каждом подходе вам нужно выполнить шаги, а затем продолжить читать больше данных, чтобы заполнить кэш ZFS ARC и инициировать подачу из ARC в L2ARC. Обратите внимание, что если данные уже кэшированы в памяти или если сжатый размер на диске каждого блока превышает 32 КБ, эти методы обычно ничего не делают.

1. Установите задокументированный флаг ядраzfs_prefetch_disable

По умолчанию L2ARC отказывается кэшировать данные, которые были автоматически предварительно выбраны. Мы можем обойти это, отключив функцию предварительной выборки ZFS. Этот флаг часто является хорошей идеей для рабочих нагрузок базы данных в любом случае.

echo "zfs_prefetch_disable/W0t1" | mdb -kw

..или, чтобы установить его постоянно, добавьте следующее к /etc/system:

set zfs:zfs_prefetch_disable = 1

Теперь, когда файлы читаются с помощью dd, они по-прежнему будут иметь право на L2ARC.

На практике это изменение также улучшает поведение операций чтения в моем тестировании. Обычно, когда ZFS обнаруживает последовательное чтение, она балансирует пропускную способность между данными vdevs и кэшем vdevs вместо простого чтения из кэша - но это снижает производительность, если устройства кэширования имеют значительно меньшую задержку или более высокую пропускную способность, чем устройства данных.

2. Переписать данные

Поскольку данные записываются в файловую систему ZFS, они кэшируются в ARC и (если они соответствуют критериям размера блока) могут быть переданы в L2ARC. Переписать данные не всегда просто, но некоторые приложения и базы данных могут сделать это вживую, например, путем зеркального отображения файлов уровня приложения или перемещения файлов данных.

Проблемы:

  • Не всегда возможно в зависимости от приложения.
  • Занимает дополнительное пространство, если используются снимки.
  • (Но с другой стороны, полученные файлы дефрагментируются.)

3. Снимите недокументированный флаг ядраl2arc_noprefetch

Это основано на чтении исходного кода OpenSolaris и, без сомнения, полностью не поддерживается. Используйте на свой риск.

  1. Отключить l2arc_noprefetch флаг:

    echo "l2arc_noprefetch/W0" | mdb -kw
    

    Данные, считанные в ARC, когда этот флаг отключен, будут иметь право на L2ARC, даже если это последовательное чтение (если блоки имеют максимум 32 КБ на диске).

  2. Прочитать файл с диска:

    dd if=filename.bin of=/dev/null bs=1024k
    
  3. Снова включите l2arc_noprefetch флаг:

    echo "l2arc_noprefetch/W1" | mdb -kw
    

4. Читайте данные случайным образом

Я написал сценарий Perl для чтения файлов в 8-килобайтных блоках псевдослучайно (на основе порядка хэша Perl). Это может также работать с большими кусками, но я еще не проверял это.

#!/usr/bin/perl -W

my $BLOCK_SIZE = 8*2**10;
my $MAX_ERRS = 5;

foreach my $file (@ARGV) {
        print "Reading $file...\n";
        my $size;
        unless($size = (stat($file))[7]) {print STDERR "Unable to stat file $file.\n"; next; }
        unless(open(FILE, "<$file")) {print STDERR "Unable to open file $file.\n"; next; }
        my $buf;
        my %blocks;
        for(my $i=0;$i<$size/$BLOCK_SIZE;$i++) { $blocks{"$i"} = 0; }
        my $errs = 0;
        foreach my $block (keys %blocks) {
                unless(sysseek(FILE, $block*$BLOCK_SIZE, 0) && sysread(FILE, $buf, $BLOCK_SIZE)) {
                        print STDERR "Error reading $BLOCK_SIZE bytes from offset " . $block * $BLOCK_SIZE . "\n";
                        if(++$errs == $MAX_ERRS) { print STDERR "Giving up on this file.\n"; last; }
                        next;
                }
        }
        close(FILE);
}

Проблемы:

  • Это занимает много времени и увеличивает нагрузку на диск.

Оставшиеся проблемы

  • Вышеуказанные методы доставят данные в основную память, пригодную для подачи в L2ARC, но они не запускают подачу. Единственный известный мне способ запуска записи в L2ARC - это продолжить чтение данных, чтобы оказать давление на ARC.
  • На Solaris 11.3 с SRU 1.3.9.4.0 L2ARC очень редко увеличивает ожидаемый объем. evict_l2_eligible kstat увеличивается даже тогда, когда устройства SSD не находятся под давлением, указывая, что данные отбрасываются. Это оставшееся количество не кэшированных данных оказывает несоразмерное влияние на производительность.

Я бы посоветовал использовать реальную рабочую нагрузку и отслеживать результат с arcstat,

Что-то вроде:

arcstat.py -f "time,read,l2read,hit%,hits,miss%,miss,l2hit%,l2miss%,arcsz,c,l2size" 1

Я не думаю, что есть необходимость "заправлять" кеш. Если ваша рабочая нагрузка не заполняет кэш-память естественным образом, то это не репрезентативная рабочая нагрузка, верно?

Может быть, у вас есть исключительный вариант использования (какой у вас размер набора данных, размер ARC и размер рабочего набора?), Но в целом акцент на L2ARC переоценен.

Другие вопросы по тегам