Стратегия сохранения данных для чтения и записи с низкой задержкой

StackOverflow https://stackoverflow.com/questions/1764426

Вопрос

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

Прямо сейчас мы используем Mysql и вставляем по одной строке для каждой пары тег-документ.Запись миллионов строк в Mysql занимает некоторое время (высокий уровень ввода-вывода), даже при массовых вставках и интенсивной оптимизации.Нам нужно, чтобы это был интерактивный процесс, а не пакетный.

Для данных, которые мы храним и считываем, согласованность и доступность данных не так важны, как производительность и масштабируемость.Таким образом, в случае сбоя системы во время выполнения записи я могу справиться с некоторой потерей данных.Однако в какой-то момент данные определенно должны быть сохранены во вторичном хранилище.

Итак, подводя итог, вот требования:

  • Массовая запись с низкой задержкой, потенциально содержащая десятки миллионов записей
  • Данные должны каким-то образом сохраняться
  • Случайные чтения с низкой задержкой
  • Длительная запись не требуется
  • Конечная консистенция - это нормально

Вот несколько решений, которые я рассмотрел:

  • Запись за кэшами (Terracotta, Gigaspaces, Coherence), где записи записываются в память и асинхронно передаются в базу данных.Это немного пугает меня, потому что, похоже, добавляет приложению определенную сложность, которой я бы хотел избежать.
  • Масштабируемые хранилища значений ключей, такие как MongoDB, HBase, Tokyo Tyrant
Это было полезно?

Решение

Если у вас есть бюджет на использование Coherence для этого, я настоятельно рекомендую это сделать.В Coherence имеется прямая поддержка отложенной записи и возможной согласованности, и она очень устойчива как к сбоям в работе базы данных, так и к сбоям в работе узлов кластера Coherence (если вы используете >= 3 узла Coherence на отдельных JVM, желательно на отдельных хостах).Я реализовал это для создания CRM большого объема для сайта электронной коммерции компании из списка Fortune 100, и это работает фантастически.

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

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

Наконец, я реализовал упомянутое выше решение в 2005-2007 годах, когда компания Tangosol разработала Coherence и имела самую лучшую поддержку.Я не уверен, как обстоят дела сейчас под Oracle — надеюсь, все еще хорошо.

Другие советы

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

Одна вещь, которая, безусловно, ускорит запись в базу данных, — это делать ее пакетно.Пакетные обновления JDBC могут быть на несколько порядков быстрее, чем отдельные записи, и если вы выполняете их асинхронно, вы можете просто записать их по 500 за раз.

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

Berkeley DB имеет очень высокопроизводительную дисковую хеш-таблицу, которая поддерживает транзакции и интегрируется со средой Java EE, если вам это нужно.Если вы можете моделировать данные как пары ключ/значение, это может быть очень масштабируемым решением.

http://www.oracle.com/technology/products/berkeley-db/je/index.html

(Примечание:Oracle купил Berkeley db около 5-10 лет назад;оригинальный продукт существует уже 15-20 лет).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top