1

Для простоты предположим, что мое приложение должно позволить тысячам пользователей видеть поток в режиме реального времени только для чтения в чате. Хост может печатать сообщения, но ни один другой пользователь не может - они просто видят, что набирают хосты, в режиме реального времени. Представьте, что пользователи следуют текстовой игре по спортивному событию.Как передавать данные во все экземпляры Google App Engine?

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

Учитывая, что это приложение используется многими тысячами пользователей одновременно, что означает, что работают десятки до сотен экземпляров GAE, как я могу получить эти /get-recent-messages звонки, чтобы возвращать последние сообщения в чат-комнате с задержкой менее 1000 мс, минимизируя нагрузку на сервер и затраты на GAE?

Некоторые идеи, которые я имел:

  1. сообщения магазин чат в хранилище данных лиц.
    • Очевидно, что это слишком медленно и дорого, особенно при использовании запросов/индексы
  2. магазин сообщения чата в Memcache ключей. Думаю, я бы использовал один ключ для хранения списка ключей для последних 50 сообщений, а затем еще 50 ключей, по одному для каждого сообщения.
    • Это вызовет огромные узкие места, поскольку черепашка Memcache App Engine будет чередоваться по ключу, и, следовательно, все 500 экземпляров будут постоянно считывать из тех же ключей memcache и, таким образом, одного и того же сервера memcache.
  3. Хранить сообщения чата в памяти экземпляра, поддерживаемые memcache. И вытащите из memcache (как в # 2), когда память экземпляра устарела.
    • Это может привести к дорогостоящему состоянию гонки, когда несколько запросов видят устаревший кеш памяти экземпляра и одновременно извлекают из memcache.
  4. Используйте фоновый поток для обновления памяти экземпляра из memcache. Это может выполняться один раз в секунду для каждого экземпляра, используя поток, запущенный в запросе на разминку. Он будет работать как # 3, но только с одним потоком, вместо случайных запросов, запускающих считывание memcache.
    • Я не думаю, что это то, как фоновые потоки работают на App Engine. Я также не знаю, подходит ли это использование запросов на разминку.
  5. Использование Google's Pub/Sub service.
    • Я понятия не имею, как это работает, и кажется, что это может быть излишним для этого прецедента.
  6. Запустите однократное задание cron, чтобы извлечь из memcache. Это было бы как # 4, за исключением того, что он не полагался на потоки фона.
    • мне нужно это, чтобы работать на каждый экземпляр каждый второй. Я не верю, что API cron/taskqueue имеет способ запустить задание или задачу во всех активных экземплярах.

Мысли?

+0

Если вы действительно попали в пределы, описанные в https://cloud.google.com/appengine/articles/best-practices-for-app-engine-memcache#distribute_load_across_the_keyspace, вы могли бы сделать что-то простое, как использование двух проектов движка приложений и балансировщик нагрузки. Я бы начал с стандартного подхода с хранилищем данных и memcache и посмотреть, как далеко это меня достает. – konqi

+0

Моя первая мысль, когда я прочитал вопрос, был Cloud Pub/Sub, но я недостаточно осведомлен об этом, чтобы быть уверенным. Не зная больше о вашем приложении, я хотел бы сначала начать с datastore + memcache. Вы не говорите, как часто каждый чат будет публиковать новые сообщения, поэтому я не уверен, что хранилище данных будет «слишком медленным» (вы не говорите, если вам нужна сильная консистенция здесь). Вы можете использовать memcache как свой первый порт захода и агрегировать свои записи в хранилище данных, используя очередь для повышения устойчивости. – tx802

+0

@konqi Меня не беспокоят ограничения. Просто беспокоился о стоимости. – Keith

ответ

2

Вы должны проверить this video. Я бы выбрал версию memcache/datastore и небольшой объем кеша (1-2 секунды), чтобы уменьшить количество экземпляров, необходимых для обслуживания трафика. Если вам все еще нужно как 100-500 экземпляров для обслуживания вашего трафика, я все равно буду искать версию memcache/datastore. Если memcache является узким местом для вас, оставьте его как 10 ключей.

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

Если вам действительно нужно сообщить всем экземплярам, ​​посмотрите на communicating between modules

Паб/к югу может быть аа хороший вариант для вас, чтобы общаться между экземпляром, который публикует новые сообщения и экземпляры, которые читают новый Сообщения. Из того, что я прочитал в docs, вы можете подписаться на своих пользователей непосредственно в Pub/Sub тоже (pull only tho).

+0

pub/sub не гарантирует порядок сообщений –