Обновить
36
0
Kirill@gatech

Пользователь

Отправить сообщение
А зачем оно? Шифрование на уровне сервера поможет только в одном случае — если сопрут сам сервер и доступ к нему. Даже если данные на сервере зашифрованы, через CIFS/NFS/iScsi/FC они передаются в открытом виде. С этой точки зрения, имеет смысл использовать софт типа TrueCrypt на клиенте.
А можно конфиг системы и примерное описание workload'a в студию? Из параметров интересует recordsize, zpool status, если используются какие-либо нестандартные параметры (и ZFS и ядра), то их тоже. Ну и если хостинг фоток, то средний размер и количество одновременных потоков чтения.

Я достаточно часто занимаюсь оптимизацией ZFS для очень специфических use-case'ов, может помогу разобраться. Правда если есть какие-либо различия между Illumos и FreeBSD, то здесь помочь не смогу.

Навскидку, здесь может помочь "zfs set atime=off pool/fs", а дальше надо смотреть.
Да, логично. Я бы сказал, что сжатие имеет смысл если в результате ratio будет 1.05х и выше. Дедуп — 3.0х и выше.

Про async destroy можно почитать в багтрекере — www.illumos.org/issues/2619 и www.illumos.org/issues/2747 (второй — SPA feature flags, фактически уход от zpool версий).

В FreeBSD вроде тоже уже есть, но не в stable:

[1] r236884: zfs feature support, June 11, MFC after 1 month
[2] r238422: fixes for defer-destroy, July 13, MFC after 1 week
[3] r238926: fixes for zpool feature support, July 30, MFC after 2 weeks
Так же опасаюсь, что Ваш вариант ускорения мы увидим нескоро, так как пока актуальный zpool появится в ОС отличных от Solaris, пройдет немало времени.


Зависит от того, что Вы подразумеваете под «увидим». Поиграться с ним в виде беты скорее всего можно будет уже в Q1'2013, но пока он дойдёт upstream до Illumos, а оттуда портанётся в FreeBSD, может пройти достаточно много времени.

Пока же приходится выкручиваться или объемом RAM+процессором, благо это недорого либо использовать сжатие — зависит от характера использования.


Сжатие (lzjb) кстати имеет смысл использовать почти всегда — оно занимает очень мало CPU ресурсов, а декомпрессия добавляет <0.5мс задержки в read pipeline для 128К блоков.

root@myhost:/# dtrace -qn 'lzjb_decompress:entry{self->t = timestamp} lzjb_decompress:return/self->t/{self->t=(timestamp - self->t)/1000; @=quantize(self->t); @a=avg(self->t)} tick-60sec{printa("Latency in microseconds: %@d\nAvg latency: %@d us",@,@a); trunc(@); trunc(@a); exit(0)}'      

Latency in microseconds:
           value  ------------- Distribution ------------- count
               4 |                                         0
               8 |                                         54
              16 |@                                        385
              32 |                                         131
              64 |                                         39
             128 |@@@@@@@                                  1789
             256 |@@@@@@@@@@@@@@@@@@@@@@@                  6289
             512 |@@@@@@@@                                 2149
            1024 |                                         32
            2048 |                                         1
            4096 |                                         0

Avg latency: 361 us

root@myhost:/# prtdiag | head -10 | tail -2
Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz CPU 1
Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz CPU 2


А для дедупликации, да, объём RAM критичен, хотя в Illumos недавно закоммитили async destroy, который решает главную проблему dedup — долгое и очень печальное для продакшн удаление данных.
Естественно, реализации у обеих систем разные, к примеру, мне бы хотелось видеть механизм нетапповской дедубликации WAFL в ZFS.


Да, с дедупликацией всё не так просто. Чтобы сделать аналог offline dedup в ZFS, необходим механизм перезаписи блоков данных и метаданных, не нарушая доступ к ним с точки зрения клиента. Для этого надо перезаписать не только сам блок, но и поинтер к нему в блоке метаданных, и поинтер к блоку метаданных, и так по цепочке АВЛ-дерева до самого uberblock'a, в процессе чего возможно придётся перебалансировать само дерево. Собственно та же причина не позволяет делать онлайн-дефрагментацию (reallocate), балансировку данных по vdev'ам (rebalance), изменение размера пула или vdev'a в меньшую сторону, эвакуацию vdev'a, и т.д.

Такой механизм называется Block Pointer Rewrite, и он уже обрёл статус мема — все говорят, что он когда-то будет написан (с 2008 года), но пока никто его не написал :) Последний раз когда я пытался его включить в roadmap, мы прикинули, что докрутить его до production quality «как надо» займёт порядка 8,000 developer/QA-часов, и на этом обсуждения заглохли. Может его на Kickstarter разместить? :)

Зато есть другой вариант, который ускоряет online-dedup больше чем на порядок для реальных нагрузок, и почти готов. Stay tuned.
Упс, не туда ответил. См. коммент ниже (2 декабря 2012 в 12:01)
По поводу копирования данных — я спросил потому что, например, во FreeBSD именно так и происходит (возможно в соляре ситуация другая), и такой подход крайне тормознутый. Технология маппинга страниц отработана десятилетиями, она позволяет очень эффективно кешировать данные файловых систем, особенно страниц с кодом программ, которые не надо копировать от процесса к процессу, например. А так получается, что ZFS требует двойного кеширования (raw block-ов средствами zfs и страниц с данным средствами os)… ;(


Такой подход имеет смысл с точки зрения cache consistency — если дать доступ на страницу памяти напрямую какому-либо процессу, особенно вне ядра, и данные в этой странице устареют (блок перезаписан чем-либо ещё), то Солярис либо не сможет его освободить без разрешения процесса (может быть дедлок из-за non-zero reference count), либо освободит без спроса и перезапишет, что тоже нехорошо. Если процесс грохнется, то опять же будет проблема с reference count.

Тут всё зависит от use case — например, если использовать ZFS для локальных баз данныx, у которых есть свой кеш, имеет смысл ограничить размер ARC, или сказать ему кешировать только метаданные (zfs set primarycache=metadata pool/fs), оставив большую часть оперативной памяти для внутреннего кеша программы. Нормальные базы данных кешируют более эффективно, чем ZFS, поскольку они знают собственно какие данные более важны для них самих.

Если использовать SAN/NAS на базе ZFS, то в userland ничего такого вообще быть не должно, и под ARC отдаётся почти вся оперативная память системы; больше нигде кеш не нужен и не используется. К тому же, в zvol'ax (ZFS Volume, блочный девайс эмулируемый средствами ZFS, используется в COMSTAR для экспорта iScsi/FC LUNов клиентам) доступ идет напрямую в ARC. Для CIFS и NFS вроде как тоже что-то такое есть, или в процессе написания — там это сделать реально поскольку они в ядре, но может быть нетривиально.

А с точки зрения скорости — я особо не замечал проблем с этим на нормальных SAN машинах; реально получить 3 ГБ/с sustained read/write, или 250к IOPs в продакшн. Latency от такого подхода если и страдает, то очень мало. В бенчмарках до 1млн IOPs, но в продакте я такого пока не видел — там будут нужны сумасшедшие размеры очереди.
Хм, похоже я ошибся немного. Более подробно:
The vdev portion of each DVA is a 32 bit integer which uniquely identifies the vdev ID containing this block. The offset portion of the DVA is a 63 bit integer value holding the offset (starting after the vdev labels (L0 and L1) and boot block) within that device where the data lives. Together, the vdev and offset uniquely identify the block address of the data it points to. The value stored in offset is the offset in terms of sectors (512 byte blocks).

Перевод с моими комментариями: DVA — Data Virtual Address — входит в состав указателя блока, blkptr_t. DVA состоит из 2х 64-бит переменных. Первая переменная указывает на vdev, в котором данные (используется 32 бит); вторая — на адрес внутри vdev'а (используется 63 бит).

#define DVA_GET_VDEV(dva) BF64_GET((dva)->dva_word[0], 32, 32)
#define DVA_GET_OFFSET(dva) BF64_GET_SB((dva)->dva_word[1], 0, 63, SPA_MINBLOCKSHIFT, 0)

Отсюда выходит, что сам указатель блока ограничивает размер адресного пространства пула до 2^105 байт, и 2^72 байт на vdev, причём если когда-нибудь этого места станет мало, можно увеличить минимальный размер сектора, или увеличить лимит на количество vdev'ов в пуле без изменения структуры ZFS. Лет через 100 наверное придётся…
Содраны были всё-таки не фичи, а концепты. Uberblock, Copy-on-Write, tree of blocks. Сравнивать ZFS с WAFL не совсем корректно — они похожи на самом низком уровне, но работают далеко не одинаково. На ZFS многие переходят как раз с NetApp'ов, по нескольким причинам.
Пруф:
communities.netapp.com/community/netapp-blogs/dave/blog/2007/09/05/netapp-sues-sun-for-zfs-patent-infringement
первый: zfs использует 128-ми битные указатели. Бывает ли что в старших 64-х битах содержатся не нули? Если сейчас нет, то когда (и какие конкретно) наступят условия того, что такая длина указателей окажется востребованной?

Точно не знаю — на 1ПБ пуле вроде используются только младшие 64 бит. Теоретически, будут использоваться старшие, когда будет 16 Exabyte данных, что пока практически недостижимо.
второй: когда zfs отдает данные os, маппит ли она страницу своего кеша на страницу, где os хочет видеть данные (либо передает указатель на страницу кеша, а OS делает это самостоятельно), или же только копирует данные из своего кеша в ту страницу, где хочет видеть данные os?

Копирует данные в страницу, где их хочет видеть ОС. В кеше (ARC) хранятся raw blocks — их надо обработать, распаковать (если они запакованы), и т.д.
Пока все хорошо, продолжайте писать, пожалуйста.

Спасибо.
Не понял, почему onboard write cache работает, только если диск выделен полностью? Контроллеру не все равно ли, что кэшировать, особенно если у него батарейка?

Смысл в том, что для каждой синхронной записи надо делать DKIOCFLUSHWRITECACHE() для гарантии сохранности данных, а на partition/slice/файл его сделать нельзя.

ZFS не нужен RAID-контроллер, так что батарейки может не быть. Для сохранности данных используется ZFS Intent Log на быстрых SSD, если они есть; если нет — синхронная запись идет прямо на диски, что сильно тормозит I/O. Конечно, можно отключить sync полностью, но лучше не надо.
PS В принципе для ZFS должна работать схема дефрагментации «скинул все на стриммер, отформатировал диск, вернул назад».

Дефрагментация таким образом работает, с помощью zfs send/receive например. Но для этого нужен downtime.
Но вопрос в другом — является ли фрагментация проблемой для ZFS?

В некоторых случаях да, является. На сильно фрагментированном пуле страдает скорость записи из-за скорости прохода по space map и free map. Может разберусь с этим — там есть пара вариантов использовать другие аллокаторы, или написать новый — прототип у меня уже есть.
Да, на данный момент от Оракла никто больше ничего не ждёт — работа над открытой версией ZFS на базе zpool v28 продолжается в Illumos и FreeBSD. Fork yeah.
И да, про скорость скорее всего будет отдельная статья с DTrace скриптами и измерением latency на разных уровнях.
Код, где даже игнорирование результата функции прописывается явно, меня разует.

В большинстве случаев, в ZFS и Solaris kernel, результат функции без контекста не даст почти ничего. Функция может быть void потому-что она меняет непосредственно один из аргументов, или что-то делает с данными на которые мы дали pointer. It's C, which explains everything. Я дал примеры кода в основном ради комментариев — без них что-то понять вообще почти нереально.
Про структуры хотелось бы подробнее, ибо привычные нам оценки скорости работы могут быть не применимы к операциям чтения/записи на диск.

Два основных принципа работы ZFS — как и огромного количества C кода в *nix — асинхронность. Например, функция zfs_vdev_io_start() запишет поинтер на структуру, в которой записано что надо сделать, в очередь исполнения; из очереди другая функция (возможно, из отдельного модуля, или из самого I/O драйвера) её подберет, и когда цепочка завершится, обработчик исполнения очереди запустит zfs_vdev_io_done(), callback pointer на которую был в struct'e, который мы послали на исполнение.

Таким образом достигается и асинхронность, и параллельность кода, но пытаться разобраться в таких цепочках очень непросто даже с DTrace.
Так я собственно и говорю, что в какой-то момент без scale out не обойтись. Вопрос в том, когда, и сколько это будет стоить с точки зрения поддержки нескольких систем против одной. Кластер для big data или image/video production (большие объемы данных под одним namespace) — имеет смысл до 1Пб на ноду (а несколько нод можно объединить через NFS Referrals). Кластер для cloud/VM/VDI — до 200Тб на ноду — одной виртуалке очень редко нужны LUNы >10Тб, а если нужны, это надо учитывать в дизайне. Есть варианты где имеет смысл делать 100+ маленьких 2U нод с 15к дисками или SSD, особенно если доступ к данным идет через умный прокси (OpenStack Swift/Nova или другие API).

Иногда делаем back-end на FC или iScsi/AoE/FCoE/IB и скейлим front-end независимо от back-end'a, таким образом обходим практические ограничения SAS полок на ноду.
Вот система с которой работал на выходных — 14 полок, правда по 24 диска всего. 2 контроллера. 240 3Тб дисков и 120 SSD. i48.tinypic.com/2mlp3.jpg
Потом пропадает питание у ОДНОЙ полки и весь раздел разваливается. Или у вас 32 раздела получается?

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

И эта схема не скейлится, 2ПБ уже не сделать никак.

Скейлится прекрасно, минимум до 11 полок (между полками и контроллером два SAS-свича). Кстати, если добить до 11-12 полок, то можно потерять и 3, но тогда совсем хреново будет. 2 — нормально. 11 полок — это 2.6Пб (1.92 usable).

Теоретически можно и больше, но практически после 1Пб usable затык будет уже в контроллере (PCIe, память), так что реально там уже надо будет scale out.
С Xyratex ошибся, там 84 дисков в 5U. Ну неважно.

Вот пример 1Пб системы с примерным раскладом цен на базе Illumos+ZFS (Free Open-Source) и DataOn DNS-1660 (все компоненты enterprise-class):

6x DataOn DNS-1660D: $66,000
360x Seagate Constellation ES.3 4Tb: $180,000
2x LSI SAS6160 Switch: $4,000

Head node типа Dell R720xd с 384Гб памяти, парой Xeon E5, 2x LSI 9201-16e, 2x Dual-port 10Gbe — скажем, $30,000 (лень считать).
~$4000 на всякие мелочи вроде кабелей, итд.

Если надо, добавить несколько STEC ZeusRAM для write cache; STEC Z16 для read cache, можно прямо в контроллер — от $15к и выше.

В базе получается <$300k + налоги в США.

Потом делаем 32*(11-disk raidz3) + 8 hot spare, получается 1Пб usable space, или 1.44Пб raw space.

Такие системы народ реально использует в продакшн, правда обычно делают 2 контроллера в кластере, и коммерческий софт.
Я же говорю, 1ПБ на одном сервере не завести никак, это несколько серверов в сети.

Запросто :) И без всяких NetApp/EMC/Hitachi. Правда будет сервер + несколько полок с дисками, но 1Пб raw в одной системе под ZFS — не проблема.

Xyratex уже делает 4U JBODы на 72 диска каждый; DataOn есть на 60 дисков в 4U. Так что с Xyratex, например, можно в 18U сделать массив с 1.15Пб; в 42U — 2.88Пб. Для data warehousing вполне подходит; для general purpose storage (DB, VM) более важны IOPs, так что там имеет смысл делать либо 10к/15к диски, либо SSD.
Хм, может написать пост про варианты архитектуры СХД? Их дохрена, и в каждом свои плюсы и минусы. В общем, есть много вариантов набрать 1Пб стораджа гораздо дешевле, чем Амазон, а спорить о том, какой из них эффективнее для чего, я в 5 утра не готов :) Спать давно пора.

Информация

В рейтинге
Не участвует
Откуда
США
Дата рождения
Зарегистрирован
Активность