Веб-сайты Azure и веб-приложение с отслеживанием состояния

У меня есть наивная версия PokerApp, работающая как веб-сайт Azure.

Сервер хранит в своей памяти состояние столов (чей сейчас ход, значение блайндов, карты…) и т.д.

Проблема здесь в том, что я не знаю, насколько я могу полагаться на то, что память веб-сервера будет «постоянной». Простой перезапуск сервера приведет к потере этой памяти, и, следовательно, все игры, запущенные до перезапуска, будут потеряны / вызовут проблемы.

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


Это очень приблизительно структура объекта, который у меня есть в памяти.

введите здесь описание изображения


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

Должен ли я рассмотреть лазурную виртуальную машину, которая, как я надеюсь, будет иметь постоянную память вместо веб-сайта? Или есть лучший подход для достижения чего-то подобного?


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

Однако мне приходят в голову два вопроса, и как только вы прольете свет на них, я обещаю, что заткнусь и приму отличный ответ @astaykov.

СОВМЕСТНОСТЬ НА УРОВНЕ ЭКЗЕМПЛЯРА. У меня есть классические блокировки потоков в моем приложении, чтобы избежать проблем с параллелизмом, поэтому я надеюсь, что есть что-то эквивалентное для тех служб кэширования, которые вы, ребята, предлагаете?

Кроме того, у меня есть несколько тайм-аутов за столом (увеличение блайндов, количество секунд, в течение которых игроки должны действовать…). Допустим, пользователь только что сбросил карты, он закончил взаимодействие с объектом состояния, поэтому я обновляю кеш. Пока этот объект состояния (к которому принадлежат таймеры) кэшируется, мои таймеры перестают тикать…
Я знаю, что не очень хорошо объясняю здесь свои мысли, но надеюсь, вы, ребята, понимаете мою точку зрения.


person Ruben Serrate    schedule 28.09.2014    source источник
comment
Боюсь, вопрос слишком широк. Если вы просмотрите любое из руководств, вы быстро узнаете, что таблицы Azure не только хранят строки, но и могут хранить объекты. Однако я не думаю, что Azure Tables — лучший вариант для ваших целей. Вы можете прочитать о Redis (доступном в Azure) для краткосрочного сохранения в памяти.   -  person trailmax    schedule 29.09.2014
comment
Что произойдет в вашем текущем дизайне со всем, что находится в памяти, если произойдет сброс AppPool или вы выполните новое развертывание? Все потеряно?   -  person Craig    schedule 29.09.2014
comment
@Крейг Да, все потеряно :/   -  person Ruben Serrate    schedule 29.09.2014
comment
Кажется, самое простое решение: а) сделать объект в памяти сериализуемым б) сохранить его в хранилище больших двоичных объектов.   -  person Craig    schedule 29.09.2014
comment
@Craig Хм, но тогда каждый раз, когда игрок что-то делает, мне нужно десериализовать, обновить, а затем сериализовать и снова написать ... насколько это эффективно?   -  person Ruben Serrate    schedule 29.09.2014
comment
Невозможно сказать, не зная приложения или структуры данных. Вы можете использовать хранилище в памяти (или распределенный кеш, например Redis) для повышения производительности, а затем хранилище BLOB-объектов для постоянного хранения — гибридный подход. Но на самом деле нужно видеть, как объекты сохраняются.   -  person Craig    schedule 29.09.2014
comment
@Craig Я обновил вопрос, добавив подробное описание объекта, который мне нужно сохранить в памяти.   -  person Ruben Serrate    schedule 29.09.2014
comment
@RubenSerrate Я думаю, что вопрос достаточно разошелся, поэтому пришло время открыть новый вопрос :)   -  person Zain Rizvi    schedule 30.09.2014


Ответы (1)


Я бы предложил использовать Кэш Azure Redis.

Вот хороший пример того, как за 15 минут создать приложение MVC с Redis Cache.

Конечно, вы можете использовать управляемый кэш Azure. Или используйте Azure Tables. А таблицы Azure могут содержать гораздо больше, чем просто строку. Но я считаю, что решения для кэширования будут иметь меньшую задержку при обмене данными.

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

ОБНОВЛЕНИЕ

Когда вы запрашиваете виртуальную машину, работающую в облаке, виртуальная машина будет перезапущена рано или поздно! Пул приложений будет перезапущен, произойдет плановое обслуживание, произойдет внеплановое обслуживание, выйдет из строя жесткий диск, выйдет из строя модуль памяти, произойдет непредвиденная катастрофа.

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

Второе обновление — для часов

Что ж, придется поиграть со своим воображением и опытом. Я бы усомнился в том, что ваши часы все равно работают в контексте приложения ASP.NET (если только все они не являются статическими свойствами статического типа, что было бы немного адом). Мой подход также будет сильно расширять мое приложение для клиента (JavaScript). Существует множество отличных фреймворков — SignalR, AngularJS, KnockoutJS, ни один из них нельзя недооценивать! Расширяя свою объектную модель до клиента, вы можете поддерживать время жизни объектов игроков на клиенте (поддерживая тиканье часов) и отправляя обновления с клиента на сервер для всех этих событий. Если вы посмотрите на SignalR, вы можете поддерживать связь в реальном времени между несколькими клиентами (скажем, игроками) и сервером. А серверная часть SignalR прекрасно масштабируется с помощью Azure Service Bus. и даже Redis.

person astaykov    schedule 29.09.2014
comment
Большое спасибо, я посмотрю на это, но, как я сказал в своем обновленном вопросе, рассматриваемый объект довольно большой и очень часто обновляется ... вы все еще думаете, что сериализация/десериализация будет работать? - person Ruben Serrate; 29.09.2014
comment
у вас нет другой альтернативы, чем удаление этого объекта из локальной памяти. И это включает сериализацию. Теперь об оптимизации - вы, вероятно, могли бы оптимизировать для повышения производительности, если считаете, что вам это нужно. - person astaykov; 29.09.2014
comment
А как насчет ВМ? Если у меня есть достаточно мощный, чтобы мне не нужно было масштабироваться, в этом случае Azure никогда не сбросит память моего сервера, не так ли? - person Ruben Serrate; 29.09.2014
comment
Этот ответ на месте. Если вы собираетесь запускать веб-приложение с отслеживанием состояния в облаке, будь то на виртуальной машине PaaS или IaaS, вам действительно нужно переместить состояние из памяти. - person BenV; 29.09.2014
comment
@RubenSerrate плохие вещи всегда могут случиться с вашей виртуальной машиной. Как сказал Астайков, жесткие диски могут выйти из строя, машины могут выйти из строя, кто-то может споткнуться о кабель Ethernet. Облачные службы всегда должны проектироваться таким образом, чтобы в случае выхода из строя одной машины остальная часть службы могла продолжать работать до тех пор, пока не будет подключена замена. - person Zain Rizvi; 30.09.2014
comment
@BenV, ZainRizvi, astaykob - Большое спасибо, ребята, теперь я понимаю, что не могу доверять локальной памяти :) Однако я обновил свой вопрос в последний раз .. ха-ха! - person Ruben Serrate; 30.09.2014