Ключ/значение хранится очень медленно на SSD

В чем я уверен:

  • Я работаю с Java/Eclipse в Linux и пытаюсь хранить на диске очень большое количество пар ключ/значение размером 16/32 байта соответственно. Ключи полностью случайны, сгенерированы с помощью SecureRandom.
  • Скорость остается постоянной на уровне ~ 50000 вставок в секунду, пока не достигнет ~ 1 миллиона записей.
  • Как только этот предел достигнут, процесс Java колеблется каждые 1-2 секунды от 0% ЦП до 100%, от 150 МБ памяти до 400 МБ и от 10 вставок в секунду до 100.
  • Я пробовал и с Berkeley DB, и с Kyoto Cabinet, и с Btrees, и с Hashtables. Те же результаты.

Что может способствовать:

  • Пишет на SSD.
  • На каждую вставку приходится в среднем 1,5 операции чтения — постоянно чередующиеся операции чтения и записи.

Я подозреваю, что хорошая скорость 50000 сохраняется до тех пор, пока не будет достигнут какой-то предел кеша/буфера. Тогда большое замедление может быть связано с тем, что SSD не обрабатывает смешанные операции чтения/записи, как это предлагается в этом вопросе: Хранилище ключей и значений с малой задержкой для SSD.

Вопрос:
Откуда может быть такое сильное замедление? Это не может быть полностью вина SSD. Многие люди с радостью используют SSD для высокоскоростного процесса БД, и я уверен, что они много смешивают чтение и запись.

Спасибо.

Редактировать: я удалил все ограничения памяти, и у процесса java всегда есть место для выделения дополнительной памяти.
Изменить: удаление чтений и выполнение только вставок не меняет проблемы.

Последнее редактирование: для записи, для хэш-таблиц это, похоже, связано с первоначальным числом сегментов. В кабинете Киото это число не может быть изменено и по умолчанию равно примерно 1 миллиону, поэтому лучше получить число прямо во время создания (от 1 до 4 раз больше максимального количества записей для хранения). Для BDB он предназначен для постепенного увеличения количества сегментов, но, поскольку он потребляет ресурсы, лучше заранее определить количество.


person Kai Elvin    schedule 23.10.2012    source источник
comment
Попробуйте мониторить GC. Это может быть проблема на стороне java.   -  person Vadzim    schedule 23.10.2012
comment
Я не следил за GC, но игра с -Xms –Xmx -XX:NewRatio, похоже, не имеет большого значения. Кроме того, когда происходит сбор, я думаю, что процесс использует 100% ЦП, а здесь он снижается до 0%, когда начинается замедление. Больше похоже на то, что он ждет ответа от ssd.   -  person Kai Elvin    schedule 23.10.2012


Ответы (1)


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

По сути, для любой базы данных, совместимой с ACID, потребуется по крайней мере один вызов fsync() для каждой фиксации базы данных. Это должно произойти, чтобы гарантировать надежность (в противном случае обновления могут быть потеряны в случае сбоя системы), а также гарантировать внутреннюю согласованность базы данных на диске. API базы данных не вернется из операции вставки до завершения вызова fsync().

fsync() может быть очень тяжелой операцией во многих операционных системах и дисковом оборудовании, даже на твердотельных накопителях. (Исключением могут быть корпоративные твердотельные накопители с питанием от батареи или конденсатора — они могут обрабатывать операцию очистки кеша в основном как операцию без операции, чтобы избежать именно той задержки, с которой вы, вероятно, сталкиваетесь.)

Решением было бы сделать все ваши магазины внутри одной большой транзакции. Я не знаю о Berkeley DB, но для sqlite производительность может быть значительно улучшена.

Чтобы выяснить, является ли это вашей проблемой, вы можете попытаться наблюдать за процессом записи вашей базы данных с помощью strace и искать частые вызовы fsync() (более нескольких раз в секунду было бы довольно сильным намеком).

Обновление: если вы абсолютно уверены, что вам не нужна надежность, вы можете попробовать ответ на Оптимизация производительности Put в Berkeley DB; если вы это сделаете, вам следует изучить функцию TDS (хранилище транзакционных данных) Berkeley DB.

person lxgr    schedule 23.10.2012
comment
Я попытался активировать транзакцию и установить TxnNoSync, но это не улучшается. - person Kai Elvin; 23.10.2012