#python #google-app-engine #google-cloud-datastore #app-engine-ndb
#python #google-app-engine #google-облако-хранилище данных #app-engine-ndb
Вопрос:
У меня есть игра, в которой пользователи связываются с сервером, чтобы найти пользователя своего уровня, который хочет сыграть в игру. Вот базовая архитектура игрового запроса.
Я использую ndb
для хранения очереди ожидания для каждого уровня пользователя в хранилище данных Google.
Я получаю доступ к этим очередям по их ключам, чтобы обеспечить строгую согласованность (согласно этой статье). Объекты хранятся в очереди с использованием повторяющегося (списка) LocalStructuredProperty .
Вопросы:
- Объект удаляется из очереди ожидания, поскольку он соответствует запросу. Транзакция зафиксирована, но еще не применена. Тот же объект сопоставляется с другим запросом и удаляется. Будет ли это выдавать ошибку?
- Эти строго согласованные обращения ограничены ~ 1 записью в секунду. Существует ли лучшая архитектура, которая устранила бы это ограничение?
Одна вещь, которую я рассмотрел для последнего вопроса, заключается в поддержании нескольких очередей (число которых растет и уменьшается в зависимости от спроса).
Ответ №1:
Не уверен в вашем первом вопросе, но вы могли бы смоделировать его с помощью инструкции sleep в вашей транзакции.
Для вашего второго вопроса существует другая архитектура, которую вы могли бы использовать. Если продолжительность очереди ожидания относительно невелика (минуты вместо часов), вы можете захотеть использовать memcache. Это будет намного быстрее, чем запись на диск, и вы сможете избежать проблем с согласованностью.
Комментарии:
1. Да, надеялся, что кто-то знает теорию :). Беспокоился о том, что memcache будет удален . Есть идеи, как часто это происходит?
2. Я не знаю, как часто удаляется memcache, я понимаю, что это зависит от общей нагрузки / спроса на memcache (включая других пользователей). Вы можете управлять этим, записывая как в NDB, так и в memcache. Если у вашей очереди нет предков в ключе, вы не должны быть ограничены ограничением 1 запись / сек, оно применяется только к родительским ключам.
Ответ №2:
1. — Если вы выполняете объект get и post внутри транзакции, то один и тот же объект не может быть сопоставлен для игры и, следовательно, ошибки нет, и он остается согласованным.
2. — 1 запись в секунду — это ограничение для транзакций внутри одной и той же группы объектов. Если вам нужно больше, вы можете разделить объект очереди.
Вы можете использовать выделенный memcache или экземпляр redis, чтобы избежать конфликтов. Это намного быстрее, чем хранилище данных.
Посмотрите, как эти ребята используют узлы дерева для сопоставления: https://www.youtube.com/watch?v=9nWyWwY2Onc
Комментарии:
1. Беспокоился о том, что memcache будет удален . Есть идеи, как часто это происходит?
2. Система подбора партнеров в этом видео (с использованием наборов уровней игроков) выглядит аналогично тому, что предлагается в вопросе (разные очереди для каждого уровня). Есть ли что-то, чего мне не хватает?
3. Memcache удаляет ключи по мере заполнения. Вы не сможете контролировать это, если не заплатите за выделенный сервер только для себя.
4. система в видео отличается тем, что она не использует повторяющиеся свойства для хранения фактических очередей.
5. По моему опыту, оплата за выделенный memcache приведет к тому, что будет удалено гораздо меньше предметов