Запись небольшого количества данных в большое количество файлов в GlusterFS 3.7
Я экспериментирую с 2 серверами Gluster 3.7 в конфигурации 1x2. Серверы подключены по сети 1 Гбит. Я использую Debian Jessie.
Мой пример использования следующий: открыть файл -> добавить 64 байта -> закрыть файл и сделать это в цикле около 5000 различных файлов. Время выполнения такого цикла составляет примерно 10 секунд, если я обращаюсь к файлам через подключенный диск glusterfs. Если я использую libgfsapi напрямую, время выполнения составляет около 5 секунд (в 2 раза быстрее).
Однако тот же цикл выполняется за 50 мс на обычном диске ext4.
Существует огромная разница в производительности между Gluster 3.7 и более ранними версиями, что, как мне кажется, связано с параметром cluster.eager-lock.
Моя цель - выполнить цикл менее чем за 1 секунду.
Я пытался поэкспериментировать с большим количеством настроек Gluster, но безуспешно. Тесты dd с различными значениями bsize ведут себя так, что опция TCP no-delay не установлена, хотя из исходного кода Gluster кажется, что no-delay по умолчанию.
Есть идеи, как улучшить производительность?
Редактировать:
Я нашел решение, которое работает в моем случае, поэтому я хотел бы поделиться им, если кто-то еще столкнется с той же проблемой.
Основной причиной проблемы является количество обращений между клиентом и сервером Gluster во время выполнения последовательности открытия / записи / закрытия. Я не знаю точно, что происходит позади, но измерения времени показывают именно эту картину. Теперь очевидной идеей было бы "упаковать" последовательность открытия / записи / закрытия в одну функцию записи. Грубо говоря, прототип C такой функции будет:
int write(const char* fname, const void *buf, size_t nbyte, off_t offset)
Но уже есть такая функция API glfs_h_anonymous_write
в libgfapi (спасибо Suomya из почтовой группы Gluster). Вид скрытой вещи - это идентификатор файла, который является не простым именем файла, а чем-то типа struct glfs_object
, Клиенты получают экземпляр такого объекта через вызовы API glfs_h_lookupat/glfs_h_creat
, Дело в том, что glfs_object
представляющий имя файла является "не имеющим состояния" в том смысле, что соответствующий inode
оставлен нетронутым (не считается). Надо думать о glfs_object
как простой идентификатор файла и использовать его так же, как вы бы использовали имя файла (на самом деле, glfs_object
хранит простой указатель на соответствующий inode
без учета подсчета).
Наконец, мы должны использовать glfs_h_lookupat/glfs_h_creat
один раз и много раз записать в файл, используя glfs_h_anonymous_write
,
Таким образом, я смог добавить 64 байта к 5000 файлам за 0,5 секунды, что в 20 раз быстрее, чем при использовании смонтированного тома и последовательности открытия / записи / закрытия.