dadv: (chuck)
[personal profile] dadv

Довелось поэкспериментировать с компрессией и шифрованием данных на системном уровне в FreeBSD 9/i386. Шифрование делал через GELI, компрессию через ZFS. Обнаружил забавное. В моём случае контейнер для GELI расположен на медленной сетевой шаре (CIFS over 100Mbit/s & mtu=1500) и для уменьшения дополнительных тормозов от "read-modify-write" поигрался с размерами блоков.

И geli init позволяет задать "размер сектора" в создаваемом GEOM, и ZFS позволяет задать размер блока (recordsize). Оказалось, что даже при отлично сжимаемых данных и включенной компрессии ZFS реально ничего не жмет, если размер сектора и recordsize одинаково равны 4096: zfs get compressratio всегда показывает 1.00 и всё работает довольно медленно, упираясь в сеть.

При том же размере сектора в 4k увеличение recordsize до 8k позволяет ZFS достичь compressratio до 2.0 и операции на хорошо жмущихся данных заметно ускоряются. Если при recordsize=8k уменьшить размер сектора до 512 байт, то на тех же данных степень компрессии взлетает до 16.0 и скорость обработки хорошо жмущихся данных, соответственно, взлетает в разы. Например, показания benchmarks/bonnie, который оперирует как раз такими данными, хорошо демонстрируют эффект.

Маленький "размер сектора" контейнера GELI не слишком хорош по разным причинам: и относительные накладные расходы на собственно шифрование возрастают, и совсем мелкие обмены шифрованными данными по сети через CIFS генерируют относительно высокие накладные расходы в TCP. Поэтому "размер сектора" GELI-контейнера увеличил обратно до размера страницы памяти 4k и выставил ZFS recordsize в 8k - при этом на моих характерных данных коэффициент сжатия получается около 1.85.

Это лишь первая серия тестов и, может быть, в итоге - и для других наборов данных - параметры придется поменять.

dir="/mnt/cifs"
size="100g"
poolopts="-O recordsize=8k -O atime=off -O compression=gzip-9 -o failmode=continue"
truncate -s $size $dir/backend
md=$(mdconfig -af $dir/backend)
geli init -s 4096 /dev/$md
geli attach /dev/$md
zpool create $poolopts es /dev/$md.eli

Date: 2016-01-15 21:16 (UTC)
From: [identity profile] karpion.livejournal.com
Оказалось, что даже при отлично сжимаемых данных и включенной компрессии ZFS реально ничего не жмет, если размер сектора и recordsize одинаково равны 4096: zfs get compressratio всегда показывает 1.00 и всё работает довольно медленно, упираясь в сеть.
Простите, а чего Вы ожидали? IMHO, то было вполне предсказуемо.

Поэтому "размер сектора" GELI-контейнера увеличил обратно до размера страницы памяти 4k и выставил ZFS recordsize в 8k
Я бы советовал поднять recordsize до 16, 32 и 64 KB - и протестировать.

Date: 2016-01-15 21:58 (UTC)
From: [identity profile] dadv.livejournal.com
> Простите, а чего Вы ожидали? IMHO, то было вполне предсказуемо.

А могло быть и иначе. Например, протокол IPCOMP (часть IPSEC) сжимает каждый блок по отдельности: берет готовый IP-пакет (обычно не более 1500 байт), сжимает и если результат того стоит - посылает дальше мелкий пакет, предварительно зашифровав. ZFS работает с файлами и могла бы файлы размера более одного сектора сжимать даже когда recordsize не превышает размера сектора. Но она этого даже не пытается, что меня и удивило.

> поднять recordsize до 16, 32 и 64 KB

ZFS читает данные из файлов блоками не менее чем recordsize, засовывая "лишние" прочитанные байты в кеш. Например, при чтении из файла 1024 байтов в моём случае по сети будет запрошено, принято и дешифровано 128k при дефолтном recordsize - это 90 пакетов TCP (с подтверждениями) вместо одного. Я уже проходил подобное не так давно: http://dadv.livejournal.com/204385.html

А при записи небольшого блока данных в файл (например, изменение даты модификации файла в каталоге) будет ещё хуже - сначала ZFS прочитает целиком 128k, поменяет несколько байтов и станет обратно записывать весь блок.
Edited Date: 2016-01-15 22:01 (UTC)

Date: 2016-01-16 18:45 (UTC)
From: [identity profile] karpion.livejournal.com
Например, протокол IPCOMP (часть IPSEC)
Мне странно читать, как Вы в качестве аргумента сылаетесь на сетевой протокол. Ведь диск - это явление пространственное, а сеть (канал) - временное. Поэтому диск разбит на куски фиксированного объёма (секторы), а сеть делит информацию на куски произвольного размера (пакеты), но не более заданного (MTU).

Если ж притягивать Вашу аналогию за уши - то у сети размер сектора вообще равен одному байту. А в PPP - одному биту, что тем более!

ZFS читает данные из файлов блоками не менее чем recordsize
Наверно, не "не менее", а "кратно".

Например, при чтении из файла 1024 байтов в моём случае по сети будет запрошено, принято и дешифровано 128k
Я не понял, откуда тут "128k".
Вроде, сколько именно - должно зависеть от степени компрессии, т.е. в пределе - один "сектор".

Собственно, я прекрасно понимаю Ваш аргумент. Но тут надо смотреть, блоками какого размера читают данные Ваши программы. И ещё надо смотреть, как часто программы читают файлы пусть и малыми блоками, но последовательно - тогда "засовывая "лишние" прочитанные байты в кеш" будет вполне выгодно.
Edited Date: 2016-01-16 18:46 (UTC)

Date: 2016-01-16 02:13 (UTC)
From: [identity profile] posfix.livejournal.com
А если метод компрессии выбрать не gzip, а lz4?

Date: 2016-01-16 07:59 (UTC)
From: [identity profile] dadv.livejournal.com
Разницы в скорости и степени компресии практически нет, так как узкое место по скорости тут сеть, а степень компрессии ограничена, как выяснилось, соотношением recordsize/sectorsize.

Date: 2016-04-15 17:47 (UTC)
From: [identity profile] actika.livejournal.com
У вас всё точно в сеть упиралось ?

Date: 2016-04-15 18:00 (UTC)
From: [identity profile] dadv.livejournal.com
TCP по 100-мегабитной сети с mtu=1500 это в лучшем случае 11 мегабайт в секунду, откуда удивление? Это невысокая скорость.

Date: 2016-04-15 18:01 (UTC)
From: [identity profile] actika.livejournal.com
А 10-ти гигабитных сетевых для тестирования не найдётся ?

Date: 2016-04-15 18:04 (UTC)
From: [identity profile] dadv.livejournal.com
Моя цель была не поставить рекорд скорости с хорошим железом, а потестировать производительность как раз на дешевом и максимально доступном.

Date: 2016-04-15 18:06 (UTC)
From: [identity profile] actika.livejournal.com
Две гигабитных сетевых думаю можно себе позволить ...

Date: 2016-04-15 18:11 (UTC)
From: [identity profile] dadv.livejournal.com
Это был просто эксперимент. В данном случае ZFS работала внутри самой дешевой виртуалки, купленной у дешевого хостера, который кроме дискового пространства самой виртуалки даёт ещё 100 гигабайт пространства на отдельных собственных серверах внутри локальной сети хостера, доступные для монтирования через CIFS на скорости 100Mbit/s.
Edited Date: 2016-04-15 18:14 (UTC)

Date: 2016-04-15 20:34 (UTC)
From: [identity profile] actika.livejournal.com
Хотел зделать загрузку по iscsi вот берут меня теперь сомнения ...

Date: 2016-04-16 20:03 (UTC)
From: [identity profile] dadv.livejournal.com
Какая связь загрузки по iSCSI с темой поста?

Date: 2016-04-16 20:51 (UTC)
From: [identity profile] actika.livejournal.com
FreeNAS ZFS iSCSI ...

Profile

dadv: (Default)
Choose your future

June 2017

M T W T F S S
   1234
56 7891011
12131415161718
19202122232425
2627282930  

Tags

Style Credit

Powered by Dreamwidth Studios