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

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

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

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

Итак, резюмируя, вот требования:

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

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

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

person bajafresh4life    schedule 19.11.2009    source источник


Ответы (4)


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

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

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

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

person shadit    schedule 19.11.2009

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

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

person Steve B.    schedule 19.11.2009

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

person Rickard    schedule 19.11.2009

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

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

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

person Edward Q. Bridges    schedule 19.11.2009