Выбор/настройка базы данных для обеспечения высокой пропускной способности, надежности, постоянной скорости записи и снижения задержки

Я работаю над приложением реального времени со следующими характеристиками:

  • Сотни клиентов будут вставлять строки/документы одновременно, каждый из которых вставляет строку каждые пару секунд.
  • В основном только для добавления; почти все строки/документы, однажды вставленные, никогда не изменяются.
  • Клиент должен увидеть успех только в том случае, если данные были сброшены на диск, и после этого должна сохраняться согласованность чтения и записи.
  • Клиенты готовы ждать подтверждения порядка секунд — достаточно долго, чтобы выполнить несколько операций поиска и записи на диск.
  • Слишком много данных, чтобы поместиться в ОЗУ (исключая такие варианты, как Redis). Но доступ к давно записанным строкам осуществляется редко, поэтому допустимо не хранить их в памяти.
  • В идеале эти записи не должны блокировать чтение.
  • Хранилище «ключ-значение» — это хорошо, но должен быть хотя бы один надежный автоинкрементный индекс.

Другими словами (и tl;dr), клиенты могут терпеть задержку, но им нужна большая доверенная пропускная способность записи - больше пропускной способности, чем "одна запись - одна дисковая операция".

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

Я думаю, что с такой высокой устойчивостью к задержке это не слишком много. И я полагаю, что у других была эта проблема, например, у финансовых компаний, которые не могут позволить себе потерять данные, но могут позволить себе задержать ответ любому клиенту.

Поддерживают ли такие проверенные решения для баз данных, как Postgres, CouchDB/Couchbase или MongoDB, такие режимы работы?


person btown    schedule 11.10.2012    source источник


Ответы (1)


PostgreSQL вполне подходит для этой рабочей нагрузки; почти все, что вы указали, находится в пределах своего обычного набора функций. Pg совместим с ACID, поддерживает групповую фиксацию для уменьшения накладных расходов на синхронизацию, модули записи не блокируют считыватели и использует операционную систему для кэширования, поэтому, естественно, он будет хранить в памяти только самые горячие данные.

«Клиенты готовы ждать подтверждения порядка нескольких секунд — достаточно долго, чтобы произошло несколько операций поиска и записи на диск»

Если рассматривать PostgreSQL, ваше приложение идеально подходит для действительно большого commit_delay, что значительно увеличит скорость записи. Вы не можете использовать synchronous_commit = off, потому что вам нужно подтверждение коммита перед ответом, но вы можете просто поставить коммиты в очередь на несколько секунд, чтобы сэкономить на затратах на синхронизацию.

Если вы используете Pg для такого задания, вам потребуется настроить контрольные точки, чтобы убедиться, что контрольные точки не останавливают ввод-вывод. Убедитесь, что bgwriter агрессивно записывает грязные буферы. Убедитесь, что автоочистка выполняется часто — вы не удаляете данные из таблиц, но индексы по-прежнему нуждаются в обслуживании, как и статистика таблиц.

Если вы ожидаете много данных и ваши запросы обычно содержат временной элемент, рассмотрите возможность разделение таблицы на куски (скажем) по 1 месяцу в течение 1-го года, объединение всего, что старше 12 месяцев, в таблицы, разбитые по годам. Pg имеет только ограниченное встроенное разделение (он взломан вместе с использованием наследования и исключения ограничений), поэтому вам нужно делать это вручную/скриптом с использованием триггеров, но он выполняет свою работу.

Видеть:

person Craig Ringer    schedule 11.10.2012
comment
Именно такой ответ я и искал! Меня немного смущает документация, в которой говорится Since all pending commit data will be written at every flush regardless of this setting, it is rare that adding delay by increasing this parameter will actually improve performance, но я предполагаю, что мой вариант использования является одним из тех «редких» случаев? В любом случае, мне нужно будет много читать об этом и тестировать/настраивать, но это выглядит очень многообещающе. - person btown; 12.10.2012
comment
@btown Вам, безусловно, нужно протестировать и сравнить, прежде чем принимать какие-либо решения. Я нахожу этот фрагмент в документации немного неясным; Я подозреваю, что это может относиться к тому факту, что любая неотложенная фиксация приведет к тому, что отложенная фиксация также будет сброшена на диск. Мне будут интересны ваши результаты. - person Craig Ringer; 12.10.2012
comment
@btown Кстати, лучшее, что вы можете сделать для такой рабочей нагрузки, — это убедиться, что ваше хранилище имеет очень быструю синхронизацию. RAID-контроллер с кэш-памятью с резервным питанием от батареи в режиме обратной записи — самый дешевый вариант. Вы не поверите, какая разница. Хороший SAN — более дорогой вариант. Что бы вы ни делали, не запускайте такую ​​рабочую нагрузку на чем-то вроде EC2. Если вы используете RAID-контроллер с BBU, они не все одинаковы; или спросите в списке рассылки pgsql-general. Периодически проверяйте свой BBU, если используете его, чтобы убедиться, что батарея все еще работает. - person Craig Ringer; 12.10.2012