понедельник, 15 июня 2009 г.

ZIL на RAM-диске и скорость, Часть I

"Здравствуйте, джентльмены, здравствуйте, мои дорогие! Что-то вы плохо выглядите, давайте-ка я вас осмотрю!" *

В одной из прошлых статей я собирался рассказать об одном занятном эксперименте, который планировал.

Ну, в общем, первый результат уже есть. Он еще сырой и не претендует на полноту и глубину, но некоторые предварительные проработки были сделаны.

Как сказано в Писании, если читать глубоко и внимательно - если положить ZIL (ZFS Intent Log) файловой системы ZFS на быстродействующее устройство, то можно ощутимо ускорить операции записи.

Поскольку быстрее памяти диска нет, идея заключается в том, чтобы попытаться положить ZIL на RAM-диск и посмотреть, стоит ли овчинка выделки.

Давайте посмотрим, как это выглядит.

Итак, я взял игрушечную машинку, SunFire v215, об одном процессоре SPARC-IIIi, одном гигабайте RAM, и двух одинаковых дисках SAS 10K по 73 Гб. Установил на нее Solaris 10 5/09 JumpStart'ом на UFS на второй диск, и, после минимизации (дабы легче летелось и чтобы освободить оперативную память), установил на нее уже написанный SMF-сервис RAM-диска.

Предварительно опытным путем был определен максимальный размер RAM-диска на данной системе - он составил 190 Мб.

Мда, не густо. Ну, у нас и на руках-то всего 1 Гб RAM. Жаловаться грех, а поиграться хватит.

Нам нужно устройство без файловой системы, без бэкапа (пока) и восстановления данных (нам пофигу на данный момент целостность лога), посему делаем необходимые изменения в управляющем методе, согласно readme, и приступаем к установке сервиса:

server5# ./ramdisk_smf_inst.sh
-------------------------------------------
- Ramdisk SMF service will be install now -
- ... -
-------------------------------------------

Copying Ramdisk SMF files...
*** XML service descriptor validation successful
*** XML service descriptor import successful
Verify Ramdisk SMF installation...
STATE STIME FMRI
disabled 19:04:35 svc:/system/ramdisk:default
If Ramdisk services installed correctly, enable and start it now
server5# svcadm enable ramdisk
server5# svcs ramdisk
STATE STIME FMRI
online 19:04:41 svc:/system/ramdisk:default

Порядок. Проверяем наличие RAM-диска:

server5# ramdiskadm
Block Device Size Removable
/dev/ramdisk/root 167116800 No
/dev/ramdisk/ramdisk1

Присутствует.

Теперь создадим ZFS-пул на первом (свободном) диске:

server5# zpool create -f data c0t0d0s0 log /dev/ramdisk/ramdisk1
server5# zpool status
pool: data
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
c0t0d0s0 ONLINE 0 0 0
logs ONLINE 0 0 0
/dev/ramdisk/ramdisk1 ONLINE 0 0 0

errors: No known data errors

Обратите внимание, что на корне системы (c0t1d0s0) у нас смонтированы все UFS операционной системы, а на диске c0t0d0s0 во весь объем создан ZFS-пул.

Поскольку машина откровенно слабовата для, скажем, заруба в Oracle EE, мы пока поиграем совсем в простые игры.

Итак, тесты. Мы будем создавать и копировать файлы. На UFS и ZFS. На время, насколько точно мы сможем его измерить. Не очень огромные файлы (позже я объясню, почему), а просто чтобы увидеть закономерности, буде таковые будут.

Тест 1
------

На UFS:
server5# cd /
server5# date; mkfile 100m test1.file; date
Monday, June 15, 2009 8:21:06 PM ALMT
Monday, June 15, 2009 8:21:08 PM ALMT
~3 сек

На ZFS:
server5# cd /data
server5# date; mkfile 100m test2.file; date
Monday, June 15, 2009 8:21:22 PM ALMT
Monday, June 15, 2009 8:21:23 PM ALMT
~1 сек

Гм, недурной разбег. Однако один раз - не голубой, и надо хоть какую-то статистику. Обратите внимание, размер файла составил примерно 60% от объема ZIL.

Играем далее.

Тест 2
------

На UFS:
server5# cd /
server5# date; mkfile 180m test1.file; date
Monday, June 15, 2009 8:28:12 PM ALMT
Monday, June 15, 2009 8:28:15 PM ALMT
~3 сек

На ZFS:
server5# cd /data
server5# date; mkfile 180m test2.file; date
Monday, June 15, 2009 8:28:30 PM ALMT
Monday, June 15, 2009 8:28:32 PM ALMT
~2 сек

Так, при приближении к размеру ZIL разница практически выравнивается (множественные прогоны это подтверждают, особенно следующий тест). Прошу заметить, что одиночную запись такого размера вы нечастно встретите, скажем, в СУБД. Разве что LOB.

Ради полноты проверки подтвердим одну нарождающуюся гипотезу:

Тест 3
------

На UFS:
server5# cd /
server5# date; mkfile 512m test1.file; date
Monday, June 15, 2009 8:32:40 PM ALMT
Monday, June 15, 2009 8:32:48 PM ALMT
~8 сек

На ZFS:
server5# cd /data
server5# date; mkfile 512m test2.file; date
Monday, June 15, 2009 8:33:03 PM ALMT
Monday, June 15, 2009 8:33:11 PM ALMT
~8 сек

"Ага!!!" - сказали мужики. Если объем записи превышает размер ZIL, разница в скорости записи на UFS и ZFS практически стремиться к нулю. Напоминаю - диски абсолютно идентичные.

Ладно, хорошо. Идем дальше.

Давайте возьмем записи более реалистичного размера и менее реалистичного и покатаемся с ними. Причем покатаемся так. Будем копировать из файла в файл в пределах файловой системы, то есть прямо так - с UFS на UFS, с ZFS на ZFS.

Это не БД, конечно, но что-то ее хотя бы отдаленно напоминающее - читаем с диска и на него же пишем.

Тест 4
------

Копирование созданного файла 512m

На UFS:
server5# cd /
server5# date; cp test1.file test2.file; date
Monday, June 15, 2009 8:37:06 PM ALMT
Monday, June 15, 2009 8:37:22 PM ALMT
~14 сек

На ZFS:
server5# cd /data
server5# date; cp test2.file test3.file; date
Monday, June 15, 2009 8:35:12 PM ALMT
Monday, June 15, 2009 8:35:26 PM ALMT
~14 секунд

Тэкс, что мы видим. Тот же результат, что и просто при записи. Все, что превышает размер ZIL, не тормозит, конечно, но разница практически отсутствует по отношению к ZFS. Что ж, замечательно и то, что не хуже результат (Эй, у кого там ZFS в три раза медленней UFS при асинхронной записи?).

Ну, а теперь дискотека. Пулеметчик Ганс достал новые диски. Размер записи, примерно соответствующий среднестатистическому оракловскому параметру DB_FILE_MULTIBLOCK_READ_COUNT на OLTP.

Держитесь за кресла, а то выпадете:

Тест 5
------

Копирование созданного файла 50m

На UFS:
server5# cd /
server5# date; cp file1.test file2.test; date
Monday, June 15, 2009 8:41:42 PM ALMT
Monday, June 15, 2009 8:41:43 PM ALMT
~1-1,5 сек

На ZFS:
server5# cd /data
server5# date; cp file1.test file2.test; date
Monday, June 15, 2009 8:41:52 PM ALMT
Monday, June 15, 2009 8:41:52 PM ALMT
Менее 1 сек

"О так от,миста Тейба, о так от..." © Кен Кизи, "Полет над гнездом кукушки"

Менее 1 секунды во второй части данного теста (неоднократно - более 20 раз - повторенном) выглядело так - бдыщь! - мгновенно. То есть сильно менее 1 секунды.

Необходимое пояснение

Итак, что все это, вышеприведенное, означает?

Означает вот что.

ZIL, размещенный на быстродействующем устройстве, дает существенный прирост в скорости асинхронной записи на ZFS. По результататм (более 100 прогонов) приведенных тестов и при размере записи, меньшем, чем размер ZIL - порядка 50-60%.

Главный вопрос - почему?

Потому что.

ZIL играет при ZFS ту же самую роль, что и redo logs при Oracle. Фактически мы пишем изменения в него, а, так как он в наших тестах находится в памяти, то мы весьма мало пишем на сам диск. При этом запись практически полностью является отложенной, что и обусловливает такой скоростной разбег.

Да, это весьма напоминает JFS. Однако есть существенная разница. Механизм записи и метаданные в ZFS существенно отличаются от JFS/UFS. Еще не курившие мануалов почитают в концепциях, остальные знают, что грубо разница в объеме метаданных составляет почти те самые пресловутые три раза, ко всему прочему, метаданные ZFS организованы таким образом, что накладные расходы на их обмолот сильно меньше, нежели у JFS/UFS.

А это, в свою очередь, с высокой вероятностью означает, что политрук лжет.

Иначе говоря, заявления о том, что ZFS при записи по меньшей мере в три раза медленнее UFS в режиме forcedirectio, мягко говоря, кажутся недостоверными. Как минимум, производительность асинхронной записи даже на дефолтной ZFS не хуже, чем на UFS **.

С другой стороны, я не исключаю наличие некоего локального нарушения законов сохранения, этакой сингулярности (в железе, софте или в прокладке между креслом и консолью;)), в силу которой ньютоновские законы перестают действовать и начинают действовать релятивистские. ;) И из-за этого ZFS тормозит. Фазы Луны. Козерог в Тельце. Плохая карма для IT-систем.

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

Однако я отвлекся. Мы говорили не о тормозах, а о дальнейшем поиске весьма высокопроизводительной конфигурации ZFS-пула. Как знать, можем, мы сможем помочь сингулярным сисадминам и релятивистским DBA. ;)***

Да, это не тесты, более того, это просто одиночные однопоточные операции, простые как три рубля, весьма отдаленно похожие на настоящую дисковую активность. Однако тенденция достоверно вписывается в теоретические объяснения Sun Microsystems и подтверждается статистикой функционирования реальных приложений на ZFS.

(Необходимое пояснение закончено)

Дабы избежать засады с ограничением на размер ZIL - есть два варианта.

Первый. Положить ZIL на пару (round-robin load balancing в этом случае у ZFS работает автоматически) раскиданных на физически разные контроллеры максимально быстродействующих диска - SAS 15K или SSD. Их размеры обычно заведомо превосходят совокупные размеры всех одновременно выполняющихся записей. Мало - добавим еще дисков туда же, масштабирование по горизонтали ограничено лишь возможностями выделения контроллеров и/или каналов ввода-вывода.

Второй. Если оставить в покое пока не выясненный вопрос с целостностью БД (на операциях startup/shutdown Solaris/RDBMS) при такой организации пула - взять машину с большим количеством RAM, и раскочегарить RAM-диск, и, соответственно, ZIL, на размер этак в 10-20 Гб. В памяти. Меньше - зато 50-60% прироста производительности подсистемы ввода-вывода. Сколько это будет в результирующей производительности СУБД - прикиньте сами. Можно вообще представить монструозную конфигурацию, где 128 Гб оперативной памяти отдано для RAM-диска двухтерабайтного ZFS-пула... нет, с утра я ничего не пил. ;)


Кстати, далеко не факт, что при размещении ZIL на нескольких 15K SAS (скажем, восьми) не получится почти такого же (или во всяком случае соизмеримого) прироста производительности.

Как бы то ни было - тесты не закончены. На данный момент у меня нет подходящей машины для полномасштабных тестов с Oracle Enterprise Edition и реалистичной базой данных, однако как только она будет - продолжение обязательно воспоследует.

Будут и скоростные тесты, и тесты на целостность БД, и подробный отчет обо всем. А также - если заключение будет положительным - то и готовые скрипты для поддержки подобной конфигурации (во всяком случае, с RAM-диском) на продуктивных системах.

To be continued...

PS. Не пытайтесь пока повторить данный трюк в домашних условиях. В данном эксперименте перед шатдауном опытной машины необходимо обязательно разрушать ZFS-пул с логом на RAM-диске. В противном случае после рестарта вы получите дергадировавший пул и дедлок на ZFS (это лечится, расслабьтесь, и не переустановкой). Это связано с тем, что ZFS-пул создан с автоматическим монтированием после старта ядра, а RAM-диск приходит позже - я не могу его инициализировать ранее, чем ОС перемонтирует файловую систему /usr в read/write, а ramdiskadm находится именно там. Сервис монтирования подобного пула после старта ramdisk и с соответствующими депендентами в репозитории SMF будет написан чуть позже.
____________________________________________
* © Доктор Ливси, "Остров Сокровищ".
** Единственное разумное объяснение тому, что ZFS может в некоторых -весьма редких - случаях быть медленней, чем UFS- это вот это: Tuning is often evil and should rarely be done. В отношении ZFS это практически во всех случаях справедливо. "Let's my people go!". За исключением параметра recordsize (и то зачастую его не нужно трогать) - в ZFS практически отсутствуют параметы, способные улучшить и ускорить работу файловой системы. Замедлить - всегда пожалуйста, если менять их без учета законов сохранения - а они в IT действуют, как это ни удивительно отдельным личностям, незнакомым с матаном.
*** Конечно же, следует читать "реляционным". ;) Шутка юмора.