И всё оказалось не так просто как, не задумываясь, ожидалось.
Нужно мне это для NNCP. В нём есть возможность посылать файлы разбитыми
на куски. В итоге на приёмной стороне оказывается file.part0,
file.part1, итд. nncp-reass команда учитывая файл с метаинформацией и
хэшами, просто делает фактически: cat file.part0 file.part1 ... > file.
То есть копирование файлов as-is. Идеальный вариант для dedup.
Сделал я временный файл с рандомом внутри:
dd if=/dev/zero bs=1M count=100 | gohpenc -psk ... > out
Копирую его:
for i in `seq 100`; do cp out out$i ; done
Вижу что zfs list показывает что занято 1 гигабайт (а не 100 мегабайт),
однако свободное место практически не тронуто. zpool get dedup
показывает что дофига данных дедуплицировано. Всё хорошо.
Но сделав аналог cat file.part* > file:
for i in `seq 100`; do cat out >> out2 ; done
я вижу что дедуплицировано почти ничего: жалкий 1%.
Проблема в том какие данные попадают в блоки. Выхлоп gohpenc оказался
кратен только одному килобайту, но не кратен даже двум или, тем более,
128 килобайт. При копировании файла блоки действительно будут созданы
точно такие же.
то есть совпадёт только N-1 блоков этого out файла, а дальше ничего,
возможно местами только будут совпадения.
Что делать и как быть? Знать свои данные. Делать данные кратными
recordsize или его выставлять чтобы был кратный данным. В случае с NNCP
это значит надо выставлять размер chunk-а соответствующий (например
кратный 128 килобайтам).