Как получить огромное (> 2000) количество объектов из хранилища данных GAE менее чем за 1 секунду?

У нас есть часть нашего приложения, которое должно загрузить большой набор данных ( > 2000 объектов) и выполнить вычисления на этом наборе. Размер каждого объекта составляет приблизительно 5 КБ.

В нашей начальной, наивной реализации узким местом, как представляется, является время, необходимое для загрузки всех объектов (~ 40 секунд для 2000 сущностей), а время, необходимое для выполнения самого вычисления, очень маленький (< 1 секунда).

Мы попробовали несколько стратегий для ускорения поиска объектов:

  • Разделение запроса на поиск на несколько параллельных экземпляров и последующее объединение результата: ~ 20 секунд для 2000 объектов.
  • Сохранение объектов в кеше в памяти, размещенном на резидентном бэкэнд: ~ 5 секунд для 2000 объектов.

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

Мы надеемся, что сможем получить ~ 2000 сущностей всего за одну секунду. Является ли это возможностью GAE/J? Любые другие стратегии, которые мы могли бы реализовать для такого рода поиска?

ОБНОВЛЕНИЕ: предоставление дополнительной информации о нашем примере использования и результатах распараллеливания:

  • У нас более 200 000 объектов одного типа в хранилище данных, и операция выполняется только для поиска.
  • Мы экспериментировали с 10 параллельными рабочими экземплярами, и типичный результат, который мы получили, можно было увидеть в this pastebin. Кажется, что сериализация и десериализация, требуемые при передаче объектов обратно на главный экземпляр, препятствуют производительности.

ОБНОВЛЕНИЕ 2: Приведите пример того, что мы пытаемся сделать:

  • Предположим, что у нас есть объект StockDerivative, который необходимо проанализировать, чтобы узнать, действительно ли это хорошая инвестиция или нет.
  • Выполненный анализ требует сложных вычислений, основанных на многих факторах как внешнего (например, предпочтения пользователя, состояния рынка), так и внутреннего (т.е. от свойств объекта), и выводит одно значение "инвестиционной оценки".
  • Пользователь может запросить деривацию для сортировки на основе ее инвестиционной оценки и попросить представить N-число наивысших деривативов.

Ответ 1

В конце концов, не получается, что мы могли бы извлечь > 2000 объектов из одного экземпляра за одну секунду, поэтому мы вынуждены использовать кэширование в памяти, размещенное на нашем экземпляре бэкэнд, как описано в исходном вопросе. Если кто-то придумает лучший ответ или если мы найдем лучшую стратегию/реализацию для этой проблемы, я бы изменил или обновил принятый ответ.

Ответ 2

200 000 на 5 килобайт составляет 1 ГБ. Вы можете сохранить все это в памяти на наибольшем экземпляре backend или иметь несколько экземпляров. Это было бы самым быстрым решением - ничего не бьет память.

Вам нужны все 5kb каждого объекта для вычисления? Вам нужны все 200 тыс. Сущностей при запросе перед вычислением? Вопросы касаются всех объектов?

Кроме того, проверьте BigQuery. Это может удовлетворить ваши потребности.

Ответ 3

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

Ответ 4

Это очень интересно, но да, его возможные и Iv видели некоторые потрясающие результаты.

Я бы сделал то же самое; концепция сокращения карты

Было бы здорово, если бы вы предоставили нам больше показателей о том, сколько параллельных экземпляров вы используете и каковы результаты каждого экземпляра?

Кроме того, наш процесс включает извлечение самостоятельно или поиск и сохранение?

Сколько у вас элементов в вашем хранилище данных? 4000? 10000? Причина в том, что вы можете кэшировать его из предыдущего запроса.

рассматривает

Ответ 5

Наше решение включает в себя периодическое чтение объектов в фоновом задании и сохранение результата в json blob. Таким образом, мы можем быстро вернуть более 100 тыс. Строк. Вся фильтрация и сортировка выполняется в javascript с использованием модели SlickGrid DataView.

Как кто-то уже прокомментировал, MapReduce - это путь к GAE. К сожалению, библиотека Java для MapReduce нарушена для меня, поэтому мы используем не оптимальную задачу для выполнения всего чтения, но мы планируем получить MapReduce в ближайшем будущем (и/или Pipeline API).

Помните, что в прошлый раз, когда я проверил, Blobstore не возвращал gzipped entity > 1MB, так что в настоящий момент мы загружаем контент из сжатого объекта и расширяем его в память, таким образом, конечная полезная нагрузка получает gzip. Мне это не нравится, он вводит латентность, я надеюсь, что они исправят проблемы с GZIP в ближайшее время!