понедельник, 26 октября 2009 г.

Оперативная память и ZFS III

Несмотря на утверждения некоторых специалистов Sun, что-де ZFS лучше знает и в тюнинге не нуждается, все чаще оказывается, что это утверждение не вполне соответствует действительности. Касательно очень многих приложений, прежде всего, СУБД и некоторых комплексных решений.

В предыдущих статьях - здесь и здесь - я писал о том, что нужно во многих случаях менять параметры хранения ZFS. Это действительно так, подстройка recordsize позволяет облегчить выполнение IO-операций.

Несмотря на эти мероприятия, однако, ZFS (а точнее, его ARC) по умолчанию склонен к расползанию по оперативной памяти. Насколько велико это расползание? Давайте попробуем посмотреть, сколько в точности потребляет ARC и нельзя ли что-нибудь с этим сделать.

Замечание: Да, понятно, что тюнинг-зло. Да, понятно, что ZFS разработана чтобы не красть память у приложений и возвращать ее по первому требованию. Однако, как быть с накладными расходами на освобождение в критичных по отклику системах?

Так как статистика ZFS не находится на поверхности и не относится к легкодоступным, воспользуемся почти сановскими инструментами - arcstat.pl и arc_summary.pl.

Можно также взять сырые данные непосредственно при помощи kstat -m zfs, однако они не вполне в удобоваримом виде.

Вышеуказанные скрипты как раз дают возможность перемолоть данные kstat и представить в пригодном к употреблению виде.

Посмотрим на две системы. Первая - SPARC, 4 Гб RAM, вся на ZFS, вторая x64, 4 Гб RAM, тоже вся на ZFS:

root @ host1 / # ./arcstat.pl
Time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
13:19:21 997K 20K 2 9K 1 10K 10 11K 4 1G 3G
13:19:22 2 0 0 0 0 0 0 0 0 1G 3G
13:19:23 0 0 0 0 0 0 0 0 0 1G 3G
13:19:24 0 0 0 0 0 0 0 0 0 1G 3G
13:19:25 0 0 0 0 0 0 0 0 0 1G 3G
^C

root @ host2 / # arcstat.pl
Time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
13:20:51 157K 25K 16 15K 11 10K 44 4K 12 743M 3G
13:20:52 4 0 0 0 0 0 0 0 0 743M 3G
13:20:53 0 0 0 0 0 0 0 0 0 743M 3G
13:20:54 0 0 0 0 0 0 0 0 0 743M 3G
13:20:55 0 0 0 0 0 0 0 0 0 743M 3G
^C

Нас особенно интересуют два последних столбца. Что они означают?

Дабы это понять, спросим второй скрипт (обратите внимание, что это статистика первого хоста):

root @ host1 / # ./arc_summary.pl
System Memory:
Physical RAM: 4017 MB
Free Memory : 1731 MB
LotsFree: 62 MB

ZFS Tunables (/etc/system):

ARC Size:
Current Size: 1179 MB (arcsize)
Target Size (Adaptive): 3013 MB (c)
Min Size (Hard Limit): 376 MB (zfs_arc_min)
Max Size (Hard Limit): 3013 MB (zfs_arc_max)

ARC Size Breakdown:
Most Recently Used Cache Size: 49% 1506 MB (p)
Most Frequently Used Cache Size: 50% 1506 MB (c-p)

ARC Efficency:
Cache Access Total: 997204
Cache Hit Ratio: 97% 976716 [Defined State for buffer]
Cache Miss Ratio: 2% 20488 [Undefined State for Buffer]
REAL Hit Ratio: 88% 885287 [MRU/MFU Hits Only]

Data Demand Efficiency: 99%
Data Prefetch Efficiency: 58%
....

А вот что: arcsz это текущий размер ARC, а в последнем столбце у нас Target Size, то есть величина, до которой разрешается расползаться кэшу. Первая же поверхностная проверка показывает, что в большинстве машин с ZFS данное значение выбирается из соотношения приблизительно 3/4 всей оперативной памяти.

Для некоторых приложений это то, что нужно. Но не для всех.

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

Нельзя ли что-нибудь втереть, или вправить или еще что-нибудь?

Конечно, можно.

Воспользуемся лимитом и ограничим для второй машины размеры ARC величиной 1 Гб - то есть 1/4 от оперативной памяти (на ней как раз находится Oracle, OHS и webcache):

set zfs:zfs_arc_max=1073741824

Насколько изменились показатели?

root @ host2 / # arc_summary.pl
System Memory:
Physical RAM: 4087 MB
Free Memory : 2032 MB
LotsFree: 63 MB

ZFS Tunables (/etc/system):
set zfs:zfs_arc_max=1073741824

ARC Size:
Current Size: 797 MB (arcsize)
Target Size (Adaptive): 1024 MB (c)
Min Size (Hard Limit): 128 MB (zfs_arc_min)
Max Size (Hard Limit): 1024 MB (zfs_arc_max)

ARC Size Breakdown:
Most Recently Used Cache Size: 61% 630 MB (p)
Most Frequently Used Cache Size: 38% 393 MB (c-p)

ARC Efficency:
Cache Access Total: 232698
Cache Hit Ratio: 87% 203107 [Defined State for buffer]
Cache Miss Ratio: 12% 29591 [Undefined State for Buffer]
REAL Hit Ratio: 80% 188141 [MRU/MFU Hits Only]

Data Demand Efficiency: 92%
Data Prefetch Efficiency: 33%
...

Первое приближение показывает, что объем свободной памяти (действительно свободной) увеличился примерно вчетверо, статистика ARC (выше) хуже не стала, отклик остался практически прежним, однако количество переключений контекста упало.

Что важно - практически минимизировался чекпоинтинг ZFS (больший кэш не всегда лучше), реально освободилась память. Если раньше эта машина была весьма склонна к пожиранию свободной памяти настолько (не безвозвратно, и тем не менее), что метрику Oracle EM free_memory приходилось задирать, то теперь она удерживается в разумных рамках.

Кроме того, чрезмерно большой кэш в ряде случаев будет склонен к переохлаждению, то есть будет заметно падать Hit ratio.

У меня не сохранилось для интересующей нас машины начальной статистики, однако новая статистика ARC объективно лучше:

root @ host2 / # arc_summary.pl
System Memory:
Physical RAM: 4087 MB
Free Memory : 2028 MB
LotsFree: 63 MB

ZFS Tunables (/etc/system):
set zfs:zfs_arc_max=1073741824

ARC Size:
Current Size: 800 MB (arcsize)
Target Size (Adaptive): 1024 MB (c)
Min Size (Hard Limit): 128 MB (zfs_arc_min)
Max Size (Hard Limit): 1024 MB (zfs_arc_max)

ARC Size Breakdown:
Most Recently Used Cache Size: 61% 632 MB (p)
Most Frequently Used Cache Size: 38% 391 MB (c-p)

ARC Efficency:
Cache Access Total: 237200
Cache Hit Ratio: 87% 207433 [Defined State for buffer]
Cache Miss Ratio: 12% 29767 [Undefined State for Buffer]
REAL Hit Ratio: 80% 191734 [MRU/MFU Hits Only]

Data Demand Efficiency: 92%
Data Prefetch Efficiency: 35%
...

Кроме того, ообратите внимание, что, поскольку мы реально не используем 3 Гб под кэш ARC, то нет смысла резервировать под target 3/4 оперативной памяти, оставив эту память под другие приложения.

Да, ZFS и так бы освободила память по запросу - однако в большинстве случаев ценой дисковой записи по чекпойнту.

Так что, заявления вида "Tuning is Evil" представляются в некоторых случаях весьма спорными. ;)

Лучше, чем у авторов заявления не скажешь (читать внимательно):

[цитата]
Tuning is Evil

Tuning is often evil and should rarely be done.

First, consider that the default values are set by the people who know the most about the effects of the tuning on the software that they supply. If a better value exists, it should be the default. While alternative values might help a given workload, it could quite possibly degrade some other aspects of performance. Occasionally, catastrophically so.

Over time, tuning recommendations might become stale at best or might lead to performance degradations. Customers are leery of changing a tuning that is in place and the net effect is a worse product than what it could be. Moreover, tuning enabled on a given system might spread to other systems, where it might not be warranted at all.

Nevertheless, it is understood that customers who carefully observe their own system may understand aspects of their workloads that cannot be anticipated by the defaults. In such cases, the tuning information below may be applied, provided that one works to carefully understand its effects.

[конец цитаты]

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